< prev index next >

src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp

Print this page
rev 50073 : [mq]: cont


  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "asm/macroAssembler.hpp"
  27 #include "gc/shared/barrierSetAssembler.hpp"
  28 #include "interpreter/bytecodeHistogram.hpp"
  29 #include "interpreter/interp_masm.hpp"
  30 #include "interpreter/interpreter.hpp"
  31 #include "interpreter/interpreterRuntime.hpp"
  32 #include "interpreter/templateInterpreterGenerator.hpp"
  33 #include "interpreter/templateTable.hpp"
  34 #include "oops/arrayOop.hpp"
  35 #include "oops/methodData.hpp"
  36 #include "oops/method.hpp"
  37 #include "oops/oop.inline.hpp"
  38 #include "prims/jvmtiExport.hpp"
  39 #include "prims/jvmtiThreadState.hpp"
  40 #include "runtime/arguments.hpp"

  41 #include "runtime/deoptimization.hpp"
  42 #include "runtime/frame.inline.hpp"
  43 #include "runtime/sharedRuntime.hpp"
  44 #include "runtime/stubRoutines.hpp"
  45 #include "runtime/synchronizer.hpp"
  46 #include "runtime/timer.hpp"
  47 #include "runtime/vframeArray.hpp"
  48 #include "utilities/debug.hpp"
  49 #include "utilities/macros.hpp"
  50 
  51 #define __ _masm->
  52 
  53 // Size of interpreter code.  Increase if too small.  Interpreter will
  54 // fail with a guarantee ("not enough space for interpreter generation");
  55 // if too small.
  56 // Run with +PrintInterpreter to get the VM to print out the size.
  57 // Max size with JVMTI
  58 #ifdef AMD64
  59 int TemplateInterpreter::InterpreterCodeSize = JVMCI_ONLY(268) NOT_JVMCI(256) * 1024;
  60 #else


 156   __ empty_expression_stack();
 157   // setup parameters
 158   __ lea(rarg, ExternalAddress((address)name));
 159   if (pass_oop) {
 160     __ call_VM(rax, CAST_FROM_FN_PTR(address,
 161                                      InterpreterRuntime::
 162                                      create_klass_exception),
 163                rarg, rarg2);
 164   } else {
 165     __ lea(rarg2, ExternalAddress((address)message));
 166     __ call_VM(rax,
 167                CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception),
 168                rarg, rarg2);
 169   }
 170   // throw exception
 171   __ jump(ExternalAddress(Interpreter::throw_exception_entry()));
 172   return entry;
 173 }
 174 
 175 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) {




 176   address entry = __ pc();
 177 

 178 #ifndef _LP64
 179 #ifdef COMPILER2
 180   // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases
 181   if ((state == ftos && UseSSE < 1) || (state == dtos && UseSSE < 2)) {
 182     for (int i = 1; i < 8; i++) {
 183         __ ffree(i);
 184     }
 185   } else if (UseSSE < 2) {
 186     __ empty_FPU_stack();
 187   }
 188 #endif // COMPILER2
 189   if ((state == ftos && UseSSE < 1) || (state == dtos && UseSSE < 2)) {
 190     __ MacroAssembler::verify_FPU(1, "generate_return_entry_for compiled");
 191   } else {
 192     __ MacroAssembler::verify_FPU(0, "generate_return_entry_for compiled");
 193   }
 194 
 195   if (state == ftos) {
 196     __ MacroAssembler::verify_FPU(UseSSE >= 1 ? 0 : 1, "generate_return_entry_for in interpreter");
 197   } else if (state == dtos) {
 198     __ MacroAssembler::verify_FPU(UseSSE >= 2 ? 0 : 1, "generate_return_entry_for in interpreter");
 199   }
 200 #endif // _LP64
 201 


 202   // Restore stack bottom in case i2c adjusted stack
 203   __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
 204   // and NULL it as marker that esp is now tos until next java call
 205   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
 206 


 207   __ restore_bcp();
 208   __ restore_locals();
 209 


 210   if (state == atos) {
 211     Register mdp = rbx;
 212     Register tmp = rcx;
 213     __ profile_return_type(mdp, rax, tmp);
 214   }
 215 
 216   const Register cache = rbx;
 217   const Register index = rcx;
 218   __ get_cache_and_index_at_bcp(cache, index, 1, index_size);
 219 
 220   const Register flags = cache;
 221   __ movl(flags, Address(cache, index, Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
 222   __ andl(flags, ConstantPoolCacheEntry::parameter_size_mask);
 223   __ lea(rsp, Address(rsp, flags, Interpreter::stackElementScale()));
 224 
 225    const Register java_thread = NOT_LP64(rcx) LP64_ONLY(r15_thread);
 226    if (JvmtiExport::can_pop_frame()) {
 227      NOT_LP64(__ get_thread(java_thread));
 228      __ check_and_handle_popframe(java_thread);
 229    }
 230    if (JvmtiExport::can_force_early_return()) {
 231      NOT_LP64(__ get_thread(java_thread));
 232      __ check_and_handle_earlyret(java_thread);
 233    }
 234 


 235   __ dispatch_next(state, step);
 236 
 237   return entry;
 238 }
 239 
 240 
 241 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step, address continuation) {
 242   address entry = __ pc();
 243 
 244 #ifndef _LP64
 245   if (state == ftos) {
 246     __ MacroAssembler::verify_FPU(UseSSE >= 1 ? 0 : 1, "generate_deopt_entry_for in interpreter");
 247   } else if (state == dtos) {
 248     __ MacroAssembler::verify_FPU(UseSSE >= 2 ? 0 : 1, "generate_deopt_entry_for in interpreter");
 249   }
 250 #endif // _LP64
 251 
 252   // NULL last_sp until next java call
 253   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
 254   __ restore_bcp();


 678   } else {
 679     __ push(0);
 680   }
 681 
 682   __ movptr(rdx, Address(rbx, Method::const_offset()));
 683   __ movptr(rdx, Address(rdx, ConstMethod::constants_offset()));
 684   __ movptr(rdx, Address(rdx, ConstantPool::cache_offset_in_bytes()));
 685   __ push(rdx); // set constant pool cache
 686   __ push(rlocals); // set locals pointer
 687   if (native_call) {
 688     __ push(0); // no bcp
 689   } else {
 690     __ push(rbcp); // set bcp
 691   }
 692   __ push(0); // reserve word for pointer to expression stack bottom
 693   __ movptr(Address(rsp, 0), rsp); // set expression stack bottom
 694 }
 695 
 696 // End of helpers
 697 

















































 698 // Method entry for java.lang.ref.Reference.get.
 699 address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
 700   // Code: _aload_0, _getfield, _areturn
 701   // parameter size = 1
 702   //
 703   // The code that gets generated by this routine is split into 2 parts:
 704   //    1. The "intrinsified" code performing an ON_WEAK_OOP_REF load,
 705   //    2. The slow path - which is an expansion of the regular method entry.
 706   //
 707   // Notes:-
 708   // * An intrinsic is always executed, where an ON_WEAK_OOP_REF load is performed.
 709   // * We may jump to the slow path iff the receiver is null. If the
 710   //   Reference object is null then we no longer perform an ON_WEAK_OOP_REF load
 711   //   Thus we can use the regular method entry code to generate the NPE.
 712   //
 713   // rbx: Method*
 714 
 715   // r13: senderSP must preserve for slow path, set SP to it on fast path
 716 
 717   address entry = __ pc();


