< prev index next >

src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp

Print this page




  32 #include "interpreter/templateTable.hpp"
  33 #include "oops/arrayOop.hpp"
  34 #include "oops/methodData.hpp"
  35 #include "oops/method.hpp"
  36 #include "oops/oop.inline.hpp"
  37 #include "prims/jvmtiExport.hpp"
  38 #include "prims/jvmtiThreadState.hpp"
  39 #include "runtime/arguments.hpp"
  40 #include "runtime/deoptimization.hpp"
  41 #include "runtime/frame.inline.hpp"
  42 #include "runtime/sharedRuntime.hpp"
  43 #include "runtime/stubRoutines.hpp"
  44 #include "runtime/synchronizer.hpp"
  45 #include "runtime/timer.hpp"
  46 #include "runtime/vframeArray.hpp"
  47 #include "utilities/debug.hpp"
  48 #include "utilities/macros.hpp"
  49 
  50 #define __ _masm->
  51 











  52 // Global Register Names
  53 static const Register rbcp     = LP64_ONLY(r13) NOT_LP64(rsi);
  54 static const Register rlocals  = LP64_ONLY(r14) NOT_LP64(rdi);
  55 
  56 const int method_offset = frame::interpreter_frame_method_offset * wordSize;
  57 const int bcp_offset    = frame::interpreter_frame_bcp_offset    * wordSize;
  58 const int locals_offset = frame::interpreter_frame_locals_offset * wordSize;
  59 

  60 //-----------------------------------------------------------------------------
  61 
  62 address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
  63   address entry = __ pc();
  64 
  65 #ifdef ASSERT
  66   {
  67     Label L;
  68     __ lea(rax, Address(rbp,
  69                         frame::interpreter_frame_monitor_block_top_offset *
  70                         wordSize));
  71     __ cmpptr(rax, rsp); // rax = maximal rsp for current rbp (stack
  72                          // grows negative)
  73     __ jcc(Assembler::aboveEqual, L); // check if frame is complete
  74     __ stop ("interpreter frame not set up");
  75     __ bind(L);
  76   }
  77 #endif // ASSERT
  78   // Restore bcp under the assumption that the current frame is still
  79   // interpreted


 761 
 762     // _areturn
 763     NOT_LP64(__ pop(rsi));      // get sender sp
 764     __ pop(rdi);                // get return address
 765     __ mov(rsp, sender_sp);     // set sp to sender sp
 766     __ jmp(rdi);
 767     __ ret(0);
 768 
 769     // generate a vanilla interpreter entry as the slow path
 770     __ bind(slow_path);
 771     __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals));
 772     return entry;
 773   }
 774 #endif // INCLUDE_ALL_GCS
 775 
 776   // If G1 is not enabled then attempt to go through the accessor entry point
 777   // Reference.get is an accessor
 778   return NULL;
 779 }
 780 
























 781 // Interpreter stub for calling a native method. (asm interpreter)
 782 // This sets up a somewhat different looking stack for calling the
 783 // native method than the typical interpreter frame setup.
 784 address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
 785   // determine code generation flags
 786   bool inc_counter  = UseCompiler || CountCompiledCalls || LogTouchedMethods;
 787 
 788   // rbx: Method*
 789   // rbcp: sender sp
 790 
 791   address entry_point = __ pc();
 792 
 793   const Address constMethod       (rbx, Method::const_offset());
 794   const Address access_flags      (rbx, Method::access_flags_offset());
 795   const Address size_of_parameters(rcx, ConstMethod::
 796                                         size_of_parameters_offset());
 797 
 798 
 799   // get parameter size (always needed)
 800   __ movptr(rcx, constMethod);


1283   LP64_ONLY( __ pop(dtos));
1284 
1285   __ movptr(t, Address(rbp,
1286                        (frame::interpreter_frame_result_handler_offset) * wordSize));
1287   __ call(t);
1288 
1289   // remove activation
1290   __ movptr(t, Address(rbp,
1291                        frame::interpreter_frame_sender_sp_offset *
1292                        wordSize)); // get sender sp
1293   __ leave();                                // remove frame anchor
1294   __ pop(rdi);                               // get return address
1295   __ mov(rsp, t);                            // set sp to sender sp
1296   __ jmp(rdi);
1297 
1298   if (inc_counter) {
1299     // Handle overflow of counter and compile method
1300     __ bind(invocation_counter_overflow);
1301     generate_counter_overflow(continue_after_compile);
1302   }





















