676 // If the code for the getfield template is modified so that the
677 // G1 pre-barrier code is executed when the current method is
678 // Reference.get() then going through the normal method entry
679 // will be fine.
680 // * The G1 code can, however, check the receiver object (the instance
681 // of java.lang.Reference) and jump to the slow path if null. If the
682 // Reference object is null then we obviously cannot fetch the referent
683 // and so we don't need to call the G1 pre-barrier. Thus we can use the
684 // regular method entry code to generate the NPE.
685 //
686 // This code is based on generate_accessor_entry.
687 //
688 // rmethod: Method*
689 // r13: senderSP must preserve for slow path, set SP to it on fast path
690
691 address entry = __ pc();
692
693 const int referent_offset = java_lang_ref_Reference::referent_offset;
694 guarantee(referent_offset > 0, "referent offset not initialized");
695
696 if (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) {
697 Label slow_path;
698 const Register local_0 = c_rarg0;
699 // Check if local 0 != NULL
700 // If the receiver is null then it is OK to jump to the slow path.
701 __ ldr(local_0, Address(esp, 0));
702 __ mov(r19, r13); // First call-saved register
703 __ cbz(local_0, slow_path);
704
705 // Load the value of the referent field.
706 const Address field_address(local_0, referent_offset);
707 __ load_heap_oop(local_0, field_address);
708
709 __ mov(r19, r13); // Move senderSP to a callee-saved register
710 // Generate the G1 pre-barrier code to log the value of
711 // the referent field in an SATB buffer.
712 __ enter(); // g1_write may call runtime
713 __ g1_write_barrier_pre(noreg /* obj */,
714 local_0 /* pre_val */,
715 rthread /* thread */,
716 rscratch2 /* tmp */,
1173 // reset handle block
1174 __ ldr(t, Address(rthread, JavaThread::active_handles_offset()));
1175 __ str(zr, Address(t, JNIHandleBlock::top_offset_in_bytes()));
1176
1177 // If result is an oop unbox and store it in frame where gc will see it
1178 // and result handler will pick it up
1179
1180 {
1181 Label no_oop, not_weak, store_result;
1182 __ adr(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT)));
1183 __ cmp(t, result_handler);
1184 __ br(Assembler::NE, no_oop);
1185 // Unbox oop result, e.g. JNIHandles::resolve result.
1186 __ pop(ltos);
1187 __ cbz(r0, store_result); // Use NULL as-is.
1188 STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u);
1189 __ tbz(r0, 0, not_weak); // Test for jweak tag.
1190 // Resolve jweak.
1191 __ ldr(r0, Address(r0, -JNIHandles::weak_tag_value));
1192 #if INCLUDE_ALL_GCS
1193 if (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) {
1194 __ enter(); // Barrier may call runtime.
1195 __ g1_write_barrier_pre(noreg /* obj */,
1196 r0 /* pre_val */,
1197 rthread /* thread */,
1198 t /* tmp */,
1199 true /* tosca_live */,
1200 true /* expand_call */);
1201 __ leave();
1202 }
1203 #endif // INCLUDE_ALL_GCS
1204 __ b(store_result);
1205 __ bind(not_weak);
1206 // Resolve (untagged) jobject.
1207 __ ldr(r0, Address(r0, 0));
1208 __ bind(store_result);
1209 __ str(r0, Address(rfp, frame::interpreter_frame_oop_temp_offset*wordSize));
1210 // keep stack depth as expected by pushing oop which will eventually be discarded
1211 __ push(ltos);
1212 __ bind(no_oop);
1213 }
|
676 // If the code for the getfield template is modified so that the
677 // G1 pre-barrier code is executed when the current method is
678 // Reference.get() then going through the normal method entry
679 // will be fine.
680 // * The G1 code can, however, check the receiver object (the instance
681 // of java.lang.Reference) and jump to the slow path if null. If the
682 // Reference object is null then we obviously cannot fetch the referent
683 // and so we don't need to call the G1 pre-barrier. Thus we can use the
684 // regular method entry code to generate the NPE.
685 //
686 // This code is based on generate_accessor_entry.
687 //
688 // rmethod: Method*
689 // r13: senderSP must preserve for slow path, set SP to it on fast path
690
691 address entry = __ pc();
692
693 const int referent_offset = java_lang_ref_Reference::referent_offset;
694 guarantee(referent_offset > 0, "referent offset not initialized");
695
696 if (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) {
697 Label slow_path;
698 const Register local_0 = c_rarg0;
699 // Check if local 0 != NULL
700 // If the receiver is null then it is OK to jump to the slow path.
701 __ ldr(local_0, Address(esp, 0));
702 __ mov(r19, r13); // First call-saved register
703 __ cbz(local_0, slow_path);
704
705 // Load the value of the referent field.
706 const Address field_address(local_0, referent_offset);
707 __ load_heap_oop(local_0, field_address);
708
709 __ mov(r19, r13); // Move senderSP to a callee-saved register
710 // Generate the G1 pre-barrier code to log the value of
711 // the referent field in an SATB buffer.
712 __ enter(); // g1_write may call runtime
713 __ g1_write_barrier_pre(noreg /* obj */,
714 local_0 /* pre_val */,
715 rthread /* thread */,
716 rscratch2 /* tmp */,
1173 // reset handle block
1174 __ ldr(t, Address(rthread, JavaThread::active_handles_offset()));
1175 __ str(zr, Address(t, JNIHandleBlock::top_offset_in_bytes()));
1176
1177 // If result is an oop unbox and store it in frame where gc will see it
1178 // and result handler will pick it up
1179
1180 {
1181 Label no_oop, not_weak, store_result;
1182 __ adr(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT)));
1183 __ cmp(t, result_handler);
1184 __ br(Assembler::NE, no_oop);
1185 // Unbox oop result, e.g. JNIHandles::resolve result.
1186 __ pop(ltos);
1187 __ cbz(r0, store_result); // Use NULL as-is.
1188 STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u);
1189 __ tbz(r0, 0, not_weak); // Test for jweak tag.
1190 // Resolve jweak.
1191 __ ldr(r0, Address(r0, -JNIHandles::weak_tag_value));
1192 #if INCLUDE_ALL_GCS
1193 if (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) {
1194 __ enter(); // Barrier may call runtime.
1195 __ g1_write_barrier_pre(noreg /* obj */,
1196 r0 /* pre_val */,
1197 rthread /* thread */,
1198 t /* tmp */,
1199 true /* tosca_live */,
1200 true /* expand_call */);
1201 __ leave();
1202 }
1203 #endif // INCLUDE_ALL_GCS
1204 __ b(store_result);
1205 __ bind(not_weak);
1206 // Resolve (untagged) jobject.
1207 __ ldr(r0, Address(r0, 0));
1208 __ bind(store_result);
1209 __ str(r0, Address(rfp, frame::interpreter_frame_oop_temp_offset*wordSize));
1210 // keep stack depth as expected by pushing oop which will eventually be discarded
1211 __ push(ltos);
1212 __ bind(no_oop);
1213 }
|