< prev index next > src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
Print this page
// 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)));
// 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)));
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
}
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 >