src/cpu/sparc/vm/templateInterpreter_sparc.cpp

Print this page
rev 2237 : [mq]: initial-intrinsification-changes
rev 2238 : [mq]: code-review-comments-vladimir


 746     __ cmp(G1_scratch, btos);
 747     __ br(Assembler::equal, true, Assembler::pt, xreturn_path);
 748     __ delayed()->ldsb(Otos_i, G3_scratch, Otos_i);
 749     __ should_not_reach_here();
 750 #endif
 751     __ ldsb(Otos_i, G3_scratch, Otos_i);
 752     __ bind(xreturn_path);
 753 
 754     // _ireturn/_areturn
 755     __ retl();                      // return from leaf routine
 756     __ delayed()->mov(O5_savedSP, SP);
 757 
 758     // Generate regular method entry
 759     __ bind(slow_path);
 760     (void) generate_normal_entry(false);
 761     return entry;
 762   }
 763   return NULL;
 764 }
 765 

















































































 766 //
 767 // Interpreter stub for calling a native method. (asm interpreter)
 768 // This sets up a somewhat different looking stack for calling the native method
 769 // than the typical interpreter frame setup.
 770 //
 771 
 772 address InterpreterGenerator::generate_native_entry(bool synchronized) {
 773   address entry = __ pc();
 774 
 775   // the following temporary registers are used during frame creation
 776   const Register Gtmp1 = G3_scratch ;
 777   const Register Gtmp2 = G1_scratch;
 778   bool inc_counter  = UseCompiler || CountCompiledCalls;
 779 
 780   // make sure registers are different!
 781   assert_different_registers(G2_thread, G5_method, Gargs, Gtmp1, Gtmp2);
 782 
 783   const Address Laccess_flags(Lmethod, methodOopDesc::access_flags_offset());
 784 
 785   __ verify_oop(G5_method);




 746     __ cmp(G1_scratch, btos);
 747     __ br(Assembler::equal, true, Assembler::pt, xreturn_path);
 748     __ delayed()->ldsb(Otos_i, G3_scratch, Otos_i);
 749     __ should_not_reach_here();
 750 #endif
 751     __ ldsb(Otos_i, G3_scratch, Otos_i);
 752     __ bind(xreturn_path);
 753 
 754     // _ireturn/_areturn
 755     __ retl();                      // return from leaf routine
 756     __ delayed()->mov(O5_savedSP, SP);
 757 
 758     // Generate regular method entry
 759     __ bind(slow_path);
 760     (void) generate_normal_entry(false);
 761     return entry;
 762   }
 763   return NULL;
 764 }
 765 
 766 // Method entry for java.lang.ref.Reference.get.
 767 address InterpreterGenerator::generate_Reference_get_entry(void) {
 768 #ifndef SERIALGC
 769   // Code: _aload_0, _getfield, _areturn
 770   // parameter size = 1
 771   //
 772   // The code that gets generated by this routine is split into 2 parts:
 773   //    1. The "intrinsified" code for G1 (or any SATB based GC),
 774   //    2. The slow path - which is an expansion of the regular method entry.
 775   //
 776   // Notes:-
 777   // * In the G1 code we do not check whether we need to block for
 778   //   a safepoint. If G1 is enabled then we must execute the specialized
 779   //   code for Reference.get (except when the Reference object is null)
 780   //   so that we can log the value in the referent field with an SATB
 781   //   update buffer.
 782   //   If the code for the getfield template is modified so that the
 783   //   G1 pre-barrier code is executed when the current method is
 784   //   Reference.get() then going through the normal method entry
 785   //   will be fine.
 786   // * The G1 code can, however, check the receiver object (the instance
 787   //   of java.lang.Reference) and jump to the slow path if null. If the
 788   //   Reference object is null then we obviously cannot fetch the referent
 789   //   and so we don't need to call the G1 pre-barrier. Thus we can use the
 790   //   regular method entry code to generate the NPE.
 791   //
 792   // This code is based on generate_accessor_enty.
 793 
 794   address entry = __ pc();
 795 
 796   const int referent_offset = java_lang_ref_Reference::referent_offset;
 797   guarantee(referent_offset > 0, "referent offset not initialized");
 798 
 799   if (UseG1GC) {
 800      Label slow_path;
 801 
 802     // In the G1 code we don't check if we need to reach a safepoint. We
 803     // continue and the thread will safepoint at the next bytecode dispatch.
 804 
 805     // Check if local 0 != NULL
 806     // If the receiver is null then it is OK to jump to the slow path.
 807     __ ld_ptr(Gargs, G0, Otos_i ); // get local 0
 808     __ tst(Otos_i);  // check if local 0 == NULL and go the slow path
 809     __ brx(Assembler::zero, false, Assembler::pn, slow_path);
 810     __ delayed()->nop();
 811 
 812 
 813     // Load the value of the referent field.
 814     if (Assembler::is_simm13(referent_offset)) {
 815       __ load_heap_oop(Otos_i, referent_offset, Otos_i);
 816     } else {
 817       __ set(referent_offset, G3_scratch);
 818       __ load_heap_oop(Otos_i, G3_scratch, Otos_i);
 819     }
 820 
 821     // Generate the G1 pre-barrier code to log the value of
 822     // the referent field in an SATB buffer. Note with
 823     // these parameters the pre-barrier does not generate
 824     // the load of the previous value
 825 
 826     __ g1_write_barrier_pre(noreg /* obj */, noreg /* index */, 0 /* offset */,
 827                             Otos_i /* pre_val */, 
 828                             G3_scratch /* tmp */,
 829                             true /* preserve_o_regs */);
 830 
 831     // _areturn
 832     __ retl();                      // return from leaf routine
 833     __ delayed()->mov(O5_savedSP, SP);
 834 
 835     // Generate regular method entry
 836     __ bind(slow_path);
 837     (void) generate_normal_entry(false);
 838     return entry;
 839   }
 840 #endif // SERIALGC
 841 
 842   // If G1 is not enabled then attempt to go through the accessor entry point
 843   // Reference.get is an accessor
 844   return generate_accessor_entry();
 845 }
 846 
 847 //
 848 // Interpreter stub for calling a native method. (asm interpreter)
 849 // This sets up a somewhat different looking stack for calling the native method
 850 // than the typical interpreter frame setup.
 851 //
 852 
 853 address InterpreterGenerator::generate_native_entry(bool synchronized) {
 854   address entry = __ pc();
 855 
 856   // the following temporary registers are used during frame creation
 857   const Register Gtmp1 = G3_scratch ;
 858   const Register Gtmp2 = G1_scratch;
 859   bool inc_counter  = UseCompiler || CountCompiledCalls;
 860 
 861   // make sure registers are different!
 862   assert_different_registers(G2_thread, G5_method, Gargs, Gtmp1, Gtmp2);
 863 
 864   const Address Laccess_flags(Lmethod, methodOopDesc::access_flags_offset());
 865 
 866   __ verify_oop(G5_method);