< prev index next >

src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp

Print this page

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

  41 #include "prims/jvmtiExport.hpp"
  42 #include "prims/jvmtiThreadState.hpp"
  43 #include "runtime/continuation.hpp"
  44 #include "runtime/deoptimization.hpp"
  45 #include "runtime/frame.inline.hpp"
  46 #include "runtime/globals.hpp"
  47 #include "runtime/jniHandles.hpp"
  48 #include "runtime/sharedRuntime.hpp"
  49 #include "runtime/stubRoutines.hpp"
  50 #include "runtime/synchronizer.hpp"
  51 #include "runtime/timer.hpp"
  52 #include "runtime/vframeArray.hpp"
  53 #include "utilities/debug.hpp"
  54 #include "utilities/macros.hpp"
  55 
  56 #define __ Disassembler::hook<InterpreterMacroAssembler>(__FILE__, __LINE__, _masm)->
  57 
  58 // Size of interpreter code.  Increase if too small.  Interpreter will
  59 // fail with a guarantee ("not enough space for interpreter generation");
  60 // if too small.
  61 // Run with +PrintInterpreter to get the VM to print out the size.
  62 // Max size with JVMTI
  63 #ifdef AMD64
  64 int TemplateInterpreter::InterpreterCodeSize = JVMCI_ONLY(268) NOT_JVMCI(256) * 1024;
  65 #else
  66 int TemplateInterpreter::InterpreterCodeSize = 224 * 1024;
  67 #endif // AMD64
  68 
  69 // Global Register Names
  70 static const Register rbcp     = LP64_ONLY(r13) NOT_LP64(rsi);
  71 static const Register rlocals  = LP64_ONLY(r14) NOT_LP64(rdi);
  72 
  73 const int method_offset = frame::interpreter_frame_method_offset * wordSize;
  74 const int bcp_offset    = frame::interpreter_frame_bcp_offset    * wordSize;
  75 const int locals_offset = frame::interpreter_frame_locals_offset * wordSize;
  76 
  77 
  78 //-----------------------------------------------------------------------------
  79 
  80 address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
  81   address entry = __ pc();
  82 
  83 #ifdef ASSERT
  84   {

 192   }
 193 #endif // COMPILER2
 194   if ((state == ftos && UseSSE < 1) || (state == dtos && UseSSE < 2)) {
 195     __ MacroAssembler::verify_FPU(1, "generate_return_entry_for compiled");
 196   } else {
 197     __ MacroAssembler::verify_FPU(0, "generate_return_entry_for compiled");
 198   }
 199 
 200   if (state == ftos) {
 201     __ MacroAssembler::verify_FPU(UseSSE >= 1 ? 0 : 1, "generate_return_entry_for in interpreter");
 202   } else if (state == dtos) {
 203     __ MacroAssembler::verify_FPU(UseSSE >= 2 ? 0 : 1, "generate_return_entry_for in interpreter");
 204   }
 205 #endif // _LP64
 206 
 207   // Restore stack bottom in case i2c adjusted stack
 208   __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
 209   // and NULL it as marker that esp is now tos until next java call
 210   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
 211 




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

 334         // Store as float and empty fpu stack
 335         __ fstp_s(Address(rsp, 0));
 336         // and reload
 337         __ movflt(xmm0, Address(rsp, 0));
 338       } else if (type == T_DOUBLE && UseSSE >= 2 ) {
 339         __ movdbl(xmm0, Address(rsp, 0));
 340       } else {
 341         // restore ST0
 342         __ fld_d(Address(rsp, 0));
 343       }
 344       // and pop the temp
 345       __ addptr(rsp, 2 * wordSize);
 346       __ push(t);                           // restore return address
 347     }
 348     break;
 349 #else
 350   case T_FLOAT  : /* nothing to do */        break;
 351   case T_DOUBLE : /* nothing to do */        break;
 352 #endif // _LP64
 353 

 354   case T_OBJECT :
 355     // retrieve result from frame
 356     __ movptr(rax, Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize));
 357     // and verify it
 358     __ verify_oop(rax);
 359     break;
 360   default       : ShouldNotReachHere();
 361   }
 362   __ ret(0);                                   // return from result handler
 363   return entry;
 364 }
 365 
 366 address TemplateInterpreterGenerator::generate_safept_entry_for(
 367         TosState state,
 368         address runtime_entry) {
 369   address entry = __ pc();
 370 
 371   __ push(state);
 372   __ push_cont_fastpath();
 373   __ call_VM(noreg, runtime_entry);

  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "asm/macroAssembler.hpp"
  27 #include "classfile/javaClasses.hpp"
  28 #include "compiler/compiler_globals.hpp"
  29 #include "compiler/disassembler.hpp"
  30 #include "gc/shared/barrierSetAssembler.hpp"
  31 #include "interpreter/bytecodeHistogram.hpp"
  32 #include "interpreter/interp_masm.hpp"
  33 #include "interpreter/interpreter.hpp"
  34 #include "interpreter/interpreterRuntime.hpp"
  35 #include "interpreter/templateInterpreterGenerator.hpp"
  36 #include "interpreter/templateTable.hpp"
  37 #include "oops/arrayOop.hpp"
  38 #include "oops/methodData.hpp"
  39 #include "oops/method.hpp"
  40 #include "oops/oop.inline.hpp"
  41 #include "oops/inlineKlass.hpp"
  42 #include "prims/jvmtiExport.hpp"
  43 #include "prims/jvmtiThreadState.hpp"
  44 #include "runtime/continuation.hpp"
  45 #include "runtime/deoptimization.hpp"
  46 #include "runtime/frame.inline.hpp"
  47 #include "runtime/globals.hpp"
  48 #include "runtime/jniHandles.hpp"
  49 #include "runtime/sharedRuntime.hpp"
  50 #include "runtime/stubRoutines.hpp"
  51 #include "runtime/synchronizer.hpp"
  52 #include "runtime/timer.hpp"
  53 #include "runtime/vframeArray.hpp"
  54 #include "utilities/debug.hpp"
  55 #include "utilities/macros.hpp"
  56 
  57 #define __ Disassembler::hook<InterpreterMacroAssembler>(__FILE__, __LINE__, _masm)->
  58 
  59 // Size of interpreter code.  Increase if too small.  Interpreter will
  60 // fail with a guarantee ("not enough space for interpreter generation");
  61 // if too small.
  62 // Run with +PrintInterpreter to get the VM to print out the size.
  63 // Max size with JVMTI
  64 #ifdef AMD64
  65 int TemplateInterpreter::InterpreterCodeSize = JVMCI_ONLY(280) NOT_JVMCI(268) * 1024;
  66 #else
  67 int TemplateInterpreter::InterpreterCodeSize = 224 * 1024;
  68 #endif // AMD64
  69 
  70 // Global Register Names
  71 static const Register rbcp     = LP64_ONLY(r13) NOT_LP64(rsi);
  72 static const Register rlocals  = LP64_ONLY(r14) NOT_LP64(rdi);
  73 
  74 const int method_offset = frame::interpreter_frame_method_offset * wordSize;
  75 const int bcp_offset    = frame::interpreter_frame_bcp_offset    * wordSize;
  76 const int locals_offset = frame::interpreter_frame_locals_offset * wordSize;
  77 
  78 
  79 //-----------------------------------------------------------------------------
  80 
  81 address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
  82   address entry = __ pc();
  83 
  84 #ifdef ASSERT
  85   {

 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   // Restore stack bottom in case i2c adjusted stack
 209   __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
 210   // and NULL it as marker that esp is now tos until next java call
 211   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
 212 
 213   if (state == atos && InlineTypeReturnedAsFields) {
 214     __ store_inline_type_fields_to_buf(NULL);
 215   }
 216 
 217   __ restore_bcp();
 218   __ restore_locals();
 219 
 220   if (state == atos) {
 221     Register mdp = rbx;
 222     Register tmp = rcx;
 223     __ profile_return_type(mdp, rax, tmp);
 224   }
 225 
 226   const Register cache = rbx;
 227   const Register index = rcx;
 228   __ get_cache_and_index_at_bcp(cache, index, 1, index_size);
 229 
 230   const Register flags = cache;
 231   __ movl(flags, Address(cache, index, Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
 232   __ andl(flags, ConstantPoolCacheEntry::parameter_size_mask);
 233   __ lea(rsp, Address(rsp, flags, Interpreter::stackElementScale()));
 234 
 235    const Register java_thread = NOT_LP64(rcx) LP64_ONLY(r15_thread);
 236    if (JvmtiExport::can_pop_frame()) {

 339         // Store as float and empty fpu stack
 340         __ fstp_s(Address(rsp, 0));
 341         // and reload
 342         __ movflt(xmm0, Address(rsp, 0));
 343       } else if (type == T_DOUBLE && UseSSE >= 2 ) {
 344         __ movdbl(xmm0, Address(rsp, 0));
 345       } else {
 346         // restore ST0
 347         __ fld_d(Address(rsp, 0));
 348       }
 349       // and pop the temp
 350       __ addptr(rsp, 2 * wordSize);
 351       __ push(t);                           // restore return address
 352     }
 353     break;
 354 #else
 355   case T_FLOAT  : /* nothing to do */        break;
 356   case T_DOUBLE : /* nothing to do */        break;
 357 #endif // _LP64
 358 
 359   case T_PRIMITIVE_OBJECT: // fall through (inline types are handled with oops)
 360   case T_OBJECT :
 361     // retrieve result from frame
 362     __ movptr(rax, Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize));
 363     // and verify it
 364     __ verify_oop(rax);
 365     break;
 366   default       : ShouldNotReachHere();
 367   }
 368   __ ret(0);                                   // return from result handler
 369   return entry;
 370 }
 371 
 372 address TemplateInterpreterGenerator::generate_safept_entry_for(
 373         TosState state,
 374         address runtime_entry) {
 375   address entry = __ pc();
 376 
 377   __ push(state);
 378   __ push_cont_fastpath();
 379   __ call_VM(noreg, runtime_entry);
< prev index next >