1303 
1304   return entry_point;
1305 }
1306 
1307 //
1308 // Generic interpreted method entry to (asm) interpreter
1309 //
1310 address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
1311   // determine code generation flags
1312   bool inc_counter  = UseCompiler || CountCompiledCalls || LogTouchedMethods;
1313 
1314   // ebx: Method*
1315   // rbcp: sender sp
1316   address entry_point = __ pc();
1317 
1318   const Address constMethod(rbx, Method::const_offset());
1319   const Address access_flags(rbx, Method::access_flags_offset());
1320   const Address size_of_parameters(rdx,
1321                                    ConstMethod::size_of_parameters_offset());
1322   const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset());




  32 #include "interpreter/templateTable.hpp"
  33 #include "oops/arrayOop.hpp"
  34 #include "oops/methodData.hpp"
  35 #include "oops/method.hpp"
  36 #include "oops/oop.inline.hpp"
  37 #include "prims/jvmtiExport.hpp"
  38 #include "prims/jvmtiThreadState.hpp"
  39 #include "runtime/arguments.hpp"
  40 #include "runtime/deoptimization.hpp"
  41 #include "runtime/frame.inline.hpp"
  42 #include "runtime/sharedRuntime.hpp"
  43 #include "runtime/stubRoutines.hpp"
  44 #include "runtime/synchronizer.hpp"
  45 #include "runtime/timer.hpp"
  46 #include "runtime/vframeArray.hpp"
  47 #include "utilities/debug.hpp"
  48 #include "utilities/macros.hpp"
  49 
  50 #define __ _masm->
  51 
  52 // Size of interpreter code.  Increase if too small.  Interpreter will
  53 // fail with a guarantee ("not enough space for interpreter generation");
  54 // if too small.
  55 // Run with +PrintInterpreter to get the VM to print out the size.
  56 // Max size with JVMTI
  57 #ifdef AMD64
  58 int TemplateInterpreter::InterpreterCodeSize = 256 * 1024;
  59 #else
  60 int TemplateInterpreter::InterpreterCodeSize = 224 * 1024;
  61 #endif // AMD64
  62 
  63 // Global Register Names
  64 static const Register rbcp     = LP64_ONLY(r13) NOT_LP64(rsi);
  65 static const Register rlocals  = LP64_ONLY(r14) NOT_LP64(rdi);
  66 
  67 const int method_offset = frame::interpreter_frame_method_offset * wordSize;
  68 const int bcp_offset    = frame::interpreter_frame_bcp_offset    * wordSize;
  69 const int locals_offset = frame::interpreter_frame_locals_offset * wordSize;
  70 
  71 
  72 //-----------------------------------------------------------------------------
  73 
  74 address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
  75   address entry = __ pc();
  76 
  77 #ifdef ASSERT
  78   {
  79     Label L;
  80     __ lea(rax, Address(rbp,
  81                         frame::interpreter_frame_monitor_block_top_offset *
  82                         wordSize));
  83     __ cmpptr(rax, rsp); // rax = maximal rsp for current rbp (stack
  84                          // grows negative)
  85     __ jcc(Assembler::aboveEqual, L); // check if frame is complete
  86     __ stop ("interpreter frame not set up");
  87     __ bind(L);
  88   }
  89 #endif // ASSERT
  90   // Restore bcp under the assumption that the current frame is still
  91   // interpreted


 773 
 774     // _areturn
 775     NOT_LP64(__ pop(rsi));      // get sender sp
 776     __ pop(rdi);                // get return address
 777     __ mov(rsp, sender_sp);     // set sp to sender sp
 778     __ jmp(rdi);
 779     __ ret(0);
 780 
 781     // generate a vanilla interpreter entry as the slow path
 782     __ bind(slow_path);
 783     __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals));
 784     return entry;
 785   }
 786 #endif // INCLUDE_ALL_GCS
 787 
 788   // If G1 is not enabled then attempt to go through the accessor entry point
 789   // Reference.get is an accessor
 790   return NULL;
 791 }
 792 
 793 // TODO: rather than touching all pages, check against stack_overflow_limit and bang yellow page to
 794 // generate exception.  Windows might need this to map the shadow pages though.
 795 void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
 796   // Quick & dirty stack overflow checking: bang the stack & handle trap.
 797   // Note that we do the banging after the frame is setup, since the exception
 798   // handling code expects to find a valid interpreter frame on the stack.
 799   // Doing the banging earlier fails if the caller frame is not an interpreter
 800   // frame.
 801   // (Also, the exception throwing code expects to unlock any synchronized
 802   // method receiever, so do the banging after locking the receiver.)
 803 
 804   // Bang each page in the shadow zone. We can't assume it's been done for
 805   // an interpreter frame with greater than a page of locals, so each page
 806   // needs to be checked.  Only true for non-native.
 807   if (UseStackBanging) {
 808     const int page_size = os::vm_page_size();
 809     const int n_shadow_pages = ((int)JavaThread::stack_shadow_zone_size()) / page_size;
 810     const int start_page = native_call ? n_shadow_pages : 1;
 811     for (int pages = start_page; pages <= n_shadow_pages; pages++) {
 812       __ bang_stack_with_offset(pages*page_size);
 813     }
 814   }
 815 }
 816 
 817 // Interpreter stub for calling a native method. (asm interpreter)
 818 // This sets up a somewhat different looking stack for calling the
 819 // native method than the typical interpreter frame setup.
 820 address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
 821   // determine code generation flags
 822   bool inc_counter  = UseCompiler || CountCompiledCalls || LogTouchedMethods;
 823 
 824   // rbx: Method*
 825   // rbcp: sender sp
 826 
 827   address entry_point = __ pc();
 828 
 829   const Address constMethod       (rbx, Method::const_offset());
 830   const Address access_flags      (rbx, Method::access_flags_offset());
 831   const Address size_of_parameters(rcx, ConstMethod::
 832                                         size_of_parameters_offset());
 833 
 834 
 835   // get parameter size (always needed)
 836   __ movptr(rcx, constMethod);


