1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/x86/vm/interpreter_x86_32.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,260 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "asm/macroAssembler.hpp" 1.30 +#include "interpreter/bytecodeHistogram.hpp" 1.31 +#include "interpreter/interpreter.hpp" 1.32 +#include "interpreter/interpreterGenerator.hpp" 1.33 +#include "interpreter/interpreterRuntime.hpp" 1.34 +#include "interpreter/templateTable.hpp" 1.35 +#include "oops/arrayOop.hpp" 1.36 +#include "oops/methodData.hpp" 1.37 +#include "oops/method.hpp" 1.38 +#include "oops/oop.inline.hpp" 1.39 +#include "prims/jvmtiExport.hpp" 1.40 +#include "prims/jvmtiThreadState.hpp" 1.41 +#include "prims/methodHandles.hpp" 1.42 +#include "runtime/arguments.hpp" 1.43 +#include "runtime/deoptimization.hpp" 1.44 +#include "runtime/frame.inline.hpp" 1.45 +#include "runtime/sharedRuntime.hpp" 1.46 +#include "runtime/stubRoutines.hpp" 1.47 +#include "runtime/synchronizer.hpp" 1.48 +#include "runtime/timer.hpp" 1.49 +#include "runtime/vframeArray.hpp" 1.50 +#include "utilities/debug.hpp" 1.51 +#ifdef COMPILER1 1.52 +#include "c1/c1_Runtime1.hpp" 1.53 +#endif 1.54 + 1.55 +#define __ _masm-> 1.56 + 1.57 +//------------------------------------------------------------------------------------------------------------------------ 1.58 + 1.59 +address AbstractInterpreterGenerator::generate_slow_signature_handler() { 1.60 + address entry = __ pc(); 1.61 + // rbx,: method 1.62 + // rcx: temporary 1.63 + // rdi: pointer to locals 1.64 + // rsp: end of copied parameters area 1.65 + __ mov(rcx, rsp); 1.66 + __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::slow_signature_handler), rbx, rdi, rcx); 1.67 + __ ret(0); 1.68 + return entry; 1.69 +} 1.70 + 1.71 + 1.72 +// 1.73 +// Various method entries (that c++ and asm interpreter agree upon) 1.74 +//------------------------------------------------------------------------------------------------------------------------ 1.75 +// 1.76 +// 1.77 + 1.78 +// Empty method, generate a very fast return. 1.79 + 1.80 +address InterpreterGenerator::generate_empty_entry(void) { 1.81 + 1.82 + // rbx,: Method* 1.83 + // rcx: receiver (unused) 1.84 + // rsi: previous interpreter state (C++ interpreter) must preserve 1.85 + // rsi: sender sp must set sp to this value on return 1.86 + 1.87 + if (!UseFastEmptyMethods) return NULL; 1.88 + 1.89 + address entry_point = __ pc(); 1.90 + 1.91 + // If we need a safepoint check, generate full interpreter entry. 1.92 + Label slow_path; 1.93 + ExternalAddress state(SafepointSynchronize::address_of_state()); 1.94 + __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), 1.95 + SafepointSynchronize::_not_synchronized); 1.96 + __ jcc(Assembler::notEqual, slow_path); 1.97 + 1.98 + // do nothing for empty methods (do not even increment invocation counter) 1.99 + // Code: _return 1.100 + // _return 1.101 + // return w/o popping parameters 1.102 + __ pop(rax); 1.103 + __ mov(rsp, rsi); 1.104 + __ jmp(rax); 1.105 + 1.106 + __ bind(slow_path); 1.107 + (void) generate_normal_entry(false); 1.108 + return entry_point; 1.109 +} 1.110 + 1.111 +address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) { 1.112 + 1.113 + // rbx,: Method* 1.114 + // rcx: scratrch 1.115 + // rsi: sender sp 1.116 + 1.117 + if (!InlineIntrinsics) return NULL; // Generate a vanilla entry 1.118 + 1.119 + address entry_point = __ pc(); 1.120 + 1.121 + // These don't need a safepoint check because they aren't virtually 1.122 + // callable. We won't enter these intrinsics from compiled code. 1.123 + // If in the future we added an intrinsic which was virtually callable 1.124 + // we'd have to worry about how to safepoint so that this code is used. 1.125 + 1.126 + // mathematical functions inlined by compiler 1.127 + // (interpreter must provide identical implementation 1.128 + // in order to avoid monotonicity bugs when switching 1.129 + // from interpreter to compiler in the middle of some 1.130 + // computation) 1.131 + // 1.132 + // stack: [ ret adr ] <-- rsp 1.133 + // [ lo(arg) ] 1.134 + // [ hi(arg) ] 1.135 + // 1.136 + 1.137 + // Note: For JDK 1.2 StrictMath doesn't exist and Math.sin/cos/sqrt are 1.138 + // native methods. Interpreter::method_kind(...) does a check for 1.139 + // native methods first before checking for intrinsic methods and 1.140 + // thus will never select this entry point. Make sure it is not 1.141 + // called accidentally since the SharedRuntime entry points will 1.142 + // not work for JDK 1.2. 1.143 + // 1.144 + // We no longer need to check for JDK 1.2 since it's EOL'ed. 1.145 + // The following check existed in pre 1.6 implementation, 1.146 + // if (Universe::is_jdk12x_version()) { 1.147 + // __ should_not_reach_here(); 1.148 + // } 1.149 + // Universe::is_jdk12x_version() always returns false since 1.150 + // the JDK version is not yet determined when this method is called. 1.151 + // This method is called during interpreter_init() whereas 1.152 + // JDK version is only determined when universe2_init() is called. 1.153 + 1.154 + // Note: For JDK 1.3 StrictMath exists and Math.sin/cos/sqrt are 1.155 + // java methods. Interpreter::method_kind(...) will select 1.156 + // this entry point for the corresponding methods in JDK 1.3. 1.157 + // get argument 1.158 + __ fld_d(Address(rsp, 1*wordSize)); 1.159 + switch (kind) { 1.160 + case Interpreter::java_lang_math_sin : 1.161 + __ trigfunc('s'); 1.162 + break; 1.163 + case Interpreter::java_lang_math_cos : 1.164 + __ trigfunc('c'); 1.165 + break; 1.166 + case Interpreter::java_lang_math_tan : 1.167 + __ trigfunc('t'); 1.168 + break; 1.169 + case Interpreter::java_lang_math_sqrt: 1.170 + __ fsqrt(); 1.171 + break; 1.172 + case Interpreter::java_lang_math_abs: 1.173 + __ fabs(); 1.174 + break; 1.175 + case Interpreter::java_lang_math_log: 1.176 + __ flog(); 1.177 + // Store to stack to convert 80bit precision back to 64bits 1.178 + __ push_fTOS(); 1.179 + __ pop_fTOS(); 1.180 + break; 1.181 + case Interpreter::java_lang_math_log10: 1.182 + __ flog10(); 1.183 + // Store to stack to convert 80bit precision back to 64bits 1.184 + __ push_fTOS(); 1.185 + __ pop_fTOS(); 1.186 + break; 1.187 + case Interpreter::java_lang_math_pow: 1.188 + __ fld_d(Address(rsp, 3*wordSize)); // second argument 1.189 + __ pow_with_fallback(0); 1.190 + // Store to stack to convert 80bit precision back to 64bits 1.191 + __ push_fTOS(); 1.192 + __ pop_fTOS(); 1.193 + break; 1.194 + case Interpreter::java_lang_math_exp: 1.195 + __ exp_with_fallback(0); 1.196 + // Store to stack to convert 80bit precision back to 64bits 1.197 + __ push_fTOS(); 1.198 + __ pop_fTOS(); 1.199 + break; 1.200 + default : 1.201 + ShouldNotReachHere(); 1.202 + } 1.203 + 1.204 + // return double result in xmm0 for interpreter and compilers. 1.205 + if (UseSSE >= 2) { 1.206 + __ subptr(rsp, 2*wordSize); 1.207 + __ fstp_d(Address(rsp, 0)); 1.208 + __ movdbl(xmm0, Address(rsp, 0)); 1.209 + __ addptr(rsp, 2*wordSize); 1.210 + } 1.211 + 1.212 + // done, result in FPU ST(0) or XMM0 1.213 + __ pop(rdi); // get return address 1.214 + __ mov(rsp, rsi); // set sp to sender sp 1.215 + __ jmp(rdi); 1.216 + 1.217 + return entry_point; 1.218 +} 1.219 + 1.220 + 1.221 +// Abstract method entry 1.222 +// Attempt to execute abstract method. Throw exception 1.223 +address InterpreterGenerator::generate_abstract_entry(void) { 1.224 + 1.225 + // rbx,: Method* 1.226 + // rcx: receiver (unused) 1.227 + // rsi: previous interpreter state (C++ interpreter) must preserve 1.228 + 1.229 + // rsi: sender SP 1.230 + 1.231 + address entry_point = __ pc(); 1.232 + 1.233 + // abstract method entry 1.234 + 1.235 + // pop return address, reset last_sp to NULL 1.236 + __ empty_expression_stack(); 1.237 + __ restore_bcp(); // rsi must be correct for exception handler (was destroyed) 1.238 + __ restore_locals(); // make sure locals pointer is correct as well (was destroyed) 1.239 + 1.240 + // throw exception 1.241 + __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError)); 1.242 + // the call_VM checks for exception, so we should never return here. 1.243 + __ should_not_reach_here(); 1.244 + 1.245 + return entry_point; 1.246 +} 1.247 + 1.248 + 1.249 +void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) { 1.250 + 1.251 + // This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in 1.252 + // the days we had adapter frames. When we deoptimize a situation where a 1.253 + // compiled caller calls a compiled caller will have registers it expects 1.254 + // to survive the call to the callee. If we deoptimize the callee the only 1.255 + // way we can restore these registers is to have the oldest interpreter 1.256 + // frame that we create restore these values. That is what this routine 1.257 + // will accomplish. 1.258 + 1.259 + // At the moment we have modified c2 to not have any callee save registers 1.260 + // so this problem does not exist and this routine is just a place holder. 1.261 + 1.262 + assert(f->is_interpreted_frame(), "must be interpreted"); 1.263 +}