< prev index next >

src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp

Print this page
*** 583,12 ***
      // instruction here because the flags register is live.
      __ eor(c_rarg2, c_rarg2, c_rarg3);
      __ cbnz(c_rarg2, error);
  
      // make sure klass is 'reasonable', which is not zero.
!     __ load_klass(r0, r0);  // get klass
!     __ cbz(r0, error);      // if klass is NULL it is broken
  
      // return if everything seems ok
      __ bind(exit);
  
      __ ldp(c_rarg3, c_rarg2, Address(__ post(sp, 16)));
--- 583,22 ---
      // instruction here because the flags register is live.
      __ eor(c_rarg2, c_rarg2, c_rarg3);
      __ cbnz(c_rarg2, error);
  
      // make sure klass is 'reasonable', which is not zero.
!     // NOTE: We used to load the Klass* here, and compare that to zero.
!     // However, with current Lilliput implementation, that would require
+     // checking the locking bits and calling into the runtime, which
+     // clobbers the condition flags, which may be live around this call.
+     // OTOH, this is a simple NULL-check, and we can simply load the upper
+     // 32bit of the header as narrowKlass, and compare that to 0. The
+     // worst that can happen (rarely) is that the object is locked and
+     // we have lock pointer bits in the upper 32bits. We can't get a false
+     // negative.
+     assert(oopDesc::klass_offset_in_bytes() % 4 == 0, "must be 4 byte aligned");
+     __ ldrw(r0, Address(r0, oopDesc::klass_offset_in_bytes()));  // get klass
+     __ cbzw(r0, error);      // if klass is NULL it is broken
  
      // return if everything seems ok
      __ bind(exit);
  
      __ ldp(c_rarg3, c_rarg2, Address(__ post(sp, 16)));

*** 6464,10 ***
--- 6474,33 ---
  
      ICache::invalidate_range(first_entry, __ pc() - first_entry);
    }
  #endif // LINUX
  
+   // Pass object argument in r0 (which has to be preserved outside this stub)
+   // Pass back result in r0
+   // Clobbers rscratch1
+   address generate_load_nklass() {
+     __ align(CodeEntryAlignment);
+     StubCodeMark mark(this, "StubRoutines", "load_nklass");
+ 
+     address start = __ pc();
+ 
+     __ set_last_Java_frame(sp, rfp, lr, rscratch1);
+     __ enter();
+     __ push(RegSet::of(rscratch1, rscratch2), sp);
+     __ push_call_clobbered_registers_except(r0);
+     __ call_VM_leaf(CAST_FROM_FN_PTR(address, oopDesc::load_nklass_runtime), 1);
+     __ pop_call_clobbered_registers_except(r0);
+     __ pop(RegSet::of(rscratch1, rscratch2), sp);
+     __ leave();
+     __ reset_last_Java_frame(true);
+     __ ret(lr);
+ 
+     return start;
+   }
+ 
    // Continuation point for throwing of implicit exceptions that are
    // not handled in the current activation. Fabricates an exception
    // oop and initiates normal exception dispatching in this
    // frame. Since we need to preserve callee-saved values (currently
    // only for C2, but done for C1 as well) we need a callee-saved oop

*** 7446,10 ***
--- 7479,12 ---
      }
  
      if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) {
        StubRoutines::_dcos = generate_dsin_dcos(/* isCos = */ true);
      }
+ 
+     StubRoutines::_load_nklass = generate_load_nklass();
    }
  
    void generate_all() {
      // support for verify_oop (must happen after universe_init)
      if (VerifyOops) {
< prev index next >