hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
changeset 9179 6db9c9dffe1f
parent 8883 5569135acca3
parent 9176 42d9d1010f38
child 9636 363ca5579aff
equal deleted inserted replaced
8932:a676b28e2093 9179:6db9c9dffe1f
   774   }
   774   }
   775   return NULL;
   775   return NULL;
   776 
   776 
   777 }
   777 }
   778 
   778 
       
   779 // Method entry for java.lang.ref.Reference.get.
       
   780 address InterpreterGenerator::generate_Reference_get_entry(void) {
       
   781 #ifndef SERIALGC
       
   782   // Code: _aload_0, _getfield, _areturn
       
   783   // parameter size = 1
       
   784   //
       
   785   // The code that gets generated by this routine is split into 2 parts:
       
   786   //    1. The "intrinsified" code for G1 (or any SATB based GC),
       
   787   //    2. The slow path - which is an expansion of the regular method entry.
       
   788   //
       
   789   // Notes:-
       
   790   // * In the G1 code we do not check whether we need to block for
       
   791   //   a safepoint. If G1 is enabled then we must execute the specialized
       
   792   //   code for Reference.get (except when the Reference object is null)
       
   793   //   so that we can log the value in the referent field with an SATB
       
   794   //   update buffer.
       
   795   //   If the code for the getfield template is modified so that the
       
   796   //   G1 pre-barrier code is executed when the current method is
       
   797   //   Reference.get() then going through the normal method entry
       
   798   //   will be fine.
       
   799   // * The G1 code below can, however, check the receiver object (the instance
       
   800   //   of java.lang.Reference) and jump to the slow path if null. If the
       
   801   //   Reference object is null then we obviously cannot fetch the referent
       
   802   //   and so we don't need to call the G1 pre-barrier. Thus we can use the
       
   803   //   regular method entry code to generate the NPE.
       
   804   //
       
   805   // This code is based on generate_accessor_enty.
       
   806 
       
   807   // rbx,: methodOop
       
   808   // rcx: receiver (preserve for slow entry into asm interpreter)
       
   809 
       
   810   // rsi: senderSP must preserved for slow path, set SP to it on fast path
       
   811 
       
   812   address entry = __ pc();
       
   813 
       
   814   const int referent_offset = java_lang_ref_Reference::referent_offset;
       
   815   guarantee(referent_offset > 0, "referent offset not initialized");
       
   816 
       
   817   if (UseG1GC) {
       
   818     Label slow_path;
       
   819 
       
   820     // Check if local 0 != NULL
       
   821     // If the receiver is null then it is OK to jump to the slow path.
       
   822     __ movptr(rax, Address(rsp, wordSize));
       
   823     __ testptr(rax, rax);
       
   824     __ jcc(Assembler::zero, slow_path);
       
   825 
       
   826     // rax: local 0 (must be preserved across the G1 barrier call)
       
   827     //
       
   828     // rbx: method (at this point it's scratch)
       
   829     // rcx: receiver (at this point it's scratch)
       
   830     // rdx: scratch
       
   831     // rdi: scratch
       
   832     //
       
   833     // rsi: sender sp
       
   834 
       
   835     // Preserve the sender sp in case the pre-barrier
       
   836     // calls the runtime
       
   837     __ push(rsi);
       
   838 
       
   839     // Load the value of the referent field.
       
   840     const Address field_address(rax, referent_offset);
       
   841     __ movptr(rax, field_address);
       
   842 
       
   843     // Generate the G1 pre-barrier code to log the value of
       
   844     // the referent field in an SATB buffer.
       
   845     __ get_thread(rcx);
       
   846     __ g1_write_barrier_pre(noreg /* obj */,
       
   847                             rax /* pre_val */,
       
   848                             rcx /* thread */,
       
   849                             rbx /* tmp */,
       
   850                             true /* tosca_save */,
       
   851                             true /* expand_call */);
       
   852 
       
   853     // _areturn
       
   854     __ pop(rsi);                // get sender sp
       
   855     __ pop(rdi);                // get return address
       
   856     __ mov(rsp, rsi);           // set sp to sender sp
       
   857     __ jmp(rdi);
       
   858 
       
   859     __ bind(slow_path);
       
   860     (void) generate_normal_entry(false);
       
   861 
       
   862     return entry;
       
   863   }
       
   864 #endif // SERIALGC
       
   865 
       
   866   // If G1 is not enabled then attempt to go through the accessor entry point
       
   867   // Reference.get is an accessor
       
   868   return generate_accessor_entry();
       
   869 }
       
   870 
   779 //
   871 //
   780 // Interpreter stub for calling a native method. (asm interpreter)
   872 // Interpreter stub for calling a native method. (asm interpreter)
   781 // This sets up a somewhat different looking stack for calling the native method
   873 // This sets up a somewhat different looking stack for calling the native method
   782 // than the typical interpreter frame setup.
   874 // than the typical interpreter frame setup.
   783 //
   875 //
  1442     case Interpreter::java_lang_math_tan     : // fall thru
  1534     case Interpreter::java_lang_math_tan     : // fall thru
  1443     case Interpreter::java_lang_math_abs     : // fall thru
  1535     case Interpreter::java_lang_math_abs     : // fall thru
  1444     case Interpreter::java_lang_math_log     : // fall thru
  1536     case Interpreter::java_lang_math_log     : // fall thru
  1445     case Interpreter::java_lang_math_log10   : // fall thru
  1537     case Interpreter::java_lang_math_log10   : // fall thru
  1446     case Interpreter::java_lang_math_sqrt    : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind);     break;
  1538     case Interpreter::java_lang_math_sqrt    : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind);     break;
       
  1539     case Interpreter::java_lang_ref_reference_get
       
  1540                                              : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
  1447     default                                  : ShouldNotReachHere();                                                       break;
  1541     default                                  : ShouldNotReachHere();                                                       break;
  1448   }
  1542   }
  1449 
  1543 
  1450   if (entry_point) return entry_point;
  1544   if (entry_point) return entry_point;
  1451 
  1545