Fri, 07 Jan 2011 10:42:32 -0500
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
Summary: Track allocated bytes in Thread's, update on TLAB retirement and direct allocation in Eden and tenured, add JNI methods for ThreadMXBean.
Reviewed-by: coleenp, kvn, dholmes, ysr
duke@435 | 1 | /* |
stefank@2314 | 2 | * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
trims@1907 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
trims@1907 | 20 | * or visit www.oracle.com if you need additional information or have any |
trims@1907 | 21 | * questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
stefank@2314 | 25 | #include "precompiled.hpp" |
stefank@2314 | 26 | #include "asm/assembler.hpp" |
stefank@2314 | 27 | #include "interpreter/bytecodeHistogram.hpp" |
stefank@2314 | 28 | #include "interpreter/cppInterpreter.hpp" |
stefank@2314 | 29 | #include "interpreter/interpreter.hpp" |
stefank@2314 | 30 | #include "interpreter/interpreterGenerator.hpp" |
stefank@2314 | 31 | #include "interpreter/interpreterRuntime.hpp" |
stefank@2314 | 32 | #include "oops/arrayOop.hpp" |
stefank@2314 | 33 | #include "oops/methodDataOop.hpp" |
stefank@2314 | 34 | #include "oops/methodOop.hpp" |
stefank@2314 | 35 | #include "oops/oop.inline.hpp" |
stefank@2314 | 36 | #include "prims/jvmtiExport.hpp" |
stefank@2314 | 37 | #include "prims/jvmtiThreadState.hpp" |
stefank@2314 | 38 | #include "runtime/arguments.hpp" |
stefank@2314 | 39 | #include "runtime/deoptimization.hpp" |
stefank@2314 | 40 | #include "runtime/frame.inline.hpp" |
stefank@2314 | 41 | #include "runtime/interfaceSupport.hpp" |
stefank@2314 | 42 | #include "runtime/sharedRuntime.hpp" |
stefank@2314 | 43 | #include "runtime/stubRoutines.hpp" |
stefank@2314 | 44 | #include "runtime/synchronizer.hpp" |
stefank@2314 | 45 | #include "runtime/timer.hpp" |
stefank@2314 | 46 | #include "runtime/vframeArray.hpp" |
stefank@2314 | 47 | #include "utilities/debug.hpp" |
stefank@2314 | 48 | #ifdef SHARK |
stefank@2314 | 49 | #include "shark/shark_globals.hpp" |
stefank@2314 | 50 | #endif |
duke@435 | 51 | |
duke@435 | 52 | #ifdef CC_INTERP |
duke@435 | 53 | |
duke@435 | 54 | // Routine exists to make tracebacks look decent in debugger |
duke@435 | 55 | // while we are recursed in the frame manager/c++ interpreter. |
duke@435 | 56 | // We could use an address in the frame manager but having |
duke@435 | 57 | // frames look natural in the debugger is a plus. |
duke@435 | 58 | extern "C" void RecursiveInterpreterActivation(interpreterState istate ) |
duke@435 | 59 | { |
duke@435 | 60 | // |
duke@435 | 61 | ShouldNotReachHere(); |
duke@435 | 62 | } |
duke@435 | 63 | |
duke@435 | 64 | |
duke@435 | 65 | #define __ _masm-> |
duke@435 | 66 | #define STATE(field_name) (Address(state, byte_offset_of(BytecodeInterpreter, field_name))) |
duke@435 | 67 | |
duke@435 | 68 | Label fast_accessor_slow_entry_path; // fast accessor methods need to be able to jmp to unsynchronized |
duke@435 | 69 | // c++ interpreter entry point this holds that entry point label. |
duke@435 | 70 | |
never@739 | 71 | // default registers for state and sender_sp |
never@739 | 72 | // state and sender_sp are the same on 32bit because we have no choice. |
never@739 | 73 | // state could be rsi on 64bit but it is an arg reg and not callee save |
never@739 | 74 | // so r13 is better choice. |
never@739 | 75 | |
never@739 | 76 | const Register state = NOT_LP64(rsi) LP64_ONLY(r13); |
never@739 | 77 | const Register sender_sp_on_entry = NOT_LP64(rsi) LP64_ONLY(r13); |
never@739 | 78 | |
duke@435 | 79 | // NEEDED for JVMTI? |
duke@435 | 80 | // address AbstractInterpreter::_remove_activation_preserving_args_entry; |
duke@435 | 81 | |
duke@435 | 82 | static address unctrap_frame_manager_entry = NULL; |
duke@435 | 83 | |
duke@435 | 84 | static address deopt_frame_manager_return_atos = NULL; |
duke@435 | 85 | static address deopt_frame_manager_return_btos = NULL; |
duke@435 | 86 | static address deopt_frame_manager_return_itos = NULL; |
duke@435 | 87 | static address deopt_frame_manager_return_ltos = NULL; |
duke@435 | 88 | static address deopt_frame_manager_return_ftos = NULL; |
duke@435 | 89 | static address deopt_frame_manager_return_dtos = NULL; |
duke@435 | 90 | static address deopt_frame_manager_return_vtos = NULL; |
duke@435 | 91 | |
duke@435 | 92 | int AbstractInterpreter::BasicType_as_index(BasicType type) { |
duke@435 | 93 | int i = 0; |
duke@435 | 94 | switch (type) { |
duke@435 | 95 | case T_BOOLEAN: i = 0; break; |
duke@435 | 96 | case T_CHAR : i = 1; break; |
duke@435 | 97 | case T_BYTE : i = 2; break; |
duke@435 | 98 | case T_SHORT : i = 3; break; |
duke@435 | 99 | case T_INT : i = 4; break; |
duke@435 | 100 | case T_VOID : i = 5; break; |
duke@435 | 101 | case T_FLOAT : i = 8; break; |
duke@435 | 102 | case T_LONG : i = 9; break; |
duke@435 | 103 | case T_DOUBLE : i = 6; break; |
duke@435 | 104 | case T_OBJECT : // fall through |
duke@435 | 105 | case T_ARRAY : i = 7; break; |
duke@435 | 106 | default : ShouldNotReachHere(); |
duke@435 | 107 | } |
duke@435 | 108 | assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, "index out of bounds"); |
duke@435 | 109 | return i; |
duke@435 | 110 | } |
duke@435 | 111 | |
duke@435 | 112 | // Is this pc anywhere within code owned by the interpreter? |
duke@435 | 113 | // This only works for pc that might possibly be exposed to frame |
duke@435 | 114 | // walkers. It clearly misses all of the actual c++ interpreter |
duke@435 | 115 | // implementation |
duke@435 | 116 | bool CppInterpreter::contains(address pc) { |
duke@435 | 117 | return (_code->contains(pc) || |
duke@435 | 118 | pc == CAST_FROM_FN_PTR(address, RecursiveInterpreterActivation)); |
duke@435 | 119 | } |
duke@435 | 120 | |
duke@435 | 121 | |
duke@435 | 122 | address CppInterpreterGenerator::generate_result_handler_for(BasicType type) { |
duke@435 | 123 | address entry = __ pc(); |
duke@435 | 124 | switch (type) { |
duke@435 | 125 | case T_BOOLEAN: __ c2bool(rax); break; |
duke@435 | 126 | case T_CHAR : __ andl(rax, 0xFFFF); break; |
duke@435 | 127 | case T_BYTE : __ sign_extend_byte (rax); break; |
duke@435 | 128 | case T_SHORT : __ sign_extend_short(rax); break; |
duke@435 | 129 | case T_VOID : // fall thru |
duke@435 | 130 | case T_LONG : // fall thru |
duke@435 | 131 | case T_INT : /* nothing to do */ break; |
never@739 | 132 | |
duke@435 | 133 | case T_DOUBLE : |
duke@435 | 134 | case T_FLOAT : |
never@739 | 135 | { |
never@739 | 136 | const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); |
never@739 | 137 | __ pop(t); // remove return address first |
duke@435 | 138 | // Must return a result for interpreter or compiler. In SSE |
duke@435 | 139 | // mode, results are returned in xmm0 and the FPU stack must |
duke@435 | 140 | // be empty. |
duke@435 | 141 | if (type == T_FLOAT && UseSSE >= 1) { |
never@739 | 142 | #ifndef _LP64 |
duke@435 | 143 | // Load ST0 |
duke@435 | 144 | __ fld_d(Address(rsp, 0)); |
duke@435 | 145 | // Store as float and empty fpu stack |
duke@435 | 146 | __ fstp_s(Address(rsp, 0)); |
never@739 | 147 | #endif // !_LP64 |
duke@435 | 148 | // and reload |
duke@435 | 149 | __ movflt(xmm0, Address(rsp, 0)); |
duke@435 | 150 | } else if (type == T_DOUBLE && UseSSE >= 2 ) { |
duke@435 | 151 | __ movdbl(xmm0, Address(rsp, 0)); |
duke@435 | 152 | } else { |
duke@435 | 153 | // restore ST0 |
duke@435 | 154 | __ fld_d(Address(rsp, 0)); |
duke@435 | 155 | } |
duke@435 | 156 | // and pop the temp |
never@739 | 157 | __ addptr(rsp, 2 * wordSize); |
never@739 | 158 | __ push(t); // restore return address |
duke@435 | 159 | } |
duke@435 | 160 | break; |
duke@435 | 161 | case T_OBJECT : |
duke@435 | 162 | // retrieve result from frame |
never@739 | 163 | __ movptr(rax, STATE(_oop_temp)); |
duke@435 | 164 | // and verify it |
duke@435 | 165 | __ verify_oop(rax); |
duke@435 | 166 | break; |
duke@435 | 167 | default : ShouldNotReachHere(); |
duke@435 | 168 | } |
duke@435 | 169 | __ ret(0); // return from result handler |
duke@435 | 170 | return entry; |
duke@435 | 171 | } |
duke@435 | 172 | |
duke@435 | 173 | // tosca based result to c++ interpreter stack based result. |
duke@435 | 174 | // Result goes to top of native stack. |
duke@435 | 175 | |
duke@435 | 176 | #undef EXTEND // SHOULD NOT BE NEEDED |
duke@435 | 177 | address CppInterpreterGenerator::generate_tosca_to_stack_converter(BasicType type) { |
duke@435 | 178 | // A result is in the tosca (abi result) from either a native method call or compiled |
duke@435 | 179 | // code. Place this result on the java expression stack so C++ interpreter can use it. |
duke@435 | 180 | address entry = __ pc(); |
duke@435 | 181 | |
duke@435 | 182 | const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); |
never@739 | 183 | __ pop(t); // remove return address first |
duke@435 | 184 | switch (type) { |
duke@435 | 185 | case T_VOID: |
duke@435 | 186 | break; |
duke@435 | 187 | case T_BOOLEAN: |
duke@435 | 188 | #ifdef EXTEND |
duke@435 | 189 | __ c2bool(rax); |
duke@435 | 190 | #endif |
never@739 | 191 | __ push(rax); |
duke@435 | 192 | break; |
duke@435 | 193 | case T_CHAR : |
duke@435 | 194 | #ifdef EXTEND |
duke@435 | 195 | __ andl(rax, 0xFFFF); |
duke@435 | 196 | #endif |
never@739 | 197 | __ push(rax); |
duke@435 | 198 | break; |
duke@435 | 199 | case T_BYTE : |
duke@435 | 200 | #ifdef EXTEND |
duke@435 | 201 | __ sign_extend_byte (rax); |
duke@435 | 202 | #endif |
never@739 | 203 | __ push(rax); |
duke@435 | 204 | break; |
duke@435 | 205 | case T_SHORT : |
duke@435 | 206 | #ifdef EXTEND |
duke@435 | 207 | __ sign_extend_short(rax); |
duke@435 | 208 | #endif |
never@739 | 209 | __ push(rax); |
duke@435 | 210 | break; |
duke@435 | 211 | case T_LONG : |
never@739 | 212 | __ push(rdx); // pushes useless junk on 64bit |
never@739 | 213 | __ push(rax); |
duke@435 | 214 | break; |
duke@435 | 215 | case T_INT : |
never@739 | 216 | __ push(rax); |
duke@435 | 217 | break; |
duke@435 | 218 | case T_FLOAT : |
never@739 | 219 | // Result is in ST(0)/xmm0 |
never@739 | 220 | __ subptr(rsp, wordSize); |
duke@435 | 221 | if ( UseSSE < 1) { |
never@739 | 222 | __ fstp_s(Address(rsp, 0)); |
duke@435 | 223 | } else { |
duke@435 | 224 | __ movflt(Address(rsp, 0), xmm0); |
duke@435 | 225 | } |
duke@435 | 226 | break; |
duke@435 | 227 | case T_DOUBLE : |
never@739 | 228 | __ subptr(rsp, 2*wordSize); |
duke@435 | 229 | if ( UseSSE < 2 ) { |
never@739 | 230 | __ fstp_d(Address(rsp, 0)); |
duke@435 | 231 | } else { |
duke@435 | 232 | __ movdbl(Address(rsp, 0), xmm0); |
duke@435 | 233 | } |
duke@435 | 234 | break; |
duke@435 | 235 | case T_OBJECT : |
duke@435 | 236 | __ verify_oop(rax); // verify it |
never@739 | 237 | __ push(rax); |
duke@435 | 238 | break; |
duke@435 | 239 | default : ShouldNotReachHere(); |
duke@435 | 240 | } |
duke@435 | 241 | __ jmp(t); // return from result handler |
duke@435 | 242 | return entry; |
duke@435 | 243 | } |
duke@435 | 244 | |
duke@435 | 245 | address CppInterpreterGenerator::generate_stack_to_stack_converter(BasicType type) { |
duke@435 | 246 | // A result is in the java expression stack of the interpreted method that has just |
duke@435 | 247 | // returned. Place this result on the java expression stack of the caller. |
duke@435 | 248 | // |
never@739 | 249 | // The current interpreter activation in rsi/r13 is for the method just returning its |
duke@435 | 250 | // result. So we know that the result of this method is on the top of the current |
duke@435 | 251 | // execution stack (which is pre-pushed) and will be return to the top of the caller |
duke@435 | 252 | // stack. The top of the callers stack is the bottom of the locals of the current |
duke@435 | 253 | // activation. |
duke@435 | 254 | // Because of the way activation are managed by the frame manager the value of rsp is |
duke@435 | 255 | // below both the stack top of the current activation and naturally the stack top |
duke@435 | 256 | // of the calling activation. This enable this routine to leave the return address |
duke@435 | 257 | // to the frame manager on the stack and do a vanilla return. |
duke@435 | 258 | // |
never@739 | 259 | // On entry: rsi/r13 - interpreter state of activation returning a (potential) result |
never@739 | 260 | // On Return: rsi/r13 - unchanged |
duke@435 | 261 | // rax - new stack top for caller activation (i.e. activation in _prev_link) |
duke@435 | 262 | // |
duke@435 | 263 | // Can destroy rdx, rcx. |
duke@435 | 264 | // |
duke@435 | 265 | |
duke@435 | 266 | address entry = __ pc(); |
duke@435 | 267 | const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); |
duke@435 | 268 | switch (type) { |
duke@435 | 269 | case T_VOID: |
never@739 | 270 | __ movptr(rax, STATE(_locals)); // pop parameters get new stack value |
never@739 | 271 | __ addptr(rax, wordSize); // account for prepush before we return |
duke@435 | 272 | break; |
duke@435 | 273 | case T_FLOAT : |
duke@435 | 274 | case T_BOOLEAN: |
duke@435 | 275 | case T_CHAR : |
duke@435 | 276 | case T_BYTE : |
duke@435 | 277 | case T_SHORT : |
duke@435 | 278 | case T_INT : |
duke@435 | 279 | // 1 word result |
never@739 | 280 | __ movptr(rdx, STATE(_stack)); |
never@739 | 281 | __ movptr(rax, STATE(_locals)); // address for result |
duke@435 | 282 | __ movl(rdx, Address(rdx, wordSize)); // get result |
never@739 | 283 | __ movptr(Address(rax, 0), rdx); // and store it |
duke@435 | 284 | break; |
duke@435 | 285 | case T_LONG : |
duke@435 | 286 | case T_DOUBLE : |
duke@435 | 287 | // return top two words on current expression stack to caller's expression stack |
duke@435 | 288 | // The caller's expression stack is adjacent to the current frame manager's intepretState |
duke@435 | 289 | // except we allocated one extra word for this intepretState so we won't overwrite it |
duke@435 | 290 | // when we return a two word result. |
duke@435 | 291 | |
never@739 | 292 | __ movptr(rax, STATE(_locals)); // address for result |
never@739 | 293 | __ movptr(rcx, STATE(_stack)); |
never@739 | 294 | __ subptr(rax, wordSize); // need addition word besides locals[0] |
never@739 | 295 | __ movptr(rdx, Address(rcx, 2*wordSize)); // get result word (junk in 64bit) |
never@739 | 296 | __ movptr(Address(rax, wordSize), rdx); // and store it |
never@739 | 297 | __ movptr(rdx, Address(rcx, wordSize)); // get result word |
never@739 | 298 | __ movptr(Address(rax, 0), rdx); // and store it |
duke@435 | 299 | break; |
duke@435 | 300 | case T_OBJECT : |
never@739 | 301 | __ movptr(rdx, STATE(_stack)); |
never@739 | 302 | __ movptr(rax, STATE(_locals)); // address for result |
never@739 | 303 | __ movptr(rdx, Address(rdx, wordSize)); // get result |
duke@435 | 304 | __ verify_oop(rdx); // verify it |
never@739 | 305 | __ movptr(Address(rax, 0), rdx); // and store it |
duke@435 | 306 | break; |
duke@435 | 307 | default : ShouldNotReachHere(); |
duke@435 | 308 | } |
duke@435 | 309 | __ ret(0); |
duke@435 | 310 | return entry; |
duke@435 | 311 | } |
duke@435 | 312 | |
duke@435 | 313 | address CppInterpreterGenerator::generate_stack_to_native_abi_converter(BasicType type) { |
duke@435 | 314 | // A result is in the java expression stack of the interpreted method that has just |
duke@435 | 315 | // returned. Place this result in the native abi that the caller expects. |
duke@435 | 316 | // |
duke@435 | 317 | // Similar to generate_stack_to_stack_converter above. Called at a similar time from the |
duke@435 | 318 | // frame manager execept in this situation the caller is native code (c1/c2/call_stub) |
duke@435 | 319 | // and so rather than return result onto caller's java expression stack we return the |
duke@435 | 320 | // result in the expected location based on the native abi. |
never@739 | 321 | // On entry: rsi/r13 - interpreter state of activation returning a (potential) result |
never@739 | 322 | // On Return: rsi/r13 - unchanged |
duke@435 | 323 | // Other registers changed [rax/rdx/ST(0) as needed for the result returned] |
duke@435 | 324 | |
duke@435 | 325 | address entry = __ pc(); |
duke@435 | 326 | switch (type) { |
duke@435 | 327 | case T_VOID: |
duke@435 | 328 | break; |
duke@435 | 329 | case T_BOOLEAN: |
duke@435 | 330 | case T_CHAR : |
duke@435 | 331 | case T_BYTE : |
duke@435 | 332 | case T_SHORT : |
duke@435 | 333 | case T_INT : |
never@739 | 334 | __ movptr(rdx, STATE(_stack)); // get top of stack |
duke@435 | 335 | __ movl(rax, Address(rdx, wordSize)); // get result word 1 |
duke@435 | 336 | break; |
duke@435 | 337 | case T_LONG : |
never@739 | 338 | __ movptr(rdx, STATE(_stack)); // get top of stack |
never@739 | 339 | __ movptr(rax, Address(rdx, wordSize)); // get result low word |
never@739 | 340 | NOT_LP64(__ movl(rdx, Address(rdx, 2*wordSize));) // get result high word |
duke@435 | 341 | break; |
duke@435 | 342 | case T_FLOAT : |
never@739 | 343 | __ movptr(rdx, STATE(_stack)); // get top of stack |
duke@435 | 344 | if ( UseSSE >= 1) { |
duke@435 | 345 | __ movflt(xmm0, Address(rdx, wordSize)); |
duke@435 | 346 | } else { |
duke@435 | 347 | __ fld_s(Address(rdx, wordSize)); // pushd float result |
duke@435 | 348 | } |
duke@435 | 349 | break; |
duke@435 | 350 | case T_DOUBLE : |
never@739 | 351 | __ movptr(rdx, STATE(_stack)); // get top of stack |
duke@435 | 352 | if ( UseSSE > 1) { |
duke@435 | 353 | __ movdbl(xmm0, Address(rdx, wordSize)); |
duke@435 | 354 | } else { |
duke@435 | 355 | __ fld_d(Address(rdx, wordSize)); // push double result |
duke@435 | 356 | } |
duke@435 | 357 | break; |
duke@435 | 358 | case T_OBJECT : |
never@739 | 359 | __ movptr(rdx, STATE(_stack)); // get top of stack |
never@739 | 360 | __ movptr(rax, Address(rdx, wordSize)); // get result word 1 |
duke@435 | 361 | __ verify_oop(rax); // verify it |
duke@435 | 362 | break; |
duke@435 | 363 | default : ShouldNotReachHere(); |
duke@435 | 364 | } |
duke@435 | 365 | __ ret(0); |
duke@435 | 366 | return entry; |
duke@435 | 367 | } |
duke@435 | 368 | |
duke@435 | 369 | address CppInterpreter::return_entry(TosState state, int length) { |
duke@435 | 370 | // make it look good in the debugger |
duke@435 | 371 | return CAST_FROM_FN_PTR(address, RecursiveInterpreterActivation); |
duke@435 | 372 | } |
duke@435 | 373 | |
duke@435 | 374 | address CppInterpreter::deopt_entry(TosState state, int length) { |
duke@435 | 375 | address ret = NULL; |
duke@435 | 376 | if (length != 0) { |
duke@435 | 377 | switch (state) { |
duke@435 | 378 | case atos: ret = deopt_frame_manager_return_atos; break; |
duke@435 | 379 | case btos: ret = deopt_frame_manager_return_btos; break; |
duke@435 | 380 | case ctos: |
duke@435 | 381 | case stos: |
duke@435 | 382 | case itos: ret = deopt_frame_manager_return_itos; break; |
duke@435 | 383 | case ltos: ret = deopt_frame_manager_return_ltos; break; |
duke@435 | 384 | case ftos: ret = deopt_frame_manager_return_ftos; break; |
duke@435 | 385 | case dtos: ret = deopt_frame_manager_return_dtos; break; |
duke@435 | 386 | case vtos: ret = deopt_frame_manager_return_vtos; break; |
duke@435 | 387 | } |
duke@435 | 388 | } else { |
duke@435 | 389 | ret = unctrap_frame_manager_entry; // re-execute the bytecode ( e.g. uncommon trap) |
duke@435 | 390 | } |
duke@435 | 391 | assert(ret != NULL, "Not initialized"); |
duke@435 | 392 | return ret; |
duke@435 | 393 | } |
duke@435 | 394 | |
duke@435 | 395 | // C++ Interpreter |
duke@435 | 396 | void CppInterpreterGenerator::generate_compute_interpreter_state(const Register state, |
duke@435 | 397 | const Register locals, |
duke@435 | 398 | const Register sender_sp, |
duke@435 | 399 | bool native) { |
duke@435 | 400 | |
duke@435 | 401 | // On entry the "locals" argument points to locals[0] (or where it would be in case no locals in |
duke@435 | 402 | // a static method). "state" contains any previous frame manager state which we must save a link |
duke@435 | 403 | // to in the newly generated state object. On return "state" is a pointer to the newly allocated |
duke@435 | 404 | // state object. We must allocate and initialize a new interpretState object and the method |
duke@435 | 405 | // expression stack. Because the returned result (if any) of the method will be placed on the caller's |
duke@435 | 406 | // expression stack and this will overlap with locals[0] (and locals[1] if double/long) we must |
duke@435 | 407 | // be sure to leave space on the caller's stack so that this result will not overwrite values when |
duke@435 | 408 | // locals[0] and locals[1] do not exist (and in fact are return address and saved rbp). So when |
duke@435 | 409 | // we are non-native we in essence ensure that locals[0-1] exist. We play an extra trick in |
duke@435 | 410 | // non-product builds and initialize this last local with the previous interpreterState as |
duke@435 | 411 | // this makes things look real nice in the debugger. |
duke@435 | 412 | |
duke@435 | 413 | // State on entry |
duke@435 | 414 | // Assumes locals == &locals[0] |
duke@435 | 415 | // Assumes state == any previous frame manager state (assuming call path from c++ interpreter) |
duke@435 | 416 | // Assumes rax = return address |
duke@435 | 417 | // rcx == senders_sp |
duke@435 | 418 | // rbx == method |
duke@435 | 419 | // Modifies rcx, rdx, rax |
duke@435 | 420 | // Returns: |
duke@435 | 421 | // state == address of new interpreterState |
duke@435 | 422 | // rsp == bottom of method's expression stack. |
duke@435 | 423 | |
duke@435 | 424 | const Address const_offset (rbx, methodOopDesc::const_offset()); |
duke@435 | 425 | |
duke@435 | 426 | |
duke@435 | 427 | // On entry sp is the sender's sp. This includes the space for the arguments |
duke@435 | 428 | // that the sender pushed. If the sender pushed no args (a static) and the |
duke@435 | 429 | // caller returns a long then we need two words on the sender's stack which |
duke@435 | 430 | // are not present (although when we return a restore full size stack the |
duke@435 | 431 | // space will be present). If we didn't allocate two words here then when |
duke@435 | 432 | // we "push" the result of the caller's stack we would overwrite the return |
duke@435 | 433 | // address and the saved rbp. Not good. So simply allocate 2 words now |
duke@435 | 434 | // just to be safe. This is the "static long no_params() method" issue. |
duke@435 | 435 | // See Lo.java for a testcase. |
duke@435 | 436 | // We don't need this for native calls because they return result in |
duke@435 | 437 | // register and the stack is expanded in the caller before we store |
duke@435 | 438 | // the results on the stack. |
duke@435 | 439 | |
duke@435 | 440 | if (!native) { |
duke@435 | 441 | #ifdef PRODUCT |
never@739 | 442 | __ subptr(rsp, 2*wordSize); |
duke@435 | 443 | #else /* PRODUCT */ |
never@739 | 444 | __ push((int32_t)NULL_WORD); |
never@739 | 445 | __ push(state); // make it look like a real argument |
duke@435 | 446 | #endif /* PRODUCT */ |
duke@435 | 447 | } |
duke@435 | 448 | |
duke@435 | 449 | // Now that we are assure of space for stack result, setup typical linkage |
duke@435 | 450 | |
never@739 | 451 | __ push(rax); |
duke@435 | 452 | __ enter(); |
duke@435 | 453 | |
never@739 | 454 | __ mov(rax, state); // save current state |
never@739 | 455 | |
never@739 | 456 | __ lea(rsp, Address(rsp, -(int)sizeof(BytecodeInterpreter))); |
never@739 | 457 | __ mov(state, rsp); |
never@739 | 458 | |
never@739 | 459 | // rsi/r13 == state/locals rax == prevstate |
duke@435 | 460 | |
duke@435 | 461 | // initialize the "shadow" frame so that use since C++ interpreter not directly |
duke@435 | 462 | // recursive. Simpler to recurse but we can't trim expression stack as we call |
duke@435 | 463 | // new methods. |
never@739 | 464 | __ movptr(STATE(_locals), locals); // state->_locals = locals() |
never@739 | 465 | __ movptr(STATE(_self_link), state); // point to self |
never@739 | 466 | __ movptr(STATE(_prev_link), rax); // state->_link = state on entry (NULL or previous state) |
never@739 | 467 | __ movptr(STATE(_sender_sp), sender_sp); // state->_sender_sp = sender_sp |
never@739 | 468 | #ifdef _LP64 |
never@739 | 469 | __ movptr(STATE(_thread), r15_thread); // state->_bcp = codes() |
never@739 | 470 | #else |
duke@435 | 471 | __ get_thread(rax); // get vm's javathread* |
never@739 | 472 | __ movptr(STATE(_thread), rax); // state->_bcp = codes() |
never@739 | 473 | #endif // _LP64 |
never@739 | 474 | __ movptr(rdx, Address(rbx, methodOopDesc::const_offset())); // get constantMethodOop |
never@739 | 475 | __ lea(rdx, Address(rdx, constMethodOopDesc::codes_offset())); // get code base |
duke@435 | 476 | if (native) { |
never@739 | 477 | __ movptr(STATE(_bcp), (int32_t)NULL_WORD); // state->_bcp = NULL |
duke@435 | 478 | } else { |
never@739 | 479 | __ movptr(STATE(_bcp), rdx); // state->_bcp = codes() |
duke@435 | 480 | } |
never@739 | 481 | __ xorptr(rdx, rdx); |
never@739 | 482 | __ movptr(STATE(_oop_temp), rdx); // state->_oop_temp = NULL (only really needed for native) |
never@739 | 483 | __ movptr(STATE(_mdx), rdx); // state->_mdx = NULL |
never@739 | 484 | __ movptr(rdx, Address(rbx, methodOopDesc::constants_offset())); |
never@739 | 485 | __ movptr(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); |
never@739 | 486 | __ movptr(STATE(_constants), rdx); // state->_constants = constants() |
never@739 | 487 | |
never@739 | 488 | __ movptr(STATE(_method), rbx); // state->_method = method() |
never@739 | 489 | __ movl(STATE(_msg), (int32_t) BytecodeInterpreter::method_entry); // state->_msg = initial method entry |
never@739 | 490 | __ movptr(STATE(_result._to_call._callee), (int32_t) NULL_WORD); // state->_result._to_call._callee_callee = NULL |
never@739 | 491 | |
never@739 | 492 | |
never@739 | 493 | __ movptr(STATE(_monitor_base), rsp); // set monitor block bottom (grows down) this would point to entry [0] |
duke@435 | 494 | // entries run from -1..x where &monitor[x] == |
duke@435 | 495 | |
duke@435 | 496 | { |
duke@435 | 497 | // Must not attempt to lock method until we enter interpreter as gc won't be able to find the |
duke@435 | 498 | // initial frame. However we allocate a free monitor so we don't have to shuffle the expression stack |
duke@435 | 499 | // immediately. |
duke@435 | 500 | |
duke@435 | 501 | // synchronize method |
duke@435 | 502 | const Address access_flags (rbx, methodOopDesc::access_flags_offset()); |
duke@435 | 503 | const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; |
duke@435 | 504 | Label not_synced; |
duke@435 | 505 | |
duke@435 | 506 | __ movl(rax, access_flags); |
duke@435 | 507 | __ testl(rax, JVM_ACC_SYNCHRONIZED); |
duke@435 | 508 | __ jcc(Assembler::zero, not_synced); |
duke@435 | 509 | |
duke@435 | 510 | // Allocate initial monitor and pre initialize it |
duke@435 | 511 | // get synchronization object |
duke@435 | 512 | |
duke@435 | 513 | Label done; |
duke@435 | 514 | const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); |
duke@435 | 515 | __ movl(rax, access_flags); |
duke@435 | 516 | __ testl(rax, JVM_ACC_STATIC); |
never@739 | 517 | __ movptr(rax, Address(locals, 0)); // get receiver (assume this is frequent case) |
duke@435 | 518 | __ jcc(Assembler::zero, done); |
never@739 | 519 | __ movptr(rax, Address(rbx, methodOopDesc::constants_offset())); |
never@739 | 520 | __ movptr(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes())); |
never@739 | 521 | __ movptr(rax, Address(rax, mirror_offset)); |
duke@435 | 522 | __ bind(done); |
duke@435 | 523 | // add space for monitor & lock |
never@739 | 524 | __ subptr(rsp, entry_size); // add space for a monitor entry |
never@739 | 525 | __ movptr(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); // store object |
duke@435 | 526 | __ bind(not_synced); |
duke@435 | 527 | } |
duke@435 | 528 | |
never@739 | 529 | __ movptr(STATE(_stack_base), rsp); // set expression stack base ( == &monitors[-count]) |
duke@435 | 530 | if (native) { |
never@739 | 531 | __ movptr(STATE(_stack), rsp); // set current expression stack tos |
never@739 | 532 | __ movptr(STATE(_stack_limit), rsp); |
duke@435 | 533 | } else { |
never@739 | 534 | __ subptr(rsp, wordSize); // pre-push stack |
never@739 | 535 | __ movptr(STATE(_stack), rsp); // set current expression stack tos |
duke@435 | 536 | |
duke@435 | 537 | // compute full expression stack limit |
duke@435 | 538 | |
duke@435 | 539 | const Address size_of_stack (rbx, methodOopDesc::max_stack_offset()); |
jrose@1145 | 540 | const int extra_stack = 0; //6815692//methodOopDesc::extra_stack_words(); |
jrose@1057 | 541 | __ load_unsigned_short(rdx, size_of_stack); // get size of expression stack in words |
never@739 | 542 | __ negptr(rdx); // so we can subtract in next step |
duke@435 | 543 | // Allocate expression stack |
jrose@1145 | 544 | __ lea(rsp, Address(rsp, rdx, Address::times_ptr, -extra_stack)); |
never@739 | 545 | __ movptr(STATE(_stack_limit), rsp); |
duke@435 | 546 | } |
duke@435 | 547 | |
never@739 | 548 | #ifdef _LP64 |
never@739 | 549 | // Make sure stack is properly aligned and sized for the abi |
never@739 | 550 | __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows |
twisti@1040 | 551 | __ andptr(rsp, -16); // must be 16 byte boundary (see amd64 ABI) |
never@739 | 552 | #endif // _LP64 |
never@739 | 553 | |
never@739 | 554 | |
never@739 | 555 | |
duke@435 | 556 | } |
duke@435 | 557 | |
duke@435 | 558 | // Helpers for commoning out cases in the various type of method entries. |
duke@435 | 559 | // |
duke@435 | 560 | |
duke@435 | 561 | // increment invocation count & check for overflow |
duke@435 | 562 | // |
duke@435 | 563 | // Note: checking for negative value instead of overflow |
duke@435 | 564 | // so we have a 'sticky' overflow test |
duke@435 | 565 | // |
duke@435 | 566 | // rbx,: method |
duke@435 | 567 | // rcx: invocation counter |
duke@435 | 568 | // |
duke@435 | 569 | void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { |
duke@435 | 570 | |
duke@435 | 571 | const Address invocation_counter(rbx, methodOopDesc::invocation_counter_offset() + InvocationCounter::counter_offset()); |
duke@435 | 572 | const Address backedge_counter (rbx, methodOopDesc::backedge_counter_offset() + InvocationCounter::counter_offset()); |
duke@435 | 573 | |
duke@435 | 574 | if (ProfileInterpreter) { // %%% Merge this into methodDataOop |
never@739 | 575 | __ incrementl(Address(rbx,methodOopDesc::interpreter_invocation_counter_offset())); |
duke@435 | 576 | } |
duke@435 | 577 | // Update standard invocation counters |
duke@435 | 578 | __ movl(rax, backedge_counter); // load backedge counter |
duke@435 | 579 | |
duke@435 | 580 | __ increment(rcx, InvocationCounter::count_increment); |
duke@435 | 581 | __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits |
duke@435 | 582 | |
duke@435 | 583 | __ movl(invocation_counter, rcx); // save invocation count |
duke@435 | 584 | __ addl(rcx, rax); // add both counters |
duke@435 | 585 | |
duke@435 | 586 | // profile_method is non-null only for interpreted method so |
duke@435 | 587 | // profile_method != NULL == !native_call |
duke@435 | 588 | // BytecodeInterpreter only calls for native so code is elided. |
duke@435 | 589 | |
duke@435 | 590 | __ cmp32(rcx, |
duke@435 | 591 | ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit)); |
duke@435 | 592 | __ jcc(Assembler::aboveEqual, *overflow); |
duke@435 | 593 | |
duke@435 | 594 | } |
duke@435 | 595 | |
duke@435 | 596 | void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { |
duke@435 | 597 | |
duke@435 | 598 | // C++ interpreter on entry |
never@739 | 599 | // rsi/r13 - new interpreter state pointer |
duke@435 | 600 | // rbp - interpreter frame pointer |
duke@435 | 601 | // rbx - method |
duke@435 | 602 | |
duke@435 | 603 | // On return (i.e. jump to entry_point) [ back to invocation of interpreter ] |
duke@435 | 604 | // rbx, - method |
duke@435 | 605 | // rcx - rcvr (assuming there is one) |
duke@435 | 606 | // top of stack return address of interpreter caller |
duke@435 | 607 | // rsp - sender_sp |
duke@435 | 608 | |
duke@435 | 609 | // C++ interpreter only |
never@739 | 610 | // rsi/r13 - previous interpreter state pointer |
duke@435 | 611 | |
duke@435 | 612 | const Address size_of_parameters(rbx, methodOopDesc::size_of_parameters_offset()); |
duke@435 | 613 | |
duke@435 | 614 | // InterpreterRuntime::frequency_counter_overflow takes one argument |
duke@435 | 615 | // indicating if the counter overflow occurs at a backwards branch (non-NULL bcp). |
duke@435 | 616 | // The call returns the address of the verified entry point for the method or NULL |
duke@435 | 617 | // if the compilation did not complete (either went background or bailed out). |
never@739 | 618 | __ movptr(rax, (int32_t)false); |
duke@435 | 619 | __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), rax); |
duke@435 | 620 | |
duke@435 | 621 | // for c++ interpreter can rsi really be munged? |
coleenp@955 | 622 | __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); // restore state |
never@739 | 623 | __ movptr(rbx, Address(state, byte_offset_of(BytecodeInterpreter, _method))); // restore method |
never@739 | 624 | __ movptr(rdi, Address(state, byte_offset_of(BytecodeInterpreter, _locals))); // get locals pointer |
never@739 | 625 | |
duke@435 | 626 | __ jmp(*do_continue, relocInfo::none); |
duke@435 | 627 | |
duke@435 | 628 | } |
duke@435 | 629 | |
duke@435 | 630 | void InterpreterGenerator::generate_stack_overflow_check(void) { |
duke@435 | 631 | // see if we've got enough room on the stack for locals plus overhead. |
duke@435 | 632 | // the expression stack grows down incrementally, so the normal guard |
duke@435 | 633 | // page mechanism will work for that. |
duke@435 | 634 | // |
duke@435 | 635 | // Registers live on entry: |
duke@435 | 636 | // |
duke@435 | 637 | // Asm interpreter |
duke@435 | 638 | // rdx: number of additional locals this frame needs (what we must check) |
duke@435 | 639 | // rbx,: methodOop |
duke@435 | 640 | |
duke@435 | 641 | // C++ Interpreter |
never@739 | 642 | // rsi/r13: previous interpreter frame state object |
duke@435 | 643 | // rdi: &locals[0] |
duke@435 | 644 | // rcx: # of locals |
duke@435 | 645 | // rdx: number of additional locals this frame needs (what we must check) |
duke@435 | 646 | // rbx: methodOop |
duke@435 | 647 | |
duke@435 | 648 | // destroyed on exit |
duke@435 | 649 | // rax, |
duke@435 | 650 | |
duke@435 | 651 | // NOTE: since the additional locals are also always pushed (wasn't obvious in |
duke@435 | 652 | // generate_method_entry) so the guard should work for them too. |
duke@435 | 653 | // |
duke@435 | 654 | |
duke@435 | 655 | // monitor entry size: see picture of stack set (generate_method_entry) and frame_i486.hpp |
duke@435 | 656 | const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; |
duke@435 | 657 | |
duke@435 | 658 | // total overhead size: entry_size + (saved rbp, thru expr stack bottom). |
duke@435 | 659 | // be sure to change this if you add/subtract anything to/from the overhead area |
duke@435 | 660 | const int overhead_size = (int)sizeof(BytecodeInterpreter); |
duke@435 | 661 | |
duke@435 | 662 | const int page_size = os::vm_page_size(); |
duke@435 | 663 | |
duke@435 | 664 | Label after_frame_check; |
duke@435 | 665 | |
duke@435 | 666 | // compute rsp as if this were going to be the last frame on |
duke@435 | 667 | // the stack before the red zone |
duke@435 | 668 | |
duke@435 | 669 | Label after_frame_check_pop; |
duke@435 | 670 | |
duke@435 | 671 | // save rsi == caller's bytecode ptr (c++ previous interp. state) |
duke@435 | 672 | // QQQ problem here?? rsi overload???? |
never@739 | 673 | __ push(state); |
never@739 | 674 | |
never@739 | 675 | const Register thread = LP64_ONLY(r15_thread) NOT_LP64(rsi); |
never@739 | 676 | |
never@739 | 677 | NOT_LP64(__ get_thread(thread)); |
duke@435 | 678 | |
duke@435 | 679 | const Address stack_base(thread, Thread::stack_base_offset()); |
duke@435 | 680 | const Address stack_size(thread, Thread::stack_size_offset()); |
duke@435 | 681 | |
duke@435 | 682 | // locals + overhead, in bytes |
duke@435 | 683 | const Address size_of_stack (rbx, methodOopDesc::max_stack_offset()); |
duke@435 | 684 | // Always give one monitor to allow us to start interp if sync method. |
duke@435 | 685 | // Any additional monitors need a check when moving the expression stack |
coleenp@955 | 686 | const int one_monitor = frame::interpreter_frame_monitor_size() * wordSize; |
jrose@1145 | 687 | const int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries(); |
jrose@1057 | 688 | __ load_unsigned_short(rax, size_of_stack); // get size of expression stack in words |
jrose@1145 | 689 | __ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), extra_stack + one_monitor)); |
never@739 | 690 | __ lea(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size)); |
duke@435 | 691 | |
duke@435 | 692 | #ifdef ASSERT |
duke@435 | 693 | Label stack_base_okay, stack_size_okay; |
duke@435 | 694 | // verify that thread stack base is non-zero |
never@739 | 695 | __ cmpptr(stack_base, (int32_t)0); |
duke@435 | 696 | __ jcc(Assembler::notEqual, stack_base_okay); |
duke@435 | 697 | __ stop("stack base is zero"); |
duke@435 | 698 | __ bind(stack_base_okay); |
duke@435 | 699 | // verify that thread stack size is non-zero |
never@739 | 700 | __ cmpptr(stack_size, (int32_t)0); |
duke@435 | 701 | __ jcc(Assembler::notEqual, stack_size_okay); |
duke@435 | 702 | __ stop("stack size is zero"); |
duke@435 | 703 | __ bind(stack_size_okay); |
duke@435 | 704 | #endif |
duke@435 | 705 | |
duke@435 | 706 | // Add stack base to locals and subtract stack size |
never@739 | 707 | __ addptr(rax, stack_base); |
never@739 | 708 | __ subptr(rax, stack_size); |
duke@435 | 709 | |
duke@435 | 710 | // We should have a magic number here for the size of the c++ interpreter frame. |
duke@435 | 711 | // We can't actually tell this ahead of time. The debug version size is around 3k |
duke@435 | 712 | // product is 1k and fastdebug is 4k |
duke@435 | 713 | const int slop = 6 * K; |
duke@435 | 714 | |
duke@435 | 715 | // Use the maximum number of pages we might bang. |
duke@435 | 716 | const int max_pages = StackShadowPages > (StackRedPages+StackYellowPages) ? StackShadowPages : |
duke@435 | 717 | (StackRedPages+StackYellowPages); |
duke@435 | 718 | // Only need this if we are stack banging which is temporary while |
duke@435 | 719 | // we're debugging. |
never@739 | 720 | __ addptr(rax, slop + 2*max_pages * page_size); |
duke@435 | 721 | |
duke@435 | 722 | // check against the current stack bottom |
never@739 | 723 | __ cmpptr(rsp, rax); |
duke@435 | 724 | __ jcc(Assembler::above, after_frame_check_pop); |
duke@435 | 725 | |
never@739 | 726 | __ pop(state); // get c++ prev state. |
duke@435 | 727 | |
duke@435 | 728 | // throw exception return address becomes throwing pc |
duke@435 | 729 | __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_StackOverflowError)); |
duke@435 | 730 | |
duke@435 | 731 | // all done with frame size check |
duke@435 | 732 | __ bind(after_frame_check_pop); |
never@739 | 733 | __ pop(state); |
duke@435 | 734 | |
duke@435 | 735 | __ bind(after_frame_check); |
duke@435 | 736 | } |
duke@435 | 737 | |
duke@435 | 738 | // Find preallocated monitor and lock method (C++ interpreter) |
duke@435 | 739 | // rbx - methodOop |
duke@435 | 740 | // |
duke@435 | 741 | void InterpreterGenerator::lock_method(void) { |
never@739 | 742 | // assumes state == rsi/r13 == pointer to current interpreterState |
never@739 | 743 | // minimally destroys rax, rdx|c_rarg1, rdi |
duke@435 | 744 | // |
duke@435 | 745 | // synchronize method |
duke@435 | 746 | const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; |
duke@435 | 747 | const Address access_flags (rbx, methodOopDesc::access_flags_offset()); |
duke@435 | 748 | |
never@739 | 749 | const Register monitor = NOT_LP64(rdx) LP64_ONLY(c_rarg1); |
never@739 | 750 | |
duke@435 | 751 | // find initial monitor i.e. monitors[-1] |
never@739 | 752 | __ movptr(monitor, STATE(_monitor_base)); // get monitor bottom limit |
never@739 | 753 | __ subptr(monitor, entry_size); // point to initial monitor |
duke@435 | 754 | |
duke@435 | 755 | #ifdef ASSERT |
duke@435 | 756 | { Label L; |
duke@435 | 757 | __ movl(rax, access_flags); |
duke@435 | 758 | __ testl(rax, JVM_ACC_SYNCHRONIZED); |
duke@435 | 759 | __ jcc(Assembler::notZero, L); |
duke@435 | 760 | __ stop("method doesn't need synchronization"); |
duke@435 | 761 | __ bind(L); |
duke@435 | 762 | } |
duke@435 | 763 | #endif // ASSERT |
duke@435 | 764 | // get synchronization object |
duke@435 | 765 | { Label done; |
duke@435 | 766 | const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); |
duke@435 | 767 | __ movl(rax, access_flags); |
never@739 | 768 | __ movptr(rdi, STATE(_locals)); // prepare to get receiver (assume common case) |
duke@435 | 769 | __ testl(rax, JVM_ACC_STATIC); |
never@739 | 770 | __ movptr(rax, Address(rdi, 0)); // get receiver (assume this is frequent case) |
duke@435 | 771 | __ jcc(Assembler::zero, done); |
never@739 | 772 | __ movptr(rax, Address(rbx, methodOopDesc::constants_offset())); |
never@739 | 773 | __ movptr(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes())); |
never@739 | 774 | __ movptr(rax, Address(rax, mirror_offset)); |
duke@435 | 775 | __ bind(done); |
duke@435 | 776 | } |
duke@435 | 777 | #ifdef ASSERT |
duke@435 | 778 | { Label L; |
never@739 | 779 | __ cmpptr(rax, Address(monitor, BasicObjectLock::obj_offset_in_bytes())); // correct object? |
duke@435 | 780 | __ jcc(Assembler::equal, L); |
duke@435 | 781 | __ stop("wrong synchronization lobject"); |
duke@435 | 782 | __ bind(L); |
duke@435 | 783 | } |
duke@435 | 784 | #endif // ASSERT |
never@739 | 785 | // can destroy rax, rdx|c_rarg1, rcx, and (via call_VM) rdi! |
never@739 | 786 | __ lock_object(monitor); |
duke@435 | 787 | } |
duke@435 | 788 | |
duke@435 | 789 | // Call an accessor method (assuming it is resolved, otherwise drop into vanilla (slow path) entry |
duke@435 | 790 | |
duke@435 | 791 | address InterpreterGenerator::generate_accessor_entry(void) { |
duke@435 | 792 | |
never@739 | 793 | // rbx: methodOop |
never@739 | 794 | |
never@739 | 795 | // rsi/r13: senderSP must preserved for slow path, set SP to it on fast path |
duke@435 | 796 | |
duke@435 | 797 | Label xreturn_path; |
duke@435 | 798 | |
duke@435 | 799 | // do fastpath for resolved accessor methods |
duke@435 | 800 | if (UseFastAccessorMethods) { |
duke@435 | 801 | |
duke@435 | 802 | address entry_point = __ pc(); |
duke@435 | 803 | |
duke@435 | 804 | Label slow_path; |
duke@435 | 805 | // If we need a safepoint check, generate full interpreter entry. |
duke@435 | 806 | ExternalAddress state(SafepointSynchronize::address_of_state()); |
duke@435 | 807 | __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), |
duke@435 | 808 | SafepointSynchronize::_not_synchronized); |
duke@435 | 809 | |
duke@435 | 810 | __ jcc(Assembler::notEqual, slow_path); |
duke@435 | 811 | // ASM/C++ Interpreter |
duke@435 | 812 | // Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites thereof; parameter size = 1 |
duke@435 | 813 | // Note: We can only use this code if the getfield has been resolved |
duke@435 | 814 | // and if we don't have a null-pointer exception => check for |
duke@435 | 815 | // these conditions first and use slow path if necessary. |
duke@435 | 816 | // rbx,: method |
duke@435 | 817 | // rcx: receiver |
never@739 | 818 | __ movptr(rax, Address(rsp, wordSize)); |
duke@435 | 819 | |
duke@435 | 820 | // check if local 0 != NULL and read field |
never@739 | 821 | __ testptr(rax, rax); |
duke@435 | 822 | __ jcc(Assembler::zero, slow_path); |
duke@435 | 823 | |
never@739 | 824 | __ movptr(rdi, Address(rbx, methodOopDesc::constants_offset())); |
duke@435 | 825 | // read first instruction word and extract bytecode @ 1 and index @ 2 |
never@739 | 826 | __ movptr(rdx, Address(rbx, methodOopDesc::const_offset())); |
duke@435 | 827 | __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset())); |
duke@435 | 828 | // Shift codes right to get the index on the right. |
duke@435 | 829 | // The bytecode fetched looks like <index><0xb4><0x2a> |
duke@435 | 830 | __ shrl(rdx, 2*BitsPerByte); |
duke@435 | 831 | __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size()))); |
never@739 | 832 | __ movptr(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); |
duke@435 | 833 | |
duke@435 | 834 | // rax,: local 0 |
duke@435 | 835 | // rbx,: method |
duke@435 | 836 | // rcx: receiver - do not destroy since it is needed for slow path! |
duke@435 | 837 | // rcx: scratch |
duke@435 | 838 | // rdx: constant pool cache index |
duke@435 | 839 | // rdi: constant pool cache |
never@739 | 840 | // rsi/r13: sender sp |
duke@435 | 841 | |
duke@435 | 842 | // check if getfield has been resolved and read constant pool cache entry |
duke@435 | 843 | // check the validity of the cache entry by testing whether _indices field |
duke@435 | 844 | // contains Bytecode::_getfield in b1 byte. |
duke@435 | 845 | assert(in_words(ConstantPoolCacheEntry::size()) == 4, "adjust shift below"); |
duke@435 | 846 | __ movl(rcx, |
duke@435 | 847 | Address(rdi, |
duke@435 | 848 | rdx, |
never@739 | 849 | Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); |
duke@435 | 850 | __ shrl(rcx, 2*BitsPerByte); |
duke@435 | 851 | __ andl(rcx, 0xFF); |
duke@435 | 852 | __ cmpl(rcx, Bytecodes::_getfield); |
duke@435 | 853 | __ jcc(Assembler::notEqual, slow_path); |
duke@435 | 854 | |
duke@435 | 855 | // Note: constant pool entry is not valid before bytecode is resolved |
never@739 | 856 | __ movptr(rcx, |
duke@435 | 857 | Address(rdi, |
duke@435 | 858 | rdx, |
never@739 | 859 | Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset())); |
duke@435 | 860 | __ movl(rdx, |
duke@435 | 861 | Address(rdi, |
duke@435 | 862 | rdx, |
never@739 | 863 | Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); |
duke@435 | 864 | |
duke@435 | 865 | Label notByte, notShort, notChar; |
duke@435 | 866 | const Address field_address (rax, rcx, Address::times_1); |
duke@435 | 867 | |
duke@435 | 868 | // Need to differentiate between igetfield, agetfield, bgetfield etc. |
duke@435 | 869 | // because they are different sizes. |
duke@435 | 870 | // Use the type from the constant pool cache |
duke@435 | 871 | __ shrl(rdx, ConstantPoolCacheEntry::tosBits); |
duke@435 | 872 | // Make sure we don't need to mask rdx for tosBits after the above shift |
duke@435 | 873 | ConstantPoolCacheEntry::verify_tosBits(); |
never@739 | 874 | #ifdef _LP64 |
never@739 | 875 | Label notObj; |
never@739 | 876 | __ cmpl(rdx, atos); |
never@739 | 877 | __ jcc(Assembler::notEqual, notObj); |
never@739 | 878 | // atos |
never@739 | 879 | __ movptr(rax, field_address); |
never@739 | 880 | __ jmp(xreturn_path); |
never@739 | 881 | |
never@739 | 882 | __ bind(notObj); |
never@739 | 883 | #endif // _LP64 |
duke@435 | 884 | __ cmpl(rdx, btos); |
duke@435 | 885 | __ jcc(Assembler::notEqual, notByte); |
duke@435 | 886 | __ load_signed_byte(rax, field_address); |
duke@435 | 887 | __ jmp(xreturn_path); |
duke@435 | 888 | |
duke@435 | 889 | __ bind(notByte); |
duke@435 | 890 | __ cmpl(rdx, stos); |
duke@435 | 891 | __ jcc(Assembler::notEqual, notShort); |
jrose@1057 | 892 | __ load_signed_short(rax, field_address); |
duke@435 | 893 | __ jmp(xreturn_path); |
duke@435 | 894 | |
duke@435 | 895 | __ bind(notShort); |
duke@435 | 896 | __ cmpl(rdx, ctos); |
duke@435 | 897 | __ jcc(Assembler::notEqual, notChar); |
jrose@1057 | 898 | __ load_unsigned_short(rax, field_address); |
duke@435 | 899 | __ jmp(xreturn_path); |
duke@435 | 900 | |
duke@435 | 901 | __ bind(notChar); |
duke@435 | 902 | #ifdef ASSERT |
duke@435 | 903 | Label okay; |
never@739 | 904 | #ifndef _LP64 |
duke@435 | 905 | __ cmpl(rdx, atos); |
duke@435 | 906 | __ jcc(Assembler::equal, okay); |
never@739 | 907 | #endif // _LP64 |
duke@435 | 908 | __ cmpl(rdx, itos); |
duke@435 | 909 | __ jcc(Assembler::equal, okay); |
duke@435 | 910 | __ stop("what type is this?"); |
duke@435 | 911 | __ bind(okay); |
duke@435 | 912 | #endif // ASSERT |
duke@435 | 913 | // All the rest are a 32 bit wordsize |
duke@435 | 914 | __ movl(rax, field_address); |
duke@435 | 915 | |
duke@435 | 916 | __ bind(xreturn_path); |
duke@435 | 917 | |
duke@435 | 918 | // _ireturn/_areturn |
never@739 | 919 | __ pop(rdi); // get return address |
never@739 | 920 | __ mov(rsp, sender_sp_on_entry); // set sp to sender sp |
duke@435 | 921 | __ jmp(rdi); |
duke@435 | 922 | |
duke@435 | 923 | // generate a vanilla interpreter entry as the slow path |
duke@435 | 924 | __ bind(slow_path); |
duke@435 | 925 | // We will enter c++ interpreter looking like it was |
duke@435 | 926 | // called by the call_stub this will cause it to return |
duke@435 | 927 | // a tosca result to the invoker which might have been |
duke@435 | 928 | // the c++ interpreter itself. |
duke@435 | 929 | |
duke@435 | 930 | __ jmp(fast_accessor_slow_entry_path); |
duke@435 | 931 | return entry_point; |
duke@435 | 932 | |
duke@435 | 933 | } else { |
duke@435 | 934 | return NULL; |
duke@435 | 935 | } |
duke@435 | 936 | |
duke@435 | 937 | } |
duke@435 | 938 | |
duke@435 | 939 | // |
duke@435 | 940 | // C++ Interpreter stub for calling a native method. |
duke@435 | 941 | // This sets up a somewhat different looking stack for calling the native method |
duke@435 | 942 | // than the typical interpreter frame setup but still has the pointer to |
duke@435 | 943 | // an interpreter state. |
duke@435 | 944 | // |
duke@435 | 945 | |
duke@435 | 946 | address InterpreterGenerator::generate_native_entry(bool synchronized) { |
duke@435 | 947 | // determine code generation flags |
duke@435 | 948 | bool inc_counter = UseCompiler || CountCompiledCalls; |
duke@435 | 949 | |
duke@435 | 950 | // rbx: methodOop |
duke@435 | 951 | // rcx: receiver (unused) |
never@739 | 952 | // rsi/r13: previous interpreter state (if called from C++ interpreter) must preserve |
never@739 | 953 | // in any case. If called via c1/c2/call_stub rsi/r13 is junk (to use) but harmless |
duke@435 | 954 | // to save/restore. |
duke@435 | 955 | address entry_point = __ pc(); |
duke@435 | 956 | |
duke@435 | 957 | const Address size_of_parameters(rbx, methodOopDesc::size_of_parameters_offset()); |
duke@435 | 958 | const Address size_of_locals (rbx, methodOopDesc::size_of_locals_offset()); |
duke@435 | 959 | const Address invocation_counter(rbx, methodOopDesc::invocation_counter_offset() + InvocationCounter::counter_offset()); |
duke@435 | 960 | const Address access_flags (rbx, methodOopDesc::access_flags_offset()); |
duke@435 | 961 | |
never@739 | 962 | // rsi/r13 == state/locals rdi == prevstate |
duke@435 | 963 | const Register locals = rdi; |
duke@435 | 964 | |
duke@435 | 965 | // get parameter size (always needed) |
jrose@1057 | 966 | __ load_unsigned_short(rcx, size_of_parameters); |
duke@435 | 967 | |
duke@435 | 968 | // rbx: methodOop |
duke@435 | 969 | // rcx: size of parameters |
never@739 | 970 | __ pop(rax); // get return address |
duke@435 | 971 | // for natives the size of locals is zero |
duke@435 | 972 | |
duke@435 | 973 | // compute beginning of parameters /locals |
never@739 | 974 | __ lea(locals, Address(rsp, rcx, Address::times_ptr, -wordSize)); |
duke@435 | 975 | |
duke@435 | 976 | // initialize fixed part of activation frame |
duke@435 | 977 | |
duke@435 | 978 | // Assumes rax = return address |
duke@435 | 979 | |
duke@435 | 980 | // allocate and initialize new interpreterState and method expression stack |
duke@435 | 981 | // IN(locals) -> locals |
duke@435 | 982 | // IN(state) -> previous frame manager state (NULL from stub/c1/c2) |
duke@435 | 983 | // destroys rax, rcx, rdx |
duke@435 | 984 | // OUT (state) -> new interpreterState |
duke@435 | 985 | // OUT(rsp) -> bottom of methods expression stack |
duke@435 | 986 | |
duke@435 | 987 | // save sender_sp |
never@739 | 988 | __ mov(rcx, sender_sp_on_entry); |
duke@435 | 989 | // start with NULL previous state |
never@739 | 990 | __ movptr(state, (int32_t)NULL_WORD); |
duke@435 | 991 | generate_compute_interpreter_state(state, locals, rcx, true); |
duke@435 | 992 | |
duke@435 | 993 | #ifdef ASSERT |
duke@435 | 994 | { Label L; |
never@739 | 995 | __ movptr(rax, STATE(_stack_base)); |
never@739 | 996 | #ifdef _LP64 |
never@739 | 997 | // duplicate the alignment rsp got after setting stack_base |
never@739 | 998 | __ subptr(rax, frame::arg_reg_save_area_bytes); // windows |
twisti@1040 | 999 | __ andptr(rax, -16); // must be 16 byte boundary (see amd64 ABI) |
never@739 | 1000 | #endif // _LP64 |
never@739 | 1001 | __ cmpptr(rax, rsp); |
duke@435 | 1002 | __ jcc(Assembler::equal, L); |
duke@435 | 1003 | __ stop("broken stack frame setup in interpreter"); |
duke@435 | 1004 | __ bind(L); |
duke@435 | 1005 | } |
duke@435 | 1006 | #endif |
duke@435 | 1007 | |
duke@435 | 1008 | if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count |
duke@435 | 1009 | |
never@739 | 1010 | const Register unlock_thread = LP64_ONLY(r15_thread) NOT_LP64(rax); |
never@739 | 1011 | NOT_LP64(__ movptr(unlock_thread, STATE(_thread));) // get thread |
duke@435 | 1012 | // Since at this point in the method invocation the exception handler |
duke@435 | 1013 | // would try to exit the monitor of synchronized methods which hasn't |
duke@435 | 1014 | // been entered yet, we set the thread local variable |
duke@435 | 1015 | // _do_not_unlock_if_synchronized to true. The remove_activation will |
duke@435 | 1016 | // check this flag. |
duke@435 | 1017 | |
never@739 | 1018 | const Address do_not_unlock_if_synchronized(unlock_thread, |
duke@435 | 1019 | in_bytes(JavaThread::do_not_unlock_if_synchronized_offset())); |
duke@435 | 1020 | __ movbool(do_not_unlock_if_synchronized, true); |
duke@435 | 1021 | |
duke@435 | 1022 | // make sure method is native & not abstract |
duke@435 | 1023 | #ifdef ASSERT |
duke@435 | 1024 | __ movl(rax, access_flags); |
duke@435 | 1025 | { |
duke@435 | 1026 | Label L; |
duke@435 | 1027 | __ testl(rax, JVM_ACC_NATIVE); |
duke@435 | 1028 | __ jcc(Assembler::notZero, L); |
duke@435 | 1029 | __ stop("tried to execute non-native method as native"); |
duke@435 | 1030 | __ bind(L); |
duke@435 | 1031 | } |
duke@435 | 1032 | { Label L; |
duke@435 | 1033 | __ testl(rax, JVM_ACC_ABSTRACT); |
duke@435 | 1034 | __ jcc(Assembler::zero, L); |
duke@435 | 1035 | __ stop("tried to execute abstract method in interpreter"); |
duke@435 | 1036 | __ bind(L); |
duke@435 | 1037 | } |
duke@435 | 1038 | #endif |
duke@435 | 1039 | |
duke@435 | 1040 | |
duke@435 | 1041 | // increment invocation count & check for overflow |
duke@435 | 1042 | Label invocation_counter_overflow; |
duke@435 | 1043 | if (inc_counter) { |
duke@435 | 1044 | generate_counter_incr(&invocation_counter_overflow, NULL, NULL); |
duke@435 | 1045 | } |
duke@435 | 1046 | |
duke@435 | 1047 | Label continue_after_compile; |
duke@435 | 1048 | |
duke@435 | 1049 | __ bind(continue_after_compile); |
duke@435 | 1050 | |
duke@435 | 1051 | bang_stack_shadow_pages(true); |
duke@435 | 1052 | |
duke@435 | 1053 | // reset the _do_not_unlock_if_synchronized flag |
never@739 | 1054 | NOT_LP64(__ movl(rax, STATE(_thread));) // get thread |
duke@435 | 1055 | __ movbool(do_not_unlock_if_synchronized, false); |
duke@435 | 1056 | |
duke@435 | 1057 | |
duke@435 | 1058 | // check for synchronized native methods |
duke@435 | 1059 | // |
duke@435 | 1060 | // Note: This must happen *after* invocation counter check, since |
duke@435 | 1061 | // when overflow happens, the method should not be locked. |
duke@435 | 1062 | if (synchronized) { |
duke@435 | 1063 | // potentially kills rax, rcx, rdx, rdi |
duke@435 | 1064 | lock_method(); |
duke@435 | 1065 | } else { |
duke@435 | 1066 | // no synchronization necessary |
duke@435 | 1067 | #ifdef ASSERT |
duke@435 | 1068 | { Label L; |
duke@435 | 1069 | __ movl(rax, access_flags); |
duke@435 | 1070 | __ testl(rax, JVM_ACC_SYNCHRONIZED); |
duke@435 | 1071 | __ jcc(Assembler::zero, L); |
duke@435 | 1072 | __ stop("method needs synchronization"); |
duke@435 | 1073 | __ bind(L); |
duke@435 | 1074 | } |
duke@435 | 1075 | #endif |
duke@435 | 1076 | } |
duke@435 | 1077 | |
duke@435 | 1078 | // start execution |
duke@435 | 1079 | |
duke@435 | 1080 | // jvmti support |
duke@435 | 1081 | __ notify_method_entry(); |
duke@435 | 1082 | |
duke@435 | 1083 | // work registers |
duke@435 | 1084 | const Register method = rbx; |
never@739 | 1085 | const Register thread = LP64_ONLY(r15_thread) NOT_LP64(rdi); |
never@739 | 1086 | const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); // rcx|rscratch1 |
duke@435 | 1087 | |
duke@435 | 1088 | // allocate space for parameters |
never@739 | 1089 | __ movptr(method, STATE(_method)); |
duke@435 | 1090 | __ verify_oop(method); |
jrose@1057 | 1091 | __ load_unsigned_short(t, Address(method, methodOopDesc::size_of_parameters_offset())); |
duke@435 | 1092 | __ shll(t, 2); |
never@739 | 1093 | #ifdef _LP64 |
never@739 | 1094 | __ subptr(rsp, t); |
never@739 | 1095 | __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows |
twisti@1040 | 1096 | __ andptr(rsp, -16); // must be 16 byte boundary (see amd64 ABI) |
never@739 | 1097 | #else |
never@739 | 1098 | __ addptr(t, 2*wordSize); // allocate two more slots for JNIEnv and possible mirror |
never@739 | 1099 | __ subptr(rsp, t); |
never@739 | 1100 | __ andptr(rsp, -(StackAlignmentInBytes)); // gcc needs 16 byte aligned stacks to do XMM intrinsics |
never@739 | 1101 | #endif // _LP64 |
duke@435 | 1102 | |
duke@435 | 1103 | // get signature handler |
duke@435 | 1104 | Label pending_exception_present; |
duke@435 | 1105 | |
duke@435 | 1106 | { Label L; |
never@739 | 1107 | __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); |
never@739 | 1108 | __ testptr(t, t); |
duke@435 | 1109 | __ jcc(Assembler::notZero, L); |
duke@435 | 1110 | __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method, false); |
never@739 | 1111 | __ movptr(method, STATE(_method)); |
never@739 | 1112 | __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); |
duke@435 | 1113 | __ jcc(Assembler::notEqual, pending_exception_present); |
duke@435 | 1114 | __ verify_oop(method); |
never@739 | 1115 | __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); |
duke@435 | 1116 | __ bind(L); |
duke@435 | 1117 | } |
duke@435 | 1118 | #ifdef ASSERT |
duke@435 | 1119 | { |
duke@435 | 1120 | Label L; |
never@739 | 1121 | __ push(t); |
duke@435 | 1122 | __ get_thread(t); // get vm's javathread* |
never@739 | 1123 | __ cmpptr(t, STATE(_thread)); |
duke@435 | 1124 | __ jcc(Assembler::equal, L); |
duke@435 | 1125 | __ int3(); |
duke@435 | 1126 | __ bind(L); |
never@739 | 1127 | __ pop(t); |
duke@435 | 1128 | } |
duke@435 | 1129 | #endif // |
duke@435 | 1130 | |
never@739 | 1131 | const Register from_ptr = InterpreterRuntime::SignatureHandlerGenerator::from(); |
duke@435 | 1132 | // call signature handler |
duke@435 | 1133 | assert(InterpreterRuntime::SignatureHandlerGenerator::to () == rsp, "adjust this code"); |
never@739 | 1134 | |
duke@435 | 1135 | // The generated handlers do not touch RBX (the method oop). |
duke@435 | 1136 | // However, large signatures cannot be cached and are generated |
duke@435 | 1137 | // each time here. The slow-path generator will blow RBX |
duke@435 | 1138 | // sometime, so we must reload it after the call. |
never@739 | 1139 | __ movptr(from_ptr, STATE(_locals)); // get the from pointer |
duke@435 | 1140 | __ call(t); |
never@739 | 1141 | __ movptr(method, STATE(_method)); |
duke@435 | 1142 | __ verify_oop(method); |
duke@435 | 1143 | |
duke@435 | 1144 | // result handler is in rax |
duke@435 | 1145 | // set result handler |
never@739 | 1146 | __ movptr(STATE(_result_handler), rax); |
never@739 | 1147 | |
never@739 | 1148 | |
never@739 | 1149 | // get native function entry point |
never@739 | 1150 | { Label L; |
never@739 | 1151 | __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); |
never@739 | 1152 | __ testptr(rax, rax); |
never@739 | 1153 | __ jcc(Assembler::notZero, L); |
never@739 | 1154 | __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method); |
never@739 | 1155 | __ movptr(method, STATE(_method)); |
never@739 | 1156 | __ verify_oop(method); |
never@739 | 1157 | __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); |
never@739 | 1158 | __ bind(L); |
never@739 | 1159 | } |
duke@435 | 1160 | |
duke@435 | 1161 | // pass mirror handle if static call |
duke@435 | 1162 | { Label L; |
duke@435 | 1163 | const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); |
duke@435 | 1164 | __ movl(t, Address(method, methodOopDesc::access_flags_offset())); |
duke@435 | 1165 | __ testl(t, JVM_ACC_STATIC); |
duke@435 | 1166 | __ jcc(Assembler::zero, L); |
duke@435 | 1167 | // get mirror |
never@739 | 1168 | __ movptr(t, Address(method, methodOopDesc:: constants_offset())); |
never@739 | 1169 | __ movptr(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); |
never@739 | 1170 | __ movptr(t, Address(t, mirror_offset)); |
duke@435 | 1171 | // copy mirror into activation object |
never@739 | 1172 | __ movptr(STATE(_oop_temp), t); |
duke@435 | 1173 | // pass handle to mirror |
never@739 | 1174 | #ifdef _LP64 |
never@739 | 1175 | __ lea(c_rarg1, STATE(_oop_temp)); |
never@739 | 1176 | #else |
never@739 | 1177 | __ lea(t, STATE(_oop_temp)); |
never@739 | 1178 | __ movptr(Address(rsp, wordSize), t); |
never@739 | 1179 | #endif // _LP64 |
duke@435 | 1180 | __ bind(L); |
duke@435 | 1181 | } |
duke@435 | 1182 | #ifdef ASSERT |
duke@435 | 1183 | { |
duke@435 | 1184 | Label L; |
never@739 | 1185 | __ push(t); |
duke@435 | 1186 | __ get_thread(t); // get vm's javathread* |
never@739 | 1187 | __ cmpptr(t, STATE(_thread)); |
duke@435 | 1188 | __ jcc(Assembler::equal, L); |
duke@435 | 1189 | __ int3(); |
duke@435 | 1190 | __ bind(L); |
never@739 | 1191 | __ pop(t); |
duke@435 | 1192 | } |
duke@435 | 1193 | #endif // |
duke@435 | 1194 | |
duke@435 | 1195 | // pass JNIEnv |
never@739 | 1196 | #ifdef _LP64 |
never@739 | 1197 | __ lea(c_rarg0, Address(thread, JavaThread::jni_environment_offset())); |
never@739 | 1198 | #else |
never@739 | 1199 | __ movptr(thread, STATE(_thread)); // get thread |
never@739 | 1200 | __ lea(t, Address(thread, JavaThread::jni_environment_offset())); |
never@739 | 1201 | |
never@739 | 1202 | __ movptr(Address(rsp, 0), t); |
never@739 | 1203 | #endif // _LP64 |
never@739 | 1204 | |
duke@435 | 1205 | #ifdef ASSERT |
duke@435 | 1206 | { |
duke@435 | 1207 | Label L; |
never@739 | 1208 | __ push(t); |
duke@435 | 1209 | __ get_thread(t); // get vm's javathread* |
never@739 | 1210 | __ cmpptr(t, STATE(_thread)); |
duke@435 | 1211 | __ jcc(Assembler::equal, L); |
duke@435 | 1212 | __ int3(); |
duke@435 | 1213 | __ bind(L); |
never@739 | 1214 | __ pop(t); |
duke@435 | 1215 | } |
duke@435 | 1216 | #endif // |
duke@435 | 1217 | |
duke@435 | 1218 | #ifdef ASSERT |
duke@435 | 1219 | { Label L; |
duke@435 | 1220 | __ movl(t, Address(thread, JavaThread::thread_state_offset())); |
duke@435 | 1221 | __ cmpl(t, _thread_in_Java); |
duke@435 | 1222 | __ jcc(Assembler::equal, L); |
duke@435 | 1223 | __ stop("Wrong thread state in native stub"); |
duke@435 | 1224 | __ bind(L); |
duke@435 | 1225 | } |
duke@435 | 1226 | #endif |
duke@435 | 1227 | |
duke@435 | 1228 | // Change state to native (we save the return address in the thread, since it might not |
duke@435 | 1229 | // be pushed on the stack when we do a a stack traversal). It is enough that the pc() |
duke@435 | 1230 | // points into the right code segment. It does not have to be the correct return pc. |
duke@435 | 1231 | |
duke@435 | 1232 | __ set_last_Java_frame(thread, noreg, rbp, __ pc()); |
duke@435 | 1233 | |
duke@435 | 1234 | __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native); |
duke@435 | 1235 | |
duke@435 | 1236 | __ call(rax); |
duke@435 | 1237 | |
duke@435 | 1238 | // result potentially in rdx:rax or ST0 |
never@739 | 1239 | __ movptr(method, STATE(_method)); |
never@739 | 1240 | NOT_LP64(__ movptr(thread, STATE(_thread));) // get thread |
duke@435 | 1241 | |
duke@435 | 1242 | // The potential result is in ST(0) & rdx:rax |
duke@435 | 1243 | // With C++ interpreter we leave any possible result in ST(0) until we are in result handler and then |
duke@435 | 1244 | // we do the appropriate stuff for returning the result. rdx:rax must always be saved because just about |
duke@435 | 1245 | // anything we do here will destroy it, st(0) is only saved if we re-enter the vm where it would |
duke@435 | 1246 | // be destroyed. |
duke@435 | 1247 | // It is safe to do these pushes because state is _thread_in_native and return address will be found |
duke@435 | 1248 | // via _last_native_pc and not via _last_jave_sp |
duke@435 | 1249 | |
never@739 | 1250 | // Must save the value of ST(0)/xmm0 since it could be destroyed before we get to result handler |
duke@435 | 1251 | { Label Lpush, Lskip; |
duke@435 | 1252 | ExternalAddress float_handler(AbstractInterpreter::result_handler(T_FLOAT)); |
duke@435 | 1253 | ExternalAddress double_handler(AbstractInterpreter::result_handler(T_DOUBLE)); |
duke@435 | 1254 | __ cmpptr(STATE(_result_handler), float_handler.addr()); |
duke@435 | 1255 | __ jcc(Assembler::equal, Lpush); |
duke@435 | 1256 | __ cmpptr(STATE(_result_handler), double_handler.addr()); |
duke@435 | 1257 | __ jcc(Assembler::notEqual, Lskip); |
duke@435 | 1258 | __ bind(Lpush); |
never@739 | 1259 | __ subptr(rsp, 2*wordSize); |
never@739 | 1260 | if ( UseSSE < 2 ) { |
never@739 | 1261 | __ fstp_d(Address(rsp, 0)); |
never@739 | 1262 | } else { |
never@739 | 1263 | __ movdbl(Address(rsp, 0), xmm0); |
never@739 | 1264 | } |
duke@435 | 1265 | __ bind(Lskip); |
duke@435 | 1266 | } |
duke@435 | 1267 | |
never@739 | 1268 | // save rax:rdx for potential use by result handler. |
never@739 | 1269 | __ push(rax); |
never@739 | 1270 | #ifndef _LP64 |
never@739 | 1271 | __ push(rdx); |
never@739 | 1272 | #endif // _LP64 |
duke@435 | 1273 | |
duke@435 | 1274 | // Either restore the MXCSR register after returning from the JNI Call |
duke@435 | 1275 | // or verify that it wasn't changed. |
duke@435 | 1276 | if (VM_Version::supports_sse()) { |
duke@435 | 1277 | if (RestoreMXCSROnJNICalls) { |
duke@435 | 1278 | __ ldmxcsr(ExternalAddress(StubRoutines::addr_mxcsr_std())); |
duke@435 | 1279 | } |
duke@435 | 1280 | else if (CheckJNICalls ) { |
never@739 | 1281 | __ call(RuntimeAddress(StubRoutines::x86::verify_mxcsr_entry())); |
duke@435 | 1282 | } |
duke@435 | 1283 | } |
duke@435 | 1284 | |
never@739 | 1285 | #ifndef _LP64 |
duke@435 | 1286 | // Either restore the x87 floating pointer control word after returning |
duke@435 | 1287 | // from the JNI call or verify that it wasn't changed. |
duke@435 | 1288 | if (CheckJNICalls) { |
never@739 | 1289 | __ call(RuntimeAddress(StubRoutines::x86::verify_fpu_cntrl_wrd_entry())); |
duke@435 | 1290 | } |
never@739 | 1291 | #endif // _LP64 |
duke@435 | 1292 | |
duke@435 | 1293 | |
duke@435 | 1294 | // change thread state |
duke@435 | 1295 | __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native_trans); |
duke@435 | 1296 | if(os::is_MP()) { |
duke@435 | 1297 | // Write serialization page so VM thread can do a pseudo remote membar. |
duke@435 | 1298 | // We use the current thread pointer to calculate a thread specific |
duke@435 | 1299 | // offset to write to within the page. This minimizes bus traffic |
duke@435 | 1300 | // due to cache line collision. |
duke@435 | 1301 | __ serialize_memory(thread, rcx); |
duke@435 | 1302 | } |
duke@435 | 1303 | |
duke@435 | 1304 | // check for safepoint operation in progress and/or pending suspend requests |
duke@435 | 1305 | { Label Continue; |
duke@435 | 1306 | |
duke@435 | 1307 | __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), |
duke@435 | 1308 | SafepointSynchronize::_not_synchronized); |
duke@435 | 1309 | |
duke@435 | 1310 | // threads running native code and they are expected to self-suspend |
duke@435 | 1311 | // when leaving the _thread_in_native state. We need to check for |
duke@435 | 1312 | // pending suspend requests here. |
duke@435 | 1313 | Label L; |
duke@435 | 1314 | __ jcc(Assembler::notEqual, L); |
duke@435 | 1315 | __ cmpl(Address(thread, JavaThread::suspend_flags_offset()), 0); |
duke@435 | 1316 | __ jcc(Assembler::equal, Continue); |
duke@435 | 1317 | __ bind(L); |
duke@435 | 1318 | |
duke@435 | 1319 | // Don't use call_VM as it will see a possible pending exception and forward it |
duke@435 | 1320 | // and never return here preventing us from clearing _last_native_pc down below. |
duke@435 | 1321 | // Also can't use call_VM_leaf either as it will check to see if rsi & rdi are |
never@739 | 1322 | // preserved and correspond to the bcp/locals pointers. |
duke@435 | 1323 | // |
never@739 | 1324 | |
never@739 | 1325 | ((MacroAssembler*)_masm)->call_VM_leaf(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans), |
never@739 | 1326 | thread); |
duke@435 | 1327 | __ increment(rsp, wordSize); |
duke@435 | 1328 | |
never@739 | 1329 | __ movptr(method, STATE(_method)); |
duke@435 | 1330 | __ verify_oop(method); |
never@739 | 1331 | __ movptr(thread, STATE(_thread)); // get thread |
duke@435 | 1332 | |
duke@435 | 1333 | __ bind(Continue); |
duke@435 | 1334 | } |
duke@435 | 1335 | |
duke@435 | 1336 | // change thread state |
duke@435 | 1337 | __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_Java); |
duke@435 | 1338 | |
duke@435 | 1339 | __ reset_last_Java_frame(thread, true, true); |
duke@435 | 1340 | |
duke@435 | 1341 | // reset handle block |
never@739 | 1342 | __ movptr(t, Address(thread, JavaThread::active_handles_offset())); |
never@739 | 1343 | __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); |
duke@435 | 1344 | |
duke@435 | 1345 | // If result was an oop then unbox and save it in the frame |
duke@435 | 1346 | { Label L; |
duke@435 | 1347 | Label no_oop, store_result; |
duke@435 | 1348 | ExternalAddress oop_handler(AbstractInterpreter::result_handler(T_OBJECT)); |
duke@435 | 1349 | __ cmpptr(STATE(_result_handler), oop_handler.addr()); |
duke@435 | 1350 | __ jcc(Assembler::notEqual, no_oop); |
never@739 | 1351 | #ifndef _LP64 |
never@739 | 1352 | __ pop(rdx); |
never@739 | 1353 | #endif // _LP64 |
never@739 | 1354 | __ pop(rax); |
never@739 | 1355 | __ testptr(rax, rax); |
duke@435 | 1356 | __ jcc(Assembler::zero, store_result); |
duke@435 | 1357 | // unbox |
never@739 | 1358 | __ movptr(rax, Address(rax, 0)); |
duke@435 | 1359 | __ bind(store_result); |
never@739 | 1360 | __ movptr(STATE(_oop_temp), rax); |
duke@435 | 1361 | // keep stack depth as expected by pushing oop which will eventually be discarded |
never@739 | 1362 | __ push(rax); |
never@739 | 1363 | #ifndef _LP64 |
never@739 | 1364 | __ push(rdx); |
never@739 | 1365 | #endif // _LP64 |
duke@435 | 1366 | __ bind(no_oop); |
duke@435 | 1367 | } |
duke@435 | 1368 | |
duke@435 | 1369 | { |
duke@435 | 1370 | Label no_reguard; |
duke@435 | 1371 | __ cmpl(Address(thread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_yellow_disabled); |
duke@435 | 1372 | __ jcc(Assembler::notEqual, no_reguard); |
duke@435 | 1373 | |
never@739 | 1374 | __ pusha(); |
duke@435 | 1375 | __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages))); |
never@739 | 1376 | __ popa(); |
duke@435 | 1377 | |
duke@435 | 1378 | __ bind(no_reguard); |
duke@435 | 1379 | } |
duke@435 | 1380 | |
duke@435 | 1381 | |
duke@435 | 1382 | // QQQ Seems like for native methods we simply return and the caller will see the pending |
duke@435 | 1383 | // exception and do the right thing. Certainly the interpreter will, don't know about |
duke@435 | 1384 | // compiled methods. |
duke@435 | 1385 | // Seems that the answer to above is no this is wrong. The old code would see the exception |
duke@435 | 1386 | // and forward it before doing the unlocking and notifying jvmdi that method has exited. |
duke@435 | 1387 | // This seems wrong need to investigate the spec. |
duke@435 | 1388 | |
duke@435 | 1389 | // handle exceptions (exception handling will handle unlocking!) |
duke@435 | 1390 | { Label L; |
never@739 | 1391 | __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); |
duke@435 | 1392 | __ jcc(Assembler::zero, L); |
duke@435 | 1393 | __ bind(pending_exception_present); |
duke@435 | 1394 | |
duke@435 | 1395 | // There are potential results on the stack (rax/rdx, ST(0)) we ignore these and simply |
duke@435 | 1396 | // return and let caller deal with exception. This skips the unlocking here which |
duke@435 | 1397 | // seems wrong but seems to be what asm interpreter did. Can't find this in the spec. |
duke@435 | 1398 | // Note: must preverve method in rbx |
duke@435 | 1399 | // |
duke@435 | 1400 | |
duke@435 | 1401 | // remove activation |
duke@435 | 1402 | |
never@739 | 1403 | __ movptr(t, STATE(_sender_sp)); |
duke@435 | 1404 | __ leave(); // remove frame anchor |
never@739 | 1405 | __ pop(rdi); // get return address |
never@739 | 1406 | __ movptr(state, STATE(_prev_link)); // get previous state for return |
never@739 | 1407 | __ mov(rsp, t); // set sp to sender sp |
never@739 | 1408 | __ push(rdi); // push throwing pc |
duke@435 | 1409 | // The skips unlocking!! This seems to be what asm interpreter does but seems |
duke@435 | 1410 | // very wrong. Not clear if this violates the spec. |
duke@435 | 1411 | __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); |
duke@435 | 1412 | __ bind(L); |
duke@435 | 1413 | } |
duke@435 | 1414 | |
duke@435 | 1415 | // do unlocking if necessary |
duke@435 | 1416 | { Label L; |
duke@435 | 1417 | __ movl(t, Address(method, methodOopDesc::access_flags_offset())); |
duke@435 | 1418 | __ testl(t, JVM_ACC_SYNCHRONIZED); |
duke@435 | 1419 | __ jcc(Assembler::zero, L); |
duke@435 | 1420 | // the code below should be shared with interpreter macro assembler implementation |
duke@435 | 1421 | { Label unlock; |
never@739 | 1422 | const Register monitor = NOT_LP64(rdx) LP64_ONLY(c_rarg1); |
duke@435 | 1423 | // BasicObjectLock will be first in list, since this is a synchronized method. However, need |
duke@435 | 1424 | // to check that the object has not been unlocked by an explicit monitorexit bytecode. |
never@739 | 1425 | __ movptr(monitor, STATE(_monitor_base)); |
never@739 | 1426 | __ subptr(monitor, frame::interpreter_frame_monitor_size() * wordSize); // address of initial monitor |
never@739 | 1427 | |
never@739 | 1428 | __ movptr(t, Address(monitor, BasicObjectLock::obj_offset_in_bytes())); |
never@739 | 1429 | __ testptr(t, t); |
duke@435 | 1430 | __ jcc(Assembler::notZero, unlock); |
duke@435 | 1431 | |
duke@435 | 1432 | // Entry already unlocked, need to throw exception |
duke@435 | 1433 | __ MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_illegal_monitor_state_exception)); |
duke@435 | 1434 | __ should_not_reach_here(); |
duke@435 | 1435 | |
duke@435 | 1436 | __ bind(unlock); |
never@739 | 1437 | __ unlock_object(monitor); |
duke@435 | 1438 | // unlock can blow rbx so restore it for path that needs it below |
never@739 | 1439 | __ movptr(method, STATE(_method)); |
duke@435 | 1440 | } |
duke@435 | 1441 | __ bind(L); |
duke@435 | 1442 | } |
duke@435 | 1443 | |
duke@435 | 1444 | // jvmti support |
duke@435 | 1445 | // Note: This must happen _after_ handling/throwing any exceptions since |
duke@435 | 1446 | // the exception handler code notifies the runtime of method exits |
duke@435 | 1447 | // too. If this happens before, method entry/exit notifications are |
duke@435 | 1448 | // not properly paired (was bug - gri 11/22/99). |
duke@435 | 1449 | __ notify_method_exit(vtos, InterpreterMacroAssembler::NotifyJVMTI); |
duke@435 | 1450 | |
duke@435 | 1451 | // restore potential result in rdx:rax, call result handler to restore potential result in ST0 & handle result |
never@739 | 1452 | #ifndef _LP64 |
never@739 | 1453 | __ pop(rdx); |
never@739 | 1454 | #endif // _LP64 |
never@739 | 1455 | __ pop(rax); |
never@739 | 1456 | __ movptr(t, STATE(_result_handler)); // get result handler |
duke@435 | 1457 | __ call(t); // call result handler to convert to tosca form |
duke@435 | 1458 | |
duke@435 | 1459 | // remove activation |
duke@435 | 1460 | |
never@739 | 1461 | __ movptr(t, STATE(_sender_sp)); |
duke@435 | 1462 | |
duke@435 | 1463 | __ leave(); // remove frame anchor |
never@739 | 1464 | __ pop(rdi); // get return address |
never@739 | 1465 | __ movptr(state, STATE(_prev_link)); // get previous state for return (if c++ interpreter was caller) |
never@739 | 1466 | __ mov(rsp, t); // set sp to sender sp |
duke@435 | 1467 | __ jmp(rdi); |
duke@435 | 1468 | |
duke@435 | 1469 | // invocation counter overflow |
duke@435 | 1470 | if (inc_counter) { |
duke@435 | 1471 | // Handle overflow of counter and compile method |
duke@435 | 1472 | __ bind(invocation_counter_overflow); |
duke@435 | 1473 | generate_counter_overflow(&continue_after_compile); |
duke@435 | 1474 | } |
duke@435 | 1475 | |
duke@435 | 1476 | return entry_point; |
duke@435 | 1477 | } |
duke@435 | 1478 | |
duke@435 | 1479 | // Generate entries that will put a result type index into rcx |
duke@435 | 1480 | void CppInterpreterGenerator::generate_deopt_handling() { |
duke@435 | 1481 | |
duke@435 | 1482 | Label return_from_deopt_common; |
duke@435 | 1483 | |
duke@435 | 1484 | // Generate entries that will put a result type index into rcx |
duke@435 | 1485 | // deopt needs to jump to here to enter the interpreter (return a result) |
duke@435 | 1486 | deopt_frame_manager_return_atos = __ pc(); |
duke@435 | 1487 | |
duke@435 | 1488 | // rax is live here |
duke@435 | 1489 | __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_OBJECT)); // Result stub address array index |
duke@435 | 1490 | __ jmp(return_from_deopt_common); |
duke@435 | 1491 | |
duke@435 | 1492 | |
duke@435 | 1493 | // deopt needs to jump to here to enter the interpreter (return a result) |
duke@435 | 1494 | deopt_frame_manager_return_btos = __ pc(); |
duke@435 | 1495 | |
duke@435 | 1496 | // rax is live here |
duke@435 | 1497 | __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_BOOLEAN)); // Result stub address array index |
duke@435 | 1498 | __ jmp(return_from_deopt_common); |
duke@435 | 1499 | |
duke@435 | 1500 | // deopt needs to jump to here to enter the interpreter (return a result) |
duke@435 | 1501 | deopt_frame_manager_return_itos = __ pc(); |
duke@435 | 1502 | |
duke@435 | 1503 | // rax is live here |
duke@435 | 1504 | __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_INT)); // Result stub address array index |
duke@435 | 1505 | __ jmp(return_from_deopt_common); |
duke@435 | 1506 | |
duke@435 | 1507 | // deopt needs to jump to here to enter the interpreter (return a result) |
duke@435 | 1508 | |
duke@435 | 1509 | deopt_frame_manager_return_ltos = __ pc(); |
duke@435 | 1510 | // rax,rdx are live here |
duke@435 | 1511 | __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_LONG)); // Result stub address array index |
duke@435 | 1512 | __ jmp(return_from_deopt_common); |
duke@435 | 1513 | |
duke@435 | 1514 | // deopt needs to jump to here to enter the interpreter (return a result) |
duke@435 | 1515 | |
duke@435 | 1516 | deopt_frame_manager_return_ftos = __ pc(); |
duke@435 | 1517 | // st(0) is live here |
duke@435 | 1518 | __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_FLOAT)); // Result stub address array index |
duke@435 | 1519 | __ jmp(return_from_deopt_common); |
duke@435 | 1520 | |
duke@435 | 1521 | // deopt needs to jump to here to enter the interpreter (return a result) |
duke@435 | 1522 | deopt_frame_manager_return_dtos = __ pc(); |
duke@435 | 1523 | |
duke@435 | 1524 | // st(0) is live here |
duke@435 | 1525 | __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_DOUBLE)); // Result stub address array index |
duke@435 | 1526 | __ jmp(return_from_deopt_common); |
duke@435 | 1527 | |
duke@435 | 1528 | // deopt needs to jump to here to enter the interpreter (return a result) |
duke@435 | 1529 | deopt_frame_manager_return_vtos = __ pc(); |
duke@435 | 1530 | |
duke@435 | 1531 | __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_VOID)); |
duke@435 | 1532 | |
duke@435 | 1533 | // Deopt return common |
duke@435 | 1534 | // an index is present in rcx that lets us move any possible result being |
duke@435 | 1535 | // return to the interpreter's stack |
duke@435 | 1536 | // |
duke@435 | 1537 | // Because we have a full sized interpreter frame on the youngest |
duke@435 | 1538 | // activation the stack is pushed too deep to share the tosca to |
duke@435 | 1539 | // stack converters directly. We shrink the stack to the desired |
duke@435 | 1540 | // amount and then push result and then re-extend the stack. |
duke@435 | 1541 | // We could have the code in size_activation layout a short |
duke@435 | 1542 | // frame for the top activation but that would look different |
duke@435 | 1543 | // than say sparc (which needs a full size activation because |
duke@435 | 1544 | // the windows are in the way. Really it could be short? QQQ |
duke@435 | 1545 | // |
duke@435 | 1546 | __ bind(return_from_deopt_common); |
duke@435 | 1547 | |
never@739 | 1548 | __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); |
duke@435 | 1549 | |
duke@435 | 1550 | // setup rsp so we can push the "result" as needed. |
never@739 | 1551 | __ movptr(rsp, STATE(_stack)); // trim stack (is prepushed) |
never@739 | 1552 | __ addptr(rsp, wordSize); // undo prepush |
duke@435 | 1553 | |
duke@435 | 1554 | ExternalAddress tosca_to_stack((address)CppInterpreter::_tosca_to_stack); |
never@739 | 1555 | // Address index(noreg, rcx, Address::times_ptr); |
never@739 | 1556 | __ movptr(rcx, ArrayAddress(tosca_to_stack, Address(noreg, rcx, Address::times_ptr))); |
never@739 | 1557 | // __ movl(rcx, Address(noreg, rcx, Address::times_ptr, int(AbstractInterpreter::_tosca_to_stack))); |
duke@435 | 1558 | __ call(rcx); // call result converter |
duke@435 | 1559 | |
duke@435 | 1560 | __ movl(STATE(_msg), (int)BytecodeInterpreter::deopt_resume); |
never@739 | 1561 | __ lea(rsp, Address(rsp, -wordSize)); // prepush stack (result if any already present) |
never@739 | 1562 | __ movptr(STATE(_stack), rsp); // inform interpreter of new stack depth (parameters removed, |
duke@435 | 1563 | // result if any on stack already ) |
never@739 | 1564 | __ movptr(rsp, STATE(_stack_limit)); // restore expression stack to full depth |
duke@435 | 1565 | } |
duke@435 | 1566 | |
duke@435 | 1567 | // Generate the code to handle a more_monitors message from the c++ interpreter |
duke@435 | 1568 | void CppInterpreterGenerator::generate_more_monitors() { |
duke@435 | 1569 | |
duke@435 | 1570 | |
duke@435 | 1571 | Label entry, loop; |
duke@435 | 1572 | const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; |
never@739 | 1573 | // 1. compute new pointers // rsp: old expression stack top |
never@739 | 1574 | __ movptr(rdx, STATE(_stack_base)); // rdx: old expression stack bottom |
never@739 | 1575 | __ subptr(rsp, entry_size); // move expression stack top limit |
never@739 | 1576 | __ subptr(STATE(_stack), entry_size); // update interpreter stack top |
never@739 | 1577 | __ subptr(STATE(_stack_limit), entry_size); // inform interpreter |
never@739 | 1578 | __ subptr(rdx, entry_size); // move expression stack bottom |
never@739 | 1579 | __ movptr(STATE(_stack_base), rdx); // inform interpreter |
never@739 | 1580 | __ movptr(rcx, STATE(_stack)); // set start value for copy loop |
duke@435 | 1581 | __ jmp(entry); |
duke@435 | 1582 | // 2. move expression stack contents |
duke@435 | 1583 | __ bind(loop); |
never@739 | 1584 | __ movptr(rbx, Address(rcx, entry_size)); // load expression stack word from old location |
never@739 | 1585 | __ movptr(Address(rcx, 0), rbx); // and store it at new location |
never@739 | 1586 | __ addptr(rcx, wordSize); // advance to next word |
duke@435 | 1587 | __ bind(entry); |
never@739 | 1588 | __ cmpptr(rcx, rdx); // check if bottom reached |
never@739 | 1589 | __ jcc(Assembler::notEqual, loop); // if not at bottom then copy next word |
duke@435 | 1590 | // now zero the slot so we can find it. |
never@739 | 1591 | __ movptr(Address(rdx, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL_WORD); |
duke@435 | 1592 | __ movl(STATE(_msg), (int)BytecodeInterpreter::got_monitors); |
duke@435 | 1593 | } |
duke@435 | 1594 | |
duke@435 | 1595 | |
duke@435 | 1596 | // Initial entry to C++ interpreter from the call_stub. |
duke@435 | 1597 | // This entry point is called the frame manager since it handles the generation |
duke@435 | 1598 | // of interpreter activation frames via requests directly from the vm (via call_stub) |
duke@435 | 1599 | // and via requests from the interpreter. The requests from the call_stub happen |
duke@435 | 1600 | // directly thru the entry point. Requests from the interpreter happen via returning |
duke@435 | 1601 | // from the interpreter and examining the message the interpreter has returned to |
duke@435 | 1602 | // the frame manager. The frame manager can take the following requests: |
duke@435 | 1603 | |
duke@435 | 1604 | // NO_REQUEST - error, should never happen. |
duke@435 | 1605 | // MORE_MONITORS - need a new monitor. Shuffle the expression stack on down and |
duke@435 | 1606 | // allocate a new monitor. |
duke@435 | 1607 | // CALL_METHOD - setup a new activation to call a new method. Very similar to what |
duke@435 | 1608 | // happens during entry during the entry via the call stub. |
duke@435 | 1609 | // RETURN_FROM_METHOD - remove an activation. Return to interpreter or call stub. |
duke@435 | 1610 | // |
duke@435 | 1611 | // Arguments: |
duke@435 | 1612 | // |
duke@435 | 1613 | // rbx: methodOop |
duke@435 | 1614 | // rcx: receiver - unused (retrieved from stack as needed) |
never@739 | 1615 | // rsi/r13: previous frame manager state (NULL from the call_stub/c1/c2) |
duke@435 | 1616 | // |
duke@435 | 1617 | // |
duke@435 | 1618 | // Stack layout at entry |
duke@435 | 1619 | // |
duke@435 | 1620 | // [ return address ] <--- rsp |
duke@435 | 1621 | // [ parameter n ] |
duke@435 | 1622 | // ... |
duke@435 | 1623 | // [ parameter 1 ] |
duke@435 | 1624 | // [ expression stack ] |
duke@435 | 1625 | // |
duke@435 | 1626 | // |
duke@435 | 1627 | // We are free to blow any registers we like because the call_stub which brought us here |
duke@435 | 1628 | // initially has preserved the callee save registers already. |
duke@435 | 1629 | // |
duke@435 | 1630 | // |
duke@435 | 1631 | |
duke@435 | 1632 | static address interpreter_frame_manager = NULL; |
duke@435 | 1633 | |
duke@435 | 1634 | address InterpreterGenerator::generate_normal_entry(bool synchronized) { |
duke@435 | 1635 | |
duke@435 | 1636 | // rbx: methodOop |
never@739 | 1637 | // rsi/r13: sender sp |
duke@435 | 1638 | |
duke@435 | 1639 | // Because we redispatch "recursive" interpreter entries thru this same entry point |
duke@435 | 1640 | // the "input" register usage is a little strange and not what you expect coming |
duke@435 | 1641 | // from the call_stub. From the call stub rsi/rdi (current/previous) interpreter |
duke@435 | 1642 | // state are NULL but on "recursive" dispatches they are what you'd expect. |
duke@435 | 1643 | // rsi: current interpreter state (C++ interpreter) must preserve (null from call_stub/c1/c2) |
duke@435 | 1644 | |
duke@435 | 1645 | |
duke@435 | 1646 | // A single frame manager is plenty as we don't specialize for synchronized. We could and |
duke@435 | 1647 | // the code is pretty much ready. Would need to change the test below and for good measure |
duke@435 | 1648 | // modify generate_interpreter_state to only do the (pre) sync stuff stuff for synchronized |
duke@435 | 1649 | // routines. Not clear this is worth it yet. |
duke@435 | 1650 | |
duke@435 | 1651 | if (interpreter_frame_manager) return interpreter_frame_manager; |
duke@435 | 1652 | |
duke@435 | 1653 | address entry_point = __ pc(); |
duke@435 | 1654 | |
duke@435 | 1655 | // Fast accessor methods share this entry point. |
duke@435 | 1656 | // This works because frame manager is in the same codelet |
duke@435 | 1657 | if (UseFastAccessorMethods && !synchronized) __ bind(fast_accessor_slow_entry_path); |
duke@435 | 1658 | |
duke@435 | 1659 | Label dispatch_entry_2; |
never@739 | 1660 | __ movptr(rcx, sender_sp_on_entry); |
never@739 | 1661 | __ movptr(state, (int32_t)NULL_WORD); // no current activation |
duke@435 | 1662 | |
duke@435 | 1663 | __ jmp(dispatch_entry_2); |
duke@435 | 1664 | |
duke@435 | 1665 | const Register locals = rdi; |
duke@435 | 1666 | |
duke@435 | 1667 | Label re_dispatch; |
duke@435 | 1668 | |
duke@435 | 1669 | __ bind(re_dispatch); |
duke@435 | 1670 | |
duke@435 | 1671 | // save sender sp (doesn't include return address |
never@739 | 1672 | __ lea(rcx, Address(rsp, wordSize)); |
duke@435 | 1673 | |
duke@435 | 1674 | __ bind(dispatch_entry_2); |
duke@435 | 1675 | |
duke@435 | 1676 | // save sender sp |
never@739 | 1677 | __ push(rcx); |
duke@435 | 1678 | |
duke@435 | 1679 | const Address size_of_parameters(rbx, methodOopDesc::size_of_parameters_offset()); |
duke@435 | 1680 | const Address size_of_locals (rbx, methodOopDesc::size_of_locals_offset()); |
duke@435 | 1681 | const Address access_flags (rbx, methodOopDesc::access_flags_offset()); |
duke@435 | 1682 | |
duke@435 | 1683 | // const Address monitor_block_top (rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); |
duke@435 | 1684 | // const Address monitor_block_bot (rbp, frame::interpreter_frame_initial_sp_offset * wordSize); |
duke@435 | 1685 | // const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset * wordSize - (int)sizeof(BasicObjectLock)); |
duke@435 | 1686 | |
duke@435 | 1687 | // get parameter size (always needed) |
jrose@1057 | 1688 | __ load_unsigned_short(rcx, size_of_parameters); |
duke@435 | 1689 | |
duke@435 | 1690 | // rbx: methodOop |
duke@435 | 1691 | // rcx: size of parameters |
jrose@1057 | 1692 | __ load_unsigned_short(rdx, size_of_locals); // get size of locals in words |
duke@435 | 1693 | |
never@739 | 1694 | __ subptr(rdx, rcx); // rdx = no. of additional locals |
duke@435 | 1695 | |
duke@435 | 1696 | // see if we've got enough room on the stack for locals plus overhead. |
duke@435 | 1697 | generate_stack_overflow_check(); // C++ |
duke@435 | 1698 | |
duke@435 | 1699 | // c++ interpreter does not use stack banging or any implicit exceptions |
duke@435 | 1700 | // leave for now to verify that check is proper. |
duke@435 | 1701 | bang_stack_shadow_pages(false); |
duke@435 | 1702 | |
duke@435 | 1703 | |
duke@435 | 1704 | |
duke@435 | 1705 | // compute beginning of parameters (rdi) |
never@739 | 1706 | __ lea(locals, Address(rsp, rcx, Address::times_ptr, wordSize)); |
duke@435 | 1707 | |
duke@435 | 1708 | // save sender's sp |
duke@435 | 1709 | // __ movl(rcx, rsp); |
duke@435 | 1710 | |
duke@435 | 1711 | // get sender's sp |
never@739 | 1712 | __ pop(rcx); |
duke@435 | 1713 | |
duke@435 | 1714 | // get return address |
never@739 | 1715 | __ pop(rax); |
duke@435 | 1716 | |
duke@435 | 1717 | // rdx - # of additional locals |
duke@435 | 1718 | // allocate space for locals |
duke@435 | 1719 | // explicitly initialize locals |
duke@435 | 1720 | { |
duke@435 | 1721 | Label exit, loop; |
never@739 | 1722 | __ testl(rdx, rdx); // (32bit ok) |
duke@435 | 1723 | __ jcc(Assembler::lessEqual, exit); // do nothing if rdx <= 0 |
duke@435 | 1724 | __ bind(loop); |
never@739 | 1725 | __ push((int32_t)NULL_WORD); // initialize local variables |
duke@435 | 1726 | __ decrement(rdx); // until everything initialized |
duke@435 | 1727 | __ jcc(Assembler::greater, loop); |
duke@435 | 1728 | __ bind(exit); |
duke@435 | 1729 | } |
duke@435 | 1730 | |
duke@435 | 1731 | |
duke@435 | 1732 | // Assumes rax = return address |
duke@435 | 1733 | |
duke@435 | 1734 | // allocate and initialize new interpreterState and method expression stack |
duke@435 | 1735 | // IN(locals) -> locals |
duke@435 | 1736 | // IN(state) -> any current interpreter activation |
duke@435 | 1737 | // destroys rax, rcx, rdx, rdi |
duke@435 | 1738 | // OUT (state) -> new interpreterState |
duke@435 | 1739 | // OUT(rsp) -> bottom of methods expression stack |
duke@435 | 1740 | |
duke@435 | 1741 | generate_compute_interpreter_state(state, locals, rcx, false); |
duke@435 | 1742 | |
duke@435 | 1743 | // Call interpreter |
duke@435 | 1744 | |
duke@435 | 1745 | Label call_interpreter; |
duke@435 | 1746 | __ bind(call_interpreter); |
duke@435 | 1747 | |
duke@435 | 1748 | // c++ interpreter does not use stack banging or any implicit exceptions |
duke@435 | 1749 | // leave for now to verify that check is proper. |
duke@435 | 1750 | bang_stack_shadow_pages(false); |
duke@435 | 1751 | |
duke@435 | 1752 | |
duke@435 | 1753 | // Call interpreter enter here if message is |
duke@435 | 1754 | // set and we know stack size is valid |
duke@435 | 1755 | |
duke@435 | 1756 | Label call_interpreter_2; |
duke@435 | 1757 | |
duke@435 | 1758 | __ bind(call_interpreter_2); |
duke@435 | 1759 | |
duke@435 | 1760 | { |
never@739 | 1761 | const Register thread = NOT_LP64(rcx) LP64_ONLY(r15_thread); |
never@739 | 1762 | |
never@739 | 1763 | #ifdef _LP64 |
never@739 | 1764 | __ mov(c_rarg0, state); |
never@739 | 1765 | #else |
never@739 | 1766 | __ push(state); // push arg to interpreter |
never@739 | 1767 | __ movptr(thread, STATE(_thread)); |
never@739 | 1768 | #endif // _LP64 |
duke@435 | 1769 | |
duke@435 | 1770 | // We can setup the frame anchor with everything we want at this point |
duke@435 | 1771 | // as we are thread_in_Java and no safepoints can occur until we go to |
duke@435 | 1772 | // vm mode. We do have to clear flags on return from vm but that is it |
duke@435 | 1773 | // |
never@739 | 1774 | __ movptr(Address(thread, JavaThread::last_Java_fp_offset()), rbp); |
never@739 | 1775 | __ movptr(Address(thread, JavaThread::last_Java_sp_offset()), rsp); |
duke@435 | 1776 | |
duke@435 | 1777 | // Call the interpreter |
duke@435 | 1778 | |
duke@435 | 1779 | RuntimeAddress normal(CAST_FROM_FN_PTR(address, BytecodeInterpreter::run)); |
duke@435 | 1780 | RuntimeAddress checking(CAST_FROM_FN_PTR(address, BytecodeInterpreter::runWithChecks)); |
duke@435 | 1781 | |
duke@435 | 1782 | __ call(JvmtiExport::can_post_interpreter_events() ? checking : normal); |
never@739 | 1783 | NOT_LP64(__ pop(rax);) // discard parameter to run |
duke@435 | 1784 | // |
duke@435 | 1785 | // state is preserved since it is callee saved |
duke@435 | 1786 | // |
duke@435 | 1787 | |
duke@435 | 1788 | // reset_last_Java_frame |
duke@435 | 1789 | |
never@739 | 1790 | NOT_LP64(__ movl(thread, STATE(_thread));) |
duke@435 | 1791 | __ reset_last_Java_frame(thread, true, true); |
duke@435 | 1792 | } |
duke@435 | 1793 | |
duke@435 | 1794 | // examine msg from interpreter to determine next action |
duke@435 | 1795 | |
duke@435 | 1796 | __ movl(rdx, STATE(_msg)); // Get new message |
duke@435 | 1797 | |
duke@435 | 1798 | Label call_method; |
duke@435 | 1799 | Label return_from_interpreted_method; |
duke@435 | 1800 | Label throw_exception; |
duke@435 | 1801 | Label bad_msg; |
duke@435 | 1802 | Label do_OSR; |
duke@435 | 1803 | |
never@739 | 1804 | __ cmpl(rdx, (int32_t)BytecodeInterpreter::call_method); |
duke@435 | 1805 | __ jcc(Assembler::equal, call_method); |
never@739 | 1806 | __ cmpl(rdx, (int32_t)BytecodeInterpreter::return_from_method); |
duke@435 | 1807 | __ jcc(Assembler::equal, return_from_interpreted_method); |
never@739 | 1808 | __ cmpl(rdx, (int32_t)BytecodeInterpreter::do_osr); |
duke@435 | 1809 | __ jcc(Assembler::equal, do_OSR); |
never@739 | 1810 | __ cmpl(rdx, (int32_t)BytecodeInterpreter::throwing_exception); |
duke@435 | 1811 | __ jcc(Assembler::equal, throw_exception); |
never@739 | 1812 | __ cmpl(rdx, (int32_t)BytecodeInterpreter::more_monitors); |
duke@435 | 1813 | __ jcc(Assembler::notEqual, bad_msg); |
duke@435 | 1814 | |
duke@435 | 1815 | // Allocate more monitor space, shuffle expression stack.... |
duke@435 | 1816 | |
duke@435 | 1817 | generate_more_monitors(); |
duke@435 | 1818 | |
duke@435 | 1819 | __ jmp(call_interpreter); |
duke@435 | 1820 | |
duke@435 | 1821 | // uncommon trap needs to jump to here to enter the interpreter (re-execute current bytecode) |
duke@435 | 1822 | unctrap_frame_manager_entry = __ pc(); |
duke@435 | 1823 | // |
duke@435 | 1824 | // Load the registers we need. |
never@739 | 1825 | __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); |
never@739 | 1826 | __ movptr(rsp, STATE(_stack_limit)); // restore expression stack to full depth |
duke@435 | 1827 | __ jmp(call_interpreter_2); |
duke@435 | 1828 | |
duke@435 | 1829 | |
duke@435 | 1830 | |
duke@435 | 1831 | //============================================================================= |
duke@435 | 1832 | // Returning from a compiled method into a deopted method. The bytecode at the |
duke@435 | 1833 | // bcp has completed. The result of the bytecode is in the native abi (the tosca |
duke@435 | 1834 | // for the template based interpreter). Any stack space that was used by the |
duke@435 | 1835 | // bytecode that has completed has been removed (e.g. parameters for an invoke) |
duke@435 | 1836 | // so all that we have to do is place any pending result on the expression stack |
duke@435 | 1837 | // and resume execution on the next bytecode. |
duke@435 | 1838 | |
duke@435 | 1839 | |
duke@435 | 1840 | generate_deopt_handling(); |
duke@435 | 1841 | __ jmp(call_interpreter); |
duke@435 | 1842 | |
duke@435 | 1843 | |
duke@435 | 1844 | // Current frame has caught an exception we need to dispatch to the |
duke@435 | 1845 | // handler. We can get here because a native interpreter frame caught |
duke@435 | 1846 | // an exception in which case there is no handler and we must rethrow |
duke@435 | 1847 | // If it is a vanilla interpreted frame the we simply drop into the |
duke@435 | 1848 | // interpreter and let it do the lookup. |
duke@435 | 1849 | |
duke@435 | 1850 | Interpreter::_rethrow_exception_entry = __ pc(); |
duke@435 | 1851 | // rax: exception |
duke@435 | 1852 | // rdx: return address/pc that threw exception |
duke@435 | 1853 | |
duke@435 | 1854 | Label return_with_exception; |
duke@435 | 1855 | Label unwind_and_forward; |
duke@435 | 1856 | |
duke@435 | 1857 | // restore state pointer. |
coleenp@955 | 1858 | __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); |
never@739 | 1859 | |
never@739 | 1860 | __ movptr(rbx, STATE(_method)); // get method |
never@739 | 1861 | #ifdef _LP64 |
never@739 | 1862 | __ movptr(Address(r15_thread, Thread::pending_exception_offset()), rax); |
never@739 | 1863 | #else |
duke@435 | 1864 | __ movl(rcx, STATE(_thread)); // get thread |
duke@435 | 1865 | |
duke@435 | 1866 | // Store exception with interpreter will expect it |
never@739 | 1867 | __ movptr(Address(rcx, Thread::pending_exception_offset()), rax); |
never@739 | 1868 | #endif // _LP64 |
duke@435 | 1869 | |
duke@435 | 1870 | // is current frame vanilla or native? |
duke@435 | 1871 | |
duke@435 | 1872 | __ movl(rdx, access_flags); |
duke@435 | 1873 | __ testl(rdx, JVM_ACC_NATIVE); |
duke@435 | 1874 | __ jcc(Assembler::zero, return_with_exception); // vanilla interpreted frame, handle directly |
duke@435 | 1875 | |
duke@435 | 1876 | // We drop thru to unwind a native interpreted frame with a pending exception |
duke@435 | 1877 | // We jump here for the initial interpreter frame with exception pending |
duke@435 | 1878 | // We unwind the current acivation and forward it to our caller. |
duke@435 | 1879 | |
duke@435 | 1880 | __ bind(unwind_and_forward); |
duke@435 | 1881 | |
duke@435 | 1882 | // unwind rbp, return stack to unextended value and re-push return address |
duke@435 | 1883 | |
never@739 | 1884 | __ movptr(rcx, STATE(_sender_sp)); |
duke@435 | 1885 | __ leave(); |
never@739 | 1886 | __ pop(rdx); |
never@739 | 1887 | __ mov(rsp, rcx); |
never@739 | 1888 | __ push(rdx); |
duke@435 | 1889 | __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); |
duke@435 | 1890 | |
duke@435 | 1891 | // Return point from a call which returns a result in the native abi |
duke@435 | 1892 | // (c1/c2/jni-native). This result must be processed onto the java |
duke@435 | 1893 | // expression stack. |
duke@435 | 1894 | // |
duke@435 | 1895 | // A pending exception may be present in which case there is no result present |
duke@435 | 1896 | |
duke@435 | 1897 | Label resume_interpreter; |
duke@435 | 1898 | Label do_float; |
duke@435 | 1899 | Label do_double; |
duke@435 | 1900 | Label done_conv; |
duke@435 | 1901 | |
duke@435 | 1902 | address compiled_entry = __ pc(); |
duke@435 | 1903 | |
duke@435 | 1904 | // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases |
duke@435 | 1905 | if (UseSSE < 2) { |
coleenp@955 | 1906 | __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); |
never@739 | 1907 | __ movptr(rbx, STATE(_result._to_call._callee)); // get method just executed |
duke@435 | 1908 | __ movl(rcx, Address(rbx, methodOopDesc::result_index_offset())); |
duke@435 | 1909 | __ cmpl(rcx, AbstractInterpreter::BasicType_as_index(T_FLOAT)); // Result stub address array index |
duke@435 | 1910 | __ jcc(Assembler::equal, do_float); |
duke@435 | 1911 | __ cmpl(rcx, AbstractInterpreter::BasicType_as_index(T_DOUBLE)); // Result stub address array index |
duke@435 | 1912 | __ jcc(Assembler::equal, do_double); |
coleenp@955 | 1913 | #if !defined(_LP64) || defined(COMPILER1) || !defined(COMPILER2) |
duke@435 | 1914 | __ empty_FPU_stack(); |
duke@435 | 1915 | #endif // COMPILER2 |
duke@435 | 1916 | __ jmp(done_conv); |
duke@435 | 1917 | |
duke@435 | 1918 | __ bind(do_float); |
duke@435 | 1919 | #ifdef COMPILER2 |
duke@435 | 1920 | for (int i = 1; i < 8; i++) { |
duke@435 | 1921 | __ ffree(i); |
duke@435 | 1922 | } |
duke@435 | 1923 | #endif // COMPILER2 |
duke@435 | 1924 | __ jmp(done_conv); |
duke@435 | 1925 | __ bind(do_double); |
duke@435 | 1926 | #ifdef COMPILER2 |
duke@435 | 1927 | for (int i = 1; i < 8; i++) { |
duke@435 | 1928 | __ ffree(i); |
duke@435 | 1929 | } |
duke@435 | 1930 | #endif // COMPILER2 |
duke@435 | 1931 | __ jmp(done_conv); |
duke@435 | 1932 | } else { |
duke@435 | 1933 | __ MacroAssembler::verify_FPU(0, "generate_return_entry_for compiled"); |
duke@435 | 1934 | __ jmp(done_conv); |
duke@435 | 1935 | } |
duke@435 | 1936 | |
never@739 | 1937 | #if 0 |
duke@435 | 1938 | // emit a sentinel we can test for when converting an interpreter |
duke@435 | 1939 | // entry point to a compiled entry point. |
duke@435 | 1940 | __ a_long(Interpreter::return_sentinel); |
duke@435 | 1941 | __ a_long((int)compiled_entry); |
never@739 | 1942 | #endif |
duke@435 | 1943 | |
duke@435 | 1944 | // Return point to interpreter from compiled/native method |
duke@435 | 1945 | |
duke@435 | 1946 | InternalAddress return_from_native_method(__ pc()); |
duke@435 | 1947 | |
duke@435 | 1948 | __ bind(done_conv); |
duke@435 | 1949 | |
duke@435 | 1950 | |
duke@435 | 1951 | // Result if any is in tosca. The java expression stack is in the state that the |
duke@435 | 1952 | // calling convention left it (i.e. params may or may not be present) |
duke@435 | 1953 | // Copy the result from tosca and place it on java expression stack. |
duke@435 | 1954 | |
never@739 | 1955 | // Restore rsi/r13 as compiled code may not preserve it |
never@739 | 1956 | |
coleenp@955 | 1957 | __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); |
duke@435 | 1958 | |
duke@435 | 1959 | // restore stack to what we had when we left (in case i2c extended it) |
duke@435 | 1960 | |
never@739 | 1961 | __ movptr(rsp, STATE(_stack)); |
never@739 | 1962 | __ lea(rsp, Address(rsp, wordSize)); |
duke@435 | 1963 | |
duke@435 | 1964 | // If there is a pending exception then we don't really have a result to process |
duke@435 | 1965 | |
never@739 | 1966 | #ifdef _LP64 |
never@739 | 1967 | __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); |
never@739 | 1968 | #else |
never@739 | 1969 | __ movptr(rcx, STATE(_thread)); // get thread |
never@739 | 1970 | __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD); |
coleenp@955 | 1971 | #endif // _LP64 |
duke@435 | 1972 | __ jcc(Assembler::notZero, return_with_exception); |
duke@435 | 1973 | |
duke@435 | 1974 | // get method just executed |
never@739 | 1975 | __ movptr(rbx, STATE(_result._to_call._callee)); |
duke@435 | 1976 | |
duke@435 | 1977 | // callee left args on top of expression stack, remove them |
jrose@1057 | 1978 | __ load_unsigned_short(rcx, Address(rbx, methodOopDesc::size_of_parameters_offset())); |
never@739 | 1979 | __ lea(rsp, Address(rsp, rcx, Address::times_ptr)); |
duke@435 | 1980 | |
duke@435 | 1981 | __ movl(rcx, Address(rbx, methodOopDesc::result_index_offset())); |
duke@435 | 1982 | ExternalAddress tosca_to_stack((address)CppInterpreter::_tosca_to_stack); |
never@739 | 1983 | // Address index(noreg, rax, Address::times_ptr); |
never@739 | 1984 | __ movptr(rcx, ArrayAddress(tosca_to_stack, Address(noreg, rcx, Address::times_ptr))); |
never@739 | 1985 | // __ movl(rcx, Address(noreg, rcx, Address::times_ptr, int(AbstractInterpreter::_tosca_to_stack))); |
duke@435 | 1986 | __ call(rcx); // call result converter |
duke@435 | 1987 | __ jmp(resume_interpreter); |
duke@435 | 1988 | |
duke@435 | 1989 | // An exception is being caught on return to a vanilla interpreter frame. |
duke@435 | 1990 | // Empty the stack and resume interpreter |
duke@435 | 1991 | |
duke@435 | 1992 | __ bind(return_with_exception); |
duke@435 | 1993 | |
duke@435 | 1994 | // Exception present, empty stack |
never@739 | 1995 | __ movptr(rsp, STATE(_stack_base)); |
duke@435 | 1996 | __ jmp(resume_interpreter); |
duke@435 | 1997 | |
duke@435 | 1998 | // Return from interpreted method we return result appropriate to the caller (i.e. "recursive" |
duke@435 | 1999 | // interpreter call, or native) and unwind this interpreter activation. |
duke@435 | 2000 | // All monitors should be unlocked. |
duke@435 | 2001 | |
duke@435 | 2002 | __ bind(return_from_interpreted_method); |
duke@435 | 2003 | |
duke@435 | 2004 | Label return_to_initial_caller; |
duke@435 | 2005 | |
never@739 | 2006 | __ movptr(rbx, STATE(_method)); // get method just executed |
never@739 | 2007 | __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from "recursive" interpreter call? |
duke@435 | 2008 | __ movl(rax, Address(rbx, methodOopDesc::result_index_offset())); // get result type index |
duke@435 | 2009 | __ jcc(Assembler::equal, return_to_initial_caller); // back to native code (call_stub/c1/c2) |
duke@435 | 2010 | |
duke@435 | 2011 | // Copy result to callers java stack |
duke@435 | 2012 | ExternalAddress stack_to_stack((address)CppInterpreter::_stack_to_stack); |
never@739 | 2013 | // Address index(noreg, rax, Address::times_ptr); |
never@739 | 2014 | |
never@739 | 2015 | __ movptr(rax, ArrayAddress(stack_to_stack, Address(noreg, rax, Address::times_ptr))); |
never@739 | 2016 | // __ movl(rax, Address(noreg, rax, Address::times_ptr, int(AbstractInterpreter::_stack_to_stack))); |
duke@435 | 2017 | __ call(rax); // call result converter |
duke@435 | 2018 | |
duke@435 | 2019 | Label unwind_recursive_activation; |
duke@435 | 2020 | __ bind(unwind_recursive_activation); |
duke@435 | 2021 | |
duke@435 | 2022 | // returning to interpreter method from "recursive" interpreter call |
duke@435 | 2023 | // result converter left rax pointing to top of the java stack for method we are returning |
duke@435 | 2024 | // to. Now all we must do is unwind the state from the completed call |
duke@435 | 2025 | |
never@739 | 2026 | __ movptr(state, STATE(_prev_link)); // unwind state |
duke@435 | 2027 | __ leave(); // pop the frame |
never@739 | 2028 | __ mov(rsp, rax); // unwind stack to remove args |
duke@435 | 2029 | |
duke@435 | 2030 | // Resume the interpreter. The current frame contains the current interpreter |
duke@435 | 2031 | // state object. |
duke@435 | 2032 | // |
duke@435 | 2033 | |
duke@435 | 2034 | __ bind(resume_interpreter); |
duke@435 | 2035 | |
duke@435 | 2036 | // state == interpreterState object for method we are resuming |
duke@435 | 2037 | |
duke@435 | 2038 | __ movl(STATE(_msg), (int)BytecodeInterpreter::method_resume); |
never@739 | 2039 | __ lea(rsp, Address(rsp, -wordSize)); // prepush stack (result if any already present) |
never@739 | 2040 | __ movptr(STATE(_stack), rsp); // inform interpreter of new stack depth (parameters removed, |
duke@435 | 2041 | // result if any on stack already ) |
never@739 | 2042 | __ movptr(rsp, STATE(_stack_limit)); // restore expression stack to full depth |
duke@435 | 2043 | __ jmp(call_interpreter_2); // No need to bang |
duke@435 | 2044 | |
duke@435 | 2045 | // interpreter returning to native code (call_stub/c1/c2) |
duke@435 | 2046 | // convert result and unwind initial activation |
duke@435 | 2047 | // rax - result index |
duke@435 | 2048 | |
duke@435 | 2049 | __ bind(return_to_initial_caller); |
duke@435 | 2050 | ExternalAddress stack_to_native((address)CppInterpreter::_stack_to_native_abi); |
never@739 | 2051 | // Address index(noreg, rax, Address::times_ptr); |
never@739 | 2052 | |
never@739 | 2053 | __ movptr(rax, ArrayAddress(stack_to_native, Address(noreg, rax, Address::times_ptr))); |
duke@435 | 2054 | __ call(rax); // call result converter |
duke@435 | 2055 | |
duke@435 | 2056 | Label unwind_initial_activation; |
duke@435 | 2057 | __ bind(unwind_initial_activation); |
duke@435 | 2058 | |
duke@435 | 2059 | // RETURN TO CALL_STUB/C1/C2 code (result if any in rax/rdx ST(0)) |
duke@435 | 2060 | |
duke@435 | 2061 | /* Current stack picture |
duke@435 | 2062 | |
duke@435 | 2063 | [ incoming parameters ] |
duke@435 | 2064 | [ extra locals ] |
duke@435 | 2065 | [ return address to CALL_STUB/C1/C2] |
duke@435 | 2066 | fp -> [ CALL_STUB/C1/C2 fp ] |
duke@435 | 2067 | BytecodeInterpreter object |
duke@435 | 2068 | expression stack |
duke@435 | 2069 | sp -> |
duke@435 | 2070 | |
duke@435 | 2071 | */ |
duke@435 | 2072 | |
duke@435 | 2073 | // return restoring the stack to the original sender_sp value |
duke@435 | 2074 | |
never@739 | 2075 | __ movptr(rcx, STATE(_sender_sp)); |
duke@435 | 2076 | __ leave(); |
never@739 | 2077 | __ pop(rdi); // get return address |
duke@435 | 2078 | // set stack to sender's sp |
never@739 | 2079 | __ mov(rsp, rcx); |
duke@435 | 2080 | __ jmp(rdi); // return to call_stub |
duke@435 | 2081 | |
duke@435 | 2082 | // OSR request, adjust return address to make current frame into adapter frame |
duke@435 | 2083 | // and enter OSR nmethod |
duke@435 | 2084 | |
duke@435 | 2085 | __ bind(do_OSR); |
duke@435 | 2086 | |
duke@435 | 2087 | Label remove_initial_frame; |
duke@435 | 2088 | |
duke@435 | 2089 | // We are going to pop this frame. Is there another interpreter frame underneath |
duke@435 | 2090 | // it or is it callstub/compiled? |
duke@435 | 2091 | |
duke@435 | 2092 | // Move buffer to the expected parameter location |
never@739 | 2093 | __ movptr(rcx, STATE(_result._osr._osr_buf)); |
never@739 | 2094 | |
never@739 | 2095 | __ movptr(rax, STATE(_result._osr._osr_entry)); |
never@739 | 2096 | |
never@739 | 2097 | __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from "recursive" interpreter call? |
duke@435 | 2098 | __ jcc(Assembler::equal, remove_initial_frame); // back to native code (call_stub/c1/c2) |
duke@435 | 2099 | |
never@739 | 2100 | __ movptr(sender_sp_on_entry, STATE(_sender_sp)); // get sender's sp in expected register |
duke@435 | 2101 | __ leave(); // pop the frame |
never@739 | 2102 | __ mov(rsp, sender_sp_on_entry); // trim any stack expansion |
duke@435 | 2103 | |
duke@435 | 2104 | |
duke@435 | 2105 | // We know we are calling compiled so push specialized return |
duke@435 | 2106 | // method uses specialized entry, push a return so we look like call stub setup |
duke@435 | 2107 | // this path will handle fact that result is returned in registers and not |
duke@435 | 2108 | // on the java stack. |
duke@435 | 2109 | |
duke@435 | 2110 | __ pushptr(return_from_native_method.addr()); |
duke@435 | 2111 | |
duke@435 | 2112 | __ jmp(rax); |
duke@435 | 2113 | |
duke@435 | 2114 | __ bind(remove_initial_frame); |
duke@435 | 2115 | |
never@739 | 2116 | __ movptr(rdx, STATE(_sender_sp)); |
duke@435 | 2117 | __ leave(); |
duke@435 | 2118 | // get real return |
never@739 | 2119 | __ pop(rsi); |
duke@435 | 2120 | // set stack to sender's sp |
never@739 | 2121 | __ mov(rsp, rdx); |
duke@435 | 2122 | // repush real return |
never@739 | 2123 | __ push(rsi); |
duke@435 | 2124 | // Enter OSR nmethod |
duke@435 | 2125 | __ jmp(rax); |
duke@435 | 2126 | |
duke@435 | 2127 | |
duke@435 | 2128 | |
duke@435 | 2129 | |
duke@435 | 2130 | // Call a new method. All we do is (temporarily) trim the expression stack |
duke@435 | 2131 | // push a return address to bring us back to here and leap to the new entry. |
duke@435 | 2132 | |
duke@435 | 2133 | __ bind(call_method); |
duke@435 | 2134 | |
duke@435 | 2135 | // stack points to next free location and not top element on expression stack |
duke@435 | 2136 | // method expects sp to be pointing to topmost element |
duke@435 | 2137 | |
never@739 | 2138 | __ movptr(rsp, STATE(_stack)); // pop args to c++ interpreter, set sp to java stack top |
never@739 | 2139 | __ lea(rsp, Address(rsp, wordSize)); |
never@739 | 2140 | |
never@739 | 2141 | __ movptr(rbx, STATE(_result._to_call._callee)); // get method to execute |
duke@435 | 2142 | |
duke@435 | 2143 | // don't need a return address if reinvoking interpreter |
duke@435 | 2144 | |
duke@435 | 2145 | // Make it look like call_stub calling conventions |
duke@435 | 2146 | |
duke@435 | 2147 | // Get (potential) receiver |
jrose@1057 | 2148 | __ load_unsigned_short(rcx, size_of_parameters); // get size of parameters in words |
duke@435 | 2149 | |
duke@435 | 2150 | ExternalAddress recursive(CAST_FROM_FN_PTR(address, RecursiveInterpreterActivation)); |
duke@435 | 2151 | __ pushptr(recursive.addr()); // make it look good in the debugger |
duke@435 | 2152 | |
duke@435 | 2153 | InternalAddress entry(entry_point); |
duke@435 | 2154 | __ cmpptr(STATE(_result._to_call._callee_entry_point), entry.addr()); // returning to interpreter? |
duke@435 | 2155 | __ jcc(Assembler::equal, re_dispatch); // yes |
duke@435 | 2156 | |
never@739 | 2157 | __ pop(rax); // pop dummy address |
duke@435 | 2158 | |
duke@435 | 2159 | |
duke@435 | 2160 | // get specialized entry |
never@739 | 2161 | __ movptr(rax, STATE(_result._to_call._callee_entry_point)); |
duke@435 | 2162 | // set sender SP |
never@739 | 2163 | __ mov(sender_sp_on_entry, rsp); |
duke@435 | 2164 | |
duke@435 | 2165 | // method uses specialized entry, push a return so we look like call stub setup |
duke@435 | 2166 | // this path will handle fact that result is returned in registers and not |
duke@435 | 2167 | // on the java stack. |
duke@435 | 2168 | |
duke@435 | 2169 | __ pushptr(return_from_native_method.addr()); |
duke@435 | 2170 | |
duke@435 | 2171 | __ jmp(rax); |
duke@435 | 2172 | |
duke@435 | 2173 | __ bind(bad_msg); |
duke@435 | 2174 | __ stop("Bad message from interpreter"); |
duke@435 | 2175 | |
duke@435 | 2176 | // Interpreted method "returned" with an exception pass it on... |
duke@435 | 2177 | // Pass result, unwind activation and continue/return to interpreter/call_stub |
duke@435 | 2178 | // We handle result (if any) differently based on return to interpreter or call_stub |
duke@435 | 2179 | |
duke@435 | 2180 | Label unwind_initial_with_pending_exception; |
duke@435 | 2181 | |
duke@435 | 2182 | __ bind(throw_exception); |
never@739 | 2183 | __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from recursive interpreter call? |
duke@435 | 2184 | __ jcc(Assembler::equal, unwind_initial_with_pending_exception); // no, back to native code (call_stub/c1/c2) |
never@739 | 2185 | __ movptr(rax, STATE(_locals)); // pop parameters get new stack value |
never@739 | 2186 | __ addptr(rax, wordSize); // account for prepush before we return |
duke@435 | 2187 | __ jmp(unwind_recursive_activation); |
duke@435 | 2188 | |
duke@435 | 2189 | __ bind(unwind_initial_with_pending_exception); |
duke@435 | 2190 | |
duke@435 | 2191 | // We will unwind the current (initial) interpreter frame and forward |
duke@435 | 2192 | // the exception to the caller. We must put the exception in the |
duke@435 | 2193 | // expected register and clear pending exception and then forward. |
duke@435 | 2194 | |
duke@435 | 2195 | __ jmp(unwind_and_forward); |
duke@435 | 2196 | |
duke@435 | 2197 | interpreter_frame_manager = entry_point; |
duke@435 | 2198 | return entry_point; |
duke@435 | 2199 | } |
duke@435 | 2200 | |
duke@435 | 2201 | address AbstractInterpreterGenerator::generate_method_entry(AbstractInterpreter::MethodKind kind) { |
duke@435 | 2202 | // determine code generation flags |
duke@435 | 2203 | bool synchronized = false; |
duke@435 | 2204 | address entry_point = NULL; |
duke@435 | 2205 | |
duke@435 | 2206 | switch (kind) { |
duke@435 | 2207 | case Interpreter::zerolocals : break; |
duke@435 | 2208 | case Interpreter::zerolocals_synchronized: synchronized = true; break; |
duke@435 | 2209 | case Interpreter::native : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); break; |
duke@435 | 2210 | case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true); break; |
duke@435 | 2211 | case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break; |
duke@435 | 2212 | case Interpreter::accessor : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); break; |
duke@435 | 2213 | case Interpreter::abstract : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); break; |
jrose@1145 | 2214 | case Interpreter::method_handle : entry_point = ((InterpreterGenerator*)this)->generate_method_handle_entry(); break; |
duke@435 | 2215 | |
duke@435 | 2216 | case Interpreter::java_lang_math_sin : // fall thru |
duke@435 | 2217 | case Interpreter::java_lang_math_cos : // fall thru |
duke@435 | 2218 | case Interpreter::java_lang_math_tan : // fall thru |
duke@435 | 2219 | case Interpreter::java_lang_math_abs : // fall thru |
duke@435 | 2220 | case Interpreter::java_lang_math_log : // fall thru |
duke@435 | 2221 | case Interpreter::java_lang_math_log10 : // fall thru |
duke@435 | 2222 | case Interpreter::java_lang_math_sqrt : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind); break; |
duke@435 | 2223 | default : ShouldNotReachHere(); break; |
duke@435 | 2224 | } |
duke@435 | 2225 | |
duke@435 | 2226 | if (entry_point) return entry_point; |
duke@435 | 2227 | |
duke@435 | 2228 | return ((InterpreterGenerator*)this)->generate_normal_entry(synchronized); |
duke@435 | 2229 | |
duke@435 | 2230 | } |
duke@435 | 2231 | |
duke@435 | 2232 | InterpreterGenerator::InterpreterGenerator(StubQueue* code) |
duke@435 | 2233 | : CppInterpreterGenerator(code) { |
duke@435 | 2234 | generate_all(); // down here so it can be "virtual" |
duke@435 | 2235 | } |
duke@435 | 2236 | |
duke@435 | 2237 | // Deoptimization helpers for C++ interpreter |
duke@435 | 2238 | |
duke@435 | 2239 | // How much stack a method activation needs in words. |
duke@435 | 2240 | int AbstractInterpreter::size_top_interpreter_activation(methodOop method) { |
duke@435 | 2241 | |
duke@435 | 2242 | const int stub_code = 4; // see generate_call_stub |
duke@435 | 2243 | // Save space for one monitor to get into the interpreted method in case |
duke@435 | 2244 | // the method is synchronized |
duke@435 | 2245 | int monitor_size = method->is_synchronized() ? |
duke@435 | 2246 | 1*frame::interpreter_frame_monitor_size() : 0; |
duke@435 | 2247 | |
duke@435 | 2248 | // total static overhead size. Account for interpreter state object, return |
duke@435 | 2249 | // address, saved rbp and 2 words for a "static long no_params() method" issue. |
duke@435 | 2250 | |
duke@435 | 2251 | const int overhead_size = sizeof(BytecodeInterpreter)/wordSize + |
duke@435 | 2252 | ( frame::sender_sp_offset - frame::link_offset) + 2; |
duke@435 | 2253 | |
jrose@1145 | 2254 | const int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries(); |
jrose@1145 | 2255 | const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) * |
duke@435 | 2256 | Interpreter::stackElementWords(); |
duke@435 | 2257 | return overhead_size + method_stack + stub_code; |
duke@435 | 2258 | } |
duke@435 | 2259 | |
duke@435 | 2260 | // returns the activation size. |
duke@435 | 2261 | static int size_activation_helper(int extra_locals_size, int monitor_size) { |
duke@435 | 2262 | return (extra_locals_size + // the addition space for locals |
duke@435 | 2263 | 2*BytesPerWord + // return address and saved rbp |
duke@435 | 2264 | 2*BytesPerWord + // "static long no_params() method" issue |
duke@435 | 2265 | sizeof(BytecodeInterpreter) + // interpreterState |
duke@435 | 2266 | monitor_size); // monitors |
duke@435 | 2267 | } |
duke@435 | 2268 | |
duke@435 | 2269 | void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill, |
duke@435 | 2270 | frame* caller, |
duke@435 | 2271 | frame* current, |
duke@435 | 2272 | methodOop method, |
duke@435 | 2273 | intptr_t* locals, |
duke@435 | 2274 | intptr_t* stack, |
duke@435 | 2275 | intptr_t* stack_base, |
duke@435 | 2276 | intptr_t* monitor_base, |
duke@435 | 2277 | intptr_t* frame_bottom, |
duke@435 | 2278 | bool is_top_frame |
duke@435 | 2279 | ) |
duke@435 | 2280 | { |
duke@435 | 2281 | // What about any vtable? |
duke@435 | 2282 | // |
duke@435 | 2283 | to_fill->_thread = JavaThread::current(); |
duke@435 | 2284 | // This gets filled in later but make it something recognizable for now |
duke@435 | 2285 | to_fill->_bcp = method->code_base(); |
duke@435 | 2286 | to_fill->_locals = locals; |
duke@435 | 2287 | to_fill->_constants = method->constants()->cache(); |
duke@435 | 2288 | to_fill->_method = method; |
duke@435 | 2289 | to_fill->_mdx = NULL; |
duke@435 | 2290 | to_fill->_stack = stack; |
duke@435 | 2291 | if (is_top_frame && JavaThread::current()->popframe_forcing_deopt_reexecution() ) { |
duke@435 | 2292 | to_fill->_msg = deopt_resume2; |
duke@435 | 2293 | } else { |
duke@435 | 2294 | to_fill->_msg = method_resume; |
duke@435 | 2295 | } |
duke@435 | 2296 | to_fill->_result._to_call._bcp_advance = 0; |
duke@435 | 2297 | to_fill->_result._to_call._callee_entry_point = NULL; // doesn't matter to anyone |
duke@435 | 2298 | to_fill->_result._to_call._callee = NULL; // doesn't matter to anyone |
duke@435 | 2299 | to_fill->_prev_link = NULL; |
duke@435 | 2300 | |
duke@435 | 2301 | to_fill->_sender_sp = caller->unextended_sp(); |
duke@435 | 2302 | |
duke@435 | 2303 | if (caller->is_interpreted_frame()) { |
duke@435 | 2304 | interpreterState prev = caller->get_interpreterState(); |
duke@435 | 2305 | to_fill->_prev_link = prev; |
duke@435 | 2306 | // *current->register_addr(GR_Iprev_state) = (intptr_t) prev; |
duke@435 | 2307 | // Make the prev callee look proper |
duke@435 | 2308 | prev->_result._to_call._callee = method; |
duke@435 | 2309 | if (*prev->_bcp == Bytecodes::_invokeinterface) { |
duke@435 | 2310 | prev->_result._to_call._bcp_advance = 5; |
duke@435 | 2311 | } else { |
duke@435 | 2312 | prev->_result._to_call._bcp_advance = 3; |
duke@435 | 2313 | } |
duke@435 | 2314 | } |
duke@435 | 2315 | to_fill->_oop_temp = NULL; |
duke@435 | 2316 | to_fill->_stack_base = stack_base; |
duke@435 | 2317 | // Need +1 here because stack_base points to the word just above the first expr stack entry |
duke@435 | 2318 | // and stack_limit is supposed to point to the word just below the last expr stack entry. |
duke@435 | 2319 | // See generate_compute_interpreter_state. |
jrose@1145 | 2320 | int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries(); |
jrose@1145 | 2321 | to_fill->_stack_limit = stack_base - (method->max_stack() + extra_stack + 1); |
duke@435 | 2322 | to_fill->_monitor_base = (BasicObjectLock*) monitor_base; |
duke@435 | 2323 | |
duke@435 | 2324 | to_fill->_self_link = to_fill; |
duke@435 | 2325 | assert(stack >= to_fill->_stack_limit && stack < to_fill->_stack_base, |
duke@435 | 2326 | "Stack top out of range"); |
duke@435 | 2327 | } |
duke@435 | 2328 | |
duke@435 | 2329 | int AbstractInterpreter::layout_activation(methodOop method, |
duke@435 | 2330 | int tempcount, // |
duke@435 | 2331 | int popframe_extra_args, |
duke@435 | 2332 | int moncount, |
duke@435 | 2333 | int callee_param_count, |
duke@435 | 2334 | int callee_locals, |
duke@435 | 2335 | frame* caller, |
duke@435 | 2336 | frame* interpreter_frame, |
duke@435 | 2337 | bool is_top_frame) { |
duke@435 | 2338 | |
duke@435 | 2339 | assert(popframe_extra_args == 0, "FIX ME"); |
duke@435 | 2340 | // NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state() |
duke@435 | 2341 | // does as far as allocating an interpreter frame. |
duke@435 | 2342 | // If interpreter_frame!=NULL, set up the method, locals, and monitors. |
duke@435 | 2343 | // The frame interpreter_frame, if not NULL, is guaranteed to be the right size, |
duke@435 | 2344 | // as determined by a previous call to this method. |
duke@435 | 2345 | // It is also guaranteed to be walkable even though it is in a skeletal state |
duke@435 | 2346 | // NOTE: return size is in words not bytes |
duke@435 | 2347 | // NOTE: tempcount is the current size of the java expression stack. For top most |
duke@435 | 2348 | // frames we will allocate a full sized expression stack and not the curback |
duke@435 | 2349 | // version that non-top frames have. |
duke@435 | 2350 | |
duke@435 | 2351 | // Calculate the amount our frame will be adjust by the callee. For top frame |
duke@435 | 2352 | // this is zero. |
duke@435 | 2353 | |
duke@435 | 2354 | // NOTE: ia64 seems to do this wrong (or at least backwards) in that it |
duke@435 | 2355 | // calculates the extra locals based on itself. Not what the callee does |
duke@435 | 2356 | // to it. So it ignores last_frame_adjust value. Seems suspicious as far |
duke@435 | 2357 | // as getting sender_sp correct. |
duke@435 | 2358 | |
duke@435 | 2359 | int extra_locals_size = (callee_locals - callee_param_count) * BytesPerWord; |
duke@435 | 2360 | int monitor_size = sizeof(BasicObjectLock) * moncount; |
duke@435 | 2361 | |
duke@435 | 2362 | // First calculate the frame size without any java expression stack |
duke@435 | 2363 | int short_frame_size = size_activation_helper(extra_locals_size, |
duke@435 | 2364 | monitor_size); |
duke@435 | 2365 | |
duke@435 | 2366 | // Now with full size expression stack |
jrose@1145 | 2367 | int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries(); |
jrose@1145 | 2368 | int full_frame_size = short_frame_size + (method->max_stack() + extra_stack) * BytesPerWord; |
duke@435 | 2369 | |
duke@435 | 2370 | // and now with only live portion of the expression stack |
duke@435 | 2371 | short_frame_size = short_frame_size + tempcount * BytesPerWord; |
duke@435 | 2372 | |
duke@435 | 2373 | // the size the activation is right now. Only top frame is full size |
duke@435 | 2374 | int frame_size = (is_top_frame ? full_frame_size : short_frame_size); |
duke@435 | 2375 | |
duke@435 | 2376 | if (interpreter_frame != NULL) { |
duke@435 | 2377 | #ifdef ASSERT |
duke@435 | 2378 | assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable"); |
duke@435 | 2379 | #endif |
duke@435 | 2380 | |
duke@435 | 2381 | // MUCHO HACK |
duke@435 | 2382 | |
duke@435 | 2383 | intptr_t* frame_bottom = (intptr_t*) ((intptr_t)interpreter_frame->sp() - (full_frame_size - frame_size)); |
duke@435 | 2384 | |
duke@435 | 2385 | /* Now fillin the interpreterState object */ |
duke@435 | 2386 | |
duke@435 | 2387 | // The state object is the first thing on the frame and easily located |
duke@435 | 2388 | |
duke@435 | 2389 | interpreterState cur_state = (interpreterState) ((intptr_t)interpreter_frame->fp() - sizeof(BytecodeInterpreter)); |
duke@435 | 2390 | |
duke@435 | 2391 | |
duke@435 | 2392 | // Find the locals pointer. This is rather simple on x86 because there is no |
duke@435 | 2393 | // confusing rounding at the callee to account for. We can trivially locate |
duke@435 | 2394 | // our locals based on the current fp(). |
duke@435 | 2395 | // Note: the + 2 is for handling the "static long no_params() method" issue. |
duke@435 | 2396 | // (too bad I don't really remember that issue well...) |
duke@435 | 2397 | |
duke@435 | 2398 | intptr_t* locals; |
duke@435 | 2399 | // If the caller is interpreted we need to make sure that locals points to the first |
duke@435 | 2400 | // argument that the caller passed and not in an area where the stack might have been extended. |
duke@435 | 2401 | // because the stack to stack to converter needs a proper locals value in order to remove the |
duke@435 | 2402 | // arguments from the caller and place the result in the proper location. Hmm maybe it'd be |
duke@435 | 2403 | // simpler if we simply stored the result in the BytecodeInterpreter object and let the c++ code |
duke@435 | 2404 | // adjust the stack?? HMMM QQQ |
duke@435 | 2405 | // |
duke@435 | 2406 | if (caller->is_interpreted_frame()) { |
duke@435 | 2407 | // locals must agree with the caller because it will be used to set the |
duke@435 | 2408 | // caller's tos when we return. |
duke@435 | 2409 | interpreterState prev = caller->get_interpreterState(); |
duke@435 | 2410 | // stack() is prepushed. |
duke@435 | 2411 | locals = prev->stack() + method->size_of_parameters(); |
duke@435 | 2412 | // locals = caller->unextended_sp() + (method->size_of_parameters() - 1); |
duke@435 | 2413 | if (locals != interpreter_frame->fp() + frame::sender_sp_offset + (method->max_locals() - 1) + 2) { |
duke@435 | 2414 | // os::breakpoint(); |
duke@435 | 2415 | } |
duke@435 | 2416 | } else { |
duke@435 | 2417 | // this is where a c2i would have placed locals (except for the +2) |
duke@435 | 2418 | locals = interpreter_frame->fp() + frame::sender_sp_offset + (method->max_locals() - 1) + 2; |
duke@435 | 2419 | } |
duke@435 | 2420 | |
duke@435 | 2421 | intptr_t* monitor_base = (intptr_t*) cur_state; |
duke@435 | 2422 | intptr_t* stack_base = (intptr_t*) ((intptr_t) monitor_base - monitor_size); |
duke@435 | 2423 | /* +1 because stack is always prepushed */ |
duke@435 | 2424 | intptr_t* stack = (intptr_t*) ((intptr_t) stack_base - (tempcount + 1) * BytesPerWord); |
duke@435 | 2425 | |
duke@435 | 2426 | |
duke@435 | 2427 | BytecodeInterpreter::layout_interpreterState(cur_state, |
duke@435 | 2428 | caller, |
duke@435 | 2429 | interpreter_frame, |
duke@435 | 2430 | method, |
duke@435 | 2431 | locals, |
duke@435 | 2432 | stack, |
duke@435 | 2433 | stack_base, |
duke@435 | 2434 | monitor_base, |
duke@435 | 2435 | frame_bottom, |
duke@435 | 2436 | is_top_frame); |
duke@435 | 2437 | |
duke@435 | 2438 | // BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address, interpreter_frame->fp()); |
duke@435 | 2439 | } |
duke@435 | 2440 | return frame_size/BytesPerWord; |
duke@435 | 2441 | } |
duke@435 | 2442 | |
duke@435 | 2443 | #endif // CC_INTERP (all) |