< prev index next >

src/cpu/x86/vm/templateInterpreter_x86_64.cpp

Print this page




 773   //   G1 pre-barrier code is executed when the current method is
 774   //   Reference.get() then going through the normal method entry
 775   //   will be fine.
 776   // * The G1 code can, however, check the receiver object (the instance
 777   //   of java.lang.Reference) and jump to the slow path if null. If the
 778   //   Reference object is null then we obviously cannot fetch the referent
 779   //   and so we don't need to call the G1 pre-barrier. Thus we can use the
 780   //   regular method entry code to generate the NPE.
 781   //
 782   // This code is based on generate_accessor_enty.
 783   //
 784   // rbx: Method*
 785 
 786   // r13: senderSP must preserve for slow path, set SP to it on fast path
 787 
 788   address entry = __ pc();
 789 
 790   const int referent_offset = java_lang_ref_Reference::referent_offset;
 791   guarantee(referent_offset > 0, "referent offset not initialized");
 792 
 793   if (UseG1GC) {
 794     Label slow_path;
 795     // rbx: method
 796 
 797     // Check if local 0 != NULL
 798     // If the receiver is null then it is OK to jump to the slow path.
 799     __ movptr(rax, Address(rsp, wordSize));
 800 
 801     __ testptr(rax, rax);
 802     __ jcc(Assembler::zero, slow_path);
 803 
 804     // rax: local 0
 805     // rbx: method (but can be used as scratch now)
 806     // rdx: scratch
 807     // rdi: scratch
 808 
 809     // Generate the G1 pre-barrier code to log the value of
 810     // the referent field in an SATB buffer.
 811 
 812     // Load the value of the referent field.
 813     const Address field_address(rax, referent_offset);
 814     __ load_heap_oop(rax, field_address);
 815 
 816     // Generate the G1 pre-barrier code to log the value of
 817     // the referent field in an SATB buffer.


 818     __ g1_write_barrier_pre(noreg /* obj */,
 819                             rax /* pre_val */,
 820                             r15_thread /* thread */,
 821                             rbx /* tmp */,
 822                             true /* tosca_live */,
 823                             true /* expand_call */);


 824 
 825     // _areturn
 826     __ pop(rdi);                // get return address
 827     __ mov(rsp, r13);           // set sp to sender sp
 828     __ jmp(rdi);
 829     __ ret(0);
 830 
 831     // generate a vanilla interpreter entry as the slow path
 832     __ bind(slow_path);
 833     (void) generate_normal_entry(false);
 834 
 835     return entry;
 836   }
 837 #endif // INCLUDE_ALL_GCS
 838 
 839   // If G1 is not enabled then attempt to go through the accessor entry point
 840   // Reference.get is an accessor
 841   return generate_accessor_entry();
 842 }
 843 




 773   //   G1 pre-barrier code is executed when the current method is
 774   //   Reference.get() then going through the normal method entry
 775   //   will be fine.
 776   // * The G1 code can, however, check the receiver object (the instance
 777   //   of java.lang.Reference) and jump to the slow path if null. If the
 778   //   Reference object is null then we obviously cannot fetch the referent
 779   //   and so we don't need to call the G1 pre-barrier. Thus we can use the
 780   //   regular method entry code to generate the NPE.
 781   //
 782   // This code is based on generate_accessor_enty.
 783   //
 784   // rbx: Method*
 785 
 786   // r13: senderSP must preserve for slow path, set SP to it on fast path
 787 
 788   address entry = __ pc();
 789 
 790   const int referent_offset = java_lang_ref_Reference::referent_offset;
 791   guarantee(referent_offset > 0, "referent offset not initialized");
 792 
 793   if (UseG1GC || UseShenandoahGC) {
 794     Label slow_path;
 795     // rbx: method
 796 
 797     // Check if local 0 != NULL
 798     // If the receiver is null then it is OK to jump to the slow path.
 799     __ movptr(rax, Address(rsp, wordSize));
 800 
 801     __ testptr(rax, rax);
 802     __ jcc(Assembler::zero, slow_path);
 803 
 804     // rax: local 0
 805     // rbx: method (but can be used as scratch now)
 806     // rdx: scratch
 807     // rdi: scratch
 808 
 809     // Generate the G1 pre-barrier code to log the value of
 810     // the referent field in an SATB buffer.
 811 
 812     // Load the value of the referent field.
 813     const Address field_address(rax, referent_offset);
 814     __ load_heap_oop(rax, field_address);
 815 
 816     // Generate the G1 pre-barrier code to log the value of
 817     // the referent field in an SATB buffer.
 818     if (!UseShenandoahGC || ShenandoahSATBBarrier) {
 819       if (UseShenandoahGC) __ push_IU_state();
 820     __ g1_write_barrier_pre(noreg /* obj */,
 821                             rax /* pre_val */,
 822                             r15_thread /* thread */,
 823                             rbx /* tmp */,
 824                             true /* tosca_live */,
 825                             true /* expand_call */);
 826       if (UseShenandoahGC) __ pop_IU_state();
 827     }
 828 
 829     // _areturn
 830     __ pop(rdi);                // get return address
 831     __ mov(rsp, r13);           // set sp to sender sp
 832     __ jmp(rdi);
 833     __ ret(0);
 834 
 835     // generate a vanilla interpreter entry as the slow path
 836     __ bind(slow_path);
 837     (void) generate_normal_entry(false);
 838 
 839     return entry;
 840   }
 841 #endif // INCLUDE_ALL_GCS
 842 
 843   // If G1 is not enabled then attempt to go through the accessor entry point
 844   // Reference.get is an accessor
 845   return generate_accessor_entry();
 846 }
 847 


< prev index next >