< prev index next >

src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp

Print this page




  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "asm/macroAssembler.hpp"
  27 #include "compiler/disassembler.hpp"
  28 #include "gc/shared/barrierSetAssembler.hpp"
  29 #include "interpreter/bytecodeHistogram.hpp"
  30 #include "interpreter/interp_masm.hpp"
  31 #include "interpreter/interpreter.hpp"
  32 #include "interpreter/interpreterRuntime.hpp"
  33 #include "interpreter/templateInterpreterGenerator.hpp"
  34 #include "interpreter/templateTable.hpp"
  35 #include "oops/arrayOop.hpp"
  36 #include "oops/methodData.hpp"
  37 #include "oops/method.hpp"
  38 #include "oops/oop.inline.hpp"
  39 #include "prims/jvmtiExport.hpp"
  40 #include "prims/jvmtiThreadState.hpp"
  41 #include "runtime/arguments.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 __ Disassembler::hook<InterpreterMacroAssembler>(__FILE__, __LINE__, _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   address entry = __ pc();
 178 

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


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


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


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


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


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














































































































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


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




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


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


 694   } else {
 695     __ push(0);
 696   }
 697 
 698   __ movptr(rdx, Address(rbx, Method::const_offset()));
 699   __ movptr(rdx, Address(rdx, ConstMethod::constants_offset()));
 700   __ movptr(rdx, Address(rdx, ConstantPool::cache_offset_in_bytes()));
 701   __ push(rdx); // set constant pool cache
 702   __ push(rlocals); // set locals pointer
 703   if (native_call) {
 704     __ push(0); // no bcp
 705   } else {
 706     __ push(rbcp); // set bcp
 707   }
 708   __ push(0); // reserve word for pointer to expression stack bottom
 709   __ movptr(Address(rsp, 0), rsp); // set expression stack bottom
 710 }
 711 
 712 // End of helpers
 713 
 714 address TemplateInterpreterGenerator::generate_Continuation_runLevel_entry(void) {
 715 #ifdef _LP64
 716   address entry = __ pc();
 717 
 718   __ movl(rax, 0);
 719   __ ret(0);
 720 
 721   return entry;
 722 #else
 723   Unimplemented();
 724   return NULL;
 725 #endif
 726 }
 727 
 728 // return current sp
 729 address TemplateInterpreterGenerator::generate_Continuation_getSP_entry(void) {
 730 #ifdef _LP64
 731   address entry = __ pc();
 732 
 733   const Register thread1 = NOT_LP64(rdi) LP64_ONLY(r15_thread);
 734   NOT_LP64(__ get_thread(thread1));
 735   __ set_cont_fastpath(thread1, 1);
 736   __ lea(rax, Address(rsp, wordSize)); // skip return address
 737   __ ret(0);
 738 
 739   return entry;
 740 #else
 741   Unimplemented();
 742   return NULL;
 743 #endif
 744 }
 745 
 746 // return current fp
 747 address TemplateInterpreterGenerator::generate_Continuation_getFP_entry(void) {
 748 #ifdef _LP64
 749   address entry = __ pc();
 750 
 751   __ movptr(rax, rbp);
 752   __ ret(0);
 753 
 754   return entry;
 755 #else
 756   Unimplemented();
 757   return NULL;
 758 #endif
 759 }
 760 
 761 // return current pc
 762 address TemplateInterpreterGenerator::generate_Continuation_getPC_entry(void) {
 763 #ifdef _LP64
 764   address entry = __ pc();
 765 
 766   __ movptr(rax, Address(rsp, 0));
 767   __ ret(0);
 768 
 769   return entry;
 770 #else
 771   Unimplemented();
 772   return NULL;
 773 #endif
 774 }
 775 
 776 address TemplateInterpreterGenerator::generate_Continuation_doYield_entry(void) {
 777 #ifdef _LP64
 778   address entry = __ pc();
 779   assert(StubRoutines::cont_doYield() != NULL, "stub not yet generated");
 780 
 781   // __ movl(c_rarg1, Address(rsp, wordSize)); // scopes
 782   __ movl(c_rarg1, 1); // from interpreter
 783   __ jump(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::cont_doYield())));
 784   // return value is in rax
 785 
 786   return entry;
 787 #else
 788   Unimplemented();
 789   return NULL;
 790 #endif
 791 }
 792 
 793 address TemplateInterpreterGenerator::generate_Continuation_jump_entry(void) {
 794 #ifdef _LP64
 795   address entry = __ pc();
 796   assert(StubRoutines::cont_jump() != NULL, "stub not yet generated");
 797 
 798   __ movl(c_rarg1, Address(rsp, wordSize*3)); // sp
 799   __ movl(c_rarg2, Address(rsp, wordSize*2)); // fp
 800   __ movl(c_rarg3, Address(rsp, wordSize*1)); // pc
 801   __ jump(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::cont_jump())));
 802 
 803   return entry;
 804 #else
 805   Unimplemented();
 806   return NULL;
 807 #endif
 808 }
 809 
 810 address TemplateInterpreterGenerator::generate_Continuation_doContinue_entry(void) {
 811 #ifdef _LP64
 812   address entry = __ pc();
 813   assert(StubRoutines::cont_thaw() != NULL, "stub not yet generated");
 814 
 815   __ jump(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::cont_thaw())));
 816 
 817   return entry;
 818 #else
 819   Unimplemented();
 820   return NULL;
 821 #endif
 822 }
 823 
 824 // Method entry for java.lang.ref.Reference.get.
 825 address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
 826   // Code: _aload_0, _getfield, _areturn
 827   // parameter size = 1
 828   //
 829   // The code that gets generated by this routine is split into 2 parts:
 830   //    1. The "intrinsified" code performing an ON_WEAK_OOP_REF load,
 831   //    2. The slow path - which is an expansion of the regular method entry.
 832   //
 833   // Notes:-
 834   // * An intrinsic is always executed, where an ON_WEAK_OOP_REF load is performed.
 835   // * We may jump to the slow path iff the receiver is null. If the
 836   //   Reference object is null then we no longer perform an ON_WEAK_OOP_REF load
 837   //   Thus we can use the regular method entry code to generate the NPE.
 838   //
 839   // rbx: Method*
 840 
 841   // r13: senderSP must preserve for slow path, set SP to it on fast path
 842 
 843   address entry = __ pc();