1319   LP64_ONLY( __ pop(dtos));
1320 
1321   __ movptr(t, Address(rbp,
1322                        (frame::interpreter_frame_result_handler_offset) * wordSize));
1323   __ call(t);
1324 
1325   // remove activation
1326   __ movptr(t, Address(rbp,
1327                        frame::interpreter_frame_sender_sp_offset *
1328                        wordSize)); // get sender sp
1329   __ leave();                                // remove frame anchor
1330   __ pop(rdi);                               // get return address
1331   __ mov(rsp, t);                            // set sp to sender sp
1332   __ jmp(rdi);
1333 
1334   if (inc_counter) {
1335     // Handle overflow of counter and compile method
1336     __ bind(invocation_counter_overflow);
1337     generate_counter_overflow(continue_after_compile);
1338   }
1339 
1340   return entry_point;
1341 }
1342 
1343 // Abstract method entry
1344 // Attempt to execute abstract method. Throw exception
1345 address TemplateInterpreterGenerator::generate_abstract_entry(void) {
1346 
1347   address entry_point = __ pc();
1348 
1349   // abstract method entry
1350 
1351   //  pop return address, reset last_sp to NULL
1352   __ empty_expression_stack();
1353   __ restore_bcp();      // rsi must be correct for exception handler   (was destroyed)
1354   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
1355 
1356   // throw exception
1357   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));
1358   // the call_VM checks for exception, so we should never return here.
1359   __ should_not_reach_here();
1360 
1361   return entry_point;
1362 }
1363 
1364 //
1365 // Generic interpreted method entry to (asm) interpreter
1366 //
1367 address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
1368   // determine code generation flags
1369   bool inc_counter  = UseCompiler || CountCompiledCalls || LogTouchedMethods;
1370 
1371   // ebx: Method*
1372   // rbcp: sender sp
1373   address entry_point = __ pc();
1374 
1375   const Address constMethod(rbx, Method::const_offset());
1376   const Address access_flags(rbx, Method::access_flags_offset());
1377   const Address size_of_parameters(rdx,
1378                                    ConstMethod::size_of_parameters_offset());
1379   const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset());


< prev index next >