1320   __ empty_expression_stack();
1321   __ restore_bcp();      // rsi must be correct for exception handler   (was destroyed)
1322   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
1323 
1324   // throw exception
1325   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodErrorWithMethod), rbx);
1326   // the call_VM checks for exception, so we should never return here.
1327   __ should_not_reach_here();
1328 
1329   return entry_point;
1330 }
1331 
1332 //
1333 // Generic interpreted method entry to (asm) interpreter
1334 //
1335 address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
1336   // determine code generation flags
1337   bool inc_counter  = UseCompiler || CountCompiledCalls || LogTouchedMethods;
1338 
1339   // ebx: Method*
1340   // rbcp: sender sp
1341   address entry_point = __ pc();
1342 
1343   const Address constMethod(rbx, Method::const_offset());
1344   const Address access_flags(rbx, Method::access_flags_offset());
1345   const Address size_of_parameters(rdx,
1346                                    ConstMethod::size_of_parameters_offset());
1347   const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset());
1348 
1349 
1350   // get parameter size (always needed)
1351   __ movptr(rdx, constMethod);
1352   __ load_unsigned_short(rcx, size_of_parameters);
1353 
1354   // rbx: Method*
1355   // rcx: size of parameters
1356   // rbcp: sender_sp (could differ from sp+wordSize if we were called via c2i )
1357 
1358   __ load_unsigned_short(rdx, size_of_locals); // get size of locals in words
1359   __ subl(rdx, rcx); // rdx = no. of additional locals
1360 




  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "asm/macroAssembler.hpp"
  27 #include "gc/shared/barrierSetAssembler.hpp"
  28 #include "interpreter/bytecodeHistogram.hpp"
  29 #include "interpreter/interp_masm.hpp"
  30 #include "interpreter/interpreter.hpp"
  31 #include "interpreter/interpreterRuntime.hpp"
  32 #include "interpreter/templateInterpreterGenerator.hpp"
  33 #include "interpreter/templateTable.hpp"
  34 #include "oops/arrayOop.hpp"
  35 #include "oops/methodData.hpp"
  36 #include "oops/method.hpp"
  37 #include "oops/oop.inline.hpp"
  38 #include "prims/jvmtiExport.hpp"
  39 #include "prims/jvmtiThreadState.hpp"
  40 #include "runtime/arguments.hpp"
  41 #include "runtime/continuation.hpp"
  42 #include "runtime/deoptimization.hpp"
  43 #include "runtime/frame.inline.hpp"
  44 #include "runtime/sharedRuntime.hpp"
  45 #include "runtime/stubRoutines.hpp"
  46 #include "runtime/synchronizer.hpp"
  47 #include "runtime/timer.hpp"
  48 #include "runtime/vframeArray.hpp"
  49 #include "utilities/debug.hpp"
  50 #include "utilities/macros.hpp"
  51 
  52 #define __ _masm->
  53 
  54 // Size of interpreter code.  Increase if too small.  Interpreter will
  55 // fail with a guarantee ("not enough space for interpreter generation");
  56 // if too small.
  57 // Run with +PrintInterpreter to get the VM to print out the size.
  58 // Max size with JVMTI
  59 #ifdef AMD64
  60 int TemplateInterpreter::InterpreterCodeSize = JVMCI_ONLY(268) NOT_JVMCI(256) * 1024;
  61 #else


 157   __ empty_expression_stack();
 158   // setup parameters
 159   __ lea(rarg, ExternalAddress((address)name));
 160   if (pass_oop) {
 161     __ call_VM(rax, CAST_FROM_FN_PTR(address,
 162                                      InterpreterRuntime::
 163                                      create_klass_exception),
 164                rarg, rarg2);
 165   } else {
 166     __ lea(rarg2, ExternalAddress((address)message));
 167     __ call_VM(rax,
 168                CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception),
 169                rarg, rarg2);
 170   }
 171   // throw exception
 172   __ jump(ExternalAddress(Interpreter::throw_exception_entry()));
 173   return entry;
 174 }
 175 
 176 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) {
 177   return generate_return_entry_for(state, step, index_size, false);
 178 }
 179 
 180 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size, bool X) {
 181   address entry = __ pc();
 182 
 183 // if(X) __ stop("XXXXXXXX 000");
 184 #ifndef _LP64
 185 #ifdef COMPILER2
 186   // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases
 187   if ((state == ftos && UseSSE < 1) || (state == dtos && UseSSE < 2)) {
 188     for (int i = 1; i < 8; i++) {
 189         __ ffree(i);
 190     }
 191   } else if (UseSSE < 2) {
 192     __ empty_FPU_stack();
 193   }
 194 #endif // COMPILER2
 195   if ((state == ftos && UseSSE < 1) || (state == dtos && UseSSE < 2)) {
 196     __ MacroAssembler::verify_FPU(1, "generate_return_entry_for compiled");
 197   } else {
 198     __ MacroAssembler::verify_FPU(0, "generate_return_entry_for compiled");
 199   }
 200 
 201   if (state == ftos) {
 202     __ MacroAssembler::verify_FPU(UseSSE >= 1 ? 0 : 1, "generate_return_entry_for in interpreter");
 203   } else if (state == dtos) {
 204     __ MacroAssembler::verify_FPU(UseSSE >= 2 ? 0 : 1, "generate_return_entry_for in interpreter");
 205   }
 206 #endif // _LP64
 207 
 208   // if(X) __ stop("XXXXXXXX 111");
 209 
 210   // Restore stack bottom in case i2c adjusted stack
 211   __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
 212   // and NULL it as marker that esp is now tos until next java call
 213   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
 214 
 215   // if(X) __ stop("XXXXXXXX 222");
 216 
 217   __ restore_bcp();
 218   __ restore_locals();
 219 
 220   // if(X) __ stop("XXXXXXXX 333"); // rbcp = r13 locals = r14
 221 
 222   if (state == atos) {
 223     Register mdp = rbx;
 224     Register tmp = rcx;
 225     __ profile_return_type(mdp, rax, tmp);
 226   }
 227 
 228   const Register cache = rbx;
 229   const Register index = rcx;
 230   __ get_cache_and_index_at_bcp(cache, index, 1, index_size);
 231 
 232   const Register flags = cache;
 233   __ movl(flags, Address(cache, index, Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
 234   __ andl(flags, ConstantPoolCacheEntry::parameter_size_mask);
 235   __ lea(rsp, Address(rsp, flags, Interpreter::stackElementScale()));
 236 
 237    const Register java_thread = NOT_LP64(rcx) LP64_ONLY(r15_thread);
 238    if (JvmtiExport::can_pop_frame()) {
 239      NOT_LP64(__ get_thread(java_thread));
 240      __ check_and_handle_popframe(java_thread);
 241    }
 242    if (JvmtiExport::can_force_early_return()) {
 243      NOT_LP64(__ get_thread(java_thread));
 244      __ check_and_handle_earlyret(java_thread);
 245    }
 246 
 247   if(X) __ stop("XXXXXXXX 444");
 248   
 249   __ dispatch_next(state, step);
 250 
 251   return entry;
 252 }
 253 
 254 
 255 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step, address continuation) {
 256   address entry = __ pc();
 257 
 258 #ifndef _LP64
 259   if (state == ftos) {
 260     __ MacroAssembler::verify_FPU(UseSSE >= 1 ? 0 : 1, "generate_deopt_entry_for in interpreter");
 261   } else if (state == dtos) {
 262     __ MacroAssembler::verify_FPU(UseSSE >= 2 ? 0 : 1, "generate_deopt_entry_for in interpreter");
 263   }
 264 #endif // _LP64
 265 
 266   // NULL last_sp until next java call
 267   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
 268   __ restore_bcp();


 692   } else {
 693     __ push(0);
 694   }
 695 
 696   __ movptr(rdx, Address(rbx, Method::const_offset()));
 697   __ movptr(rdx, Address(rdx, ConstMethod::constants_offset()));
 698   __ movptr(rdx, Address(rdx, ConstantPool::cache_offset_in_bytes()));
 699   __ push(rdx); // set constant pool cache
 700   __ push(rlocals); // set locals pointer
 701   if (native_call) {
 702     __ push(0); // no bcp
 703   } else {
 704     __ push(rbcp); // set bcp
 705   }
 706   __ push(0); // reserve word for pointer to expression stack bottom
 707   __ movptr(Address(rsp, 0), rsp); // set expression stack bottom
 708 }
 709 
 710 // End of helpers
 711 
 712 // return current sp
 713 address TemplateInterpreterGenerator::generate_Continuation_getSP_entry(void) {
 714   address entry = __ pc();
 715   
 716   __ lea(rax, Address(rsp, wordSize)); // skip return address
 717   __ ret(0);
 718 
 719   return entry;
 720 }
 721 
 722 // return current fp
 723 address TemplateInterpreterGenerator::generate_Continuation_getFP_entry(void) {
 724   address entry = __ pc();
 725   
 726   __ movptr(rax, rbp);
 727   __ ret(0);
 728 
 729   return entry;
 730 }
 731 
 732 // return current pc
 733 address TemplateInterpreterGenerator::generate_Continuation_getPC_entry(void) {
 734   address entry = __ pc();
 735   
 736   __ movptr(rax, Address(rsp, 0));
 737   __ ret(0);
 738 
 739   return entry;
 740 }
 741 
 742 address TemplateInterpreterGenerator::generate_Continuation_doYield_entry(void) {
 743   address entry = __ pc();
 744   assert(StubRoutines::cont_doYield() != NULL, "stub not yet generated");
 745 
 746   __ movptr(c_rarg1, Address(rsp, wordSize)); // ContinuationScope
 747   __ jump(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::cont_doYield())));
 748 
 749   return entry;
 750 }
 751 
 752 address TemplateInterpreterGenerator::generate_Continuation_doContinue_entry(void) {
 753   address entry = __ pc();
 754   assert(StubRoutines::cont_thaw(2) != NULL, "stub not yet generated");
 755 
 756   __ jump(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::cont_thaw(2))));
 757 
 758   return entry;
 759 }
 760 
 761 // Method entry for java.lang.ref.Reference.get.
 762 address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
 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 performing an ON_WEAK_OOP_REF load,
 768   //    2. The slow path - which is an expansion of the regular method entry.
 769   //
 770   // Notes:-
 771   // * An intrinsic is always executed, where an ON_WEAK_OOP_REF load is performed.
 772   // * We may jump to the slow path iff the receiver is null. If the
 773   //   Reference object is null then we no longer perform an ON_WEAK_OOP_REF load
 774   //   Thus we can use the regular method entry code to generate the NPE.
 775   //
 776   // rbx: Method*
 777 
 778   // r13: senderSP must preserve for slow path, set SP to it on fast path
 779 
 780   address entry = __ pc();


