Fri, 11 Mar 2011 22:34:57 -0800
7012648: move JSR 292 to package java.lang.invoke and adjust names
Summary: package and class renaming only; delete unused methods and classes
Reviewed-by: twisti
duke@435 | 1 | /* |
iveresov@2438 | 2 | * Copyright (c) 1997, 2011, 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/interpreter.hpp" |
stefank@2314 | 29 | #include "interpreter/interpreterGenerator.hpp" |
stefank@2314 | 30 | #include "interpreter/interpreterRuntime.hpp" |
stefank@2314 | 31 | #include "interpreter/templateTable.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/sharedRuntime.hpp" |
stefank@2314 | 42 | #include "runtime/stubRoutines.hpp" |
stefank@2314 | 43 | #include "runtime/synchronizer.hpp" |
stefank@2314 | 44 | #include "runtime/timer.hpp" |
stefank@2314 | 45 | #include "runtime/vframeArray.hpp" |
stefank@2314 | 46 | #include "utilities/debug.hpp" |
duke@435 | 47 | |
duke@435 | 48 | #ifndef CC_INTERP |
duke@435 | 49 | #ifndef FAST_DISPATCH |
duke@435 | 50 | #define FAST_DISPATCH 1 |
duke@435 | 51 | #endif |
duke@435 | 52 | #undef FAST_DISPATCH |
duke@435 | 53 | |
duke@435 | 54 | |
duke@435 | 55 | // Generation of Interpreter |
duke@435 | 56 | // |
duke@435 | 57 | // The InterpreterGenerator generates the interpreter into Interpreter::_code. |
duke@435 | 58 | |
duke@435 | 59 | |
duke@435 | 60 | #define __ _masm-> |
duke@435 | 61 | |
duke@435 | 62 | |
duke@435 | 63 | //---------------------------------------------------------------------------------------------------- |
duke@435 | 64 | |
duke@435 | 65 | |
duke@435 | 66 | void InterpreterGenerator::save_native_result(void) { |
duke@435 | 67 | // result potentially in O0/O1: save it across calls |
duke@435 | 68 | const Address& l_tmp = InterpreterMacroAssembler::l_tmp; |
duke@435 | 69 | |
duke@435 | 70 | // result potentially in F0/F1: save it across calls |
duke@435 | 71 | const Address& d_tmp = InterpreterMacroAssembler::d_tmp; |
duke@435 | 72 | |
duke@435 | 73 | // save and restore any potential method result value around the unlocking operation |
duke@435 | 74 | __ stf(FloatRegisterImpl::D, F0, d_tmp); |
duke@435 | 75 | #ifdef _LP64 |
duke@435 | 76 | __ stx(O0, l_tmp); |
duke@435 | 77 | #else |
duke@435 | 78 | __ std(O0, l_tmp); |
duke@435 | 79 | #endif |
duke@435 | 80 | } |
duke@435 | 81 | |
duke@435 | 82 | void InterpreterGenerator::restore_native_result(void) { |
duke@435 | 83 | const Address& l_tmp = InterpreterMacroAssembler::l_tmp; |
duke@435 | 84 | const Address& d_tmp = InterpreterMacroAssembler::d_tmp; |
duke@435 | 85 | |
duke@435 | 86 | // Restore any method result value |
duke@435 | 87 | __ ldf(FloatRegisterImpl::D, d_tmp, F0); |
duke@435 | 88 | #ifdef _LP64 |
duke@435 | 89 | __ ldx(l_tmp, O0); |
duke@435 | 90 | #else |
duke@435 | 91 | __ ldd(l_tmp, O0); |
duke@435 | 92 | #endif |
duke@435 | 93 | } |
duke@435 | 94 | |
duke@435 | 95 | address TemplateInterpreterGenerator::generate_exception_handler_common(const char* name, const char* message, bool pass_oop) { |
duke@435 | 96 | assert(!pass_oop || message == NULL, "either oop or message but not both"); |
duke@435 | 97 | address entry = __ pc(); |
duke@435 | 98 | // expression stack must be empty before entering the VM if an exception happened |
duke@435 | 99 | __ empty_expression_stack(); |
duke@435 | 100 | // load exception object |
duke@435 | 101 | __ set((intptr_t)name, G3_scratch); |
duke@435 | 102 | if (pass_oop) { |
duke@435 | 103 | __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::create_klass_exception), G3_scratch, Otos_i); |
duke@435 | 104 | } else { |
duke@435 | 105 | __ set((intptr_t)message, G4_scratch); |
duke@435 | 106 | __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception), G3_scratch, G4_scratch); |
duke@435 | 107 | } |
duke@435 | 108 | // throw exception |
duke@435 | 109 | assert(Interpreter::throw_exception_entry() != NULL, "generate it first"); |
twisti@1162 | 110 | AddressLiteral thrower(Interpreter::throw_exception_entry()); |
twisti@1162 | 111 | __ jump_to(thrower, G3_scratch); |
duke@435 | 112 | __ delayed()->nop(); |
duke@435 | 113 | return entry; |
duke@435 | 114 | } |
duke@435 | 115 | |
duke@435 | 116 | address TemplateInterpreterGenerator::generate_ClassCastException_handler() { |
duke@435 | 117 | address entry = __ pc(); |
duke@435 | 118 | // expression stack must be empty before entering the VM if an exception |
duke@435 | 119 | // happened |
duke@435 | 120 | __ empty_expression_stack(); |
duke@435 | 121 | // load exception object |
duke@435 | 122 | __ call_VM(Oexception, |
duke@435 | 123 | CAST_FROM_FN_PTR(address, |
duke@435 | 124 | InterpreterRuntime::throw_ClassCastException), |
duke@435 | 125 | Otos_i); |
duke@435 | 126 | __ should_not_reach_here(); |
duke@435 | 127 | return entry; |
duke@435 | 128 | } |
duke@435 | 129 | |
duke@435 | 130 | |
jrose@1145 | 131 | // Arguments are: required type in G5_method_type, and |
jrose@1145 | 132 | // failing object (or NULL) in G3_method_handle. |
jrose@1145 | 133 | address TemplateInterpreterGenerator::generate_WrongMethodType_handler() { |
jrose@1145 | 134 | address entry = __ pc(); |
jrose@1145 | 135 | // expression stack must be empty before entering the VM if an exception |
jrose@1145 | 136 | // happened |
jrose@1145 | 137 | __ empty_expression_stack(); |
jrose@1145 | 138 | // load exception object |
jrose@1145 | 139 | __ call_VM(Oexception, |
jrose@1145 | 140 | CAST_FROM_FN_PTR(address, |
jrose@1145 | 141 | InterpreterRuntime::throw_WrongMethodTypeException), |
jrose@1145 | 142 | G5_method_type, // required |
jrose@1145 | 143 | G3_method_handle); // actual |
jrose@1145 | 144 | __ should_not_reach_here(); |
jrose@1145 | 145 | return entry; |
jrose@1145 | 146 | } |
jrose@1145 | 147 | |
jrose@1145 | 148 | |
duke@435 | 149 | address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(const char* name) { |
duke@435 | 150 | address entry = __ pc(); |
duke@435 | 151 | // expression stack must be empty before entering the VM if an exception happened |
duke@435 | 152 | __ empty_expression_stack(); |
duke@435 | 153 | // convention: expect aberrant index in register G3_scratch, then shuffle the |
duke@435 | 154 | // index to G4_scratch for the VM call |
duke@435 | 155 | __ mov(G3_scratch, G4_scratch); |
duke@435 | 156 | __ set((intptr_t)name, G3_scratch); |
duke@435 | 157 | __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException), G3_scratch, G4_scratch); |
duke@435 | 158 | __ should_not_reach_here(); |
duke@435 | 159 | return entry; |
duke@435 | 160 | } |
duke@435 | 161 | |
duke@435 | 162 | |
duke@435 | 163 | address TemplateInterpreterGenerator::generate_StackOverflowError_handler() { |
duke@435 | 164 | address entry = __ pc(); |
duke@435 | 165 | // expression stack must be empty before entering the VM if an exception happened |
duke@435 | 166 | __ empty_expression_stack(); |
duke@435 | 167 | __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_StackOverflowError)); |
duke@435 | 168 | __ should_not_reach_here(); |
duke@435 | 169 | return entry; |
duke@435 | 170 | } |
duke@435 | 171 | |
duke@435 | 172 | |
jrose@1494 | 173 | address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) { |
twisti@1858 | 174 | TosState incoming_state = state; |
twisti@1858 | 175 | |
twisti@1858 | 176 | Label cont; |
duke@435 | 177 | address compiled_entry = __ pc(); |
duke@435 | 178 | |
duke@435 | 179 | address entry = __ pc(); |
duke@435 | 180 | #if !defined(_LP64) && defined(COMPILER2) |
duke@435 | 181 | // All return values are where we want them, except for Longs. C2 returns |
duke@435 | 182 | // longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1. |
duke@435 | 183 | // Since the interpreter will return longs in G1 and O0/O1 in the 32bit |
duke@435 | 184 | // build even if we are returning from interpreted we just do a little |
duke@435 | 185 | // stupid shuffing. |
duke@435 | 186 | // Note: I tried to make c2 return longs in O0/O1 and G1 so we wouldn't have to |
duke@435 | 187 | // do this here. Unfortunately if we did a rethrow we'd see an machepilog node |
duke@435 | 188 | // first which would move g1 -> O0/O1 and destroy the exception we were throwing. |
duke@435 | 189 | |
twisti@1858 | 190 | if (incoming_state == ltos) { |
twisti@1858 | 191 | __ srl (G1, 0, O1); |
twisti@1858 | 192 | __ srlx(G1, 32, O0); |
duke@435 | 193 | } |
twisti@1858 | 194 | #endif // !_LP64 && COMPILER2 |
duke@435 | 195 | |
duke@435 | 196 | __ bind(cont); |
duke@435 | 197 | |
duke@435 | 198 | // The callee returns with the stack possibly adjusted by adapter transition |
duke@435 | 199 | // We remove that possible adjustment here. |
duke@435 | 200 | // All interpreter local registers are untouched. Any result is passed back |
duke@435 | 201 | // in the O0/O1 or float registers. Before continuing, the arguments must be |
duke@435 | 202 | // popped from the java expression stack; i.e., Lesp must be adjusted. |
duke@435 | 203 | |
duke@435 | 204 | __ mov(Llast_SP, SP); // Remove any adapter added stack space. |
duke@435 | 205 | |
twisti@1858 | 206 | Label L_got_cache, L_giant_index; |
duke@435 | 207 | const Register cache = G3_scratch; |
duke@435 | 208 | const Register size = G1_scratch; |
twisti@1858 | 209 | if (EnableInvokeDynamic) { |
twisti@1858 | 210 | __ ldub(Address(Lbcp, 0), G1_scratch); // Load current bytecode. |
twisti@1858 | 211 | __ cmp(G1_scratch, Bytecodes::_invokedynamic); |
twisti@1858 | 212 | __ br(Assembler::equal, false, Assembler::pn, L_giant_index); |
twisti@1858 | 213 | __ delayed()->nop(); |
twisti@1858 | 214 | } |
duke@435 | 215 | __ get_cache_and_index_at_bcp(cache, G1_scratch, 1); |
twisti@1858 | 216 | __ bind(L_got_cache); |
twisti@1162 | 217 | __ ld_ptr(cache, constantPoolCacheOopDesc::base_offset() + |
twisti@1162 | 218 | ConstantPoolCacheEntry::flags_offset(), size); |
duke@435 | 219 | __ and3(size, 0xFF, size); // argument size in words |
twisti@1861 | 220 | __ sll(size, Interpreter::logStackElementSize, size); // each argument size in bytes |
duke@435 | 221 | __ add(Lesp, size, Lesp); // pop arguments |
duke@435 | 222 | __ dispatch_next(state, step); |
duke@435 | 223 | |
twisti@1858 | 224 | // out of the main line of code... |
twisti@1858 | 225 | if (EnableInvokeDynamic) { |
twisti@1858 | 226 | __ bind(L_giant_index); |
jrose@1920 | 227 | __ get_cache_and_index_at_bcp(cache, G1_scratch, 1, sizeof(u4)); |
twisti@1858 | 228 | __ ba(false, L_got_cache); |
twisti@1858 | 229 | __ delayed()->nop(); |
twisti@1858 | 230 | } |
twisti@1858 | 231 | |
duke@435 | 232 | return entry; |
duke@435 | 233 | } |
duke@435 | 234 | |
duke@435 | 235 | |
duke@435 | 236 | address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) { |
duke@435 | 237 | address entry = __ pc(); |
duke@435 | 238 | __ get_constant_pool_cache(LcpoolCache); // load LcpoolCache |
duke@435 | 239 | { Label L; |
twisti@1162 | 240 | Address exception_addr(G2_thread, Thread::pending_exception_offset()); |
twisti@1162 | 241 | __ ld_ptr(exception_addr, Gtemp); // Load pending exception. |
duke@435 | 242 | __ tst(Gtemp); |
duke@435 | 243 | __ brx(Assembler::equal, false, Assembler::pt, L); |
duke@435 | 244 | __ delayed()->nop(); |
duke@435 | 245 | __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception)); |
duke@435 | 246 | __ should_not_reach_here(); |
duke@435 | 247 | __ bind(L); |
duke@435 | 248 | } |
duke@435 | 249 | __ dispatch_next(state, step); |
duke@435 | 250 | return entry; |
duke@435 | 251 | } |
duke@435 | 252 | |
duke@435 | 253 | // A result handler converts/unboxes a native call result into |
duke@435 | 254 | // a java interpreter/compiler result. The current frame is an |
duke@435 | 255 | // interpreter frame. The activation frame unwind code must be |
duke@435 | 256 | // consistent with that of TemplateTable::_return(...). In the |
duke@435 | 257 | // case of native methods, the caller's SP was not modified. |
duke@435 | 258 | address TemplateInterpreterGenerator::generate_result_handler_for(BasicType type) { |
duke@435 | 259 | address entry = __ pc(); |
duke@435 | 260 | Register Itos_i = Otos_i ->after_save(); |
duke@435 | 261 | Register Itos_l = Otos_l ->after_save(); |
duke@435 | 262 | Register Itos_l1 = Otos_l1->after_save(); |
duke@435 | 263 | Register Itos_l2 = Otos_l2->after_save(); |
duke@435 | 264 | switch (type) { |
duke@435 | 265 | case T_BOOLEAN: __ subcc(G0, O0, G0); __ addc(G0, 0, Itos_i); break; // !0 => true; 0 => false |
duke@435 | 266 | case T_CHAR : __ sll(O0, 16, O0); __ srl(O0, 16, Itos_i); break; // cannot use and3, 0xFFFF too big as immediate value! |
duke@435 | 267 | case T_BYTE : __ sll(O0, 24, O0); __ sra(O0, 24, Itos_i); break; |
duke@435 | 268 | case T_SHORT : __ sll(O0, 16, O0); __ sra(O0, 16, Itos_i); break; |
duke@435 | 269 | case T_LONG : |
duke@435 | 270 | #ifndef _LP64 |
duke@435 | 271 | __ mov(O1, Itos_l2); // move other half of long |
duke@435 | 272 | #endif // ifdef or no ifdef, fall through to the T_INT case |
duke@435 | 273 | case T_INT : __ mov(O0, Itos_i); break; |
duke@435 | 274 | case T_VOID : /* nothing to do */ break; |
duke@435 | 275 | case T_FLOAT : assert(F0 == Ftos_f, "fix this code" ); break; |
duke@435 | 276 | case T_DOUBLE : assert(F0 == Ftos_d, "fix this code" ); break; |
duke@435 | 277 | case T_OBJECT : |
duke@435 | 278 | __ ld_ptr(FP, (frame::interpreter_frame_oop_temp_offset*wordSize) + STACK_BIAS, Itos_i); |
duke@435 | 279 | __ verify_oop(Itos_i); |
duke@435 | 280 | break; |
duke@435 | 281 | default : ShouldNotReachHere(); |
duke@435 | 282 | } |
duke@435 | 283 | __ ret(); // return from interpreter activation |
duke@435 | 284 | __ delayed()->restore(I5_savedSP, G0, SP); // remove interpreter frame |
duke@435 | 285 | NOT_PRODUCT(__ emit_long(0);) // marker for disassembly |
duke@435 | 286 | return entry; |
duke@435 | 287 | } |
duke@435 | 288 | |
duke@435 | 289 | address TemplateInterpreterGenerator::generate_safept_entry_for(TosState state, address runtime_entry) { |
duke@435 | 290 | address entry = __ pc(); |
duke@435 | 291 | __ push(state); |
duke@435 | 292 | __ call_VM(noreg, runtime_entry); |
duke@435 | 293 | __ dispatch_via(vtos, Interpreter::normal_table(vtos)); |
duke@435 | 294 | return entry; |
duke@435 | 295 | } |
duke@435 | 296 | |
duke@435 | 297 | |
duke@435 | 298 | address TemplateInterpreterGenerator::generate_continuation_for(TosState state) { |
duke@435 | 299 | address entry = __ pc(); |
duke@435 | 300 | __ dispatch_next(state); |
duke@435 | 301 | return entry; |
duke@435 | 302 | } |
duke@435 | 303 | |
duke@435 | 304 | // |
duke@435 | 305 | // Helpers for commoning out cases in the various type of method entries. |
duke@435 | 306 | // |
duke@435 | 307 | |
duke@435 | 308 | // increment invocation count & check for overflow |
duke@435 | 309 | // |
duke@435 | 310 | // Note: checking for negative value instead of overflow |
duke@435 | 311 | // so we have a 'sticky' overflow test |
duke@435 | 312 | // |
duke@435 | 313 | // Lmethod: method |
duke@435 | 314 | // ??: invocation counter |
duke@435 | 315 | // |
duke@435 | 316 | void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { |
iveresov@2138 | 317 | // Note: In tiered we increment either counters in methodOop or in MDO depending if we're profiling or not. |
iveresov@2138 | 318 | if (TieredCompilation) { |
iveresov@2138 | 319 | const int increment = InvocationCounter::count_increment; |
iveresov@2138 | 320 | const int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; |
iveresov@2138 | 321 | Label no_mdo, done; |
iveresov@2138 | 322 | if (ProfileInterpreter) { |
iveresov@2138 | 323 | // If no method data exists, go to profile_continue. |
iveresov@2138 | 324 | __ ld_ptr(Lmethod, methodOopDesc::method_data_offset(), G4_scratch); |
iveresov@2138 | 325 | __ br_null(G4_scratch, false, Assembler::pn, no_mdo); |
iveresov@2138 | 326 | __ delayed()->nop(); |
iveresov@2138 | 327 | // Increment counter |
iveresov@2138 | 328 | Address mdo_invocation_counter(G4_scratch, |
iveresov@2138 | 329 | in_bytes(methodDataOopDesc::invocation_counter_offset()) + |
iveresov@2138 | 330 | in_bytes(InvocationCounter::counter_offset())); |
iveresov@2138 | 331 | __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, |
iveresov@2138 | 332 | G3_scratch, Lscratch, |
iveresov@2138 | 333 | Assembler::zero, overflow); |
iveresov@2138 | 334 | __ ba(false, done); |
iveresov@2138 | 335 | __ delayed()->nop(); |
iveresov@2138 | 336 | } |
iveresov@2138 | 337 | |
iveresov@2138 | 338 | // Increment counter in methodOop |
iveresov@2138 | 339 | __ bind(no_mdo); |
iveresov@2138 | 340 | Address invocation_counter(Lmethod, |
iveresov@2138 | 341 | in_bytes(methodOopDesc::invocation_counter_offset()) + |
iveresov@2138 | 342 | in_bytes(InvocationCounter::counter_offset())); |
iveresov@2138 | 343 | __ increment_mask_and_jump(invocation_counter, increment, mask, |
iveresov@2138 | 344 | G3_scratch, Lscratch, |
iveresov@2138 | 345 | Assembler::zero, overflow); |
iveresov@2138 | 346 | __ bind(done); |
iveresov@2138 | 347 | } else { |
iveresov@2138 | 348 | // Update standard invocation counters |
iveresov@2138 | 349 | __ increment_invocation_counter(O0, G3_scratch); |
iveresov@2138 | 350 | if (ProfileInterpreter) { // %%% Merge this into methodDataOop |
iveresov@2138 | 351 | Address interpreter_invocation_counter(Lmethod,in_bytes(methodOopDesc::interpreter_invocation_counter_offset())); |
iveresov@2138 | 352 | __ ld(interpreter_invocation_counter, G3_scratch); |
iveresov@2138 | 353 | __ inc(G3_scratch); |
iveresov@2138 | 354 | __ st(G3_scratch, interpreter_invocation_counter); |
iveresov@2138 | 355 | } |
iveresov@2138 | 356 | |
iveresov@2138 | 357 | if (ProfileInterpreter && profile_method != NULL) { |
iveresov@2138 | 358 | // Test to see if we should create a method data oop |
iveresov@2138 | 359 | AddressLiteral profile_limit((address)&InvocationCounter::InterpreterProfileLimit); |
iveresov@2138 | 360 | __ load_contents(profile_limit, G3_scratch); |
iveresov@2138 | 361 | __ cmp(O0, G3_scratch); |
iveresov@2138 | 362 | __ br(Assembler::lessUnsigned, false, Assembler::pn, *profile_method_continue); |
iveresov@2138 | 363 | __ delayed()->nop(); |
iveresov@2138 | 364 | |
iveresov@2138 | 365 | // if no method data exists, go to profile_method |
iveresov@2138 | 366 | __ test_method_data_pointer(*profile_method); |
iveresov@2138 | 367 | } |
iveresov@2138 | 368 | |
iveresov@2138 | 369 | AddressLiteral invocation_limit((address)&InvocationCounter::InterpreterInvocationLimit); |
iveresov@2138 | 370 | __ load_contents(invocation_limit, G3_scratch); |
iveresov@2138 | 371 | __ cmp(O0, G3_scratch); |
iveresov@2138 | 372 | __ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow); |
iveresov@2138 | 373 | __ delayed()->nop(); |
duke@435 | 374 | } |
duke@435 | 375 | |
duke@435 | 376 | } |
duke@435 | 377 | |
duke@435 | 378 | // Allocate monitor and lock method (asm interpreter) |
duke@435 | 379 | // ebx - methodOop |
duke@435 | 380 | // |
duke@435 | 381 | void InterpreterGenerator::lock_method(void) { |
twisti@1162 | 382 | __ ld(Lmethod, in_bytes(methodOopDesc::access_flags_offset()), O0); // Load access flags. |
duke@435 | 383 | |
duke@435 | 384 | #ifdef ASSERT |
duke@435 | 385 | { Label ok; |
duke@435 | 386 | __ btst(JVM_ACC_SYNCHRONIZED, O0); |
duke@435 | 387 | __ br( Assembler::notZero, false, Assembler::pt, ok); |
duke@435 | 388 | __ delayed()->nop(); |
duke@435 | 389 | __ stop("method doesn't need synchronization"); |
duke@435 | 390 | __ bind(ok); |
duke@435 | 391 | } |
duke@435 | 392 | #endif // ASSERT |
duke@435 | 393 | |
duke@435 | 394 | // get synchronization object to O0 |
duke@435 | 395 | { Label done; |
duke@435 | 396 | const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); |
duke@435 | 397 | __ btst(JVM_ACC_STATIC, O0); |
duke@435 | 398 | __ br( Assembler::zero, true, Assembler::pt, done); |
duke@435 | 399 | __ delayed()->ld_ptr(Llocals, Interpreter::local_offset_in_bytes(0), O0); // get receiver for not-static case |
duke@435 | 400 | |
duke@435 | 401 | __ ld_ptr( Lmethod, in_bytes(methodOopDesc::constants_offset()), O0); |
duke@435 | 402 | __ ld_ptr( O0, constantPoolOopDesc::pool_holder_offset_in_bytes(), O0); |
duke@435 | 403 | |
duke@435 | 404 | // lock the mirror, not the klassOop |
duke@435 | 405 | __ ld_ptr( O0, mirror_offset, O0); |
duke@435 | 406 | |
duke@435 | 407 | #ifdef ASSERT |
duke@435 | 408 | __ tst(O0); |
duke@435 | 409 | __ breakpoint_trap(Assembler::zero); |
duke@435 | 410 | #endif // ASSERT |
duke@435 | 411 | |
duke@435 | 412 | __ bind(done); |
duke@435 | 413 | } |
duke@435 | 414 | |
duke@435 | 415 | __ add_monitor_to_stack(true, noreg, noreg); // allocate monitor elem |
duke@435 | 416 | __ st_ptr( O0, Lmonitors, BasicObjectLock::obj_offset_in_bytes()); // store object |
duke@435 | 417 | // __ untested("lock_object from method entry"); |
duke@435 | 418 | __ lock_object(Lmonitors, O0); |
duke@435 | 419 | } |
duke@435 | 420 | |
duke@435 | 421 | |
duke@435 | 422 | void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rframe_size, |
duke@435 | 423 | Register Rscratch, |
duke@435 | 424 | Register Rscratch2) { |
duke@435 | 425 | const int page_size = os::vm_page_size(); |
twisti@1162 | 426 | Address saved_exception_pc(G2_thread, JavaThread::saved_exception_pc_offset()); |
duke@435 | 427 | Label after_frame_check; |
duke@435 | 428 | |
duke@435 | 429 | assert_different_registers(Rframe_size, Rscratch, Rscratch2); |
duke@435 | 430 | |
duke@435 | 431 | __ set( page_size, Rscratch ); |
duke@435 | 432 | __ cmp( Rframe_size, Rscratch ); |
duke@435 | 433 | |
duke@435 | 434 | __ br( Assembler::lessEqual, false, Assembler::pt, after_frame_check ); |
duke@435 | 435 | __ delayed()->nop(); |
duke@435 | 436 | |
duke@435 | 437 | // get the stack base, and in debug, verify it is non-zero |
twisti@1162 | 438 | __ ld_ptr( G2_thread, Thread::stack_base_offset(), Rscratch ); |
duke@435 | 439 | #ifdef ASSERT |
duke@435 | 440 | Label base_not_zero; |
duke@435 | 441 | __ cmp( Rscratch, G0 ); |
duke@435 | 442 | __ brx( Assembler::notEqual, false, Assembler::pn, base_not_zero ); |
duke@435 | 443 | __ delayed()->nop(); |
duke@435 | 444 | __ stop("stack base is zero in generate_stack_overflow_check"); |
duke@435 | 445 | __ bind(base_not_zero); |
duke@435 | 446 | #endif |
duke@435 | 447 | |
duke@435 | 448 | // get the stack size, and in debug, verify it is non-zero |
duke@435 | 449 | assert( sizeof(size_t) == sizeof(intptr_t), "wrong load size" ); |
twisti@1162 | 450 | __ ld_ptr( G2_thread, Thread::stack_size_offset(), Rscratch2 ); |
duke@435 | 451 | #ifdef ASSERT |
duke@435 | 452 | Label size_not_zero; |
duke@435 | 453 | __ cmp( Rscratch2, G0 ); |
duke@435 | 454 | __ brx( Assembler::notEqual, false, Assembler::pn, size_not_zero ); |
duke@435 | 455 | __ delayed()->nop(); |
duke@435 | 456 | __ stop("stack size is zero in generate_stack_overflow_check"); |
duke@435 | 457 | __ bind(size_not_zero); |
duke@435 | 458 | #endif |
duke@435 | 459 | |
duke@435 | 460 | // compute the beginning of the protected zone minus the requested frame size |
duke@435 | 461 | __ sub( Rscratch, Rscratch2, Rscratch ); |
duke@435 | 462 | __ set( (StackRedPages+StackYellowPages) * page_size, Rscratch2 ); |
duke@435 | 463 | __ add( Rscratch, Rscratch2, Rscratch ); |
duke@435 | 464 | |
duke@435 | 465 | // Add in the size of the frame (which is the same as subtracting it from the |
duke@435 | 466 | // SP, which would take another register |
duke@435 | 467 | __ add( Rscratch, Rframe_size, Rscratch ); |
duke@435 | 468 | |
duke@435 | 469 | // the frame is greater than one page in size, so check against |
duke@435 | 470 | // the bottom of the stack |
duke@435 | 471 | __ cmp( SP, Rscratch ); |
duke@435 | 472 | __ brx( Assembler::greater, false, Assembler::pt, after_frame_check ); |
duke@435 | 473 | __ delayed()->nop(); |
duke@435 | 474 | |
duke@435 | 475 | // Save the return address as the exception pc |
duke@435 | 476 | __ st_ptr(O7, saved_exception_pc); |
duke@435 | 477 | |
duke@435 | 478 | // the stack will overflow, throw an exception |
duke@435 | 479 | __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_StackOverflowError)); |
duke@435 | 480 | |
duke@435 | 481 | // if you get to here, then there is enough stack space |
duke@435 | 482 | __ bind( after_frame_check ); |
duke@435 | 483 | } |
duke@435 | 484 | |
duke@435 | 485 | |
duke@435 | 486 | // |
duke@435 | 487 | // Generate a fixed interpreter frame. This is identical setup for interpreted |
duke@435 | 488 | // methods and for native methods hence the shared code. |
duke@435 | 489 | |
duke@435 | 490 | void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { |
duke@435 | 491 | // |
duke@435 | 492 | // |
duke@435 | 493 | // The entry code sets up a new interpreter frame in 4 steps: |
duke@435 | 494 | // |
duke@435 | 495 | // 1) Increase caller's SP by for the extra local space needed: |
duke@435 | 496 | // (check for overflow) |
duke@435 | 497 | // Efficient implementation of xload/xstore bytecodes requires |
duke@435 | 498 | // that arguments and non-argument locals are in a contigously |
duke@435 | 499 | // addressable memory block => non-argument locals must be |
duke@435 | 500 | // allocated in the caller's frame. |
duke@435 | 501 | // |
duke@435 | 502 | // 2) Create a new stack frame and register window: |
duke@435 | 503 | // The new stack frame must provide space for the standard |
duke@435 | 504 | // register save area, the maximum java expression stack size, |
duke@435 | 505 | // the monitor slots (0 slots initially), and some frame local |
duke@435 | 506 | // scratch locations. |
duke@435 | 507 | // |
duke@435 | 508 | // 3) The following interpreter activation registers must be setup: |
duke@435 | 509 | // Lesp : expression stack pointer |
duke@435 | 510 | // Lbcp : bytecode pointer |
duke@435 | 511 | // Lmethod : method |
duke@435 | 512 | // Llocals : locals pointer |
duke@435 | 513 | // Lmonitors : monitor pointer |
duke@435 | 514 | // LcpoolCache: constant pool cache |
duke@435 | 515 | // |
duke@435 | 516 | // 4) Initialize the non-argument locals if necessary: |
duke@435 | 517 | // Non-argument locals may need to be initialized to NULL |
duke@435 | 518 | // for GC to work. If the oop-map information is accurate |
duke@435 | 519 | // (in the absence of the JSR problem), no initialization |
duke@435 | 520 | // is necessary. |
duke@435 | 521 | // |
duke@435 | 522 | // (gri - 2/25/2000) |
duke@435 | 523 | |
duke@435 | 524 | |
twisti@1162 | 525 | const Address size_of_parameters(G5_method, methodOopDesc::size_of_parameters_offset()); |
twisti@1162 | 526 | const Address size_of_locals (G5_method, methodOopDesc::size_of_locals_offset()); |
twisti@1162 | 527 | const Address max_stack (G5_method, methodOopDesc::max_stack_offset()); |
duke@435 | 528 | int rounded_vm_local_words = round_to( frame::interpreter_frame_vm_local_words, WordsPerLong ); |
duke@435 | 529 | |
duke@435 | 530 | const int extra_space = |
duke@435 | 531 | rounded_vm_local_words + // frame local scratch space |
jrose@1145 | 532 | //6815692//methodOopDesc::extra_stack_words() + // extra push slots for MH adapters |
duke@435 | 533 | frame::memory_parameter_word_sp_offset + // register save area |
duke@435 | 534 | (native_call ? frame::interpreter_frame_extra_outgoing_argument_words : 0); |
duke@435 | 535 | |
duke@435 | 536 | const Register Glocals_size = G3; |
duke@435 | 537 | const Register Otmp1 = O3; |
duke@435 | 538 | const Register Otmp2 = O4; |
duke@435 | 539 | // Lscratch can't be used as a temporary because the call_stub uses |
duke@435 | 540 | // it to assert that the stack frame was setup correctly. |
duke@435 | 541 | |
duke@435 | 542 | __ lduh( size_of_parameters, Glocals_size); |
duke@435 | 543 | |
duke@435 | 544 | // Gargs points to first local + BytesPerWord |
duke@435 | 545 | // Set the saved SP after the register window save |
duke@435 | 546 | // |
duke@435 | 547 | assert_different_registers(Gargs, Glocals_size, Gframe_size, O5_savedSP); |
twisti@1861 | 548 | __ sll(Glocals_size, Interpreter::logStackElementSize, Otmp1); |
duke@435 | 549 | __ add(Gargs, Otmp1, Gargs); |
duke@435 | 550 | |
duke@435 | 551 | if (native_call) { |
duke@435 | 552 | __ calc_mem_param_words( Glocals_size, Gframe_size ); |
duke@435 | 553 | __ add( Gframe_size, extra_space, Gframe_size); |
duke@435 | 554 | __ round_to( Gframe_size, WordsPerLong ); |
duke@435 | 555 | __ sll( Gframe_size, LogBytesPerWord, Gframe_size ); |
duke@435 | 556 | } else { |
duke@435 | 557 | |
duke@435 | 558 | // |
duke@435 | 559 | // Compute number of locals in method apart from incoming parameters |
duke@435 | 560 | // |
duke@435 | 561 | __ lduh( size_of_locals, Otmp1 ); |
duke@435 | 562 | __ sub( Otmp1, Glocals_size, Glocals_size ); |
duke@435 | 563 | __ round_to( Glocals_size, WordsPerLong ); |
twisti@1861 | 564 | __ sll( Glocals_size, Interpreter::logStackElementSize, Glocals_size ); |
duke@435 | 565 | |
duke@435 | 566 | // see if the frame is greater than one page in size. If so, |
duke@435 | 567 | // then we need to verify there is enough stack space remaining |
duke@435 | 568 | // Frame_size = (max_stack + extra_space) * BytesPerWord; |
duke@435 | 569 | __ lduh( max_stack, Gframe_size ); |
duke@435 | 570 | __ add( Gframe_size, extra_space, Gframe_size ); |
duke@435 | 571 | __ round_to( Gframe_size, WordsPerLong ); |
twisti@1861 | 572 | __ sll( Gframe_size, Interpreter::logStackElementSize, Gframe_size); |
duke@435 | 573 | |
duke@435 | 574 | // Add in java locals size for stack overflow check only |
duke@435 | 575 | __ add( Gframe_size, Glocals_size, Gframe_size ); |
duke@435 | 576 | |
duke@435 | 577 | const Register Otmp2 = O4; |
duke@435 | 578 | assert_different_registers(Otmp1, Otmp2, O5_savedSP); |
duke@435 | 579 | generate_stack_overflow_check(Gframe_size, Otmp1, Otmp2); |
duke@435 | 580 | |
duke@435 | 581 | __ sub( Gframe_size, Glocals_size, Gframe_size); |
duke@435 | 582 | |
duke@435 | 583 | // |
duke@435 | 584 | // bump SP to accomodate the extra locals |
duke@435 | 585 | // |
duke@435 | 586 | __ sub( SP, Glocals_size, SP ); |
duke@435 | 587 | } |
duke@435 | 588 | |
duke@435 | 589 | // |
duke@435 | 590 | // now set up a stack frame with the size computed above |
duke@435 | 591 | // |
duke@435 | 592 | __ neg( Gframe_size ); |
duke@435 | 593 | __ save( SP, Gframe_size, SP ); |
duke@435 | 594 | |
duke@435 | 595 | // |
duke@435 | 596 | // now set up all the local cache registers |
duke@435 | 597 | // |
duke@435 | 598 | // NOTE: At this point, Lbyte_code/Lscratch has been modified. Note |
duke@435 | 599 | // that all present references to Lbyte_code initialize the register |
duke@435 | 600 | // immediately before use |
duke@435 | 601 | if (native_call) { |
duke@435 | 602 | __ mov(G0, Lbcp); |
duke@435 | 603 | } else { |
twisti@1162 | 604 | __ ld_ptr(G5_method, methodOopDesc::const_offset(), Lbcp); |
twisti@1162 | 605 | __ add(Lbcp, in_bytes(constMethodOopDesc::codes_offset()), Lbcp); |
duke@435 | 606 | } |
duke@435 | 607 | __ mov( G5_method, Lmethod); // set Lmethod |
duke@435 | 608 | __ get_constant_pool_cache( LcpoolCache ); // set LcpoolCache |
duke@435 | 609 | __ sub(FP, rounded_vm_local_words * BytesPerWord, Lmonitors ); // set Lmonitors |
duke@435 | 610 | #ifdef _LP64 |
duke@435 | 611 | __ add( Lmonitors, STACK_BIAS, Lmonitors ); // Account for 64 bit stack bias |
duke@435 | 612 | #endif |
duke@435 | 613 | __ sub(Lmonitors, BytesPerWord, Lesp); // set Lesp |
duke@435 | 614 | |
duke@435 | 615 | // setup interpreter activation registers |
duke@435 | 616 | __ sub(Gargs, BytesPerWord, Llocals); // set Llocals |
duke@435 | 617 | |
duke@435 | 618 | if (ProfileInterpreter) { |
duke@435 | 619 | #ifdef FAST_DISPATCH |
duke@435 | 620 | // FAST_DISPATCH and ProfileInterpreter are mutually exclusive since |
duke@435 | 621 | // they both use I2. |
duke@435 | 622 | assert(0, "FAST_DISPATCH and +ProfileInterpreter are mutually exclusive"); |
duke@435 | 623 | #endif // FAST_DISPATCH |
duke@435 | 624 | __ set_method_data_pointer(); |
duke@435 | 625 | } |
duke@435 | 626 | |
duke@435 | 627 | } |
duke@435 | 628 | |
duke@435 | 629 | // Empty method, generate a very fast return. |
duke@435 | 630 | |
duke@435 | 631 | address InterpreterGenerator::generate_empty_entry(void) { |
duke@435 | 632 | |
duke@435 | 633 | // A method that does nother but return... |
duke@435 | 634 | |
duke@435 | 635 | address entry = __ pc(); |
duke@435 | 636 | Label slow_path; |
duke@435 | 637 | |
duke@435 | 638 | __ verify_oop(G5_method); |
duke@435 | 639 | |
duke@435 | 640 | // do nothing for empty methods (do not even increment invocation counter) |
duke@435 | 641 | if ( UseFastEmptyMethods) { |
duke@435 | 642 | // If we need a safepoint check, generate full interpreter entry. |
twisti@1162 | 643 | AddressLiteral sync_state(SafepointSynchronize::address_of_state()); |
twisti@1162 | 644 | __ set(sync_state, G3_scratch); |
duke@435 | 645 | __ cmp(G3_scratch, SafepointSynchronize::_not_synchronized); |
duke@435 | 646 | __ br(Assembler::notEqual, false, Assembler::pn, slow_path); |
duke@435 | 647 | __ delayed()->nop(); |
duke@435 | 648 | |
duke@435 | 649 | // Code: _return |
duke@435 | 650 | __ retl(); |
duke@435 | 651 | __ delayed()->mov(O5_savedSP, SP); |
duke@435 | 652 | |
duke@435 | 653 | __ bind(slow_path); |
duke@435 | 654 | (void) generate_normal_entry(false); |
duke@435 | 655 | |
duke@435 | 656 | return entry; |
duke@435 | 657 | } |
duke@435 | 658 | return NULL; |
duke@435 | 659 | } |
duke@435 | 660 | |
duke@435 | 661 | // Call an accessor method (assuming it is resolved, otherwise drop into |
duke@435 | 662 | // vanilla (slow path) entry |
duke@435 | 663 | |
duke@435 | 664 | // Generates code to elide accessor methods |
duke@435 | 665 | // Uses G3_scratch and G1_scratch as scratch |
duke@435 | 666 | address InterpreterGenerator::generate_accessor_entry(void) { |
duke@435 | 667 | |
duke@435 | 668 | // Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites thereof; |
duke@435 | 669 | // parameter size = 1 |
duke@435 | 670 | // Note: We can only use this code if the getfield has been resolved |
duke@435 | 671 | // and if we don't have a null-pointer exception => check for |
duke@435 | 672 | // these conditions first and use slow path if necessary. |
duke@435 | 673 | address entry = __ pc(); |
duke@435 | 674 | Label slow_path; |
duke@435 | 675 | |
coleenp@548 | 676 | |
coleenp@548 | 677 | // XXX: for compressed oops pointer loading and decoding doesn't fit in |
coleenp@548 | 678 | // delay slot and damages G1 |
coleenp@548 | 679 | if ( UseFastAccessorMethods && !UseCompressedOops ) { |
duke@435 | 680 | // Check if we need to reach a safepoint and generate full interpreter |
duke@435 | 681 | // frame if so. |
twisti@1162 | 682 | AddressLiteral sync_state(SafepointSynchronize::address_of_state()); |
duke@435 | 683 | __ load_contents(sync_state, G3_scratch); |
duke@435 | 684 | __ cmp(G3_scratch, SafepointSynchronize::_not_synchronized); |
duke@435 | 685 | __ br(Assembler::notEqual, false, Assembler::pn, slow_path); |
duke@435 | 686 | __ delayed()->nop(); |
duke@435 | 687 | |
duke@435 | 688 | // Check if local 0 != NULL |
duke@435 | 689 | __ ld_ptr(Gargs, G0, Otos_i ); // get local 0 |
duke@435 | 690 | __ tst(Otos_i); // check if local 0 == NULL and go the slow path |
duke@435 | 691 | __ brx(Assembler::zero, false, Assembler::pn, slow_path); |
duke@435 | 692 | __ delayed()->nop(); |
duke@435 | 693 | |
duke@435 | 694 | |
duke@435 | 695 | // read first instruction word and extract bytecode @ 1 and index @ 2 |
duke@435 | 696 | // get first 4 bytes of the bytecodes (big endian!) |
twisti@1162 | 697 | __ ld_ptr(G5_method, methodOopDesc::const_offset(), G1_scratch); |
twisti@1162 | 698 | __ ld(G1_scratch, constMethodOopDesc::codes_offset(), G1_scratch); |
duke@435 | 699 | |
duke@435 | 700 | // move index @ 2 far left then to the right most two bytes. |
duke@435 | 701 | __ sll(G1_scratch, 2*BitsPerByte, G1_scratch); |
duke@435 | 702 | __ srl(G1_scratch, 2*BitsPerByte - exact_log2(in_words( |
duke@435 | 703 | ConstantPoolCacheEntry::size()) * BytesPerWord), G1_scratch); |
duke@435 | 704 | |
duke@435 | 705 | // get constant pool cache |
twisti@1162 | 706 | __ ld_ptr(G5_method, methodOopDesc::constants_offset(), G3_scratch); |
duke@435 | 707 | __ ld_ptr(G3_scratch, constantPoolOopDesc::cache_offset_in_bytes(), G3_scratch); |
duke@435 | 708 | |
duke@435 | 709 | // get specific constant pool cache entry |
duke@435 | 710 | __ add(G3_scratch, G1_scratch, G3_scratch); |
duke@435 | 711 | |
duke@435 | 712 | // Check the constant Pool cache entry to see if it has been resolved. |
duke@435 | 713 | // If not, need the slow path. |
duke@435 | 714 | ByteSize cp_base_offset = constantPoolCacheOopDesc::base_offset(); |
twisti@1162 | 715 | __ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::indices_offset(), G1_scratch); |
duke@435 | 716 | __ srl(G1_scratch, 2*BitsPerByte, G1_scratch); |
duke@435 | 717 | __ and3(G1_scratch, 0xFF, G1_scratch); |
duke@435 | 718 | __ cmp(G1_scratch, Bytecodes::_getfield); |
duke@435 | 719 | __ br(Assembler::notEqual, false, Assembler::pn, slow_path); |
duke@435 | 720 | __ delayed()->nop(); |
duke@435 | 721 | |
duke@435 | 722 | // Get the type and return field offset from the constant pool cache |
twisti@1162 | 723 | __ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::flags_offset(), G1_scratch); |
twisti@1162 | 724 | __ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::f2_offset(), G3_scratch); |
duke@435 | 725 | |
duke@435 | 726 | Label xreturn_path; |
duke@435 | 727 | // Need to differentiate between igetfield, agetfield, bgetfield etc. |
duke@435 | 728 | // because they are different sizes. |
duke@435 | 729 | // Get the type from the constant pool cache |
duke@435 | 730 | __ srl(G1_scratch, ConstantPoolCacheEntry::tosBits, G1_scratch); |
duke@435 | 731 | // Make sure we don't need to mask G1_scratch for tosBits after the above shift |
duke@435 | 732 | ConstantPoolCacheEntry::verify_tosBits(); |
duke@435 | 733 | __ cmp(G1_scratch, atos ); |
duke@435 | 734 | __ br(Assembler::equal, true, Assembler::pt, xreturn_path); |
duke@435 | 735 | __ delayed()->ld_ptr(Otos_i, G3_scratch, Otos_i); |
duke@435 | 736 | __ cmp(G1_scratch, itos); |
duke@435 | 737 | __ br(Assembler::equal, true, Assembler::pt, xreturn_path); |
duke@435 | 738 | __ delayed()->ld(Otos_i, G3_scratch, Otos_i); |
duke@435 | 739 | __ cmp(G1_scratch, stos); |
duke@435 | 740 | __ br(Assembler::equal, true, Assembler::pt, xreturn_path); |
duke@435 | 741 | __ delayed()->ldsh(Otos_i, G3_scratch, Otos_i); |
duke@435 | 742 | __ cmp(G1_scratch, ctos); |
duke@435 | 743 | __ br(Assembler::equal, true, Assembler::pt, xreturn_path); |
duke@435 | 744 | __ delayed()->lduh(Otos_i, G3_scratch, Otos_i); |
duke@435 | 745 | #ifdef ASSERT |
duke@435 | 746 | __ cmp(G1_scratch, btos); |
duke@435 | 747 | __ br(Assembler::equal, true, Assembler::pt, xreturn_path); |
duke@435 | 748 | __ delayed()->ldsb(Otos_i, G3_scratch, Otos_i); |
duke@435 | 749 | __ should_not_reach_here(); |
duke@435 | 750 | #endif |
duke@435 | 751 | __ ldsb(Otos_i, G3_scratch, Otos_i); |
duke@435 | 752 | __ bind(xreturn_path); |
duke@435 | 753 | |
duke@435 | 754 | // _ireturn/_areturn |
duke@435 | 755 | __ retl(); // return from leaf routine |
duke@435 | 756 | __ delayed()->mov(O5_savedSP, SP); |
duke@435 | 757 | |
duke@435 | 758 | // Generate regular method entry |
duke@435 | 759 | __ bind(slow_path); |
duke@435 | 760 | (void) generate_normal_entry(false); |
duke@435 | 761 | return entry; |
duke@435 | 762 | } |
duke@435 | 763 | return NULL; |
duke@435 | 764 | } |
duke@435 | 765 | |
duke@435 | 766 | // |
duke@435 | 767 | // Interpreter stub for calling a native method. (asm interpreter) |
duke@435 | 768 | // This sets up a somewhat different looking stack for calling the native method |
duke@435 | 769 | // than the typical interpreter frame setup. |
duke@435 | 770 | // |
duke@435 | 771 | |
duke@435 | 772 | address InterpreterGenerator::generate_native_entry(bool synchronized) { |
duke@435 | 773 | address entry = __ pc(); |
duke@435 | 774 | |
duke@435 | 775 | // the following temporary registers are used during frame creation |
duke@435 | 776 | const Register Gtmp1 = G3_scratch ; |
duke@435 | 777 | const Register Gtmp2 = G1_scratch; |
duke@435 | 778 | bool inc_counter = UseCompiler || CountCompiledCalls; |
duke@435 | 779 | |
duke@435 | 780 | // make sure registers are different! |
duke@435 | 781 | assert_different_registers(G2_thread, G5_method, Gargs, Gtmp1, Gtmp2); |
duke@435 | 782 | |
twisti@1162 | 783 | const Address Laccess_flags(Lmethod, methodOopDesc::access_flags_offset()); |
duke@435 | 784 | |
duke@435 | 785 | __ verify_oop(G5_method); |
duke@435 | 786 | |
duke@435 | 787 | const Register Glocals_size = G3; |
duke@435 | 788 | assert_different_registers(Glocals_size, G4_scratch, Gframe_size); |
duke@435 | 789 | |
duke@435 | 790 | // make sure method is native & not abstract |
duke@435 | 791 | // rethink these assertions - they can be simplified and shared (gri 2/25/2000) |
duke@435 | 792 | #ifdef ASSERT |
twisti@1162 | 793 | __ ld(G5_method, methodOopDesc::access_flags_offset(), Gtmp1); |
duke@435 | 794 | { |
duke@435 | 795 | Label L; |
duke@435 | 796 | __ btst(JVM_ACC_NATIVE, Gtmp1); |
duke@435 | 797 | __ br(Assembler::notZero, false, Assembler::pt, L); |
duke@435 | 798 | __ delayed()->nop(); |
duke@435 | 799 | __ stop("tried to execute non-native method as native"); |
duke@435 | 800 | __ bind(L); |
duke@435 | 801 | } |
duke@435 | 802 | { Label L; |
duke@435 | 803 | __ btst(JVM_ACC_ABSTRACT, Gtmp1); |
duke@435 | 804 | __ br(Assembler::zero, false, Assembler::pt, L); |
duke@435 | 805 | __ delayed()->nop(); |
duke@435 | 806 | __ stop("tried to execute abstract method as non-abstract"); |
duke@435 | 807 | __ bind(L); |
duke@435 | 808 | } |
duke@435 | 809 | #endif // ASSERT |
duke@435 | 810 | |
duke@435 | 811 | // generate the code to allocate the interpreter stack frame |
duke@435 | 812 | generate_fixed_frame(true); |
duke@435 | 813 | |
duke@435 | 814 | // |
duke@435 | 815 | // No locals to initialize for native method |
duke@435 | 816 | // |
duke@435 | 817 | |
duke@435 | 818 | // this slot will be set later, we initialize it to null here just in |
duke@435 | 819 | // case we get a GC before the actual value is stored later |
twisti@1162 | 820 | __ st_ptr(G0, FP, (frame::interpreter_frame_oop_temp_offset * wordSize) + STACK_BIAS); |
duke@435 | 821 | |
twisti@1162 | 822 | const Address do_not_unlock_if_synchronized(G2_thread, |
twisti@1162 | 823 | JavaThread::do_not_unlock_if_synchronized_offset()); |
duke@435 | 824 | // Since at this point in the method invocation the exception handler |
duke@435 | 825 | // would try to exit the monitor of synchronized methods which hasn't |
duke@435 | 826 | // been entered yet, we set the thread local variable |
duke@435 | 827 | // _do_not_unlock_if_synchronized to true. If any exception was thrown by |
duke@435 | 828 | // runtime, exception handling i.e. unlock_if_synchronized_method will |
duke@435 | 829 | // check this thread local flag. |
duke@435 | 830 | // This flag has two effects, one is to force an unwind in the topmost |
duke@435 | 831 | // interpreter frame and not perform an unlock while doing so. |
duke@435 | 832 | |
duke@435 | 833 | __ movbool(true, G3_scratch); |
duke@435 | 834 | __ stbool(G3_scratch, do_not_unlock_if_synchronized); |
duke@435 | 835 | |
duke@435 | 836 | // increment invocation counter and check for overflow |
duke@435 | 837 | // |
duke@435 | 838 | // Note: checking for negative value instead of overflow |
duke@435 | 839 | // so we have a 'sticky' overflow test (may be of |
duke@435 | 840 | // importance as soon as we have true MT/MP) |
duke@435 | 841 | Label invocation_counter_overflow; |
duke@435 | 842 | Label Lcontinue; |
duke@435 | 843 | if (inc_counter) { |
duke@435 | 844 | generate_counter_incr(&invocation_counter_overflow, NULL, NULL); |
duke@435 | 845 | |
duke@435 | 846 | } |
duke@435 | 847 | __ bind(Lcontinue); |
duke@435 | 848 | |
duke@435 | 849 | bang_stack_shadow_pages(true); |
duke@435 | 850 | |
duke@435 | 851 | // reset the _do_not_unlock_if_synchronized flag |
duke@435 | 852 | __ stbool(G0, do_not_unlock_if_synchronized); |
duke@435 | 853 | |
duke@435 | 854 | // check for synchronized methods |
duke@435 | 855 | // Must happen AFTER invocation_counter check and stack overflow check, |
duke@435 | 856 | // so method is not locked if overflows. |
duke@435 | 857 | |
duke@435 | 858 | if (synchronized) { |
duke@435 | 859 | lock_method(); |
duke@435 | 860 | } else { |
duke@435 | 861 | #ifdef ASSERT |
duke@435 | 862 | { Label ok; |
duke@435 | 863 | __ ld(Laccess_flags, O0); |
duke@435 | 864 | __ btst(JVM_ACC_SYNCHRONIZED, O0); |
duke@435 | 865 | __ br( Assembler::zero, false, Assembler::pt, ok); |
duke@435 | 866 | __ delayed()->nop(); |
duke@435 | 867 | __ stop("method needs synchronization"); |
duke@435 | 868 | __ bind(ok); |
duke@435 | 869 | } |
duke@435 | 870 | #endif // ASSERT |
duke@435 | 871 | } |
duke@435 | 872 | |
duke@435 | 873 | |
duke@435 | 874 | // start execution |
duke@435 | 875 | __ verify_thread(); |
duke@435 | 876 | |
duke@435 | 877 | // JVMTI support |
duke@435 | 878 | __ notify_method_entry(); |
duke@435 | 879 | |
duke@435 | 880 | // native call |
duke@435 | 881 | |
duke@435 | 882 | // (note that O0 is never an oop--at most it is a handle) |
duke@435 | 883 | // It is important not to smash any handles created by this call, |
duke@435 | 884 | // until any oop handle in O0 is dereferenced. |
duke@435 | 885 | |
duke@435 | 886 | // (note that the space for outgoing params is preallocated) |
duke@435 | 887 | |
duke@435 | 888 | // get signature handler |
duke@435 | 889 | { Label L; |
twisti@1162 | 890 | Address signature_handler(Lmethod, methodOopDesc::signature_handler_offset()); |
twisti@1162 | 891 | __ ld_ptr(signature_handler, G3_scratch); |
duke@435 | 892 | __ tst(G3_scratch); |
duke@435 | 893 | __ brx(Assembler::notZero, false, Assembler::pt, L); |
duke@435 | 894 | __ delayed()->nop(); |
duke@435 | 895 | __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), Lmethod); |
twisti@1162 | 896 | __ ld_ptr(signature_handler, G3_scratch); |
duke@435 | 897 | __ bind(L); |
duke@435 | 898 | } |
duke@435 | 899 | |
duke@435 | 900 | // Push a new frame so that the args will really be stored in |
duke@435 | 901 | // Copy a few locals across so the new frame has the variables |
duke@435 | 902 | // we need but these values will be dead at the jni call and |
duke@435 | 903 | // therefore not gc volatile like the values in the current |
duke@435 | 904 | // frame (Lmethod in particular) |
duke@435 | 905 | |
duke@435 | 906 | // Flush the method pointer to the register save area |
duke@435 | 907 | __ st_ptr(Lmethod, SP, (Lmethod->sp_offset_in_saved_window() * wordSize) + STACK_BIAS); |
duke@435 | 908 | __ mov(Llocals, O1); |
twisti@1162 | 909 | |
duke@435 | 910 | // calculate where the mirror handle body is allocated in the interpreter frame: |
twisti@1162 | 911 | __ add(FP, (frame::interpreter_frame_oop_temp_offset * wordSize) + STACK_BIAS, O2); |
duke@435 | 912 | |
duke@435 | 913 | // Calculate current frame size |
duke@435 | 914 | __ sub(SP, FP, O3); // Calculate negative of current frame size |
duke@435 | 915 | __ save(SP, O3, SP); // Allocate an identical sized frame |
duke@435 | 916 | |
duke@435 | 917 | // Note I7 has leftover trash. Slow signature handler will fill it in |
duke@435 | 918 | // should we get there. Normal jni call will set reasonable last_Java_pc |
duke@435 | 919 | // below (and fix I7 so the stack trace doesn't have a meaningless frame |
duke@435 | 920 | // in it). |
duke@435 | 921 | |
duke@435 | 922 | // Load interpreter frame's Lmethod into same register here |
duke@435 | 923 | |
duke@435 | 924 | __ ld_ptr(FP, (Lmethod->sp_offset_in_saved_window() * wordSize) + STACK_BIAS, Lmethod); |
duke@435 | 925 | |
duke@435 | 926 | __ mov(I1, Llocals); |
duke@435 | 927 | __ mov(I2, Lscratch2); // save the address of the mirror |
duke@435 | 928 | |
duke@435 | 929 | |
duke@435 | 930 | // ONLY Lmethod and Llocals are valid here! |
duke@435 | 931 | |
duke@435 | 932 | // call signature handler, It will move the arg properly since Llocals in current frame |
duke@435 | 933 | // matches that in outer frame |
duke@435 | 934 | |
duke@435 | 935 | __ callr(G3_scratch, 0); |
duke@435 | 936 | __ delayed()->nop(); |
duke@435 | 937 | |
duke@435 | 938 | // Result handler is in Lscratch |
duke@435 | 939 | |
duke@435 | 940 | // Reload interpreter frame's Lmethod since slow signature handler may block |
duke@435 | 941 | __ ld_ptr(FP, (Lmethod->sp_offset_in_saved_window() * wordSize) + STACK_BIAS, Lmethod); |
duke@435 | 942 | |
duke@435 | 943 | { Label not_static; |
duke@435 | 944 | |
duke@435 | 945 | __ ld(Laccess_flags, O0); |
duke@435 | 946 | __ btst(JVM_ACC_STATIC, O0); |
duke@435 | 947 | __ br( Assembler::zero, false, Assembler::pt, not_static); |
twisti@1162 | 948 | // get native function entry point(O0 is a good temp until the very end) |
twisti@1162 | 949 | __ delayed()->ld_ptr(Lmethod, in_bytes(methodOopDesc::native_function_offset()), O0); |
duke@435 | 950 | // for static methods insert the mirror argument |
duke@435 | 951 | const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); |
duke@435 | 952 | |
twisti@1162 | 953 | __ ld_ptr(Lmethod, methodOopDesc:: constants_offset(), O1); |
twisti@1162 | 954 | __ ld_ptr(O1, constantPoolOopDesc::pool_holder_offset_in_bytes(), O1); |
duke@435 | 955 | __ ld_ptr(O1, mirror_offset, O1); |
duke@435 | 956 | #ifdef ASSERT |
duke@435 | 957 | if (!PrintSignatureHandlers) // do not dirty the output with this |
duke@435 | 958 | { Label L; |
duke@435 | 959 | __ tst(O1); |
duke@435 | 960 | __ brx(Assembler::notZero, false, Assembler::pt, L); |
duke@435 | 961 | __ delayed()->nop(); |
duke@435 | 962 | __ stop("mirror is missing"); |
duke@435 | 963 | __ bind(L); |
duke@435 | 964 | } |
duke@435 | 965 | #endif // ASSERT |
duke@435 | 966 | __ st_ptr(O1, Lscratch2, 0); |
duke@435 | 967 | __ mov(Lscratch2, O1); |
duke@435 | 968 | __ bind(not_static); |
duke@435 | 969 | } |
duke@435 | 970 | |
duke@435 | 971 | // At this point, arguments have been copied off of stack into |
duke@435 | 972 | // their JNI positions, which are O1..O5 and SP[68..]. |
duke@435 | 973 | // Oops are boxed in-place on the stack, with handles copied to arguments. |
duke@435 | 974 | // The result handler is in Lscratch. O0 will shortly hold the JNIEnv*. |
duke@435 | 975 | |
duke@435 | 976 | #ifdef ASSERT |
duke@435 | 977 | { Label L; |
duke@435 | 978 | __ tst(O0); |
duke@435 | 979 | __ brx(Assembler::notZero, false, Assembler::pt, L); |
duke@435 | 980 | __ delayed()->nop(); |
duke@435 | 981 | __ stop("native entry point is missing"); |
duke@435 | 982 | __ bind(L); |
duke@435 | 983 | } |
duke@435 | 984 | #endif // ASSERT |
duke@435 | 985 | |
duke@435 | 986 | // |
duke@435 | 987 | // setup the frame anchor |
duke@435 | 988 | // |
duke@435 | 989 | // The scavenge function only needs to know that the PC of this frame is |
duke@435 | 990 | // in the interpreter method entry code, it doesn't need to know the exact |
duke@435 | 991 | // PC and hence we can use O7 which points to the return address from the |
duke@435 | 992 | // previous call in the code stream (signature handler function) |
duke@435 | 993 | // |
duke@435 | 994 | // The other trick is we set last_Java_sp to FP instead of the usual SP because |
duke@435 | 995 | // we have pushed the extra frame in order to protect the volatile register(s) |
duke@435 | 996 | // in that frame when we return from the jni call |
duke@435 | 997 | // |
duke@435 | 998 | |
duke@435 | 999 | __ set_last_Java_frame(FP, O7); |
duke@435 | 1000 | __ mov(O7, I7); // make dummy interpreter frame look like one above, |
duke@435 | 1001 | // not meaningless information that'll confuse me. |
duke@435 | 1002 | |
duke@435 | 1003 | // flush the windows now. We don't care about the current (protection) frame |
duke@435 | 1004 | // only the outer frames |
duke@435 | 1005 | |
duke@435 | 1006 | __ flush_windows(); |
duke@435 | 1007 | |
duke@435 | 1008 | // mark windows as flushed |
twisti@1162 | 1009 | Address flags(G2_thread, JavaThread::frame_anchor_offset() + JavaFrameAnchor::flags_offset()); |
duke@435 | 1010 | __ set(JavaFrameAnchor::flushed, G3_scratch); |
duke@435 | 1011 | __ st(G3_scratch, flags); |
duke@435 | 1012 | |
duke@435 | 1013 | // Transition from _thread_in_Java to _thread_in_native. We are already safepoint ready. |
duke@435 | 1014 | |
twisti@1162 | 1015 | Address thread_state(G2_thread, JavaThread::thread_state_offset()); |
duke@435 | 1016 | #ifdef ASSERT |
duke@435 | 1017 | { Label L; |
duke@435 | 1018 | __ ld(thread_state, G3_scratch); |
duke@435 | 1019 | __ cmp(G3_scratch, _thread_in_Java); |
duke@435 | 1020 | __ br(Assembler::equal, false, Assembler::pt, L); |
duke@435 | 1021 | __ delayed()->nop(); |
duke@435 | 1022 | __ stop("Wrong thread state in native stub"); |
duke@435 | 1023 | __ bind(L); |
duke@435 | 1024 | } |
duke@435 | 1025 | #endif // ASSERT |
duke@435 | 1026 | __ set(_thread_in_native, G3_scratch); |
duke@435 | 1027 | __ st(G3_scratch, thread_state); |
duke@435 | 1028 | |
duke@435 | 1029 | // Call the jni method, using the delay slot to set the JNIEnv* argument. |
duke@435 | 1030 | __ save_thread(L7_thread_cache); // save Gthread |
duke@435 | 1031 | __ callr(O0, 0); |
duke@435 | 1032 | __ delayed()-> |
duke@435 | 1033 | add(L7_thread_cache, in_bytes(JavaThread::jni_environment_offset()), O0); |
duke@435 | 1034 | |
duke@435 | 1035 | // Back from jni method Lmethod in this frame is DEAD, DEAD, DEAD |
duke@435 | 1036 | |
duke@435 | 1037 | __ restore_thread(L7_thread_cache); // restore G2_thread |
coleenp@548 | 1038 | __ reinit_heapbase(); |
duke@435 | 1039 | |
duke@435 | 1040 | // must we block? |
duke@435 | 1041 | |
duke@435 | 1042 | // Block, if necessary, before resuming in _thread_in_Java state. |
duke@435 | 1043 | // In order for GC to work, don't clear the last_Java_sp until after blocking. |
duke@435 | 1044 | { Label no_block; |
twisti@1162 | 1045 | AddressLiteral sync_state(SafepointSynchronize::address_of_state()); |
duke@435 | 1046 | |
duke@435 | 1047 | // Switch thread to "native transition" state before reading the synchronization state. |
duke@435 | 1048 | // This additional state is necessary because reading and testing the synchronization |
duke@435 | 1049 | // state is not atomic w.r.t. GC, as this scenario demonstrates: |
duke@435 | 1050 | // Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted. |
duke@435 | 1051 | // VM thread changes sync state to synchronizing and suspends threads for GC. |
duke@435 | 1052 | // Thread A is resumed to finish this native method, but doesn't block here since it |
duke@435 | 1053 | // didn't see any synchronization is progress, and escapes. |
duke@435 | 1054 | __ set(_thread_in_native_trans, G3_scratch); |
duke@435 | 1055 | __ st(G3_scratch, thread_state); |
duke@435 | 1056 | if(os::is_MP()) { |
duke@435 | 1057 | if (UseMembar) { |
duke@435 | 1058 | // Force this write out before the read below |
duke@435 | 1059 | __ membar(Assembler::StoreLoad); |
duke@435 | 1060 | } else { |
duke@435 | 1061 | // Write serialization page so VM thread can do a pseudo remote membar. |
duke@435 | 1062 | // We use the current thread pointer to calculate a thread specific |
duke@435 | 1063 | // offset to write to within the page. This minimizes bus traffic |
duke@435 | 1064 | // due to cache line collision. |
duke@435 | 1065 | __ serialize_memory(G2_thread, G1_scratch, G3_scratch); |
duke@435 | 1066 | } |
duke@435 | 1067 | } |
duke@435 | 1068 | __ load_contents(sync_state, G3_scratch); |
duke@435 | 1069 | __ cmp(G3_scratch, SafepointSynchronize::_not_synchronized); |
duke@435 | 1070 | |
duke@435 | 1071 | Label L; |
duke@435 | 1072 | __ br(Assembler::notEqual, false, Assembler::pn, L); |
twisti@1162 | 1073 | __ delayed()->ld(G2_thread, JavaThread::suspend_flags_offset(), G3_scratch); |
duke@435 | 1074 | __ cmp(G3_scratch, 0); |
duke@435 | 1075 | __ br(Assembler::equal, false, Assembler::pt, no_block); |
duke@435 | 1076 | __ delayed()->nop(); |
duke@435 | 1077 | __ bind(L); |
duke@435 | 1078 | |
duke@435 | 1079 | // Block. Save any potential method result value before the operation and |
duke@435 | 1080 | // use a leaf call to leave the last_Java_frame setup undisturbed. |
duke@435 | 1081 | save_native_result(); |
duke@435 | 1082 | __ call_VM_leaf(L7_thread_cache, |
duke@435 | 1083 | CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans), |
duke@435 | 1084 | G2_thread); |
duke@435 | 1085 | |
duke@435 | 1086 | // Restore any method result value |
duke@435 | 1087 | restore_native_result(); |
duke@435 | 1088 | __ bind(no_block); |
duke@435 | 1089 | } |
duke@435 | 1090 | |
duke@435 | 1091 | // Clear the frame anchor now |
duke@435 | 1092 | |
duke@435 | 1093 | __ reset_last_Java_frame(); |
duke@435 | 1094 | |
duke@435 | 1095 | // Move the result handler address |
duke@435 | 1096 | __ mov(Lscratch, G3_scratch); |
duke@435 | 1097 | // return possible result to the outer frame |
duke@435 | 1098 | #ifndef __LP64 |
duke@435 | 1099 | __ mov(O0, I0); |
duke@435 | 1100 | __ restore(O1, G0, O1); |
duke@435 | 1101 | #else |
duke@435 | 1102 | __ restore(O0, G0, O0); |
duke@435 | 1103 | #endif /* __LP64 */ |
duke@435 | 1104 | |
duke@435 | 1105 | // Move result handler to expected register |
duke@435 | 1106 | __ mov(G3_scratch, Lscratch); |
duke@435 | 1107 | |
duke@435 | 1108 | // Back in normal (native) interpreter frame. State is thread_in_native_trans |
duke@435 | 1109 | // switch to thread_in_Java. |
duke@435 | 1110 | |
duke@435 | 1111 | __ set(_thread_in_Java, G3_scratch); |
duke@435 | 1112 | __ st(G3_scratch, thread_state); |
duke@435 | 1113 | |
duke@435 | 1114 | // reset handle block |
twisti@1162 | 1115 | __ ld_ptr(G2_thread, JavaThread::active_handles_offset(), G3_scratch); |
duke@435 | 1116 | __ st_ptr(G0, G3_scratch, JNIHandleBlock::top_offset_in_bytes()); |
duke@435 | 1117 | |
duke@435 | 1118 | // If we have an oop result store it where it will be safe for any further gc |
duke@435 | 1119 | // until we return now that we've released the handle it might be protected by |
duke@435 | 1120 | |
duke@435 | 1121 | { |
duke@435 | 1122 | Label no_oop, store_result; |
duke@435 | 1123 | |
duke@435 | 1124 | __ set((intptr_t)AbstractInterpreter::result_handler(T_OBJECT), G3_scratch); |
duke@435 | 1125 | __ cmp(G3_scratch, Lscratch); |
duke@435 | 1126 | __ brx(Assembler::notEqual, false, Assembler::pt, no_oop); |
duke@435 | 1127 | __ delayed()->nop(); |
duke@435 | 1128 | __ addcc(G0, O0, O0); |
duke@435 | 1129 | __ brx(Assembler::notZero, true, Assembler::pt, store_result); // if result is not NULL: |
duke@435 | 1130 | __ delayed()->ld_ptr(O0, 0, O0); // unbox it |
duke@435 | 1131 | __ mov(G0, O0); |
duke@435 | 1132 | |
duke@435 | 1133 | __ bind(store_result); |
duke@435 | 1134 | // Store it where gc will look for it and result handler expects it. |
duke@435 | 1135 | __ st_ptr(O0, FP, (frame::interpreter_frame_oop_temp_offset*wordSize) + STACK_BIAS); |
duke@435 | 1136 | |
duke@435 | 1137 | __ bind(no_oop); |
duke@435 | 1138 | |
duke@435 | 1139 | } |
duke@435 | 1140 | |
duke@435 | 1141 | |
duke@435 | 1142 | // handle exceptions (exception handling will handle unlocking!) |
duke@435 | 1143 | { Label L; |
twisti@1162 | 1144 | Address exception_addr(G2_thread, Thread::pending_exception_offset()); |
duke@435 | 1145 | __ ld_ptr(exception_addr, Gtemp); |
duke@435 | 1146 | __ tst(Gtemp); |
duke@435 | 1147 | __ brx(Assembler::equal, false, Assembler::pt, L); |
duke@435 | 1148 | __ delayed()->nop(); |
duke@435 | 1149 | // Note: This could be handled more efficiently since we know that the native |
duke@435 | 1150 | // method doesn't have an exception handler. We could directly return |
duke@435 | 1151 | // to the exception handler for the caller. |
duke@435 | 1152 | __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception)); |
duke@435 | 1153 | __ should_not_reach_here(); |
duke@435 | 1154 | __ bind(L); |
duke@435 | 1155 | } |
duke@435 | 1156 | |
duke@435 | 1157 | // JVMTI support (preserves thread register) |
duke@435 | 1158 | __ notify_method_exit(true, ilgl, InterpreterMacroAssembler::NotifyJVMTI); |
duke@435 | 1159 | |
duke@435 | 1160 | if (synchronized) { |
duke@435 | 1161 | // save and restore any potential method result value around the unlocking operation |
duke@435 | 1162 | save_native_result(); |
duke@435 | 1163 | |
duke@435 | 1164 | __ add( __ top_most_monitor(), O1); |
duke@435 | 1165 | __ unlock_object(O1); |
duke@435 | 1166 | |
duke@435 | 1167 | restore_native_result(); |
duke@435 | 1168 | } |
duke@435 | 1169 | |
duke@435 | 1170 | #if defined(COMPILER2) && !defined(_LP64) |
duke@435 | 1171 | |
duke@435 | 1172 | // C2 expects long results in G1 we can't tell if we're returning to interpreted |
duke@435 | 1173 | // or compiled so just be safe. |
duke@435 | 1174 | |
duke@435 | 1175 | __ sllx(O0, 32, G1); // Shift bits into high G1 |
duke@435 | 1176 | __ srl (O1, 0, O1); // Zero extend O1 |
duke@435 | 1177 | __ or3 (O1, G1, G1); // OR 64 bits into G1 |
duke@435 | 1178 | |
duke@435 | 1179 | #endif /* COMPILER2 && !_LP64 */ |
duke@435 | 1180 | |
duke@435 | 1181 | // dispose of return address and remove activation |
duke@435 | 1182 | #ifdef ASSERT |
duke@435 | 1183 | { |
duke@435 | 1184 | Label ok; |
duke@435 | 1185 | __ cmp(I5_savedSP, FP); |
duke@435 | 1186 | __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, ok); |
duke@435 | 1187 | __ delayed()->nop(); |
duke@435 | 1188 | __ stop("bad I5_savedSP value"); |
duke@435 | 1189 | __ should_not_reach_here(); |
duke@435 | 1190 | __ bind(ok); |
duke@435 | 1191 | } |
duke@435 | 1192 | #endif |
duke@435 | 1193 | if (TraceJumps) { |
duke@435 | 1194 | // Move target to register that is recordable |
duke@435 | 1195 | __ mov(Lscratch, G3_scratch); |
duke@435 | 1196 | __ JMP(G3_scratch, 0); |
duke@435 | 1197 | } else { |
duke@435 | 1198 | __ jmp(Lscratch, 0); |
duke@435 | 1199 | } |
duke@435 | 1200 | __ delayed()->nop(); |
duke@435 | 1201 | |
duke@435 | 1202 | |
duke@435 | 1203 | if (inc_counter) { |
duke@435 | 1204 | // handle invocation counter overflow |
duke@435 | 1205 | __ bind(invocation_counter_overflow); |
duke@435 | 1206 | generate_counter_overflow(Lcontinue); |
duke@435 | 1207 | } |
duke@435 | 1208 | |
duke@435 | 1209 | |
duke@435 | 1210 | |
duke@435 | 1211 | return entry; |
duke@435 | 1212 | } |
duke@435 | 1213 | |
duke@435 | 1214 | |
duke@435 | 1215 | // Generic method entry to (asm) interpreter |
duke@435 | 1216 | //------------------------------------------------------------------------------------------------------------------------ |
duke@435 | 1217 | // |
duke@435 | 1218 | address InterpreterGenerator::generate_normal_entry(bool synchronized) { |
duke@435 | 1219 | address entry = __ pc(); |
duke@435 | 1220 | |
duke@435 | 1221 | bool inc_counter = UseCompiler || CountCompiledCalls; |
duke@435 | 1222 | |
duke@435 | 1223 | // the following temporary registers are used during frame creation |
duke@435 | 1224 | const Register Gtmp1 = G3_scratch ; |
duke@435 | 1225 | const Register Gtmp2 = G1_scratch; |
duke@435 | 1226 | |
duke@435 | 1227 | // make sure registers are different! |
duke@435 | 1228 | assert_different_registers(G2_thread, G5_method, Gargs, Gtmp1, Gtmp2); |
duke@435 | 1229 | |
twisti@1162 | 1230 | const Address size_of_parameters(G5_method, methodOopDesc::size_of_parameters_offset()); |
twisti@1162 | 1231 | const Address size_of_locals (G5_method, methodOopDesc::size_of_locals_offset()); |
duke@435 | 1232 | // Seems like G5_method is live at the point this is used. So we could make this look consistent |
duke@435 | 1233 | // and use in the asserts. |
twisti@1162 | 1234 | const Address access_flags (Lmethod, methodOopDesc::access_flags_offset()); |
duke@435 | 1235 | |
duke@435 | 1236 | __ verify_oop(G5_method); |
duke@435 | 1237 | |
duke@435 | 1238 | const Register Glocals_size = G3; |
duke@435 | 1239 | assert_different_registers(Glocals_size, G4_scratch, Gframe_size); |
duke@435 | 1240 | |
duke@435 | 1241 | // make sure method is not native & not abstract |
duke@435 | 1242 | // rethink these assertions - they can be simplified and shared (gri 2/25/2000) |
duke@435 | 1243 | #ifdef ASSERT |
twisti@1162 | 1244 | __ ld(G5_method, methodOopDesc::access_flags_offset(), Gtmp1); |
duke@435 | 1245 | { |
duke@435 | 1246 | Label L; |
duke@435 | 1247 | __ btst(JVM_ACC_NATIVE, Gtmp1); |
duke@435 | 1248 | __ br(Assembler::zero, false, Assembler::pt, L); |
duke@435 | 1249 | __ delayed()->nop(); |
duke@435 | 1250 | __ stop("tried to execute native method as non-native"); |
duke@435 | 1251 | __ bind(L); |
duke@435 | 1252 | } |
duke@435 | 1253 | { Label L; |
duke@435 | 1254 | __ btst(JVM_ACC_ABSTRACT, Gtmp1); |
duke@435 | 1255 | __ br(Assembler::zero, false, Assembler::pt, L); |
duke@435 | 1256 | __ delayed()->nop(); |
duke@435 | 1257 | __ stop("tried to execute abstract method as non-abstract"); |
duke@435 | 1258 | __ bind(L); |
duke@435 | 1259 | } |
duke@435 | 1260 | #endif // ASSERT |
duke@435 | 1261 | |
duke@435 | 1262 | // generate the code to allocate the interpreter stack frame |
duke@435 | 1263 | |
duke@435 | 1264 | generate_fixed_frame(false); |
duke@435 | 1265 | |
duke@435 | 1266 | #ifdef FAST_DISPATCH |
duke@435 | 1267 | __ set((intptr_t)Interpreter::dispatch_table(), IdispatchTables); |
duke@435 | 1268 | // set bytecode dispatch table base |
duke@435 | 1269 | #endif |
duke@435 | 1270 | |
duke@435 | 1271 | // |
duke@435 | 1272 | // Code to initialize the extra (i.e. non-parm) locals |
duke@435 | 1273 | // |
duke@435 | 1274 | Register init_value = noreg; // will be G0 if we must clear locals |
duke@435 | 1275 | // The way the code was setup before zerolocals was always true for vanilla java entries. |
duke@435 | 1276 | // It could only be false for the specialized entries like accessor or empty which have |
duke@435 | 1277 | // no extra locals so the testing was a waste of time and the extra locals were always |
duke@435 | 1278 | // initialized. We removed this extra complication to already over complicated code. |
duke@435 | 1279 | |
duke@435 | 1280 | init_value = G0; |
duke@435 | 1281 | Label clear_loop; |
duke@435 | 1282 | |
duke@435 | 1283 | // NOTE: If you change the frame layout, this code will need to |
duke@435 | 1284 | // be updated! |
duke@435 | 1285 | __ lduh( size_of_locals, O2 ); |
duke@435 | 1286 | __ lduh( size_of_parameters, O1 ); |
twisti@1861 | 1287 | __ sll( O2, Interpreter::logStackElementSize, O2); |
twisti@1861 | 1288 | __ sll( O1, Interpreter::logStackElementSize, O1 ); |
duke@435 | 1289 | __ sub( Llocals, O2, O2 ); |
duke@435 | 1290 | __ sub( Llocals, O1, O1 ); |
duke@435 | 1291 | |
duke@435 | 1292 | __ bind( clear_loop ); |
duke@435 | 1293 | __ inc( O2, wordSize ); |
duke@435 | 1294 | |
duke@435 | 1295 | __ cmp( O2, O1 ); |
duke@435 | 1296 | __ brx( Assembler::lessEqualUnsigned, true, Assembler::pt, clear_loop ); |
duke@435 | 1297 | __ delayed()->st_ptr( init_value, O2, 0 ); |
duke@435 | 1298 | |
twisti@1162 | 1299 | const Address do_not_unlock_if_synchronized(G2_thread, |
twisti@1162 | 1300 | JavaThread::do_not_unlock_if_synchronized_offset()); |
duke@435 | 1301 | // Since at this point in the method invocation the exception handler |
duke@435 | 1302 | // would try to exit the monitor of synchronized methods which hasn't |
duke@435 | 1303 | // been entered yet, we set the thread local variable |
duke@435 | 1304 | // _do_not_unlock_if_synchronized to true. If any exception was thrown by |
duke@435 | 1305 | // runtime, exception handling i.e. unlock_if_synchronized_method will |
duke@435 | 1306 | // check this thread local flag. |
duke@435 | 1307 | __ movbool(true, G3_scratch); |
duke@435 | 1308 | __ stbool(G3_scratch, do_not_unlock_if_synchronized); |
duke@435 | 1309 | |
duke@435 | 1310 | // increment invocation counter and check for overflow |
duke@435 | 1311 | // |
duke@435 | 1312 | // Note: checking for negative value instead of overflow |
duke@435 | 1313 | // so we have a 'sticky' overflow test (may be of |
duke@435 | 1314 | // importance as soon as we have true MT/MP) |
duke@435 | 1315 | Label invocation_counter_overflow; |
duke@435 | 1316 | Label profile_method; |
duke@435 | 1317 | Label profile_method_continue; |
duke@435 | 1318 | Label Lcontinue; |
duke@435 | 1319 | if (inc_counter) { |
duke@435 | 1320 | generate_counter_incr(&invocation_counter_overflow, &profile_method, &profile_method_continue); |
duke@435 | 1321 | if (ProfileInterpreter) { |
duke@435 | 1322 | __ bind(profile_method_continue); |
duke@435 | 1323 | } |
duke@435 | 1324 | } |
duke@435 | 1325 | __ bind(Lcontinue); |
duke@435 | 1326 | |
duke@435 | 1327 | bang_stack_shadow_pages(false); |
duke@435 | 1328 | |
duke@435 | 1329 | // reset the _do_not_unlock_if_synchronized flag |
duke@435 | 1330 | __ stbool(G0, do_not_unlock_if_synchronized); |
duke@435 | 1331 | |
duke@435 | 1332 | // check for synchronized methods |
duke@435 | 1333 | // Must happen AFTER invocation_counter check and stack overflow check, |
duke@435 | 1334 | // so method is not locked if overflows. |
duke@435 | 1335 | |
duke@435 | 1336 | if (synchronized) { |
duke@435 | 1337 | lock_method(); |
duke@435 | 1338 | } else { |
duke@435 | 1339 | #ifdef ASSERT |
duke@435 | 1340 | { Label ok; |
duke@435 | 1341 | __ ld(access_flags, O0); |
duke@435 | 1342 | __ btst(JVM_ACC_SYNCHRONIZED, O0); |
duke@435 | 1343 | __ br( Assembler::zero, false, Assembler::pt, ok); |
duke@435 | 1344 | __ delayed()->nop(); |
duke@435 | 1345 | __ stop("method needs synchronization"); |
duke@435 | 1346 | __ bind(ok); |
duke@435 | 1347 | } |
duke@435 | 1348 | #endif // ASSERT |
duke@435 | 1349 | } |
duke@435 | 1350 | |
duke@435 | 1351 | // start execution |
duke@435 | 1352 | |
duke@435 | 1353 | __ verify_thread(); |
duke@435 | 1354 | |
duke@435 | 1355 | // jvmti support |
duke@435 | 1356 | __ notify_method_entry(); |
duke@435 | 1357 | |
duke@435 | 1358 | // start executing instructions |
duke@435 | 1359 | __ dispatch_next(vtos); |
duke@435 | 1360 | |
duke@435 | 1361 | |
duke@435 | 1362 | if (inc_counter) { |
duke@435 | 1363 | if (ProfileInterpreter) { |
duke@435 | 1364 | // We have decided to profile this method in the interpreter |
duke@435 | 1365 | __ bind(profile_method); |
duke@435 | 1366 | |
iveresov@2438 | 1367 | __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method)); |
iveresov@2438 | 1368 | __ set_method_data_pointer_for_bcp(); |
duke@435 | 1369 | __ ba(false, profile_method_continue); |
duke@435 | 1370 | __ delayed()->nop(); |
duke@435 | 1371 | } |
duke@435 | 1372 | |
duke@435 | 1373 | // handle invocation counter overflow |
duke@435 | 1374 | __ bind(invocation_counter_overflow); |
duke@435 | 1375 | generate_counter_overflow(Lcontinue); |
duke@435 | 1376 | } |
duke@435 | 1377 | |
duke@435 | 1378 | |
duke@435 | 1379 | return entry; |
duke@435 | 1380 | } |
duke@435 | 1381 | |
duke@435 | 1382 | |
duke@435 | 1383 | //---------------------------------------------------------------------------------------------------- |
duke@435 | 1384 | // Entry points & stack frame layout |
duke@435 | 1385 | // |
duke@435 | 1386 | // Here we generate the various kind of entries into the interpreter. |
duke@435 | 1387 | // The two main entry type are generic bytecode methods and native call method. |
duke@435 | 1388 | // These both come in synchronized and non-synchronized versions but the |
duke@435 | 1389 | // frame layout they create is very similar. The other method entry |
duke@435 | 1390 | // types are really just special purpose entries that are really entry |
duke@435 | 1391 | // and interpretation all in one. These are for trivial methods like |
duke@435 | 1392 | // accessor, empty, or special math methods. |
duke@435 | 1393 | // |
duke@435 | 1394 | // When control flow reaches any of the entry types for the interpreter |
duke@435 | 1395 | // the following holds -> |
duke@435 | 1396 | // |
duke@435 | 1397 | // C2 Calling Conventions: |
duke@435 | 1398 | // |
duke@435 | 1399 | // The entry code below assumes that the following registers are set |
duke@435 | 1400 | // when coming in: |
duke@435 | 1401 | // G5_method: holds the methodOop of the method to call |
duke@435 | 1402 | // Lesp: points to the TOS of the callers expression stack |
duke@435 | 1403 | // after having pushed all the parameters |
duke@435 | 1404 | // |
duke@435 | 1405 | // The entry code does the following to setup an interpreter frame |
duke@435 | 1406 | // pop parameters from the callers stack by adjusting Lesp |
duke@435 | 1407 | // set O0 to Lesp |
duke@435 | 1408 | // compute X = (max_locals - num_parameters) |
duke@435 | 1409 | // bump SP up by X to accomadate the extra locals |
duke@435 | 1410 | // compute X = max_expression_stack |
duke@435 | 1411 | // + vm_local_words |
duke@435 | 1412 | // + 16 words of register save area |
duke@435 | 1413 | // save frame doing a save sp, -X, sp growing towards lower addresses |
duke@435 | 1414 | // set Lbcp, Lmethod, LcpoolCache |
duke@435 | 1415 | // set Llocals to i0 |
duke@435 | 1416 | // set Lmonitors to FP - rounded_vm_local_words |
duke@435 | 1417 | // set Lesp to Lmonitors - 4 |
duke@435 | 1418 | // |
duke@435 | 1419 | // The frame has now been setup to do the rest of the entry code |
duke@435 | 1420 | |
duke@435 | 1421 | // Try this optimization: Most method entries could live in a |
duke@435 | 1422 | // "one size fits all" stack frame without all the dynamic size |
duke@435 | 1423 | // calculations. It might be profitable to do all this calculation |
duke@435 | 1424 | // statically and approximately for "small enough" methods. |
duke@435 | 1425 | |
duke@435 | 1426 | //----------------------------------------------------------------------------------------------- |
duke@435 | 1427 | |
duke@435 | 1428 | // C1 Calling conventions |
duke@435 | 1429 | // |
duke@435 | 1430 | // Upon method entry, the following registers are setup: |
duke@435 | 1431 | // |
duke@435 | 1432 | // g2 G2_thread: current thread |
duke@435 | 1433 | // g5 G5_method: method to activate |
duke@435 | 1434 | // g4 Gargs : pointer to last argument |
duke@435 | 1435 | // |
duke@435 | 1436 | // |
duke@435 | 1437 | // Stack: |
duke@435 | 1438 | // |
duke@435 | 1439 | // +---------------+ <--- sp |
duke@435 | 1440 | // | | |
duke@435 | 1441 | // : reg save area : |
duke@435 | 1442 | // | | |
duke@435 | 1443 | // +---------------+ <--- sp + 0x40 |
duke@435 | 1444 | // | | |
duke@435 | 1445 | // : extra 7 slots : note: these slots are not really needed for the interpreter (fix later) |
duke@435 | 1446 | // | | |
duke@435 | 1447 | // +---------------+ <--- sp + 0x5c |
duke@435 | 1448 | // | | |
duke@435 | 1449 | // : free : |
duke@435 | 1450 | // | | |
duke@435 | 1451 | // +---------------+ <--- Gargs |
duke@435 | 1452 | // | | |
duke@435 | 1453 | // : arguments : |
duke@435 | 1454 | // | | |
duke@435 | 1455 | // +---------------+ |
duke@435 | 1456 | // | | |
duke@435 | 1457 | // |
duke@435 | 1458 | // |
duke@435 | 1459 | // |
duke@435 | 1460 | // AFTER FRAME HAS BEEN SETUP for method interpretation the stack looks like: |
duke@435 | 1461 | // |
duke@435 | 1462 | // +---------------+ <--- sp |
duke@435 | 1463 | // | | |
duke@435 | 1464 | // : reg save area : |
duke@435 | 1465 | // | | |
duke@435 | 1466 | // +---------------+ <--- sp + 0x40 |
duke@435 | 1467 | // | | |
duke@435 | 1468 | // : extra 7 slots : note: these slots are not really needed for the interpreter (fix later) |
duke@435 | 1469 | // | | |
duke@435 | 1470 | // +---------------+ <--- sp + 0x5c |
duke@435 | 1471 | // | | |
duke@435 | 1472 | // : : |
duke@435 | 1473 | // | | <--- Lesp |
duke@435 | 1474 | // +---------------+ <--- Lmonitors (fp - 0x18) |
duke@435 | 1475 | // | VM locals | |
duke@435 | 1476 | // +---------------+ <--- fp |
duke@435 | 1477 | // | | |
duke@435 | 1478 | // : reg save area : |
duke@435 | 1479 | // | | |
duke@435 | 1480 | // +---------------+ <--- fp + 0x40 |
duke@435 | 1481 | // | | |
duke@435 | 1482 | // : extra 7 slots : note: these slots are not really needed for the interpreter (fix later) |
duke@435 | 1483 | // | | |
duke@435 | 1484 | // +---------------+ <--- fp + 0x5c |
duke@435 | 1485 | // | | |
duke@435 | 1486 | // : free : |
duke@435 | 1487 | // | | |
duke@435 | 1488 | // +---------------+ |
duke@435 | 1489 | // | | |
duke@435 | 1490 | // : nonarg locals : |
duke@435 | 1491 | // | | |
duke@435 | 1492 | // +---------------+ |
duke@435 | 1493 | // | | |
duke@435 | 1494 | // : arguments : |
duke@435 | 1495 | // | | <--- Llocals |
duke@435 | 1496 | // +---------------+ <--- Gargs |
duke@435 | 1497 | // | | |
duke@435 | 1498 | |
duke@435 | 1499 | static int size_activation_helper(int callee_extra_locals, int max_stack, int monitor_size) { |
duke@435 | 1500 | |
duke@435 | 1501 | // Figure out the size of an interpreter frame (in words) given that we have a fully allocated |
duke@435 | 1502 | // expression stack, the callee will have callee_extra_locals (so we can account for |
duke@435 | 1503 | // frame extension) and monitor_size for monitors. Basically we need to calculate |
duke@435 | 1504 | // this exactly like generate_fixed_frame/generate_compute_interpreter_state. |
duke@435 | 1505 | // |
duke@435 | 1506 | // |
duke@435 | 1507 | // The big complicating thing here is that we must ensure that the stack stays properly |
duke@435 | 1508 | // aligned. This would be even uglier if monitor size wasn't modulo what the stack |
duke@435 | 1509 | // needs to be aligned for). We are given that the sp (fp) is already aligned by |
duke@435 | 1510 | // the caller so we must ensure that it is properly aligned for our callee. |
duke@435 | 1511 | // |
duke@435 | 1512 | const int rounded_vm_local_words = |
duke@435 | 1513 | round_to(frame::interpreter_frame_vm_local_words,WordsPerLong); |
duke@435 | 1514 | // callee_locals and max_stack are counts, not the size in frame. |
duke@435 | 1515 | const int locals_size = |
twisti@1861 | 1516 | round_to(callee_extra_locals * Interpreter::stackElementWords, WordsPerLong); |
twisti@1861 | 1517 | const int max_stack_words = max_stack * Interpreter::stackElementWords; |
duke@435 | 1518 | return (round_to((max_stack_words |
jrose@1145 | 1519 | //6815692//+ methodOopDesc::extra_stack_words() |
duke@435 | 1520 | + rounded_vm_local_words |
duke@435 | 1521 | + frame::memory_parameter_word_sp_offset), WordsPerLong) |
duke@435 | 1522 | // already rounded |
duke@435 | 1523 | + locals_size + monitor_size); |
duke@435 | 1524 | } |
duke@435 | 1525 | |
duke@435 | 1526 | // How much stack a method top interpreter activation needs in words. |
duke@435 | 1527 | int AbstractInterpreter::size_top_interpreter_activation(methodOop method) { |
duke@435 | 1528 | |
duke@435 | 1529 | // See call_stub code |
duke@435 | 1530 | int call_stub_size = round_to(7 + frame::memory_parameter_word_sp_offset, |
duke@435 | 1531 | WordsPerLong); // 7 + register save area |
duke@435 | 1532 | |
duke@435 | 1533 | // Save space for one monitor to get into the interpreted method in case |
duke@435 | 1534 | // the method is synchronized |
duke@435 | 1535 | int monitor_size = method->is_synchronized() ? |
duke@435 | 1536 | 1*frame::interpreter_frame_monitor_size() : 0; |
duke@435 | 1537 | return size_activation_helper(method->max_locals(), method->max_stack(), |
duke@435 | 1538 | monitor_size) + call_stub_size; |
duke@435 | 1539 | } |
duke@435 | 1540 | |
duke@435 | 1541 | int AbstractInterpreter::layout_activation(methodOop method, |
duke@435 | 1542 | int tempcount, |
duke@435 | 1543 | int popframe_extra_args, |
duke@435 | 1544 | int moncount, |
duke@435 | 1545 | int callee_param_count, |
duke@435 | 1546 | int callee_local_count, |
duke@435 | 1547 | frame* caller, |
duke@435 | 1548 | frame* interpreter_frame, |
duke@435 | 1549 | bool is_top_frame) { |
duke@435 | 1550 | // Note: This calculation must exactly parallel the frame setup |
duke@435 | 1551 | // in InterpreterGenerator::generate_fixed_frame. |
duke@435 | 1552 | // If f!=NULL, set up the following variables: |
duke@435 | 1553 | // - Lmethod |
duke@435 | 1554 | // - Llocals |
duke@435 | 1555 | // - Lmonitors (to the indicated number of monitors) |
duke@435 | 1556 | // - Lesp (to the indicated number of temps) |
duke@435 | 1557 | // The frame f (if not NULL) on entry is a description of the caller of the frame |
duke@435 | 1558 | // we are about to layout. We are guaranteed that we will be able to fill in a |
duke@435 | 1559 | // new interpreter frame as its callee (i.e. the stack space is allocated and |
duke@435 | 1560 | // the amount was determined by an earlier call to this method with f == NULL). |
duke@435 | 1561 | // On return f (if not NULL) while describe the interpreter frame we just layed out. |
duke@435 | 1562 | |
duke@435 | 1563 | int monitor_size = moncount * frame::interpreter_frame_monitor_size(); |
duke@435 | 1564 | int rounded_vm_local_words = round_to(frame::interpreter_frame_vm_local_words,WordsPerLong); |
duke@435 | 1565 | |
duke@435 | 1566 | assert(monitor_size == round_to(monitor_size, WordsPerLong), "must align"); |
duke@435 | 1567 | // |
duke@435 | 1568 | // Note: if you look closely this appears to be doing something much different |
duke@435 | 1569 | // than generate_fixed_frame. What is happening is this. On sparc we have to do |
duke@435 | 1570 | // this dance with interpreter_sp_adjustment because the window save area would |
duke@435 | 1571 | // appear just below the bottom (tos) of the caller's java expression stack. Because |
duke@435 | 1572 | // the interpreter want to have the locals completely contiguous generate_fixed_frame |
duke@435 | 1573 | // will adjust the caller's sp for the "extra locals" (max_locals - parameter_size). |
duke@435 | 1574 | // Now in generate_fixed_frame the extension of the caller's sp happens in the callee. |
duke@435 | 1575 | // In this code the opposite occurs the caller adjusts it's own stack base on the callee. |
duke@435 | 1576 | // This is mostly ok but it does cause a problem when we get to the initial frame (the oldest) |
duke@435 | 1577 | // because the oldest frame would have adjust its callers frame and yet that frame |
duke@435 | 1578 | // already exists and isn't part of this array of frames we are unpacking. So at first |
duke@435 | 1579 | // glance this would seem to mess up that frame. However Deoptimization::fetch_unroll_info_helper() |
duke@435 | 1580 | // will after it calculates all of the frame's on_stack_size()'s will then figure out the |
duke@435 | 1581 | // amount to adjust the caller of the initial (oldest) frame and the calculation will all |
duke@435 | 1582 | // add up. It does seem like it simpler to account for the adjustment here (and remove the |
duke@435 | 1583 | // callee... parameters here). However this would mean that this routine would have to take |
duke@435 | 1584 | // the caller frame as input so we could adjust its sp (and set it's interpreter_sp_adjustment) |
duke@435 | 1585 | // and run the calling loop in the reverse order. This would also would appear to mean making |
duke@435 | 1586 | // this code aware of what the interactions are when that initial caller fram was an osr or |
duke@435 | 1587 | // other adapter frame. deoptimization is complicated enough and hard enough to debug that |
duke@435 | 1588 | // there is no sense in messing working code. |
duke@435 | 1589 | // |
duke@435 | 1590 | |
duke@435 | 1591 | int rounded_cls = round_to((callee_local_count - callee_param_count), WordsPerLong); |
duke@435 | 1592 | assert(rounded_cls == round_to(rounded_cls, WordsPerLong), "must align"); |
duke@435 | 1593 | |
duke@435 | 1594 | int raw_frame_size = size_activation_helper(rounded_cls, method->max_stack(), |
duke@435 | 1595 | monitor_size); |
duke@435 | 1596 | |
duke@435 | 1597 | if (interpreter_frame != NULL) { |
duke@435 | 1598 | // The skeleton frame must already look like an interpreter frame |
duke@435 | 1599 | // even if not fully filled out. |
duke@435 | 1600 | assert(interpreter_frame->is_interpreted_frame(), "Must be interpreted frame"); |
duke@435 | 1601 | |
duke@435 | 1602 | intptr_t* fp = interpreter_frame->fp(); |
duke@435 | 1603 | |
duke@435 | 1604 | JavaThread* thread = JavaThread::current(); |
duke@435 | 1605 | RegisterMap map(thread, false); |
duke@435 | 1606 | // More verification that skeleton frame is properly walkable |
duke@435 | 1607 | assert(fp == caller->sp(), "fp must match"); |
duke@435 | 1608 | |
duke@435 | 1609 | intptr_t* montop = fp - rounded_vm_local_words; |
duke@435 | 1610 | |
duke@435 | 1611 | // preallocate monitors (cf. __ add_monitor_to_stack) |
duke@435 | 1612 | intptr_t* monitors = montop - monitor_size; |
duke@435 | 1613 | |
duke@435 | 1614 | // preallocate stack space |
duke@435 | 1615 | intptr_t* esp = monitors - 1 - |
twisti@1861 | 1616 | (tempcount * Interpreter::stackElementWords) - |
duke@435 | 1617 | popframe_extra_args; |
duke@435 | 1618 | |
twisti@1861 | 1619 | int local_words = method->max_locals() * Interpreter::stackElementWords; |
twisti@1861 | 1620 | int parm_words = method->size_of_parameters() * Interpreter::stackElementWords; |
duke@435 | 1621 | NEEDS_CLEANUP; |
duke@435 | 1622 | intptr_t* locals; |
duke@435 | 1623 | if (caller->is_interpreted_frame()) { |
duke@435 | 1624 | // Can force the locals area to end up properly overlapping the top of the expression stack. |
duke@435 | 1625 | intptr_t* Lesp_ptr = caller->interpreter_frame_tos_address() - 1; |
duke@435 | 1626 | // Note that this computation means we replace size_of_parameters() values from the caller |
duke@435 | 1627 | // interpreter frame's expression stack with our argument locals |
duke@435 | 1628 | locals = Lesp_ptr + parm_words; |
duke@435 | 1629 | int delta = local_words - parm_words; |
duke@435 | 1630 | int computed_sp_adjustment = (delta > 0) ? round_to(delta, WordsPerLong) : 0; |
duke@435 | 1631 | *interpreter_frame->register_addr(I5_savedSP) = (intptr_t) (fp + computed_sp_adjustment) - STACK_BIAS; |
duke@435 | 1632 | } else { |
duke@435 | 1633 | assert(caller->is_compiled_frame() || caller->is_entry_frame(), "only possible cases"); |
duke@435 | 1634 | // Don't have Lesp available; lay out locals block in the caller |
duke@435 | 1635 | // adjacent to the register window save area. |
duke@435 | 1636 | // |
duke@435 | 1637 | // Compiled frames do not allocate a varargs area which is why this if |
duke@435 | 1638 | // statement is needed. |
duke@435 | 1639 | // |
duke@435 | 1640 | if (caller->is_compiled_frame()) { |
duke@435 | 1641 | locals = fp + frame::register_save_words + local_words - 1; |
duke@435 | 1642 | } else { |
duke@435 | 1643 | locals = fp + frame::memory_parameter_word_sp_offset + local_words - 1; |
duke@435 | 1644 | } |
duke@435 | 1645 | if (!caller->is_entry_frame()) { |
duke@435 | 1646 | // Caller wants his own SP back |
duke@435 | 1647 | int caller_frame_size = caller->cb()->frame_size(); |
duke@435 | 1648 | *interpreter_frame->register_addr(I5_savedSP) = (intptr_t)(caller->fp() - caller_frame_size) - STACK_BIAS; |
duke@435 | 1649 | } |
duke@435 | 1650 | } |
duke@435 | 1651 | if (TraceDeoptimization) { |
duke@435 | 1652 | if (caller->is_entry_frame()) { |
duke@435 | 1653 | // make sure I5_savedSP and the entry frames notion of saved SP |
duke@435 | 1654 | // agree. This assertion duplicate a check in entry frame code |
duke@435 | 1655 | // but catches the failure earlier. |
duke@435 | 1656 | assert(*caller->register_addr(Lscratch) == *interpreter_frame->register_addr(I5_savedSP), |
duke@435 | 1657 | "would change callers SP"); |
duke@435 | 1658 | } |
duke@435 | 1659 | if (caller->is_entry_frame()) { |
duke@435 | 1660 | tty->print("entry "); |
duke@435 | 1661 | } |
duke@435 | 1662 | if (caller->is_compiled_frame()) { |
duke@435 | 1663 | tty->print("compiled "); |
duke@435 | 1664 | if (caller->is_deoptimized_frame()) { |
duke@435 | 1665 | tty->print("(deopt) "); |
duke@435 | 1666 | } |
duke@435 | 1667 | } |
duke@435 | 1668 | if (caller->is_interpreted_frame()) { |
duke@435 | 1669 | tty->print("interpreted "); |
duke@435 | 1670 | } |
duke@435 | 1671 | tty->print_cr("caller fp=0x%x sp=0x%x", caller->fp(), caller->sp()); |
duke@435 | 1672 | tty->print_cr("save area = 0x%x, 0x%x", caller->sp(), caller->sp() + 16); |
duke@435 | 1673 | tty->print_cr("save area = 0x%x, 0x%x", caller->fp(), caller->fp() + 16); |
duke@435 | 1674 | tty->print_cr("interpreter fp=0x%x sp=0x%x", interpreter_frame->fp(), interpreter_frame->sp()); |
duke@435 | 1675 | tty->print_cr("save area = 0x%x, 0x%x", interpreter_frame->sp(), interpreter_frame->sp() + 16); |
duke@435 | 1676 | tty->print_cr("save area = 0x%x, 0x%x", interpreter_frame->fp(), interpreter_frame->fp() + 16); |
duke@435 | 1677 | tty->print_cr("Llocals = 0x%x", locals); |
duke@435 | 1678 | tty->print_cr("Lesp = 0x%x", esp); |
duke@435 | 1679 | tty->print_cr("Lmonitors = 0x%x", monitors); |
duke@435 | 1680 | } |
duke@435 | 1681 | |
duke@435 | 1682 | if (method->max_locals() > 0) { |
duke@435 | 1683 | assert(locals < caller->sp() || locals >= (caller->sp() + 16), "locals in save area"); |
duke@435 | 1684 | assert(locals < caller->fp() || locals > (caller->fp() + 16), "locals in save area"); |
duke@435 | 1685 | assert(locals < interpreter_frame->sp() || locals > (interpreter_frame->sp() + 16), "locals in save area"); |
duke@435 | 1686 | assert(locals < interpreter_frame->fp() || locals >= (interpreter_frame->fp() + 16), "locals in save area"); |
duke@435 | 1687 | } |
duke@435 | 1688 | #ifdef _LP64 |
duke@435 | 1689 | assert(*interpreter_frame->register_addr(I5_savedSP) & 1, "must be odd"); |
duke@435 | 1690 | #endif |
duke@435 | 1691 | |
duke@435 | 1692 | *interpreter_frame->register_addr(Lmethod) = (intptr_t) method; |
duke@435 | 1693 | *interpreter_frame->register_addr(Llocals) = (intptr_t) locals; |
duke@435 | 1694 | *interpreter_frame->register_addr(Lmonitors) = (intptr_t) monitors; |
duke@435 | 1695 | *interpreter_frame->register_addr(Lesp) = (intptr_t) esp; |
duke@435 | 1696 | // Llast_SP will be same as SP as there is no adapter space |
duke@435 | 1697 | *interpreter_frame->register_addr(Llast_SP) = (intptr_t) interpreter_frame->sp() - STACK_BIAS; |
duke@435 | 1698 | *interpreter_frame->register_addr(LcpoolCache) = (intptr_t) method->constants()->cache(); |
duke@435 | 1699 | #ifdef FAST_DISPATCH |
duke@435 | 1700 | *interpreter_frame->register_addr(IdispatchTables) = (intptr_t) Interpreter::dispatch_table(); |
duke@435 | 1701 | #endif |
duke@435 | 1702 | |
duke@435 | 1703 | |
duke@435 | 1704 | #ifdef ASSERT |
duke@435 | 1705 | BasicObjectLock* mp = (BasicObjectLock*)monitors; |
duke@435 | 1706 | |
duke@435 | 1707 | assert(interpreter_frame->interpreter_frame_method() == method, "method matches"); |
twisti@1861 | 1708 | assert(interpreter_frame->interpreter_frame_local_at(9) == (intptr_t *)((intptr_t)locals - (9 * Interpreter::stackElementSize)), "locals match"); |
duke@435 | 1709 | assert(interpreter_frame->interpreter_frame_monitor_end() == mp, "monitor_end matches"); |
duke@435 | 1710 | assert(((intptr_t *)interpreter_frame->interpreter_frame_monitor_begin()) == ((intptr_t *)mp)+monitor_size, "monitor_begin matches"); |
duke@435 | 1711 | assert(interpreter_frame->interpreter_frame_tos_address()-1 == esp, "esp matches"); |
duke@435 | 1712 | |
duke@435 | 1713 | // check bounds |
duke@435 | 1714 | intptr_t* lo = interpreter_frame->sp() + (frame::memory_parameter_word_sp_offset - 1); |
duke@435 | 1715 | intptr_t* hi = interpreter_frame->fp() - rounded_vm_local_words; |
duke@435 | 1716 | assert(lo < monitors && montop <= hi, "monitors in bounds"); |
duke@435 | 1717 | assert(lo <= esp && esp < monitors, "esp in bounds"); |
duke@435 | 1718 | #endif // ASSERT |
duke@435 | 1719 | } |
duke@435 | 1720 | |
duke@435 | 1721 | return raw_frame_size; |
duke@435 | 1722 | } |
duke@435 | 1723 | |
duke@435 | 1724 | //---------------------------------------------------------------------------------------------------- |
duke@435 | 1725 | // Exceptions |
duke@435 | 1726 | void TemplateInterpreterGenerator::generate_throw_exception() { |
duke@435 | 1727 | |
duke@435 | 1728 | // Entry point in previous activation (i.e., if the caller was interpreted) |
duke@435 | 1729 | Interpreter::_rethrow_exception_entry = __ pc(); |
duke@435 | 1730 | // O0: exception |
duke@435 | 1731 | |
duke@435 | 1732 | // entry point for exceptions thrown within interpreter code |
duke@435 | 1733 | Interpreter::_throw_exception_entry = __ pc(); |
duke@435 | 1734 | __ verify_thread(); |
duke@435 | 1735 | // expression stack is undefined here |
duke@435 | 1736 | // O0: exception, i.e. Oexception |
duke@435 | 1737 | // Lbcp: exception bcx |
duke@435 | 1738 | __ verify_oop(Oexception); |
duke@435 | 1739 | |
duke@435 | 1740 | |
duke@435 | 1741 | // expression stack must be empty before entering the VM in case of an exception |
duke@435 | 1742 | __ empty_expression_stack(); |
duke@435 | 1743 | // find exception handler address and preserve exception oop |
duke@435 | 1744 | // call C routine to find handler and jump to it |
duke@435 | 1745 | __ call_VM(O1, CAST_FROM_FN_PTR(address, InterpreterRuntime::exception_handler_for_exception), Oexception); |
duke@435 | 1746 | __ push_ptr(O1); // push exception for exception handler bytecodes |
duke@435 | 1747 | |
duke@435 | 1748 | __ JMP(O0, 0); // jump to exception handler (may be remove activation entry!) |
duke@435 | 1749 | __ delayed()->nop(); |
duke@435 | 1750 | |
duke@435 | 1751 | |
duke@435 | 1752 | // if the exception is not handled in the current frame |
duke@435 | 1753 | // the frame is removed and the exception is rethrown |
duke@435 | 1754 | // (i.e. exception continuation is _rethrow_exception) |
duke@435 | 1755 | // |
duke@435 | 1756 | // Note: At this point the bci is still the bxi for the instruction which caused |
duke@435 | 1757 | // the exception and the expression stack is empty. Thus, for any VM calls |
duke@435 | 1758 | // at this point, GC will find a legal oop map (with empty expression stack). |
duke@435 | 1759 | |
duke@435 | 1760 | // in current activation |
duke@435 | 1761 | // tos: exception |
duke@435 | 1762 | // Lbcp: exception bcp |
duke@435 | 1763 | |
duke@435 | 1764 | // |
duke@435 | 1765 | // JVMTI PopFrame support |
duke@435 | 1766 | // |
duke@435 | 1767 | |
duke@435 | 1768 | Interpreter::_remove_activation_preserving_args_entry = __ pc(); |
twisti@1162 | 1769 | Address popframe_condition_addr(G2_thread, JavaThread::popframe_condition_offset()); |
duke@435 | 1770 | // Set the popframe_processing bit in popframe_condition indicating that we are |
duke@435 | 1771 | // currently handling popframe, so that call_VMs that may happen later do not trigger new |
duke@435 | 1772 | // popframe handling cycles. |
duke@435 | 1773 | |
duke@435 | 1774 | __ ld(popframe_condition_addr, G3_scratch); |
duke@435 | 1775 | __ or3(G3_scratch, JavaThread::popframe_processing_bit, G3_scratch); |
duke@435 | 1776 | __ stw(G3_scratch, popframe_condition_addr); |
duke@435 | 1777 | |
duke@435 | 1778 | // Empty the expression stack, as in normal exception handling |
duke@435 | 1779 | __ empty_expression_stack(); |
duke@435 | 1780 | __ unlock_if_synchronized_method(vtos, /* throw_monitor_exception */ false, /* install_monitor_exception */ false); |
duke@435 | 1781 | |
duke@435 | 1782 | { |
duke@435 | 1783 | // Check to see whether we are returning to a deoptimized frame. |
duke@435 | 1784 | // (The PopFrame call ensures that the caller of the popped frame is |
duke@435 | 1785 | // either interpreted or compiled and deoptimizes it if compiled.) |
duke@435 | 1786 | // In this case, we can't call dispatch_next() after the frame is |
duke@435 | 1787 | // popped, but instead must save the incoming arguments and restore |
duke@435 | 1788 | // them after deoptimization has occurred. |
duke@435 | 1789 | // |
duke@435 | 1790 | // Note that we don't compare the return PC against the |
duke@435 | 1791 | // deoptimization blob's unpack entry because of the presence of |
duke@435 | 1792 | // adapter frames in C2. |
duke@435 | 1793 | Label caller_not_deoptimized; |
duke@435 | 1794 | __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, InterpreterRuntime::interpreter_contains), I7); |
duke@435 | 1795 | __ tst(O0); |
duke@435 | 1796 | __ brx(Assembler::notEqual, false, Assembler::pt, caller_not_deoptimized); |
duke@435 | 1797 | __ delayed()->nop(); |
duke@435 | 1798 | |
duke@435 | 1799 | const Register Gtmp1 = G3_scratch; |
duke@435 | 1800 | const Register Gtmp2 = G1_scratch; |
duke@435 | 1801 | |
duke@435 | 1802 | // Compute size of arguments for saving when returning to deoptimized caller |
duke@435 | 1803 | __ lduh(Lmethod, in_bytes(methodOopDesc::size_of_parameters_offset()), Gtmp1); |
twisti@1861 | 1804 | __ sll(Gtmp1, Interpreter::logStackElementSize, Gtmp1); |
duke@435 | 1805 | __ sub(Llocals, Gtmp1, Gtmp2); |
duke@435 | 1806 | __ add(Gtmp2, wordSize, Gtmp2); |
duke@435 | 1807 | // Save these arguments |
duke@435 | 1808 | __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), G2_thread, Gtmp1, Gtmp2); |
duke@435 | 1809 | // Inform deoptimization that it is responsible for restoring these arguments |
duke@435 | 1810 | __ set(JavaThread::popframe_force_deopt_reexecution_bit, Gtmp1); |
twisti@1162 | 1811 | Address popframe_condition_addr(G2_thread, JavaThread::popframe_condition_offset()); |
duke@435 | 1812 | __ st(Gtmp1, popframe_condition_addr); |
duke@435 | 1813 | |
duke@435 | 1814 | // Return from the current method |
duke@435 | 1815 | // The caller's SP was adjusted upon method entry to accomodate |
duke@435 | 1816 | // the callee's non-argument locals. Undo that adjustment. |
duke@435 | 1817 | __ ret(); |
duke@435 | 1818 | __ delayed()->restore(I5_savedSP, G0, SP); |
duke@435 | 1819 | |
duke@435 | 1820 | __ bind(caller_not_deoptimized); |
duke@435 | 1821 | } |
duke@435 | 1822 | |
duke@435 | 1823 | // Clear the popframe condition flag |
duke@435 | 1824 | __ stw(G0 /* popframe_inactive */, popframe_condition_addr); |
duke@435 | 1825 | |
duke@435 | 1826 | // Get out of the current method (how this is done depends on the particular compiler calling |
duke@435 | 1827 | // convention that the interpreter currently follows) |
duke@435 | 1828 | // The caller's SP was adjusted upon method entry to accomodate |
duke@435 | 1829 | // the callee's non-argument locals. Undo that adjustment. |
duke@435 | 1830 | __ restore(I5_savedSP, G0, SP); |
duke@435 | 1831 | // The method data pointer was incremented already during |
duke@435 | 1832 | // call profiling. We have to restore the mdp for the current bcp. |
duke@435 | 1833 | if (ProfileInterpreter) { |
duke@435 | 1834 | __ set_method_data_pointer_for_bcp(); |
duke@435 | 1835 | } |
duke@435 | 1836 | // Resume bytecode interpretation at the current bcp |
duke@435 | 1837 | __ dispatch_next(vtos); |
duke@435 | 1838 | // end of JVMTI PopFrame support |
duke@435 | 1839 | |
duke@435 | 1840 | Interpreter::_remove_activation_entry = __ pc(); |
duke@435 | 1841 | |
duke@435 | 1842 | // preserve exception over this code sequence (remove activation calls the vm, but oopmaps are not correct here) |
duke@435 | 1843 | __ pop_ptr(Oexception); // get exception |
duke@435 | 1844 | |
duke@435 | 1845 | // Intel has the following comment: |
duke@435 | 1846 | //// remove the activation (without doing throws on illegalMonitorExceptions) |
duke@435 | 1847 | // They remove the activation without checking for bad monitor state. |
duke@435 | 1848 | // %%% We should make sure this is the right semantics before implementing. |
duke@435 | 1849 | |
duke@435 | 1850 | // %%% changed set_vm_result_2 to set_vm_result and get_vm_result_2 to get_vm_result. Is there a bug here? |
duke@435 | 1851 | __ set_vm_result(Oexception); |
duke@435 | 1852 | __ unlock_if_synchronized_method(vtos, /* throw_monitor_exception */ false); |
duke@435 | 1853 | |
duke@435 | 1854 | __ notify_method_exit(false, vtos, InterpreterMacroAssembler::SkipNotifyJVMTI); |
duke@435 | 1855 | |
duke@435 | 1856 | __ get_vm_result(Oexception); |
duke@435 | 1857 | __ verify_oop(Oexception); |
duke@435 | 1858 | |
duke@435 | 1859 | const int return_reg_adjustment = frame::pc_return_offset; |
twisti@1162 | 1860 | Address issuing_pc_addr(I7, return_reg_adjustment); |
duke@435 | 1861 | |
duke@435 | 1862 | // We are done with this activation frame; find out where to go next. |
duke@435 | 1863 | // The continuation point will be an exception handler, which expects |
duke@435 | 1864 | // the following registers set up: |
duke@435 | 1865 | // |
duke@435 | 1866 | // Oexception: exception |
duke@435 | 1867 | // Oissuing_pc: the local call that threw exception |
duke@435 | 1868 | // Other On: garbage |
duke@435 | 1869 | // In/Ln: the contents of the caller's register window |
duke@435 | 1870 | // |
duke@435 | 1871 | // We do the required restore at the last possible moment, because we |
duke@435 | 1872 | // need to preserve some state across a runtime call. |
duke@435 | 1873 | // (Remember that the caller activation is unknown--it might not be |
duke@435 | 1874 | // interpreted, so things like Lscratch are useless in the caller.) |
duke@435 | 1875 | |
duke@435 | 1876 | // Although the Intel version uses call_C, we can use the more |
duke@435 | 1877 | // compact call_VM. (The only real difference on SPARC is a |
duke@435 | 1878 | // harmlessly ignored [re]set_last_Java_frame, compared with |
duke@435 | 1879 | // the Intel code which lacks this.) |
duke@435 | 1880 | __ mov(Oexception, Oexception ->after_save()); // get exception in I0 so it will be on O0 after restore |
duke@435 | 1881 | __ add(issuing_pc_addr, Oissuing_pc->after_save()); // likewise set I1 to a value local to the caller |
duke@435 | 1882 | __ super_call_VM_leaf(L7_thread_cache, |
duke@435 | 1883 | CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), |
twisti@1730 | 1884 | G2_thread, Oissuing_pc->after_save()); |
duke@435 | 1885 | |
duke@435 | 1886 | // The caller's SP was adjusted upon method entry to accomodate |
duke@435 | 1887 | // the callee's non-argument locals. Undo that adjustment. |
duke@435 | 1888 | __ JMP(O0, 0); // return exception handler in caller |
duke@435 | 1889 | __ delayed()->restore(I5_savedSP, G0, SP); |
duke@435 | 1890 | |
duke@435 | 1891 | // (same old exception object is already in Oexception; see above) |
duke@435 | 1892 | // Note that an "issuing PC" is actually the next PC after the call |
duke@435 | 1893 | } |
duke@435 | 1894 | |
duke@435 | 1895 | |
duke@435 | 1896 | // |
duke@435 | 1897 | // JVMTI ForceEarlyReturn support |
duke@435 | 1898 | // |
duke@435 | 1899 | |
duke@435 | 1900 | address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state) { |
duke@435 | 1901 | address entry = __ pc(); |
duke@435 | 1902 | |
duke@435 | 1903 | __ empty_expression_stack(); |
duke@435 | 1904 | __ load_earlyret_value(state); |
duke@435 | 1905 | |
twisti@1162 | 1906 | __ ld_ptr(G2_thread, JavaThread::jvmti_thread_state_offset(), G3_scratch); |
twisti@1162 | 1907 | Address cond_addr(G3_scratch, JvmtiThreadState::earlyret_state_offset()); |
duke@435 | 1908 | |
duke@435 | 1909 | // Clear the earlyret state |
duke@435 | 1910 | __ stw(G0 /* JvmtiThreadState::earlyret_inactive */, cond_addr); |
duke@435 | 1911 | |
duke@435 | 1912 | __ remove_activation(state, |
duke@435 | 1913 | /* throw_monitor_exception */ false, |
duke@435 | 1914 | /* install_monitor_exception */ false); |
duke@435 | 1915 | |
duke@435 | 1916 | // The caller's SP was adjusted upon method entry to accomodate |
duke@435 | 1917 | // the callee's non-argument locals. Undo that adjustment. |
duke@435 | 1918 | __ ret(); // return to caller |
duke@435 | 1919 | __ delayed()->restore(I5_savedSP, G0, SP); |
duke@435 | 1920 | |
duke@435 | 1921 | return entry; |
duke@435 | 1922 | } // end of JVMTI ForceEarlyReturn support |
duke@435 | 1923 | |
duke@435 | 1924 | |
duke@435 | 1925 | //------------------------------------------------------------------------------------------------------------------------ |
duke@435 | 1926 | // Helper for vtos entry point generation |
duke@435 | 1927 | |
duke@435 | 1928 | void TemplateInterpreterGenerator::set_vtos_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) { |
duke@435 | 1929 | assert(t->is_valid() && t->tos_in() == vtos, "illegal template"); |
duke@435 | 1930 | Label L; |
duke@435 | 1931 | aep = __ pc(); __ push_ptr(); __ ba(false, L); __ delayed()->nop(); |
duke@435 | 1932 | fep = __ pc(); __ push_f(); __ ba(false, L); __ delayed()->nop(); |
duke@435 | 1933 | dep = __ pc(); __ push_d(); __ ba(false, L); __ delayed()->nop(); |
duke@435 | 1934 | lep = __ pc(); __ push_l(); __ ba(false, L); __ delayed()->nop(); |
duke@435 | 1935 | iep = __ pc(); __ push_i(); |
duke@435 | 1936 | bep = cep = sep = iep; // there aren't any |
duke@435 | 1937 | vep = __ pc(); __ bind(L); // fall through |
duke@435 | 1938 | generate_and_dispatch(t); |
duke@435 | 1939 | } |
duke@435 | 1940 | |
duke@435 | 1941 | // -------------------------------------------------------------------------------- |
duke@435 | 1942 | |
duke@435 | 1943 | |
duke@435 | 1944 | InterpreterGenerator::InterpreterGenerator(StubQueue* code) |
duke@435 | 1945 | : TemplateInterpreterGenerator(code) { |
duke@435 | 1946 | generate_all(); // down here so it can be "virtual" |
duke@435 | 1947 | } |
duke@435 | 1948 | |
duke@435 | 1949 | // -------------------------------------------------------------------------------- |
duke@435 | 1950 | |
duke@435 | 1951 | // Non-product code |
duke@435 | 1952 | #ifndef PRODUCT |
duke@435 | 1953 | address TemplateInterpreterGenerator::generate_trace_code(TosState state) { |
duke@435 | 1954 | address entry = __ pc(); |
duke@435 | 1955 | |
duke@435 | 1956 | __ push(state); |
duke@435 | 1957 | __ mov(O7, Lscratch); // protect return address within interpreter |
duke@435 | 1958 | |
duke@435 | 1959 | // Pass a 0 (not used in sparc) and the top of stack to the bytecode tracer |
duke@435 | 1960 | __ mov( Otos_l2, G3_scratch ); |
duke@435 | 1961 | __ call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), G0, Otos_l1, G3_scratch); |
duke@435 | 1962 | __ mov(Lscratch, O7); // restore return address |
duke@435 | 1963 | __ pop(state); |
duke@435 | 1964 | __ retl(); |
duke@435 | 1965 | __ delayed()->nop(); |
duke@435 | 1966 | |
duke@435 | 1967 | return entry; |
duke@435 | 1968 | } |
duke@435 | 1969 | |
duke@435 | 1970 | |
duke@435 | 1971 | // helpers for generate_and_dispatch |
duke@435 | 1972 | |
duke@435 | 1973 | void TemplateInterpreterGenerator::count_bytecode() { |
twisti@1162 | 1974 | __ inc_counter(&BytecodeCounter::_counter_value, G3_scratch, G4_scratch); |
duke@435 | 1975 | } |
duke@435 | 1976 | |
duke@435 | 1977 | |
duke@435 | 1978 | void TemplateInterpreterGenerator::histogram_bytecode(Template* t) { |
twisti@1162 | 1979 | __ inc_counter(&BytecodeHistogram::_counters[t->bytecode()], G3_scratch, G4_scratch); |
duke@435 | 1980 | } |
duke@435 | 1981 | |
duke@435 | 1982 | |
duke@435 | 1983 | void TemplateInterpreterGenerator::histogram_bytecode_pair(Template* t) { |
twisti@1162 | 1984 | AddressLiteral index (&BytecodePairHistogram::_index); |
twisti@1162 | 1985 | AddressLiteral counters((address) &BytecodePairHistogram::_counters); |
duke@435 | 1986 | |
duke@435 | 1987 | // get index, shift out old bytecode, bring in new bytecode, and store it |
duke@435 | 1988 | // _index = (_index >> log2_number_of_codes) | |
duke@435 | 1989 | // (bytecode << log2_number_of_codes); |
duke@435 | 1990 | |
twisti@1162 | 1991 | __ load_contents(index, G4_scratch); |
duke@435 | 1992 | __ srl( G4_scratch, BytecodePairHistogram::log2_number_of_codes, G4_scratch ); |
duke@435 | 1993 | __ set( ((int)t->bytecode()) << BytecodePairHistogram::log2_number_of_codes, G3_scratch ); |
duke@435 | 1994 | __ or3( G3_scratch, G4_scratch, G4_scratch ); |
twisti@1162 | 1995 | __ store_contents(G4_scratch, index, G3_scratch); |
duke@435 | 1996 | |
duke@435 | 1997 | // bump bucket contents |
duke@435 | 1998 | // _counters[_index] ++; |
duke@435 | 1999 | |
twisti@1162 | 2000 | __ set(counters, G3_scratch); // loads into G3_scratch |
duke@435 | 2001 | __ sll( G4_scratch, LogBytesPerWord, G4_scratch ); // Index is word address |
duke@435 | 2002 | __ add (G3_scratch, G4_scratch, G3_scratch); // Add in index |
duke@435 | 2003 | __ ld (G3_scratch, 0, G4_scratch); |
duke@435 | 2004 | __ inc (G4_scratch); |
duke@435 | 2005 | __ st (G4_scratch, 0, G3_scratch); |
duke@435 | 2006 | } |
duke@435 | 2007 | |
duke@435 | 2008 | |
duke@435 | 2009 | void TemplateInterpreterGenerator::trace_bytecode(Template* t) { |
duke@435 | 2010 | // Call a little run-time stub to avoid blow-up for each bytecode. |
duke@435 | 2011 | // The run-time runtime saves the right registers, depending on |
duke@435 | 2012 | // the tosca in-state for the given template. |
duke@435 | 2013 | address entry = Interpreter::trace_code(t->tos_in()); |
duke@435 | 2014 | guarantee(entry != NULL, "entry must have been generated"); |
duke@435 | 2015 | __ call(entry, relocInfo::none); |
duke@435 | 2016 | __ delayed()->nop(); |
duke@435 | 2017 | } |
duke@435 | 2018 | |
duke@435 | 2019 | |
duke@435 | 2020 | void TemplateInterpreterGenerator::stop_interpreter_at() { |
twisti@1162 | 2021 | AddressLiteral counter(&BytecodeCounter::_counter_value); |
twisti@1162 | 2022 | __ load_contents(counter, G3_scratch); |
twisti@1162 | 2023 | AddressLiteral stop_at(&StopInterpreterAt); |
duke@435 | 2024 | __ load_ptr_contents(stop_at, G4_scratch); |
duke@435 | 2025 | __ cmp(G3_scratch, G4_scratch); |
duke@435 | 2026 | __ breakpoint_trap(Assembler::equal); |
duke@435 | 2027 | } |
duke@435 | 2028 | #endif // not PRODUCT |
duke@435 | 2029 | #endif // !CC_INTERP |