1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,1672 @@ 1.4 +/* 1.5 + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "incls/_precompiled.incl" 1.29 +#include "incls/_interpreter_x86_64.cpp.incl" 1.30 + 1.31 +#define __ _masm-> 1.32 + 1.33 +const int method_offset = frame::interpreter_frame_method_offset * wordSize; 1.34 +const int bci_offset = frame::interpreter_frame_bcx_offset * wordSize; 1.35 +const int locals_offset = frame::interpreter_frame_locals_offset * wordSize; 1.36 + 1.37 +//----------------------------------------------------------------------------- 1.38 + 1.39 +address TemplateInterpreterGenerator::generate_StackOverflowError_handler() { 1.40 + address entry = __ pc(); 1.41 + 1.42 +#ifdef ASSERT 1.43 + { 1.44 + Label L; 1.45 + __ leaq(rax, Address(rbp, 1.46 + frame::interpreter_frame_monitor_block_top_offset * 1.47 + wordSize)); 1.48 + __ cmpq(rax, rsp); // rax = maximal rsp for current rbp (stack 1.49 + // grows negative) 1.50 + __ jcc(Assembler::aboveEqual, L); // check if frame is complete 1.51 + __ stop ("interpreter frame not set up"); 1.52 + __ bind(L); 1.53 + } 1.54 +#endif // ASSERT 1.55 + // Restore bcp under the assumption that the current frame is still 1.56 + // interpreted 1.57 + __ restore_bcp(); 1.58 + 1.59 + // expression stack must be empty before entering the VM if an 1.60 + // exception happened 1.61 + __ empty_expression_stack(); 1.62 + // throw exception 1.63 + __ call_VM(noreg, 1.64 + CAST_FROM_FN_PTR(address, 1.65 + InterpreterRuntime::throw_StackOverflowError)); 1.66 + return entry; 1.67 +} 1.68 + 1.69 +address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler( 1.70 + const char* name) { 1.71 + address entry = __ pc(); 1.72 + // expression stack must be empty before entering the VM if an 1.73 + // exception happened 1.74 + __ empty_expression_stack(); 1.75 + // setup parameters 1.76 + // ??? convention: expect aberrant index in register ebx 1.77 + __ lea(c_rarg1, ExternalAddress((address)name)); 1.78 + __ call_VM(noreg, 1.79 + CAST_FROM_FN_PTR(address, 1.80 + InterpreterRuntime:: 1.81 + throw_ArrayIndexOutOfBoundsException), 1.82 + c_rarg1, rbx); 1.83 + return entry; 1.84 +} 1.85 + 1.86 +address TemplateInterpreterGenerator::generate_ClassCastException_handler() { 1.87 + address entry = __ pc(); 1.88 + 1.89 + // object is at TOS 1.90 + __ popq(c_rarg1); 1.91 + 1.92 + // expression stack must be empty before entering the VM if an 1.93 + // exception happened 1.94 + __ empty_expression_stack(); 1.95 + 1.96 + __ call_VM(noreg, 1.97 + CAST_FROM_FN_PTR(address, 1.98 + InterpreterRuntime:: 1.99 + throw_ClassCastException), 1.100 + c_rarg1); 1.101 + return entry; 1.102 +} 1.103 + 1.104 +address TemplateInterpreterGenerator::generate_exception_handler_common( 1.105 + const char* name, const char* message, bool pass_oop) { 1.106 + assert(!pass_oop || message == NULL, "either oop or message but not both"); 1.107 + address entry = __ pc(); 1.108 + if (pass_oop) { 1.109 + // object is at TOS 1.110 + __ popq(c_rarg2); 1.111 + } 1.112 + // expression stack must be empty before entering the VM if an 1.113 + // exception happened 1.114 + __ empty_expression_stack(); 1.115 + // setup parameters 1.116 + __ lea(c_rarg1, ExternalAddress((address)name)); 1.117 + if (pass_oop) { 1.118 + __ call_VM(rax, CAST_FROM_FN_PTR(address, 1.119 + InterpreterRuntime:: 1.120 + create_klass_exception), 1.121 + c_rarg1, c_rarg2); 1.122 + } else { 1.123 + // kind of lame ExternalAddress can't take NULL because 1.124 + // external_word_Relocation will assert. 1.125 + if (message != NULL) { 1.126 + __ lea(c_rarg2, ExternalAddress((address)message)); 1.127 + } else { 1.128 + __ movptr(c_rarg2, NULL_WORD); 1.129 + } 1.130 + __ call_VM(rax, 1.131 + CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception), 1.132 + c_rarg1, c_rarg2); 1.133 + } 1.134 + // throw exception 1.135 + __ jump(ExternalAddress(Interpreter::throw_exception_entry())); 1.136 + return entry; 1.137 +} 1.138 + 1.139 + 1.140 +address TemplateInterpreterGenerator::generate_continuation_for(TosState state) { 1.141 + address entry = __ pc(); 1.142 + // NULL last_sp until next java call 1.143 + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 1.144 + __ dispatch_next(state); 1.145 + return entry; 1.146 +} 1.147 + 1.148 + 1.149 +address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, 1.150 + int step) { 1.151 + 1.152 + // amd64 doesn't need to do anything special about compiled returns 1.153 + // to the interpreter so the code that exists on x86 to place a sentinel 1.154 + // here and the specialized cleanup code is not needed here. 1.155 + 1.156 + address entry = __ pc(); 1.157 + 1.158 + // Restore stack bottom in case i2c adjusted stack 1.159 + __ movq(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); 1.160 + // and NULL it as marker that esp is now tos until next java call 1.161 + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 1.162 + 1.163 + __ restore_bcp(); 1.164 + __ restore_locals(); 1.165 + __ get_cache_and_index_at_bcp(rbx, rcx, 1); 1.166 + __ movl(rbx, Address(rbx, rcx, 1.167 + Address::times_8, 1.168 + in_bytes(constantPoolCacheOopDesc::base_offset()) + 1.169 + 3 * wordSize)); 1.170 + __ andl(rbx, 0xFF); 1.171 + if (TaggedStackInterpreter) __ shll(rbx, 1); // 2 slots per parameter. 1.172 + __ leaq(rsp, Address(rsp, rbx, Address::times_8)); 1.173 + __ dispatch_next(state, step); 1.174 + return entry; 1.175 +} 1.176 + 1.177 + 1.178 +address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, 1.179 + int step) { 1.180 + address entry = __ pc(); 1.181 + // NULL last_sp until next java call 1.182 + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 1.183 + __ restore_bcp(); 1.184 + __ restore_locals(); 1.185 + // handle exceptions 1.186 + { 1.187 + Label L; 1.188 + __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int) NULL); 1.189 + __ jcc(Assembler::zero, L); 1.190 + __ call_VM(noreg, 1.191 + CAST_FROM_FN_PTR(address, 1.192 + InterpreterRuntime::throw_pending_exception)); 1.193 + __ should_not_reach_here(); 1.194 + __ bind(L); 1.195 + } 1.196 + __ dispatch_next(state, step); 1.197 + return entry; 1.198 +} 1.199 + 1.200 +int AbstractInterpreter::BasicType_as_index(BasicType type) { 1.201 + int i = 0; 1.202 + switch (type) { 1.203 + case T_BOOLEAN: i = 0; break; 1.204 + case T_CHAR : i = 1; break; 1.205 + case T_BYTE : i = 2; break; 1.206 + case T_SHORT : i = 3; break; 1.207 + case T_INT : i = 4; break; 1.208 + case T_LONG : i = 5; break; 1.209 + case T_VOID : i = 6; break; 1.210 + case T_FLOAT : i = 7; break; 1.211 + case T_DOUBLE : i = 8; break; 1.212 + case T_OBJECT : i = 9; break; 1.213 + case T_ARRAY : i = 9; break; 1.214 + default : ShouldNotReachHere(); 1.215 + } 1.216 + assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, 1.217 + "index out of bounds"); 1.218 + return i; 1.219 +} 1.220 + 1.221 + 1.222 +address TemplateInterpreterGenerator::generate_result_handler_for( 1.223 + BasicType type) { 1.224 + address entry = __ pc(); 1.225 + switch (type) { 1.226 + case T_BOOLEAN: __ c2bool(rax); break; 1.227 + case T_CHAR : __ movzwl(rax, rax); break; 1.228 + case T_BYTE : __ sign_extend_byte(rax); break; 1.229 + case T_SHORT : __ sign_extend_short(rax); break; 1.230 + case T_INT : /* nothing to do */ break; 1.231 + case T_LONG : /* nothing to do */ break; 1.232 + case T_VOID : /* nothing to do */ break; 1.233 + case T_FLOAT : /* nothing to do */ break; 1.234 + case T_DOUBLE : /* nothing to do */ break; 1.235 + case T_OBJECT : 1.236 + // retrieve result from frame 1.237 + __ movq(rax, Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize)); 1.238 + // and verify it 1.239 + __ verify_oop(rax); 1.240 + break; 1.241 + default : ShouldNotReachHere(); 1.242 + } 1.243 + __ ret(0); // return from result handler 1.244 + return entry; 1.245 +} 1.246 + 1.247 +address TemplateInterpreterGenerator::generate_safept_entry_for( 1.248 + TosState state, 1.249 + address runtime_entry) { 1.250 + address entry = __ pc(); 1.251 + __ push(state); 1.252 + __ call_VM(noreg, runtime_entry); 1.253 + __ dispatch_via(vtos, Interpreter::_normal_table.table_for(vtos)); 1.254 + return entry; 1.255 +} 1.256 + 1.257 + 1.258 + 1.259 +// Helpers for commoning out cases in the various type of method entries. 1.260 +// 1.261 + 1.262 + 1.263 +// increment invocation count & check for overflow 1.264 +// 1.265 +// Note: checking for negative value instead of overflow 1.266 +// so we have a 'sticky' overflow test 1.267 +// 1.268 +// rbx: method 1.269 +// ecx: invocation counter 1.270 +// 1.271 +void InterpreterGenerator::generate_counter_incr( 1.272 + Label* overflow, 1.273 + Label* profile_method, 1.274 + Label* profile_method_continue) { 1.275 + 1.276 + const Address invocation_counter(rbx, 1.277 + methodOopDesc::invocation_counter_offset() + 1.278 + InvocationCounter::counter_offset()); 1.279 + const Address backedge_counter(rbx, 1.280 + methodOopDesc::backedge_counter_offset() + 1.281 + InvocationCounter::counter_offset()); 1.282 + 1.283 + if (ProfileInterpreter) { // %%% Merge this into methodDataOop 1.284 + __ incrementl(Address(rbx, 1.285 + methodOopDesc::interpreter_invocation_counter_offset())); 1.286 + } 1.287 + // Update standard invocation counters 1.288 + __ movl(rax, backedge_counter); // load backedge counter 1.289 + 1.290 + __ incrementl(rcx, InvocationCounter::count_increment); 1.291 + __ andl(rax, InvocationCounter::count_mask_value); // mask out the 1.292 + // status bits 1.293 + 1.294 + __ movl(invocation_counter, rcx); // save invocation count 1.295 + __ addl(rcx, rax); // add both counters 1.296 + 1.297 + // profile_method is non-null only for interpreted method so 1.298 + // profile_method != NULL == !native_call 1.299 + 1.300 + if (ProfileInterpreter && profile_method != NULL) { 1.301 + // Test to see if we should create a method data oop 1.302 + __ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterProfileLimit)); 1.303 + __ jcc(Assembler::less, *profile_method_continue); 1.304 + 1.305 + // if no method data exists, go to profile_method 1.306 + __ test_method_data_pointer(rax, *profile_method); 1.307 + } 1.308 + 1.309 + __ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit)); 1.310 + __ jcc(Assembler::aboveEqual, *overflow); 1.311 +} 1.312 + 1.313 +void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { 1.314 + 1.315 + // Asm interpreter on entry 1.316 + // r14 - locals 1.317 + // r13 - bcp 1.318 + // rbx - method 1.319 + // edx - cpool --- DOES NOT APPEAR TO BE TRUE 1.320 + // rbp - interpreter frame 1.321 + 1.322 + // On return (i.e. jump to entry_point) [ back to invocation of interpreter ] 1.323 + // Everything as it was on entry 1.324 + // rdx is not restored. Doesn't appear to really be set. 1.325 + 1.326 + const Address size_of_parameters(rbx, 1.327 + methodOopDesc::size_of_parameters_offset()); 1.328 + 1.329 + // InterpreterRuntime::frequency_counter_overflow takes two 1.330 + // arguments, the first (thread) is passed by call_VM, the second 1.331 + // indicates if the counter overflow occurs at a backwards branch 1.332 + // (NULL bcp). We pass zero for it. The call returns the address 1.333 + // of the verified entry point for the method or NULL if the 1.334 + // compilation did not complete (either went background or bailed 1.335 + // out). 1.336 + __ movl(c_rarg1, 0); 1.337 + __ call_VM(noreg, 1.338 + CAST_FROM_FN_PTR(address, 1.339 + InterpreterRuntime::frequency_counter_overflow), 1.340 + c_rarg1); 1.341 + 1.342 + __ movq(rbx, Address(rbp, method_offset)); // restore methodOop 1.343 + // Preserve invariant that r13/r14 contain bcp/locals of sender frame 1.344 + // and jump to the interpreted entry. 1.345 + __ jmp(*do_continue, relocInfo::none); 1.346 +} 1.347 + 1.348 +// See if we've got enough room on the stack for locals plus overhead. 1.349 +// The expression stack grows down incrementally, so the normal guard 1.350 +// page mechanism will work for that. 1.351 +// 1.352 +// NOTE: Since the additional locals are also always pushed (wasn't 1.353 +// obvious in generate_method_entry) so the guard should work for them 1.354 +// too. 1.355 +// 1.356 +// Args: 1.357 +// rdx: number of additional locals this frame needs (what we must check) 1.358 +// rbx: methodOop 1.359 +// 1.360 +// Kills: 1.361 +// rax 1.362 +void InterpreterGenerator::generate_stack_overflow_check(void) { 1.363 + 1.364 + // monitor entry size: see picture of stack set 1.365 + // (generate_method_entry) and frame_amd64.hpp 1.366 + const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; 1.367 + 1.368 + // total overhead size: entry_size + (saved rbp through expr stack 1.369 + // bottom). be sure to change this if you add/subtract anything 1.370 + // to/from the overhead area 1.371 + const int overhead_size = 1.372 + -(frame::interpreter_frame_initial_sp_offset * wordSize) + entry_size; 1.373 + 1.374 + const int page_size = os::vm_page_size(); 1.375 + 1.376 + Label after_frame_check; 1.377 + 1.378 + // see if the frame is greater than one page in size. If so, 1.379 + // then we need to verify there is enough stack space remaining 1.380 + // for the additional locals. 1.381 + __ cmpl(rdx, (page_size - overhead_size) / Interpreter::stackElementSize()); 1.382 + __ jcc(Assembler::belowEqual, after_frame_check); 1.383 + 1.384 + // compute rsp as if this were going to be the last frame on 1.385 + // the stack before the red zone 1.386 + 1.387 + const Address stack_base(r15_thread, Thread::stack_base_offset()); 1.388 + const Address stack_size(r15_thread, Thread::stack_size_offset()); 1.389 + 1.390 + // locals + overhead, in bytes 1.391 + __ movq(rax, rdx); 1.392 + __ shll(rax, Interpreter::logStackElementSize()); // 2 slots per parameter. 1.393 + __ addq(rax, overhead_size); 1.394 + 1.395 +#ifdef ASSERT 1.396 + Label stack_base_okay, stack_size_okay; 1.397 + // verify that thread stack base is non-zero 1.398 + __ cmpq(stack_base, 0); 1.399 + __ jcc(Assembler::notEqual, stack_base_okay); 1.400 + __ stop("stack base is zero"); 1.401 + __ bind(stack_base_okay); 1.402 + // verify that thread stack size is non-zero 1.403 + __ cmpq(stack_size, 0); 1.404 + __ jcc(Assembler::notEqual, stack_size_okay); 1.405 + __ stop("stack size is zero"); 1.406 + __ bind(stack_size_okay); 1.407 +#endif 1.408 + 1.409 + // Add stack base to locals and subtract stack size 1.410 + __ addq(rax, stack_base); 1.411 + __ subq(rax, stack_size); 1.412 + 1.413 + // add in the red and yellow zone sizes 1.414 + __ addq(rax, (StackRedPages + StackYellowPages) * page_size); 1.415 + 1.416 + // check against the current stack bottom 1.417 + __ cmpq(rsp, rax); 1.418 + __ jcc(Assembler::above, after_frame_check); 1.419 + 1.420 + __ popq(rax); // get return address 1.421 + __ jump(ExternalAddress(Interpreter::throw_StackOverflowError_entry())); 1.422 + 1.423 + // all done with frame size check 1.424 + __ bind(after_frame_check); 1.425 +} 1.426 + 1.427 +// Allocate monitor and lock method (asm interpreter) 1.428 +// 1.429 +// Args: 1.430 +// rbx: methodOop 1.431 +// r14: locals 1.432 +// 1.433 +// Kills: 1.434 +// rax 1.435 +// c_rarg0, c_rarg1, c_rarg2, c_rarg3, ...(param regs) 1.436 +// rscratch1, rscratch2 (scratch regs) 1.437 +void InterpreterGenerator::lock_method(void) { 1.438 + // synchronize method 1.439 + const Address access_flags(rbx, methodOopDesc::access_flags_offset()); 1.440 + const Address monitor_block_top( 1.441 + rbp, 1.442 + frame::interpreter_frame_monitor_block_top_offset * wordSize); 1.443 + const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; 1.444 + 1.445 +#ifdef ASSERT 1.446 + { 1.447 + Label L; 1.448 + __ movl(rax, access_flags); 1.449 + __ testl(rax, JVM_ACC_SYNCHRONIZED); 1.450 + __ jcc(Assembler::notZero, L); 1.451 + __ stop("method doesn't need synchronization"); 1.452 + __ bind(L); 1.453 + } 1.454 +#endif // ASSERT 1.455 + 1.456 + // get synchronization object 1.457 + { 1.458 + const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + 1.459 + Klass::java_mirror_offset_in_bytes(); 1.460 + Label done; 1.461 + __ movl(rax, access_flags); 1.462 + __ testl(rax, JVM_ACC_STATIC); 1.463 + // get receiver (assume this is frequent case) 1.464 + __ movq(rax, Address(r14, Interpreter::local_offset_in_bytes(0))); 1.465 + __ jcc(Assembler::zero, done); 1.466 + __ movq(rax, Address(rbx, methodOopDesc::constants_offset())); 1.467 + __ movq(rax, Address(rax, 1.468 + constantPoolOopDesc::pool_holder_offset_in_bytes())); 1.469 + __ movq(rax, Address(rax, mirror_offset)); 1.470 + 1.471 +#ifdef ASSERT 1.472 + { 1.473 + Label L; 1.474 + __ testq(rax, rax); 1.475 + __ jcc(Assembler::notZero, L); 1.476 + __ stop("synchronization object is NULL"); 1.477 + __ bind(L); 1.478 + } 1.479 +#endif // ASSERT 1.480 + 1.481 + __ bind(done); 1.482 + } 1.483 + 1.484 + // add space for monitor & lock 1.485 + __ subq(rsp, entry_size); // add space for a monitor entry 1.486 + __ movq(monitor_block_top, rsp); // set new monitor block top 1.487 + // store object 1.488 + __ movq(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); 1.489 + __ movq(c_rarg1, rsp); // object address 1.490 + __ lock_object(c_rarg1); 1.491 +} 1.492 + 1.493 +// Generate a fixed interpreter frame. This is identical setup for 1.494 +// interpreted methods and for native methods hence the shared code. 1.495 +// 1.496 +// Args: 1.497 +// rax: return address 1.498 +// rbx: methodOop 1.499 +// r14: pointer to locals 1.500 +// r13: sender sp 1.501 +// rdx: cp cache 1.502 +void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { 1.503 + // initialize fixed part of activation frame 1.504 + __ pushq(rax); // save return address 1.505 + __ enter(); // save old & set new rbp 1.506 + __ pushq(r13); // set sender sp 1.507 + __ pushq((int)NULL_WORD); // leave last_sp as null 1.508 + __ movq(r13, Address(rbx, methodOopDesc::const_offset())); // get constMethodOop 1.509 + __ leaq(r13, Address(r13, constMethodOopDesc::codes_offset())); // get codebase 1.510 + __ pushq(rbx); // save methodOop 1.511 + if (ProfileInterpreter) { 1.512 + Label method_data_continue; 1.513 + __ movq(rdx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); 1.514 + __ testq(rdx, rdx); 1.515 + __ jcc(Assembler::zero, method_data_continue); 1.516 + __ addq(rdx, in_bytes(methodDataOopDesc::data_offset())); 1.517 + __ bind(method_data_continue); 1.518 + __ pushq(rdx); // set the mdp (method data pointer) 1.519 + } else { 1.520 + __ pushq(0); 1.521 + } 1.522 + 1.523 + __ movq(rdx, Address(rbx, methodOopDesc::constants_offset())); 1.524 + __ movq(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); 1.525 + __ pushq(rdx); // set constant pool cache 1.526 + __ pushq(r14); // set locals pointer 1.527 + if (native_call) { 1.528 + __ pushq(0); // no bcp 1.529 + } else { 1.530 + __ pushq(r13); // set bcp 1.531 + } 1.532 + __ pushq(0); // reserve word for pointer to expression stack bottom 1.533 + __ movq(Address(rsp, 0), rsp); // set expression stack bottom 1.534 +} 1.535 + 1.536 +// End of helpers 1.537 + 1.538 +// Interpreter stub for calling a native method. (asm interpreter) 1.539 +// This sets up a somewhat different looking stack for calling the 1.540 +// native method than the typical interpreter frame setup. 1.541 +address InterpreterGenerator::generate_native_entry(bool synchronized) { 1.542 + // determine code generation flags 1.543 + bool inc_counter = UseCompiler || CountCompiledCalls; 1.544 + 1.545 + // rbx: methodOop 1.546 + // r13: sender sp 1.547 + 1.548 + address entry_point = __ pc(); 1.549 + 1.550 + const Address size_of_parameters(rbx, methodOopDesc:: 1.551 + size_of_parameters_offset()); 1.552 + const Address invocation_counter(rbx, methodOopDesc:: 1.553 + invocation_counter_offset() + 1.554 + InvocationCounter::counter_offset()); 1.555 + const Address access_flags (rbx, methodOopDesc::access_flags_offset()); 1.556 + 1.557 + // get parameter size (always needed) 1.558 + __ load_unsigned_word(rcx, size_of_parameters); 1.559 + 1.560 + // native calls don't need the stack size check since they have no 1.561 + // expression stack and the arguments are already on the stack and 1.562 + // we only add a handful of words to the stack 1.563 + 1.564 + // rbx: methodOop 1.565 + // rcx: size of parameters 1.566 + // r13: sender sp 1.567 + __ popq(rax); // get return address 1.568 + 1.569 + // for natives the size of locals is zero 1.570 + 1.571 + // compute beginning of parameters (r14) 1.572 + if (TaggedStackInterpreter) __ shll(rcx, 1); // 2 slots per parameter. 1.573 + __ leaq(r14, Address(rsp, rcx, Address::times_8, -wordSize)); 1.574 + 1.575 + // add 2 zero-initialized slots for native calls 1.576 + // initialize result_handler slot 1.577 + __ pushq((int) NULL); 1.578 + // slot for oop temp 1.579 + // (static native method holder mirror/jni oop result) 1.580 + __ pushq((int) NULL); 1.581 + 1.582 + if (inc_counter) { 1.583 + __ movl(rcx, invocation_counter); // (pre-)fetch invocation count 1.584 + } 1.585 + 1.586 + // initialize fixed part of activation frame 1.587 + generate_fixed_frame(true); 1.588 + 1.589 + // make sure method is native & not abstract 1.590 +#ifdef ASSERT 1.591 + __ movl(rax, access_flags); 1.592 + { 1.593 + Label L; 1.594 + __ testl(rax, JVM_ACC_NATIVE); 1.595 + __ jcc(Assembler::notZero, L); 1.596 + __ stop("tried to execute non-native method as native"); 1.597 + __ bind(L); 1.598 + } 1.599 + { 1.600 + Label L; 1.601 + __ testl(rax, JVM_ACC_ABSTRACT); 1.602 + __ jcc(Assembler::zero, L); 1.603 + __ stop("tried to execute abstract method in interpreter"); 1.604 + __ bind(L); 1.605 + } 1.606 +#endif 1.607 + 1.608 + // Since at this point in the method invocation the exception handler 1.609 + // would try to exit the monitor of synchronized methods which hasn't 1.610 + // been entered yet, we set the thread local variable 1.611 + // _do_not_unlock_if_synchronized to true. The remove_activation will 1.612 + // check this flag. 1.613 + 1.614 + const Address do_not_unlock_if_synchronized(r15_thread, 1.615 + in_bytes(JavaThread::do_not_unlock_if_synchronized_offset())); 1.616 + __ movbool(do_not_unlock_if_synchronized, true); 1.617 + 1.618 + // increment invocation count & check for overflow 1.619 + Label invocation_counter_overflow; 1.620 + if (inc_counter) { 1.621 + generate_counter_incr(&invocation_counter_overflow, NULL, NULL); 1.622 + } 1.623 + 1.624 + Label continue_after_compile; 1.625 + __ bind(continue_after_compile); 1.626 + 1.627 + bang_stack_shadow_pages(true); 1.628 + 1.629 + // reset the _do_not_unlock_if_synchronized flag 1.630 + __ movbool(do_not_unlock_if_synchronized, false); 1.631 + 1.632 + // check for synchronized methods 1.633 + // Must happen AFTER invocation_counter check and stack overflow check, 1.634 + // so method is not locked if overflows. 1.635 + if (synchronized) { 1.636 + lock_method(); 1.637 + } else { 1.638 + // no synchronization necessary 1.639 +#ifdef ASSERT 1.640 + { 1.641 + Label L; 1.642 + __ movl(rax, access_flags); 1.643 + __ testl(rax, JVM_ACC_SYNCHRONIZED); 1.644 + __ jcc(Assembler::zero, L); 1.645 + __ stop("method needs synchronization"); 1.646 + __ bind(L); 1.647 + } 1.648 +#endif 1.649 + } 1.650 + 1.651 + // start execution 1.652 +#ifdef ASSERT 1.653 + { 1.654 + Label L; 1.655 + const Address monitor_block_top(rbp, 1.656 + frame::interpreter_frame_monitor_block_top_offset * wordSize); 1.657 + __ movq(rax, monitor_block_top); 1.658 + __ cmpq(rax, rsp); 1.659 + __ jcc(Assembler::equal, L); 1.660 + __ stop("broken stack frame setup in interpreter"); 1.661 + __ bind(L); 1.662 + } 1.663 +#endif 1.664 + 1.665 + // jvmti support 1.666 + __ notify_method_entry(); 1.667 + 1.668 + // work registers 1.669 + const Register method = rbx; 1.670 + const Register t = r12; 1.671 + 1.672 + // allocate space for parameters 1.673 + __ get_method(method); 1.674 + __ verify_oop(method); 1.675 + __ load_unsigned_word(t, 1.676 + Address(method, 1.677 + methodOopDesc::size_of_parameters_offset())); 1.678 + __ shll(t, Interpreter::logStackElementSize()); 1.679 + 1.680 + __ subq(rsp, t); 1.681 + __ subq(rsp, frame::arg_reg_save_area_bytes); // windows 1.682 + __ andq(rsp, -16); // must be 16 byte boundry (see amd64 ABI) 1.683 + 1.684 + // get signature handler 1.685 + { 1.686 + Label L; 1.687 + __ movq(t, Address(method, methodOopDesc::signature_handler_offset())); 1.688 + __ testq(t, t); 1.689 + __ jcc(Assembler::notZero, L); 1.690 + __ call_VM(noreg, 1.691 + CAST_FROM_FN_PTR(address, 1.692 + InterpreterRuntime::prepare_native_call), 1.693 + method); 1.694 + __ get_method(method); 1.695 + __ movq(t, Address(method, methodOopDesc::signature_handler_offset())); 1.696 + __ bind(L); 1.697 + } 1.698 + 1.699 + // call signature handler 1.700 + assert(InterpreterRuntime::SignatureHandlerGenerator::from() == r14, 1.701 + "adjust this code"); 1.702 + assert(InterpreterRuntime::SignatureHandlerGenerator::to() == rsp, 1.703 + "adjust this code"); 1.704 + assert(InterpreterRuntime::SignatureHandlerGenerator::temp() == rscratch1, 1.705 + "adjust this code"); 1.706 + 1.707 + // The generated handlers do not touch RBX (the method oop). 1.708 + // However, large signatures cannot be cached and are generated 1.709 + // each time here. The slow-path generator can do a GC on return, 1.710 + // so we must reload it after the call. 1.711 + __ call(t); 1.712 + __ get_method(method); // slow path can do a GC, reload RBX 1.713 + 1.714 + 1.715 + // result handler is in rax 1.716 + // set result handler 1.717 + __ movq(Address(rbp, 1.718 + (frame::interpreter_frame_result_handler_offset) * wordSize), 1.719 + rax); 1.720 + 1.721 + // pass mirror handle if static call 1.722 + { 1.723 + Label L; 1.724 + const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + 1.725 + Klass::java_mirror_offset_in_bytes(); 1.726 + __ movl(t, Address(method, methodOopDesc::access_flags_offset())); 1.727 + __ testl(t, JVM_ACC_STATIC); 1.728 + __ jcc(Assembler::zero, L); 1.729 + // get mirror 1.730 + __ movq(t, Address(method, methodOopDesc::constants_offset())); 1.731 + __ movq(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); 1.732 + __ movq(t, Address(t, mirror_offset)); 1.733 + // copy mirror into activation frame 1.734 + __ movq(Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize), 1.735 + t); 1.736 + // pass handle to mirror 1.737 + __ leaq(c_rarg1, 1.738 + Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize)); 1.739 + __ bind(L); 1.740 + } 1.741 + 1.742 + // get native function entry point 1.743 + { 1.744 + Label L; 1.745 + __ movq(rax, Address(method, methodOopDesc::native_function_offset())); 1.746 + ExternalAddress unsatisfied(SharedRuntime::native_method_throw_unsatisfied_link_error_entry()); 1.747 + __ movptr(rscratch2, unsatisfied.addr()); 1.748 + __ cmpq(rax, rscratch2); 1.749 + __ jcc(Assembler::notEqual, L); 1.750 + __ call_VM(noreg, 1.751 + CAST_FROM_FN_PTR(address, 1.752 + InterpreterRuntime::prepare_native_call), 1.753 + method); 1.754 + __ get_method(method); 1.755 + __ verify_oop(method); 1.756 + __ movq(rax, Address(method, methodOopDesc::native_function_offset())); 1.757 + __ bind(L); 1.758 + } 1.759 + 1.760 + // pass JNIEnv 1.761 + __ leaq(c_rarg0, Address(r15_thread, JavaThread::jni_environment_offset())); 1.762 + 1.763 + // It is enough that the pc() points into the right code 1.764 + // segment. It does not have to be the correct return pc. 1.765 + __ set_last_Java_frame(rsp, rbp, (address) __ pc()); 1.766 + 1.767 + // change thread state 1.768 +#ifdef ASSERT 1.769 + { 1.770 + Label L; 1.771 + __ movl(t, Address(r15_thread, JavaThread::thread_state_offset())); 1.772 + __ cmpl(t, _thread_in_Java); 1.773 + __ jcc(Assembler::equal, L); 1.774 + __ stop("Wrong thread state in native stub"); 1.775 + __ bind(L); 1.776 + } 1.777 +#endif 1.778 + 1.779 + // Change state to native 1.780 + 1.781 + __ movl(Address(r15_thread, JavaThread::thread_state_offset()), 1.782 + _thread_in_native); 1.783 + 1.784 + // Call the native method. 1.785 + __ call(rax); 1.786 + // result potentially in rax or xmm0 1.787 + 1.788 + // Depending on runtime options, either restore the MXCSR 1.789 + // register after returning from the JNI Call or verify that 1.790 + // it wasn't changed during -Xcheck:jni. 1.791 + if (RestoreMXCSROnJNICalls) { 1.792 + __ ldmxcsr(ExternalAddress(StubRoutines::amd64::mxcsr_std())); 1.793 + } 1.794 + else if (CheckJNICalls) { 1.795 + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::amd64::verify_mxcsr_entry()))); 1.796 + } 1.797 + 1.798 + // NOTE: The order of these pushes is known to frame::interpreter_frame_result 1.799 + // in order to extract the result of a method call. If the order of these 1.800 + // pushes change or anything else is added to the stack then the code in 1.801 + // interpreter_frame_result must also change. 1.802 + 1.803 + __ push(dtos); 1.804 + __ push(ltos); 1.805 + 1.806 + // change thread state 1.807 + __ movl(Address(r15_thread, JavaThread::thread_state_offset()), 1.808 + _thread_in_native_trans); 1.809 + 1.810 + if (os::is_MP()) { 1.811 + if (UseMembar) { 1.812 + // Force this write out before the read below 1.813 + __ membar(Assembler::Membar_mask_bits( 1.814 + Assembler::LoadLoad | Assembler::LoadStore | 1.815 + Assembler::StoreLoad | Assembler::StoreStore)); 1.816 + } else { 1.817 + // Write serialization page so VM thread can do a pseudo remote membar. 1.818 + // We use the current thread pointer to calculate a thread specific 1.819 + // offset to write to within the page. This minimizes bus traffic 1.820 + // due to cache line collision. 1.821 + __ serialize_memory(r15_thread, rscratch2); 1.822 + } 1.823 + } 1.824 + 1.825 + // check for safepoint operation in progress and/or pending suspend requests 1.826 + { 1.827 + Label Continue; 1.828 + __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), 1.829 + SafepointSynchronize::_not_synchronized); 1.830 + 1.831 + Label L; 1.832 + __ jcc(Assembler::notEqual, L); 1.833 + __ cmpl(Address(r15_thread, JavaThread::suspend_flags_offset()), 0); 1.834 + __ jcc(Assembler::equal, Continue); 1.835 + __ bind(L); 1.836 + 1.837 + // Don't use call_VM as it will see a possible pending exception 1.838 + // and forward it and never return here preventing us from 1.839 + // clearing _last_native_pc down below. Also can't use 1.840 + // call_VM_leaf either as it will check to see if r13 & r14 are 1.841 + // preserved and correspond to the bcp/locals pointers. So we do a 1.842 + // runtime call by hand. 1.843 + // 1.844 + __ movq(c_rarg0, r15_thread); 1.845 + __ movq(r12, rsp); // remember sp 1.846 + __ subq(rsp, frame::arg_reg_save_area_bytes); // windows 1.847 + __ andq(rsp, -16); // align stack as required by ABI 1.848 + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); 1.849 + __ movq(rsp, r12); // restore sp 1.850 + __ bind(Continue); 1.851 + } 1.852 + 1.853 + // change thread state 1.854 + __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_Java); 1.855 + 1.856 + // reset_last_Java_frame 1.857 + __ reset_last_Java_frame(true, true); 1.858 + 1.859 + // reset handle block 1.860 + __ movq(t, Address(r15_thread, JavaThread::active_handles_offset())); 1.861 + __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD); 1.862 + 1.863 + // If result is an oop unbox and store it in frame where gc will see it 1.864 + // and result handler will pick it up 1.865 + 1.866 + { 1.867 + Label no_oop, store_result; 1.868 + __ lea(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT))); 1.869 + __ cmpq(t, Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize)); 1.870 + __ jcc(Assembler::notEqual, no_oop); 1.871 + // retrieve result 1.872 + __ pop(ltos); 1.873 + __ testq(rax, rax); 1.874 + __ jcc(Assembler::zero, store_result); 1.875 + __ movq(rax, Address(rax, 0)); 1.876 + __ bind(store_result); 1.877 + __ movq(Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize), rax); 1.878 + // keep stack depth as expected by pushing oop which will eventually be discarde 1.879 + __ push(ltos); 1.880 + __ bind(no_oop); 1.881 + } 1.882 + 1.883 + 1.884 + { 1.885 + Label no_reguard; 1.886 + __ cmpl(Address(r15_thread, JavaThread::stack_guard_state_offset()), 1.887 + JavaThread::stack_guard_yellow_disabled); 1.888 + __ jcc(Assembler::notEqual, no_reguard); 1.889 + 1.890 + __ pushaq(); // XXX only save smashed registers 1.891 + __ movq(r12, rsp); // remember sp 1.892 + __ subq(rsp, frame::arg_reg_save_area_bytes); // windows 1.893 + __ andq(rsp, -16); // align stack as required by ABI 1.894 + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages))); 1.895 + __ movq(rsp, r12); // restore sp 1.896 + __ popaq(); // XXX only restore smashed registers 1.897 + 1.898 + __ bind(no_reguard); 1.899 + } 1.900 + 1.901 + 1.902 + // The method register is junk from after the thread_in_native transition 1.903 + // until here. Also can't call_VM until the bcp has been 1.904 + // restored. Need bcp for throwing exception below so get it now. 1.905 + __ get_method(method); 1.906 + __ verify_oop(method); 1.907 + 1.908 + // restore r13 to have legal interpreter frame, i.e., bci == 0 <=> 1.909 + // r13 == code_base() 1.910 + __ movq(r13, Address(method, methodOopDesc::const_offset())); // get constMethodOop 1.911 + __ leaq(r13, Address(r13, constMethodOopDesc::codes_offset())); // get codebase 1.912 + // handle exceptions (exception handling will handle unlocking!) 1.913 + { 1.914 + Label L; 1.915 + __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int) NULL); 1.916 + __ jcc(Assembler::zero, L); 1.917 + // Note: At some point we may want to unify this with the code 1.918 + // used in call_VM_base(); i.e., we should use the 1.919 + // StubRoutines::forward_exception code. For now this doesn't work 1.920 + // here because the rsp is not correctly set at this point. 1.921 + __ MacroAssembler::call_VM(noreg, 1.922 + CAST_FROM_FN_PTR(address, 1.923 + InterpreterRuntime::throw_pending_exception)); 1.924 + __ should_not_reach_here(); 1.925 + __ bind(L); 1.926 + } 1.927 + 1.928 + // do unlocking if necessary 1.929 + { 1.930 + Label L; 1.931 + __ movl(t, Address(method, methodOopDesc::access_flags_offset())); 1.932 + __ testl(t, JVM_ACC_SYNCHRONIZED); 1.933 + __ jcc(Assembler::zero, L); 1.934 + // the code below should be shared with interpreter macro 1.935 + // assembler implementation 1.936 + { 1.937 + Label unlock; 1.938 + // BasicObjectLock will be first in list, since this is a 1.939 + // synchronized method. However, need to check that the object 1.940 + // has not been unlocked by an explicit monitorexit bytecode. 1.941 + const Address monitor(rbp, 1.942 + (intptr_t)(frame::interpreter_frame_initial_sp_offset * 1.943 + wordSize - sizeof(BasicObjectLock))); 1.944 + 1.945 + // monitor expect in c_rarg1 for slow unlock path 1.946 + __ leaq(c_rarg1, monitor); // address of first monitor 1.947 + 1.948 + __ movq(t, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); 1.949 + __ testq(t, t); 1.950 + __ jcc(Assembler::notZero, unlock); 1.951 + 1.952 + // Entry already unlocked, need to throw exception 1.953 + __ MacroAssembler::call_VM(noreg, 1.954 + CAST_FROM_FN_PTR(address, 1.955 + InterpreterRuntime::throw_illegal_monitor_state_exception)); 1.956 + __ should_not_reach_here(); 1.957 + 1.958 + __ bind(unlock); 1.959 + __ unlock_object(c_rarg1); 1.960 + } 1.961 + __ bind(L); 1.962 + } 1.963 + 1.964 + // jvmti support 1.965 + // Note: This must happen _after_ handling/throwing any exceptions since 1.966 + // the exception handler code notifies the runtime of method exits 1.967 + // too. If this happens before, method entry/exit notifications are 1.968 + // not properly paired (was bug - gri 11/22/99). 1.969 + __ notify_method_exit(vtos, InterpreterMacroAssembler::NotifyJVMTI); 1.970 + 1.971 + // restore potential result in edx:eax, call result handler to 1.972 + // restore potential result in ST0 & handle result 1.973 + 1.974 + __ pop(ltos); 1.975 + __ pop(dtos); 1.976 + 1.977 + __ movq(t, Address(rbp, 1.978 + (frame::interpreter_frame_result_handler_offset) * wordSize)); 1.979 + __ call(t); 1.980 + 1.981 + // remove activation 1.982 + __ movq(t, Address(rbp, 1.983 + frame::interpreter_frame_sender_sp_offset * 1.984 + wordSize)); // get sender sp 1.985 + __ leave(); // remove frame anchor 1.986 + __ popq(rdi); // get return address 1.987 + __ movq(rsp, t); // set sp to sender sp 1.988 + __ jmp(rdi); 1.989 + 1.990 + if (inc_counter) { 1.991 + // Handle overflow of counter and compile method 1.992 + __ bind(invocation_counter_overflow); 1.993 + generate_counter_overflow(&continue_after_compile); 1.994 + } 1.995 + 1.996 + return entry_point; 1.997 +} 1.998 + 1.999 +// 1.1000 +// Generic interpreted method entry to (asm) interpreter 1.1001 +// 1.1002 +address InterpreterGenerator::generate_normal_entry(bool synchronized) { 1.1003 + // determine code generation flags 1.1004 + bool inc_counter = UseCompiler || CountCompiledCalls; 1.1005 + 1.1006 + // ebx: methodOop 1.1007 + // r13: sender sp 1.1008 + address entry_point = __ pc(); 1.1009 + 1.1010 + const Address size_of_parameters(rbx, 1.1011 + methodOopDesc::size_of_parameters_offset()); 1.1012 + const Address size_of_locals(rbx, methodOopDesc::size_of_locals_offset()); 1.1013 + const Address invocation_counter(rbx, 1.1014 + methodOopDesc::invocation_counter_offset() + 1.1015 + InvocationCounter::counter_offset()); 1.1016 + const Address access_flags(rbx, methodOopDesc::access_flags_offset()); 1.1017 + 1.1018 + // get parameter size (always needed) 1.1019 + __ load_unsigned_word(rcx, size_of_parameters); 1.1020 + 1.1021 + // rbx: methodOop 1.1022 + // rcx: size of parameters 1.1023 + // r13: sender_sp (could differ from sp+wordSize if we were called via c2i ) 1.1024 + 1.1025 + __ load_unsigned_word(rdx, size_of_locals); // get size of locals in words 1.1026 + __ subl(rdx, rcx); // rdx = no. of additional locals 1.1027 + 1.1028 + // YYY 1.1029 +// __ incrementl(rdx); 1.1030 +// __ andl(rdx, -2); 1.1031 + 1.1032 + // see if we've got enough room on the stack for locals plus overhead. 1.1033 + generate_stack_overflow_check(); 1.1034 + 1.1035 + // get return address 1.1036 + __ popq(rax); 1.1037 + 1.1038 + // compute beginning of parameters (r14) 1.1039 + if (TaggedStackInterpreter) __ shll(rcx, 1); // 2 slots per parameter. 1.1040 + __ leaq(r14, Address(rsp, rcx, Address::times_8, -wordSize)); 1.1041 + 1.1042 + // rdx - # of additional locals 1.1043 + // allocate space for locals 1.1044 + // explicitly initialize locals 1.1045 + { 1.1046 + Label exit, loop; 1.1047 + __ testl(rdx, rdx); 1.1048 + __ jcc(Assembler::lessEqual, exit); // do nothing if rdx <= 0 1.1049 + __ bind(loop); 1.1050 + if (TaggedStackInterpreter) __ pushq((int) NULL); // push tag 1.1051 + __ pushq((int) NULL); // initialize local variables 1.1052 + __ decrementl(rdx); // until everything initialized 1.1053 + __ jcc(Assembler::greater, loop); 1.1054 + __ bind(exit); 1.1055 + } 1.1056 + 1.1057 + // (pre-)fetch invocation count 1.1058 + if (inc_counter) { 1.1059 + __ movl(rcx, invocation_counter); 1.1060 + } 1.1061 + // initialize fixed part of activation frame 1.1062 + generate_fixed_frame(false); 1.1063 + 1.1064 + // make sure method is not native & not abstract 1.1065 +#ifdef ASSERT 1.1066 + __ movl(rax, access_flags); 1.1067 + { 1.1068 + Label L; 1.1069 + __ testl(rax, JVM_ACC_NATIVE); 1.1070 + __ jcc(Assembler::zero, L); 1.1071 + __ stop("tried to execute native method as non-native"); 1.1072 + __ bind(L); 1.1073 + } 1.1074 + { 1.1075 + Label L; 1.1076 + __ testl(rax, JVM_ACC_ABSTRACT); 1.1077 + __ jcc(Assembler::zero, L); 1.1078 + __ stop("tried to execute abstract method in interpreter"); 1.1079 + __ bind(L); 1.1080 + } 1.1081 +#endif 1.1082 + 1.1083 + // Since at this point in the method invocation the exception 1.1084 + // handler would try to exit the monitor of synchronized methods 1.1085 + // which hasn't been entered yet, we set the thread local variable 1.1086 + // _do_not_unlock_if_synchronized to true. The remove_activation 1.1087 + // will check this flag. 1.1088 + 1.1089 + const Address do_not_unlock_if_synchronized(r15_thread, 1.1090 + in_bytes(JavaThread::do_not_unlock_if_synchronized_offset())); 1.1091 + __ movbool(do_not_unlock_if_synchronized, true); 1.1092 + 1.1093 + // increment invocation count & check for overflow 1.1094 + Label invocation_counter_overflow; 1.1095 + Label profile_method; 1.1096 + Label profile_method_continue; 1.1097 + if (inc_counter) { 1.1098 + generate_counter_incr(&invocation_counter_overflow, 1.1099 + &profile_method, 1.1100 + &profile_method_continue); 1.1101 + if (ProfileInterpreter) { 1.1102 + __ bind(profile_method_continue); 1.1103 + } 1.1104 + } 1.1105 + 1.1106 + Label continue_after_compile; 1.1107 + __ bind(continue_after_compile); 1.1108 + 1.1109 + // check for synchronized interpreted methods 1.1110 + bang_stack_shadow_pages(false); 1.1111 + 1.1112 + // reset the _do_not_unlock_if_synchronized flag 1.1113 + __ movbool(do_not_unlock_if_synchronized, false); 1.1114 + 1.1115 + // check for synchronized methods 1.1116 + // Must happen AFTER invocation_counter check and stack overflow check, 1.1117 + // so method is not locked if overflows. 1.1118 + if (synchronized) { 1.1119 + // Allocate monitor and lock method 1.1120 + lock_method(); 1.1121 + } else { 1.1122 + // no synchronization necessary 1.1123 +#ifdef ASSERT 1.1124 + { 1.1125 + Label L; 1.1126 + __ movl(rax, access_flags); 1.1127 + __ testl(rax, JVM_ACC_SYNCHRONIZED); 1.1128 + __ jcc(Assembler::zero, L); 1.1129 + __ stop("method needs synchronization"); 1.1130 + __ bind(L); 1.1131 + } 1.1132 +#endif 1.1133 + } 1.1134 + 1.1135 + // start execution 1.1136 +#ifdef ASSERT 1.1137 + { 1.1138 + Label L; 1.1139 + const Address monitor_block_top (rbp, 1.1140 + frame::interpreter_frame_monitor_block_top_offset * wordSize); 1.1141 + __ movq(rax, monitor_block_top); 1.1142 + __ cmpq(rax, rsp); 1.1143 + __ jcc(Assembler::equal, L); 1.1144 + __ stop("broken stack frame setup in interpreter"); 1.1145 + __ bind(L); 1.1146 + } 1.1147 +#endif 1.1148 + 1.1149 + // jvmti support 1.1150 + __ notify_method_entry(); 1.1151 + 1.1152 + __ dispatch_next(vtos); 1.1153 + 1.1154 + // invocation counter overflow 1.1155 + if (inc_counter) { 1.1156 + if (ProfileInterpreter) { 1.1157 + // We have decided to profile this method in the interpreter 1.1158 + __ bind(profile_method); 1.1159 + 1.1160 + __ call_VM(noreg, 1.1161 + CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method), 1.1162 + r13, true); 1.1163 + 1.1164 + __ movq(rbx, Address(rbp, method_offset)); // restore methodOop 1.1165 + __ movq(rax, Address(rbx, 1.1166 + in_bytes(methodOopDesc::method_data_offset()))); 1.1167 + __ movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), 1.1168 + rax); 1.1169 + __ test_method_data_pointer(rax, profile_method_continue); 1.1170 + __ addq(rax, in_bytes(methodDataOopDesc::data_offset())); 1.1171 + __ movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), 1.1172 + rax); 1.1173 + __ jmp(profile_method_continue); 1.1174 + } 1.1175 + // Handle overflow of counter and compile method 1.1176 + __ bind(invocation_counter_overflow); 1.1177 + generate_counter_overflow(&continue_after_compile); 1.1178 + } 1.1179 + 1.1180 + return entry_point; 1.1181 +} 1.1182 + 1.1183 +// Entry points 1.1184 +// 1.1185 +// Here we generate the various kind of entries into the interpreter. 1.1186 +// The two main entry type are generic bytecode methods and native 1.1187 +// call method. These both come in synchronized and non-synchronized 1.1188 +// versions but the frame layout they create is very similar. The 1.1189 +// other method entry types are really just special purpose entries 1.1190 +// that are really entry and interpretation all in one. These are for 1.1191 +// trivial methods like accessor, empty, or special math methods. 1.1192 +// 1.1193 +// When control flow reaches any of the entry types for the interpreter 1.1194 +// the following holds -> 1.1195 +// 1.1196 +// Arguments: 1.1197 +// 1.1198 +// rbx: methodOop 1.1199 +// 1.1200 +// Stack layout immediately at entry 1.1201 +// 1.1202 +// [ return address ] <--- rsp 1.1203 +// [ parameter n ] 1.1204 +// ... 1.1205 +// [ parameter 1 ] 1.1206 +// [ expression stack ] (caller's java expression stack) 1.1207 + 1.1208 +// Assuming that we don't go to one of the trivial specialized entries 1.1209 +// the stack will look like below when we are ready to execute the 1.1210 +// first bytecode (or call the native routine). The register usage 1.1211 +// will be as the template based interpreter expects (see 1.1212 +// interpreter_amd64.hpp). 1.1213 +// 1.1214 +// local variables follow incoming parameters immediately; i.e. 1.1215 +// the return address is moved to the end of the locals). 1.1216 +// 1.1217 +// [ monitor entry ] <--- rsp 1.1218 +// ... 1.1219 +// [ monitor entry ] 1.1220 +// [ expr. stack bottom ] 1.1221 +// [ saved r13 ] 1.1222 +// [ current r14 ] 1.1223 +// [ methodOop ] 1.1224 +// [ saved ebp ] <--- rbp 1.1225 +// [ return address ] 1.1226 +// [ local variable m ] 1.1227 +// ... 1.1228 +// [ local variable 1 ] 1.1229 +// [ parameter n ] 1.1230 +// ... 1.1231 +// [ parameter 1 ] <--- r14 1.1232 + 1.1233 +address AbstractInterpreterGenerator::generate_method_entry( 1.1234 + AbstractInterpreter::MethodKind kind) { 1.1235 + // determine code generation flags 1.1236 + bool synchronized = false; 1.1237 + address entry_point = NULL; 1.1238 + 1.1239 + switch (kind) { 1.1240 + case Interpreter::zerolocals : break; 1.1241 + case Interpreter::zerolocals_synchronized: synchronized = true; break; 1.1242 + case Interpreter::native : entry_point = ((InterpreterGenerator*) this)->generate_native_entry(false); break; 1.1243 + case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*) this)->generate_native_entry(true); break; 1.1244 + case Interpreter::empty : entry_point = ((InterpreterGenerator*) this)->generate_empty_entry(); break; 1.1245 + case Interpreter::accessor : entry_point = ((InterpreterGenerator*) this)->generate_accessor_entry(); break; 1.1246 + case Interpreter::abstract : entry_point = ((InterpreterGenerator*) this)->generate_abstract_entry(); break; 1.1247 + case Interpreter::java_lang_math_sin : break; 1.1248 + case Interpreter::java_lang_math_cos : break; 1.1249 + case Interpreter::java_lang_math_tan : break; 1.1250 + case Interpreter::java_lang_math_abs : break; 1.1251 + case Interpreter::java_lang_math_log : break; 1.1252 + case Interpreter::java_lang_math_log10 : break; 1.1253 + case Interpreter::java_lang_math_sqrt : entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind); break; 1.1254 + default : ShouldNotReachHere(); break; 1.1255 + } 1.1256 + 1.1257 + if (entry_point) { 1.1258 + return entry_point; 1.1259 + } 1.1260 + 1.1261 + return ((InterpreterGenerator*) this)-> 1.1262 + generate_normal_entry(synchronized); 1.1263 +} 1.1264 + 1.1265 +// How much stack a method activation needs in words. 1.1266 +int AbstractInterpreter::size_top_interpreter_activation(methodOop method) { 1.1267 + const int entry_size = frame::interpreter_frame_monitor_size(); 1.1268 + 1.1269 + // total overhead size: entry_size + (saved rbp thru expr stack 1.1270 + // bottom). be sure to change this if you add/subtract anything 1.1271 + // to/from the overhead area 1.1272 + const int overhead_size = 1.1273 + -(frame::interpreter_frame_initial_sp_offset) + entry_size; 1.1274 + 1.1275 + const int stub_code = frame::entry_frame_after_call_words; 1.1276 + const int method_stack = (method->max_locals() + method->max_stack()) * 1.1277 + Interpreter::stackElementWords(); 1.1278 + return (overhead_size + method_stack + stub_code); 1.1279 +} 1.1280 + 1.1281 +int AbstractInterpreter::layout_activation(methodOop method, 1.1282 + int tempcount, 1.1283 + int popframe_extra_args, 1.1284 + int moncount, 1.1285 + int callee_param_count, 1.1286 + int callee_locals, 1.1287 + frame* caller, 1.1288 + frame* interpreter_frame, 1.1289 + bool is_top_frame) { 1.1290 + // Note: This calculation must exactly parallel the frame setup 1.1291 + // in AbstractInterpreterGenerator::generate_method_entry. 1.1292 + // If interpreter_frame!=NULL, set up the method, locals, and monitors. 1.1293 + // The frame interpreter_frame, if not NULL, is guaranteed to be the 1.1294 + // right size, as determined by a previous call to this method. 1.1295 + // It is also guaranteed to be walkable even though it is in a skeletal state 1.1296 + 1.1297 + // fixed size of an interpreter frame: 1.1298 + int max_locals = method->max_locals() * Interpreter::stackElementWords(); 1.1299 + int extra_locals = (method->max_locals() - method->size_of_parameters()) * 1.1300 + Interpreter::stackElementWords(); 1.1301 + 1.1302 + int overhead = frame::sender_sp_offset - 1.1303 + frame::interpreter_frame_initial_sp_offset; 1.1304 + // Our locals were accounted for by the caller (or last_frame_adjust 1.1305 + // on the transistion) Since the callee parameters already account 1.1306 + // for the callee's params we only need to account for the extra 1.1307 + // locals. 1.1308 + int size = overhead + 1.1309 + (callee_locals - callee_param_count)*Interpreter::stackElementWords() + 1.1310 + moncount * frame::interpreter_frame_monitor_size() + 1.1311 + tempcount* Interpreter::stackElementWords() + popframe_extra_args; 1.1312 + if (interpreter_frame != NULL) { 1.1313 +#ifdef ASSERT 1.1314 + assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), 1.1315 + "Frame not properly walkable"); 1.1316 + assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable(2)"); 1.1317 +#endif 1.1318 + 1.1319 + interpreter_frame->interpreter_frame_set_method(method); 1.1320 + // NOTE the difference in using sender_sp and 1.1321 + // interpreter_frame_sender_sp interpreter_frame_sender_sp is 1.1322 + // the original sp of the caller (the unextended_sp) and 1.1323 + // sender_sp is fp+16 XXX 1.1324 + intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1; 1.1325 + 1.1326 + interpreter_frame->interpreter_frame_set_locals(locals); 1.1327 + BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin(); 1.1328 + BasicObjectLock* monbot = montop - moncount; 1.1329 + interpreter_frame->interpreter_frame_set_monitor_end(monbot); 1.1330 + 1.1331 + // Set last_sp 1.1332 + intptr_t* esp = (intptr_t*) monbot - 1.1333 + tempcount*Interpreter::stackElementWords() - 1.1334 + popframe_extra_args; 1.1335 + interpreter_frame->interpreter_frame_set_last_sp(esp); 1.1336 + 1.1337 + // All frames but the initial (oldest) interpreter frame we fill in have 1.1338 + // a value for sender_sp that allows walking the stack but isn't 1.1339 + // truly correct. Correct the value here. 1.1340 + if (extra_locals != 0 && 1.1341 + interpreter_frame->sender_sp() == 1.1342 + interpreter_frame->interpreter_frame_sender_sp()) { 1.1343 + interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() + 1.1344 + extra_locals); 1.1345 + } 1.1346 + *interpreter_frame->interpreter_frame_cache_addr() = 1.1347 + method->constants()->cache(); 1.1348 + } 1.1349 + return size; 1.1350 +} 1.1351 + 1.1352 +//----------------------------------------------------------------------------- 1.1353 +// Exceptions 1.1354 + 1.1355 +void TemplateInterpreterGenerator::generate_throw_exception() { 1.1356 + // Entry point in previous activation (i.e., if the caller was 1.1357 + // interpreted) 1.1358 + Interpreter::_rethrow_exception_entry = __ pc(); 1.1359 + // Restore sp to interpreter_frame_last_sp even though we are going 1.1360 + // to empty the expression stack for the exception processing. 1.1361 + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 1.1362 + // rax: exception 1.1363 + // rdx: return address/pc that threw exception 1.1364 + __ restore_bcp(); // r13 points to call/send 1.1365 + __ restore_locals(); 1.1366 + // Entry point for exceptions thrown within interpreter code 1.1367 + Interpreter::_throw_exception_entry = __ pc(); 1.1368 + // expression stack is undefined here 1.1369 + // rax: exception 1.1370 + // r13: exception bcp 1.1371 + __ verify_oop(rax); 1.1372 + __ movq(c_rarg1, rax); 1.1373 + 1.1374 + // expression stack must be empty before entering the VM in case of 1.1375 + // an exception 1.1376 + __ empty_expression_stack(); 1.1377 + // find exception handler address and preserve exception oop 1.1378 + __ call_VM(rdx, 1.1379 + CAST_FROM_FN_PTR(address, 1.1380 + InterpreterRuntime::exception_handler_for_exception), 1.1381 + c_rarg1); 1.1382 + // rax: exception handler entry point 1.1383 + // rdx: preserved exception oop 1.1384 + // r13: bcp for exception handler 1.1385 + __ push_ptr(rdx); // push exception which is now the only value on the stack 1.1386 + __ jmp(rax); // jump to exception handler (may be _remove_activation_entry!) 1.1387 + 1.1388 + // If the exception is not handled in the current frame the frame is 1.1389 + // removed and the exception is rethrown (i.e. exception 1.1390 + // continuation is _rethrow_exception). 1.1391 + // 1.1392 + // Note: At this point the bci is still the bxi for the instruction 1.1393 + // which caused the exception and the expression stack is 1.1394 + // empty. Thus, for any VM calls at this point, GC will find a legal 1.1395 + // oop map (with empty expression stack). 1.1396 + 1.1397 + // In current activation 1.1398 + // tos: exception 1.1399 + // esi: exception bcp 1.1400 + 1.1401 + // 1.1402 + // JVMTI PopFrame support 1.1403 + // 1.1404 + 1.1405 + Interpreter::_remove_activation_preserving_args_entry = __ pc(); 1.1406 + __ empty_expression_stack(); 1.1407 + // Set the popframe_processing bit in pending_popframe_condition 1.1408 + // indicating that we are currently handling popframe, so that 1.1409 + // call_VMs that may happen later do not trigger new popframe 1.1410 + // handling cycles. 1.1411 + __ movl(rdx, Address(r15_thread, JavaThread::popframe_condition_offset())); 1.1412 + __ orl(rdx, JavaThread::popframe_processing_bit); 1.1413 + __ movl(Address(r15_thread, JavaThread::popframe_condition_offset()), rdx); 1.1414 + 1.1415 + { 1.1416 + // Check to see whether we are returning to a deoptimized frame. 1.1417 + // (The PopFrame call ensures that the caller of the popped frame is 1.1418 + // either interpreted or compiled and deoptimizes it if compiled.) 1.1419 + // In this case, we can't call dispatch_next() after the frame is 1.1420 + // popped, but instead must save the incoming arguments and restore 1.1421 + // them after deoptimization has occurred. 1.1422 + // 1.1423 + // Note that we don't compare the return PC against the 1.1424 + // deoptimization blob's unpack entry because of the presence of 1.1425 + // adapter frames in C2. 1.1426 + Label caller_not_deoptimized; 1.1427 + __ movq(c_rarg1, Address(rbp, frame::return_addr_offset * wordSize)); 1.1428 + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, 1.1429 + InterpreterRuntime::interpreter_contains), c_rarg1); 1.1430 + __ testl(rax, rax); 1.1431 + __ jcc(Assembler::notZero, caller_not_deoptimized); 1.1432 + 1.1433 + // Compute size of arguments for saving when returning to 1.1434 + // deoptimized caller 1.1435 + __ get_method(rax); 1.1436 + __ load_unsigned_word(rax, Address(rax, in_bytes(methodOopDesc:: 1.1437 + size_of_parameters_offset()))); 1.1438 + __ shll(rax, Interpreter::logStackElementSize()); 1.1439 + __ restore_locals(); // XXX do we need this? 1.1440 + __ subq(r14, rax); 1.1441 + __ addq(r14, wordSize); 1.1442 + // Save these arguments 1.1443 + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, 1.1444 + Deoptimization:: 1.1445 + popframe_preserve_args), 1.1446 + r15_thread, rax, r14); 1.1447 + 1.1448 + __ remove_activation(vtos, rdx, 1.1449 + /* throw_monitor_exception */ false, 1.1450 + /* install_monitor_exception */ false, 1.1451 + /* notify_jvmdi */ false); 1.1452 + 1.1453 + // Inform deoptimization that it is responsible for restoring 1.1454 + // these arguments 1.1455 + __ movl(Address(r15_thread, JavaThread::popframe_condition_offset()), 1.1456 + JavaThread::popframe_force_deopt_reexecution_bit); 1.1457 + 1.1458 + // Continue in deoptimization handler 1.1459 + __ jmp(rdx); 1.1460 + 1.1461 + __ bind(caller_not_deoptimized); 1.1462 + } 1.1463 + 1.1464 + __ remove_activation(vtos, rdx, /* rdx result (retaddr) is not used */ 1.1465 + /* throw_monitor_exception */ false, 1.1466 + /* install_monitor_exception */ false, 1.1467 + /* notify_jvmdi */ false); 1.1468 + 1.1469 + // Finish with popframe handling 1.1470 + // A previous I2C followed by a deoptimization might have moved the 1.1471 + // outgoing arguments further up the stack. PopFrame expects the 1.1472 + // mutations to those outgoing arguments to be preserved and other 1.1473 + // constraints basically require this frame to look exactly as 1.1474 + // though it had previously invoked an interpreted activation with 1.1475 + // no space between the top of the expression stack (current 1.1476 + // last_sp) and the top of stack. Rather than force deopt to 1.1477 + // maintain this kind of invariant all the time we call a small 1.1478 + // fixup routine to move the mutated arguments onto the top of our 1.1479 + // expression stack if necessary. 1.1480 + __ movq(c_rarg1, rsp); 1.1481 + __ movq(c_rarg2, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); 1.1482 + // PC must point into interpreter here 1.1483 + __ set_last_Java_frame(noreg, rbp, __ pc()); 1.1484 + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), r15_thread, c_rarg1, c_rarg2); 1.1485 + __ reset_last_Java_frame(true, true); 1.1486 + // Restore the last_sp and null it out 1.1487 + __ movq(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); 1.1488 + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 1.1489 + 1.1490 + __ restore_bcp(); // XXX do we need this? 1.1491 + __ restore_locals(); // XXX do we need this? 1.1492 + // The method data pointer was incremented already during 1.1493 + // call profiling. We have to restore the mdp for the current bcp. 1.1494 + if (ProfileInterpreter) { 1.1495 + __ set_method_data_pointer_for_bcp(); 1.1496 + } 1.1497 + 1.1498 + // Clear the popframe condition flag 1.1499 + __ movl(Address(r15_thread, JavaThread::popframe_condition_offset()), 1.1500 + JavaThread::popframe_inactive); 1.1501 + 1.1502 + __ dispatch_next(vtos); 1.1503 + // end of PopFrame support 1.1504 + 1.1505 + Interpreter::_remove_activation_entry = __ pc(); 1.1506 + 1.1507 + // preserve exception over this code sequence 1.1508 + __ pop_ptr(rax); 1.1509 + __ movq(Address(r15_thread, JavaThread::vm_result_offset()), rax); 1.1510 + // remove the activation (without doing throws on illegalMonitorExceptions) 1.1511 + __ remove_activation(vtos, rdx, false, true, false); 1.1512 + // restore exception 1.1513 + __ movq(rax, Address(r15_thread, JavaThread::vm_result_offset())); 1.1514 + __ movptr(Address(r15_thread, JavaThread::vm_result_offset()), NULL_WORD); 1.1515 + __ verify_oop(rax); 1.1516 + 1.1517 + // In between activations - previous activation type unknown yet 1.1518 + // compute continuation point - the continuation point expects the 1.1519 + // following registers set up: 1.1520 + // 1.1521 + // rax: exception 1.1522 + // rdx: return address/pc that threw exception 1.1523 + // rsp: expression stack of caller 1.1524 + // rbp: ebp of caller 1.1525 + __ pushq(rax); // save exception 1.1526 + __ pushq(rdx); // save return address 1.1527 + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, 1.1528 + SharedRuntime::exception_handler_for_return_address), 1.1529 + rdx); 1.1530 + __ movq(rbx, rax); // save exception handler 1.1531 + __ popq(rdx); // restore return address 1.1532 + __ popq(rax); // restore exception 1.1533 + // Note that an "issuing PC" is actually the next PC after the call 1.1534 + __ jmp(rbx); // jump to exception 1.1535 + // handler of caller 1.1536 +} 1.1537 + 1.1538 + 1.1539 +// 1.1540 +// JVMTI ForceEarlyReturn support 1.1541 +// 1.1542 +address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state) { 1.1543 + address entry = __ pc(); 1.1544 + 1.1545 + __ restore_bcp(); 1.1546 + __ restore_locals(); 1.1547 + __ empty_expression_stack(); 1.1548 + __ load_earlyret_value(state); 1.1549 + 1.1550 + __ movq(rdx, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); 1.1551 + Address cond_addr(rdx, JvmtiThreadState::earlyret_state_offset()); 1.1552 + 1.1553 + // Clear the earlyret state 1.1554 + __ movl(cond_addr, JvmtiThreadState::earlyret_inactive); 1.1555 + 1.1556 + __ remove_activation(state, rsi, 1.1557 + false, /* throw_monitor_exception */ 1.1558 + false, /* install_monitor_exception */ 1.1559 + true); /* notify_jvmdi */ 1.1560 + __ jmp(rsi); 1.1561 + 1.1562 + return entry; 1.1563 +} // end of ForceEarlyReturn support 1.1564 + 1.1565 + 1.1566 +//----------------------------------------------------------------------------- 1.1567 +// Helper for vtos entry point generation 1.1568 + 1.1569 +void TemplateInterpreterGenerator::set_vtos_entry_points(Template* t, 1.1570 + address& bep, 1.1571 + address& cep, 1.1572 + address& sep, 1.1573 + address& aep, 1.1574 + address& iep, 1.1575 + address& lep, 1.1576 + address& fep, 1.1577 + address& dep, 1.1578 + address& vep) { 1.1579 + assert(t->is_valid() && t->tos_in() == vtos, "illegal template"); 1.1580 + Label L; 1.1581 + aep = __ pc(); __ push_ptr(); __ jmp(L); 1.1582 + fep = __ pc(); __ push_f(); __ jmp(L); 1.1583 + dep = __ pc(); __ push_d(); __ jmp(L); 1.1584 + lep = __ pc(); __ push_l(); __ jmp(L); 1.1585 + bep = cep = sep = 1.1586 + iep = __ pc(); __ push_i(); 1.1587 + vep = __ pc(); 1.1588 + __ bind(L); 1.1589 + generate_and_dispatch(t); 1.1590 +} 1.1591 + 1.1592 + 1.1593 +//----------------------------------------------------------------------------- 1.1594 +// Generation of individual instructions 1.1595 + 1.1596 +// helpers for generate_and_dispatch 1.1597 + 1.1598 + 1.1599 +InterpreterGenerator::InterpreterGenerator(StubQueue* code) 1.1600 + : TemplateInterpreterGenerator(code) { 1.1601 + generate_all(); // down here so it can be "virtual" 1.1602 +} 1.1603 + 1.1604 +//----------------------------------------------------------------------------- 1.1605 + 1.1606 +// Non-product code 1.1607 +#ifndef PRODUCT 1.1608 +address TemplateInterpreterGenerator::generate_trace_code(TosState state) { 1.1609 + address entry = __ pc(); 1.1610 + 1.1611 + __ push(state); 1.1612 + __ pushq(c_rarg0); 1.1613 + __ pushq(c_rarg1); 1.1614 + __ pushq(c_rarg2); 1.1615 + __ pushq(c_rarg3); 1.1616 + __ movq(c_rarg2, rax); // Pass itos 1.1617 +#ifdef _WIN64 1.1618 + __ movflt(xmm3, xmm0); // Pass ftos 1.1619 +#endif 1.1620 + __ call_VM(noreg, 1.1621 + CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), 1.1622 + c_rarg1, c_rarg2, c_rarg3); 1.1623 + __ popq(c_rarg3); 1.1624 + __ popq(c_rarg2); 1.1625 + __ popq(c_rarg1); 1.1626 + __ popq(c_rarg0); 1.1627 + __ pop(state); 1.1628 + __ ret(0); // return from result handler 1.1629 + 1.1630 + return entry; 1.1631 +} 1.1632 + 1.1633 +void TemplateInterpreterGenerator::count_bytecode() { 1.1634 + __ incrementl(ExternalAddress((address) &BytecodeCounter::_counter_value)); 1.1635 +} 1.1636 + 1.1637 +void TemplateInterpreterGenerator::histogram_bytecode(Template* t) { 1.1638 + __ incrementl(ExternalAddress((address) &BytecodeHistogram::_counters[t->bytecode()])); 1.1639 +} 1.1640 + 1.1641 +void TemplateInterpreterGenerator::histogram_bytecode_pair(Template* t) { 1.1642 + __ mov32(rbx, ExternalAddress((address) &BytecodePairHistogram::_index)); 1.1643 + __ shrl(rbx, BytecodePairHistogram::log2_number_of_codes); 1.1644 + __ orl(rbx, 1.1645 + ((int) t->bytecode()) << 1.1646 + BytecodePairHistogram::log2_number_of_codes); 1.1647 + __ mov32(ExternalAddress((address) &BytecodePairHistogram::_index), rbx); 1.1648 + __ lea(rscratch1, ExternalAddress((address) BytecodePairHistogram::_counters)); 1.1649 + __ incrementl(Address(rscratch1, rbx, Address::times_4)); 1.1650 +} 1.1651 + 1.1652 + 1.1653 +void TemplateInterpreterGenerator::trace_bytecode(Template* t) { 1.1654 + // Call a little run-time stub to avoid blow-up for each bytecode. 1.1655 + // The run-time runtime saves the right registers, depending on 1.1656 + // the tosca in-state for the given template. 1.1657 + 1.1658 + assert(Interpreter::trace_code(t->tos_in()) != NULL, 1.1659 + "entry must have been generated"); 1.1660 + __ movq(r12, rsp); // remember sp 1.1661 + __ andq(rsp, -16); // align stack as required by ABI 1.1662 + __ call(RuntimeAddress(Interpreter::trace_code(t->tos_in()))); 1.1663 + __ movq(rsp, r12); // restore sp 1.1664 +} 1.1665 + 1.1666 + 1.1667 +void TemplateInterpreterGenerator::stop_interpreter_at() { 1.1668 + Label L; 1.1669 + __ cmp32(ExternalAddress((address) &BytecodeCounter::_counter_value), 1.1670 + StopInterpreterAt); 1.1671 + __ jcc(Assembler::notEqual, L); 1.1672 + __ int3(); 1.1673 + __ bind(L); 1.1674 +} 1.1675 +#endif // !PRODUCT