1383   __ empty_expression_stack();
1384   __ restore_bcp();      // rsi must be correct for exception handler   (was destroyed)
1385   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
1386 
1387   // throw exception
1388   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodErrorWithMethod), rbx);
1389   // the call_VM checks for exception, so we should never return here.
1390   __ should_not_reach_here();
1391 
1392   return entry_point;
1393 }
1394 
1395 //
1396 // Generic interpreted method entry to (asm) interpreter
1397 //
1398 address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
1399   // determine code generation flags
1400   bool inc_counter  = UseCompiler || CountCompiledCalls || LogTouchedMethods;
1401 
1402   // ebx: Method*
1403   // rbcp: sender sp (set in InterpreterMacroAssembler::prepare_to_jump_from_interpreted / generate_call_stub)
1404   address entry_point = __ pc();
1405 
1406   const Address constMethod(rbx, Method::const_offset());
1407   const Address access_flags(rbx, Method::access_flags_offset());
1408   const Address size_of_parameters(rdx, 
1409                                    ConstMethod::size_of_parameters_offset());
1410   const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset());
1411 
1412 
1413   // get parameter size (always needed)
1414   __ movptr(rdx, constMethod);
1415   __ load_unsigned_short(rcx, size_of_parameters);
1416 
1417   // rbx: Method*
1418   // rcx: size of parameters
1419   // rbcp: sender_sp (could differ from sp+wordSize if we were called via c2i )
1420 
1421   __ load_unsigned_short(rdx, size_of_locals); // get size of locals in words
1422   __ subl(rdx, rcx); // rdx = no. of additional locals
1423 


< prev index next >