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