1436   __ empty_expression_stack();
1437   __ restore_bcp();      // rsi must be correct for exception handler   (was destroyed)
1438   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
1439 
1440   // throw exception
1441   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodErrorWithMethod), rbx);
1442   // the call_VM checks for exception, so we should never return here.
1443   __ should_not_reach_here();
1444 
1445   return entry_point;
1446 }
1447 
1448 //
1449 // Generic interpreted method entry to (asm) interpreter
1450 //
1451 address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
1452   // determine code generation flags
1453   bool inc_counter  = UseCompiler || CountCompiledCalls || LogTouchedMethods;
1454 
1455   // ebx: Method*
1456   // rbcp: sender sp (set in InterpreterMacroAssembler::prepare_to_jump_from_interpreted / generate_call_stub)
1457   address entry_point = __ pc();
1458 
1459   const Address constMethod(rbx, Method::const_offset());
1460   const Address access_flags(rbx, Method::access_flags_offset());
1461   const Address size_of_parameters(rdx,
1462                                    ConstMethod::size_of_parameters_offset());
1463   const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset());
1464 
1465 
1466   // get parameter size (always needed)
1467   __ movptr(rdx, constMethod);
1468   __ load_unsigned_short(rcx, size_of_parameters);
1469 
1470   // rbx: Method*
1471   // rcx: size of parameters
1472   // rbcp: sender_sp (could differ from sp+wordSize if we were called via c2i )
1473 
1474   __ load_unsigned_short(rdx, size_of_locals); // get size of locals in words
1475   __ subl(rdx, rcx); // rdx = no. of additional locals
1476 


< prev index next >