hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
changeset 9179 6db9c9dffe1f
parent 8883 5569135acca3
parent 9176 42d9d1010f38
child 9636 363ca5579aff
equal deleted inserted replaced
8932:a676b28e2093 9179:6db9c9dffe1f
   755   }
   755   }
   756 
   756 
   757   return entry_point;
   757   return entry_point;
   758 }
   758 }
   759 
   759 
       
   760 // Method entry for java.lang.ref.Reference.get.
       
   761 address InterpreterGenerator::generate_Reference_get_entry(void) {
       
   762 #ifndef SERIALGC
       
   763   // Code: _aload_0, _getfield, _areturn
       
   764   // parameter size = 1
       
   765   //
       
   766   // The code that gets generated by this routine is split into 2 parts:
       
   767   //    1. The "intrinsified" code for G1 (or any SATB based GC),
       
   768   //    2. The slow path - which is an expansion of the regular method entry.
       
   769   //
       
   770   // Notes:-
       
   771   // * In the G1 code we do not check whether we need to block for
       
   772   //   a safepoint. If G1 is enabled then we must execute the specialized
       
   773   //   code for Reference.get (except when the Reference object is null)
       
   774   //   so that we can log the value in the referent field with an SATB
       
   775   //   update buffer.
       
   776   //   If the code for the getfield template is modified so that the
       
   777   //   G1 pre-barrier code is executed when the current method is
       
   778   //   Reference.get() then going through the normal method entry
       
   779   //   will be fine.
       
   780   // * The G1 code can, however, check the receiver object (the instance
       
   781   //   of java.lang.Reference) and jump to the slow path if null. If the
       
   782   //   Reference object is null then we obviously cannot fetch the referent
       
   783   //   and so we don't need to call the G1 pre-barrier. Thus we can use the
       
   784   //   regular method entry code to generate the NPE.
       
   785   //
       
   786   // This code is based on generate_accessor_enty.
       
   787   //
       
   788   // rbx: methodOop
       
   789 
       
   790   // r13: senderSP must preserve for slow path, set SP to it on fast path
       
   791 
       
   792   address entry = __ pc();
       
   793 
       
   794   const int referent_offset = java_lang_ref_Reference::referent_offset;
       
   795   guarantee(referent_offset > 0, "referent offset not initialized");
       
   796 
       
   797   if (UseG1GC) {
       
   798     Label slow_path;
       
   799     // rbx: method
       
   800 
       
   801     // Check if local 0 != NULL
       
   802     // If the receiver is null then it is OK to jump to the slow path.
       
   803     __ movptr(rax, Address(rsp, wordSize));
       
   804 
       
   805     __ testptr(rax, rax);
       
   806     __ jcc(Assembler::zero, slow_path);
       
   807 
       
   808     // rax: local 0
       
   809     // rbx: method (but can be used as scratch now)
       
   810     // rdx: scratch
       
   811     // rdi: scratch
       
   812 
       
   813     // Generate the G1 pre-barrier code to log the value of
       
   814     // the referent field in an SATB buffer.
       
   815 
       
   816     // Load the value of the referent field.
       
   817     const Address field_address(rax, referent_offset);
       
   818     __ load_heap_oop(rax, field_address);
       
   819 
       
   820     // Generate the G1 pre-barrier code to log the value of
       
   821     // the referent field in an SATB buffer.
       
   822     __ g1_write_barrier_pre(noreg /* obj */,
       
   823                             rax /* pre_val */,
       
   824                             r15_thread /* thread */,
       
   825                             rbx /* tmp */,
       
   826                             true /* tosca_live */,
       
   827                             true /* expand_call */);
       
   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 // SERIALGC
       
   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 
       
   848 
   760 // Interpreter stub for calling a native method. (asm interpreter)
   849 // Interpreter stub for calling a native method. (asm interpreter)
   761 // This sets up a somewhat different looking stack for calling the
   850 // This sets up a somewhat different looking stack for calling the
   762 // native method than the typical interpreter frame setup.
   851 // native method than the typical interpreter frame setup.
   763 address InterpreterGenerator::generate_native_entry(bool synchronized) {
   852 address InterpreterGenerator::generate_native_entry(bool synchronized) {
   764   // determine code generation flags
   853   // determine code generation flags
  1461   case Interpreter::java_lang_math_tan     : // fall thru
  1550   case Interpreter::java_lang_math_tan     : // fall thru
  1462   case Interpreter::java_lang_math_abs     : // fall thru
  1551   case Interpreter::java_lang_math_abs     : // fall thru
  1463   case Interpreter::java_lang_math_log     : // fall thru
  1552   case Interpreter::java_lang_math_log     : // fall thru
  1464   case Interpreter::java_lang_math_log10   : // fall thru
  1553   case Interpreter::java_lang_math_log10   : // fall thru
  1465   case Interpreter::java_lang_math_sqrt    : entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind);    break;
  1554   case Interpreter::java_lang_math_sqrt    : entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind);    break;
       
  1555   case Interpreter::java_lang_ref_reference_get
       
  1556                                            : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
  1466   default                                  : ShouldNotReachHere();                                                       break;
  1557   default                                  : ShouldNotReachHere();                                                       break;
  1467   }
  1558   }
  1468 
  1559 
  1469   if (entry_point) {
  1560   if (entry_point) {
  1470     return entry_point;
  1561     return entry_point;