< prev index next >

src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp

Print this page
rev 11775 : [backport] 8241700: Shenandoah: Fold ShenandoahKeepAliveBarrier flag into ShenandoahSATBBarrier
Reviewed-by: shade
rev 11831 : Merge

 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   }


< prev index next >