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