< prev index next >

src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp

Print this page
@@ -592,12 +592,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.
-     __ load_klass(r0, r0);  // get klass
-     __ cbz(r0, error);      // if klass is NULL it is broken
+     // 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)));

@@ -6642,10 +6652,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;
+   }
+ 
    address generate_cont_thaw(Continuation::thaw_kind kind) {
      bool return_barrier = Continuation::is_thaw_return_barrier(kind);
      bool return_barrier_exception = Continuation::is_thaw_return_barrier_exception(kind);
  
      address start = __ pc();

@@ -7809,10 +7842,12 @@
      }
  
      if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) {
        StubRoutines::_dcos = generate_dsin_dcos(/* isCos = */ true);
      }
+ 
+     StubRoutines::_load_nklass = generate_load_nklass();
    }
  
    void generate_phase1() {
      // Continuation stubs:
      StubRoutines::_cont_thaw          = generate_cont_thaw();
< prev index next >