Mon, 12 Mar 2012 15:28:07 -0700
7152957: VM crashes with assert(false) failed: bad AD file
Reviewed-by: kvn, never
Contributed-by: nils.eliasson@oracle.com
duke@435 | 1 | /* |
iveresov@2438 | 2 | * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
trims@1907 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
trims@1907 | 20 | * or visit www.oracle.com if you need additional information or have any |
trims@1907 | 21 | * questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
stefank@2314 | 25 | #include "precompiled.hpp" |
stefank@2314 | 26 | #include "interp_masm_sparc.hpp" |
stefank@2314 | 27 | #include "interpreter/interpreter.hpp" |
stefank@2314 | 28 | #include "interpreter/interpreterRuntime.hpp" |
stefank@2314 | 29 | #include "oops/arrayOop.hpp" |
stefank@2314 | 30 | #include "oops/markOop.hpp" |
stefank@2314 | 31 | #include "oops/methodDataOop.hpp" |
stefank@2314 | 32 | #include "oops/methodOop.hpp" |
stefank@2314 | 33 | #include "prims/jvmtiExport.hpp" |
stefank@2314 | 34 | #include "prims/jvmtiRedefineClassesTrace.hpp" |
stefank@2314 | 35 | #include "prims/jvmtiThreadState.hpp" |
stefank@2314 | 36 | #include "runtime/basicLock.hpp" |
stefank@2314 | 37 | #include "runtime/biasedLocking.hpp" |
stefank@2314 | 38 | #include "runtime/sharedRuntime.hpp" |
stefank@2314 | 39 | #ifdef TARGET_OS_FAMILY_linux |
stefank@2314 | 40 | # include "thread_linux.inline.hpp" |
stefank@2314 | 41 | #endif |
stefank@2314 | 42 | #ifdef TARGET_OS_FAMILY_solaris |
stefank@2314 | 43 | # include "thread_solaris.inline.hpp" |
stefank@2314 | 44 | #endif |
duke@435 | 45 | |
duke@435 | 46 | #ifndef CC_INTERP |
duke@435 | 47 | #ifndef FAST_DISPATCH |
duke@435 | 48 | #define FAST_DISPATCH 1 |
duke@435 | 49 | #endif |
duke@435 | 50 | #undef FAST_DISPATCH |
duke@435 | 51 | |
duke@435 | 52 | // Implementation of InterpreterMacroAssembler |
duke@435 | 53 | |
duke@435 | 54 | // This file specializes the assember with interpreter-specific macros |
duke@435 | 55 | |
twisti@1162 | 56 | const Address InterpreterMacroAssembler::l_tmp(FP, (frame::interpreter_frame_l_scratch_fp_offset * wordSize) + STACK_BIAS); |
twisti@1162 | 57 | const Address InterpreterMacroAssembler::d_tmp(FP, (frame::interpreter_frame_d_scratch_fp_offset * wordSize) + STACK_BIAS); |
duke@435 | 58 | |
duke@435 | 59 | #else // CC_INTERP |
duke@435 | 60 | #ifndef STATE |
duke@435 | 61 | #define STATE(field_name) Lstate, in_bytes(byte_offset_of(BytecodeInterpreter, field_name)) |
duke@435 | 62 | #endif // STATE |
duke@435 | 63 | |
duke@435 | 64 | #endif // CC_INTERP |
duke@435 | 65 | |
duke@435 | 66 | void InterpreterMacroAssembler::compute_extra_locals_size_in_bytes(Register args_size, Register locals_size, Register delta) { |
duke@435 | 67 | // Note: this algorithm is also used by C1's OSR entry sequence. |
duke@435 | 68 | // Any changes should also be applied to CodeEmitter::emit_osr_entry(). |
duke@435 | 69 | assert_different_registers(args_size, locals_size); |
duke@435 | 70 | // max_locals*2 for TAGS. Assumes that args_size has already been adjusted. |
duke@435 | 71 | subcc(locals_size, args_size, delta);// extra space for non-arguments locals in words |
duke@435 | 72 | // Use br/mov combination because it works on both V8 and V9 and is |
duke@435 | 73 | // faster. |
duke@435 | 74 | Label skip_move; |
duke@435 | 75 | br(Assembler::negative, true, Assembler::pt, skip_move); |
duke@435 | 76 | delayed()->mov(G0, delta); |
duke@435 | 77 | bind(skip_move); |
duke@435 | 78 | round_to(delta, WordsPerLong); // make multiple of 2 (SP must be 2-word aligned) |
duke@435 | 79 | sll(delta, LogBytesPerWord, delta); // extra space for locals in bytes |
duke@435 | 80 | } |
duke@435 | 81 | |
duke@435 | 82 | #ifndef CC_INTERP |
duke@435 | 83 | |
duke@435 | 84 | // Dispatch code executed in the prolog of a bytecode which does not do it's |
duke@435 | 85 | // own dispatch. The dispatch address is computed and placed in IdispatchAddress |
duke@435 | 86 | void InterpreterMacroAssembler::dispatch_prolog(TosState state, int bcp_incr) { |
duke@435 | 87 | assert_not_delayed(); |
duke@435 | 88 | #ifdef FAST_DISPATCH |
duke@435 | 89 | // FAST_DISPATCH and ProfileInterpreter are mutually exclusive since |
duke@435 | 90 | // they both use I2. |
duke@435 | 91 | assert(!ProfileInterpreter, "FAST_DISPATCH and +ProfileInterpreter are mutually exclusive"); |
duke@435 | 92 | ldub(Lbcp, bcp_incr, Lbyte_code); // load next bytecode |
duke@435 | 93 | add(Lbyte_code, Interpreter::distance_from_dispatch_table(state), Lbyte_code); |
duke@435 | 94 | // add offset to correct dispatch table |
duke@435 | 95 | sll(Lbyte_code, LogBytesPerWord, Lbyte_code); // multiply by wordSize |
duke@435 | 96 | ld_ptr(IdispatchTables, Lbyte_code, IdispatchAddress);// get entry addr |
duke@435 | 97 | #else |
twisti@1162 | 98 | ldub( Lbcp, bcp_incr, Lbyte_code); // load next bytecode |
duke@435 | 99 | // dispatch table to use |
twisti@1162 | 100 | AddressLiteral tbl(Interpreter::dispatch_table(state)); |
twisti@1162 | 101 | sll(Lbyte_code, LogBytesPerWord, Lbyte_code); // multiply by wordSize |
twisti@1162 | 102 | set(tbl, G3_scratch); // compute addr of table |
twisti@1162 | 103 | ld_ptr(G3_scratch, Lbyte_code, IdispatchAddress); // get entry addr |
duke@435 | 104 | #endif |
duke@435 | 105 | } |
duke@435 | 106 | |
duke@435 | 107 | |
duke@435 | 108 | // Dispatch code executed in the epilog of a bytecode which does not do it's |
duke@435 | 109 | // own dispatch. The dispatch address in IdispatchAddress is used for the |
duke@435 | 110 | // dispatch. |
duke@435 | 111 | void InterpreterMacroAssembler::dispatch_epilog(TosState state, int bcp_incr) { |
duke@435 | 112 | assert_not_delayed(); |
duke@435 | 113 | verify_FPU(1, state); |
duke@435 | 114 | interp_verify_oop(Otos_i, state, __FILE__, __LINE__); |
duke@435 | 115 | jmp( IdispatchAddress, 0 ); |
duke@435 | 116 | if (bcp_incr != 0) delayed()->inc(Lbcp, bcp_incr); |
duke@435 | 117 | else delayed()->nop(); |
duke@435 | 118 | } |
duke@435 | 119 | |
duke@435 | 120 | |
duke@435 | 121 | void InterpreterMacroAssembler::dispatch_next(TosState state, int bcp_incr) { |
duke@435 | 122 | // %%%% consider branching to a single shared dispatch stub (for each bcp_incr) |
duke@435 | 123 | assert_not_delayed(); |
duke@435 | 124 | ldub( Lbcp, bcp_incr, Lbyte_code); // load next bytecode |
duke@435 | 125 | dispatch_Lbyte_code(state, Interpreter::dispatch_table(state), bcp_incr); |
duke@435 | 126 | } |
duke@435 | 127 | |
duke@435 | 128 | |
duke@435 | 129 | void InterpreterMacroAssembler::dispatch_next_noverify_oop(TosState state, int bcp_incr) { |
duke@435 | 130 | // %%%% consider branching to a single shared dispatch stub (for each bcp_incr) |
duke@435 | 131 | assert_not_delayed(); |
duke@435 | 132 | ldub( Lbcp, bcp_incr, Lbyte_code); // load next bytecode |
duke@435 | 133 | dispatch_Lbyte_code(state, Interpreter::dispatch_table(state), bcp_incr, false); |
duke@435 | 134 | } |
duke@435 | 135 | |
duke@435 | 136 | |
duke@435 | 137 | void InterpreterMacroAssembler::dispatch_via(TosState state, address* table) { |
duke@435 | 138 | // load current bytecode |
duke@435 | 139 | assert_not_delayed(); |
duke@435 | 140 | ldub( Lbcp, 0, Lbyte_code); // load next bytecode |
duke@435 | 141 | dispatch_base(state, table); |
duke@435 | 142 | } |
duke@435 | 143 | |
duke@435 | 144 | |
duke@435 | 145 | void InterpreterMacroAssembler::call_VM_leaf_base( |
duke@435 | 146 | Register java_thread, |
duke@435 | 147 | address entry_point, |
duke@435 | 148 | int number_of_arguments |
duke@435 | 149 | ) { |
duke@435 | 150 | if (!java_thread->is_valid()) |
duke@435 | 151 | java_thread = L7_thread_cache; |
duke@435 | 152 | // super call |
duke@435 | 153 | MacroAssembler::call_VM_leaf_base(java_thread, entry_point, number_of_arguments); |
duke@435 | 154 | } |
duke@435 | 155 | |
duke@435 | 156 | |
duke@435 | 157 | void InterpreterMacroAssembler::call_VM_base( |
duke@435 | 158 | Register oop_result, |
duke@435 | 159 | Register java_thread, |
duke@435 | 160 | Register last_java_sp, |
duke@435 | 161 | address entry_point, |
duke@435 | 162 | int number_of_arguments, |
duke@435 | 163 | bool check_exception |
duke@435 | 164 | ) { |
duke@435 | 165 | if (!java_thread->is_valid()) |
duke@435 | 166 | java_thread = L7_thread_cache; |
duke@435 | 167 | // See class ThreadInVMfromInterpreter, which assumes that the interpreter |
duke@435 | 168 | // takes responsibility for setting its own thread-state on call-out. |
duke@435 | 169 | // However, ThreadInVMfromInterpreter resets the state to "in_Java". |
duke@435 | 170 | |
duke@435 | 171 | //save_bcp(); // save bcp |
duke@435 | 172 | MacroAssembler::call_VM_base(oop_result, java_thread, last_java_sp, entry_point, number_of_arguments, check_exception); |
duke@435 | 173 | //restore_bcp(); // restore bcp |
duke@435 | 174 | //restore_locals(); // restore locals pointer |
duke@435 | 175 | } |
duke@435 | 176 | |
duke@435 | 177 | |
duke@435 | 178 | void InterpreterMacroAssembler::check_and_handle_popframe(Register scratch_reg) { |
duke@435 | 179 | if (JvmtiExport::can_pop_frame()) { |
duke@435 | 180 | Label L; |
duke@435 | 181 | |
duke@435 | 182 | // Check the "pending popframe condition" flag in the current thread |
twisti@1162 | 183 | ld(G2_thread, JavaThread::popframe_condition_offset(), scratch_reg); |
duke@435 | 184 | |
duke@435 | 185 | // Initiate popframe handling only if it is not already being processed. If the flag |
duke@435 | 186 | // has the popframe_processing bit set, it means that this code is called *during* popframe |
duke@435 | 187 | // handling - we don't want to reenter. |
duke@435 | 188 | btst(JavaThread::popframe_pending_bit, scratch_reg); |
duke@435 | 189 | br(zero, false, pt, L); |
duke@435 | 190 | delayed()->nop(); |
duke@435 | 191 | btst(JavaThread::popframe_processing_bit, scratch_reg); |
duke@435 | 192 | br(notZero, false, pt, L); |
duke@435 | 193 | delayed()->nop(); |
duke@435 | 194 | |
duke@435 | 195 | // Call Interpreter::remove_activation_preserving_args_entry() to get the |
duke@435 | 196 | // address of the same-named entrypoint in the generated interpreter code. |
duke@435 | 197 | call_VM_leaf(noreg, CAST_FROM_FN_PTR(address, Interpreter::remove_activation_preserving_args_entry)); |
duke@435 | 198 | |
duke@435 | 199 | // Jump to Interpreter::_remove_activation_preserving_args_entry |
duke@435 | 200 | jmpl(O0, G0, G0); |
duke@435 | 201 | delayed()->nop(); |
duke@435 | 202 | bind(L); |
duke@435 | 203 | } |
duke@435 | 204 | } |
duke@435 | 205 | |
duke@435 | 206 | |
duke@435 | 207 | void InterpreterMacroAssembler::load_earlyret_value(TosState state) { |
duke@435 | 208 | Register thr_state = G4_scratch; |
twisti@1162 | 209 | ld_ptr(G2_thread, JavaThread::jvmti_thread_state_offset(), thr_state); |
twisti@1162 | 210 | const Address tos_addr(thr_state, JvmtiThreadState::earlyret_tos_offset()); |
twisti@1162 | 211 | const Address oop_addr(thr_state, JvmtiThreadState::earlyret_oop_offset()); |
twisti@1162 | 212 | const Address val_addr(thr_state, JvmtiThreadState::earlyret_value_offset()); |
duke@435 | 213 | switch (state) { |
duke@435 | 214 | case ltos: ld_long(val_addr, Otos_l); break; |
duke@435 | 215 | case atos: ld_ptr(oop_addr, Otos_l); |
duke@435 | 216 | st_ptr(G0, oop_addr); break; |
duke@435 | 217 | case btos: // fall through |
duke@435 | 218 | case ctos: // fall through |
duke@435 | 219 | case stos: // fall through |
duke@435 | 220 | case itos: ld(val_addr, Otos_l1); break; |
duke@435 | 221 | case ftos: ldf(FloatRegisterImpl::S, val_addr, Ftos_f); break; |
duke@435 | 222 | case dtos: ldf(FloatRegisterImpl::D, val_addr, Ftos_d); break; |
duke@435 | 223 | case vtos: /* nothing to do */ break; |
duke@435 | 224 | default : ShouldNotReachHere(); |
duke@435 | 225 | } |
duke@435 | 226 | // Clean up tos value in the jvmti thread state |
duke@435 | 227 | or3(G0, ilgl, G3_scratch); |
duke@435 | 228 | stw(G3_scratch, tos_addr); |
duke@435 | 229 | st_long(G0, val_addr); |
duke@435 | 230 | interp_verify_oop(Otos_i, state, __FILE__, __LINE__); |
duke@435 | 231 | } |
duke@435 | 232 | |
duke@435 | 233 | |
duke@435 | 234 | void InterpreterMacroAssembler::check_and_handle_earlyret(Register scratch_reg) { |
duke@435 | 235 | if (JvmtiExport::can_force_early_return()) { |
duke@435 | 236 | Label L; |
duke@435 | 237 | Register thr_state = G3_scratch; |
twisti@1162 | 238 | ld_ptr(G2_thread, JavaThread::jvmti_thread_state_offset(), thr_state); |
kvn@3037 | 239 | br_null_short(thr_state, pt, L); // if (thread->jvmti_thread_state() == NULL) exit; |
duke@435 | 240 | |
duke@435 | 241 | // Initiate earlyret handling only if it is not already being processed. |
duke@435 | 242 | // If the flag has the earlyret_processing bit set, it means that this code |
duke@435 | 243 | // is called *during* earlyret handling - we don't want to reenter. |
twisti@1162 | 244 | ld(thr_state, JvmtiThreadState::earlyret_state_offset(), G4_scratch); |
kvn@3037 | 245 | cmp_and_br_short(G4_scratch, JvmtiThreadState::earlyret_pending, Assembler::notEqual, pt, L); |
duke@435 | 246 | |
duke@435 | 247 | // Call Interpreter::remove_activation_early_entry() to get the address of the |
duke@435 | 248 | // same-named entrypoint in the generated interpreter code |
twisti@1162 | 249 | ld(thr_state, JvmtiThreadState::earlyret_tos_offset(), Otos_l1); |
duke@435 | 250 | call_VM_leaf(noreg, CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), Otos_l1); |
duke@435 | 251 | |
duke@435 | 252 | // Jump to Interpreter::_remove_activation_early_entry |
duke@435 | 253 | jmpl(O0, G0, G0); |
duke@435 | 254 | delayed()->nop(); |
duke@435 | 255 | bind(L); |
duke@435 | 256 | } |
duke@435 | 257 | } |
duke@435 | 258 | |
duke@435 | 259 | |
twisti@1730 | 260 | void InterpreterMacroAssembler::super_call_VM_leaf(Register thread_cache, address entry_point, Register arg_1, Register arg_2) { |
duke@435 | 261 | mov(arg_1, O0); |
twisti@1730 | 262 | mov(arg_2, O1); |
twisti@1730 | 263 | MacroAssembler::call_VM_leaf_base(thread_cache, entry_point, 2); |
duke@435 | 264 | } |
duke@435 | 265 | #endif /* CC_INTERP */ |
duke@435 | 266 | |
duke@435 | 267 | |
duke@435 | 268 | #ifndef CC_INTERP |
duke@435 | 269 | |
duke@435 | 270 | void InterpreterMacroAssembler::dispatch_base(TosState state, address* table) { |
duke@435 | 271 | assert_not_delayed(); |
duke@435 | 272 | dispatch_Lbyte_code(state, table); |
duke@435 | 273 | } |
duke@435 | 274 | |
duke@435 | 275 | |
duke@435 | 276 | void InterpreterMacroAssembler::dispatch_normal(TosState state) { |
duke@435 | 277 | dispatch_base(state, Interpreter::normal_table(state)); |
duke@435 | 278 | } |
duke@435 | 279 | |
duke@435 | 280 | |
duke@435 | 281 | void InterpreterMacroAssembler::dispatch_only(TosState state) { |
duke@435 | 282 | dispatch_base(state, Interpreter::dispatch_table(state)); |
duke@435 | 283 | } |
duke@435 | 284 | |
duke@435 | 285 | |
duke@435 | 286 | // common code to dispatch and dispatch_only |
duke@435 | 287 | // dispatch value in Lbyte_code and increment Lbcp |
duke@435 | 288 | |
duke@435 | 289 | void InterpreterMacroAssembler::dispatch_Lbyte_code(TosState state, address* table, int bcp_incr, bool verify) { |
duke@435 | 290 | verify_FPU(1, state); |
duke@435 | 291 | // %%%%% maybe implement +VerifyActivationFrameSize here |
duke@435 | 292 | //verify_thread(); //too slow; we will just verify on method entry & exit |
duke@435 | 293 | if (verify) interp_verify_oop(Otos_i, state, __FILE__, __LINE__); |
duke@435 | 294 | #ifdef FAST_DISPATCH |
duke@435 | 295 | if (table == Interpreter::dispatch_table(state)) { |
duke@435 | 296 | // use IdispatchTables |
duke@435 | 297 | add(Lbyte_code, Interpreter::distance_from_dispatch_table(state), Lbyte_code); |
duke@435 | 298 | // add offset to correct dispatch table |
duke@435 | 299 | sll(Lbyte_code, LogBytesPerWord, Lbyte_code); // multiply by wordSize |
duke@435 | 300 | ld_ptr(IdispatchTables, Lbyte_code, G3_scratch); // get entry addr |
duke@435 | 301 | } else { |
duke@435 | 302 | #endif |
duke@435 | 303 | // dispatch table to use |
twisti@1162 | 304 | AddressLiteral tbl(table); |
duke@435 | 305 | sll(Lbyte_code, LogBytesPerWord, Lbyte_code); // multiply by wordSize |
twisti@1162 | 306 | set(tbl, G3_scratch); // compute addr of table |
duke@435 | 307 | ld_ptr(G3_scratch, Lbyte_code, G3_scratch); // get entry addr |
duke@435 | 308 | #ifdef FAST_DISPATCH |
duke@435 | 309 | } |
duke@435 | 310 | #endif |
duke@435 | 311 | jmp( G3_scratch, 0 ); |
duke@435 | 312 | if (bcp_incr != 0) delayed()->inc(Lbcp, bcp_incr); |
duke@435 | 313 | else delayed()->nop(); |
duke@435 | 314 | } |
duke@435 | 315 | |
duke@435 | 316 | |
duke@435 | 317 | // Helpers for expression stack |
duke@435 | 318 | |
duke@435 | 319 | // Longs and doubles are Category 2 computational types in the |
duke@435 | 320 | // JVM specification (section 3.11.1) and take 2 expression stack or |
duke@435 | 321 | // local slots. |
duke@435 | 322 | // Aligning them on 32 bit with tagged stacks is hard because the code generated |
duke@435 | 323 | // for the dup* bytecodes depends on what types are already on the stack. |
duke@435 | 324 | // If the types are split into the two stack/local slots, that is much easier |
duke@435 | 325 | // (and we can use 0 for non-reference tags). |
duke@435 | 326 | |
duke@435 | 327 | // Known good alignment in _LP64 but unknown otherwise |
duke@435 | 328 | void InterpreterMacroAssembler::load_unaligned_double(Register r1, int offset, FloatRegister d) { |
duke@435 | 329 | assert_not_delayed(); |
duke@435 | 330 | |
duke@435 | 331 | #ifdef _LP64 |
duke@435 | 332 | ldf(FloatRegisterImpl::D, r1, offset, d); |
duke@435 | 333 | #else |
duke@435 | 334 | ldf(FloatRegisterImpl::S, r1, offset, d); |
twisti@1861 | 335 | ldf(FloatRegisterImpl::S, r1, offset + Interpreter::stackElementSize, d->successor()); |
duke@435 | 336 | #endif |
duke@435 | 337 | } |
duke@435 | 338 | |
duke@435 | 339 | // Known good alignment in _LP64 but unknown otherwise |
duke@435 | 340 | void InterpreterMacroAssembler::store_unaligned_double(FloatRegister d, Register r1, int offset) { |
duke@435 | 341 | assert_not_delayed(); |
duke@435 | 342 | |
duke@435 | 343 | #ifdef _LP64 |
duke@435 | 344 | stf(FloatRegisterImpl::D, d, r1, offset); |
duke@435 | 345 | // store something more useful here |
twisti@1861 | 346 | debug_only(stx(G0, r1, offset+Interpreter::stackElementSize);) |
duke@435 | 347 | #else |
duke@435 | 348 | stf(FloatRegisterImpl::S, d, r1, offset); |
twisti@1861 | 349 | stf(FloatRegisterImpl::S, d->successor(), r1, offset + Interpreter::stackElementSize); |
duke@435 | 350 | #endif |
duke@435 | 351 | } |
duke@435 | 352 | |
duke@435 | 353 | |
duke@435 | 354 | // Known good alignment in _LP64 but unknown otherwise |
duke@435 | 355 | void InterpreterMacroAssembler::load_unaligned_long(Register r1, int offset, Register rd) { |
duke@435 | 356 | assert_not_delayed(); |
duke@435 | 357 | #ifdef _LP64 |
duke@435 | 358 | ldx(r1, offset, rd); |
duke@435 | 359 | #else |
duke@435 | 360 | ld(r1, offset, rd); |
twisti@1861 | 361 | ld(r1, offset + Interpreter::stackElementSize, rd->successor()); |
duke@435 | 362 | #endif |
duke@435 | 363 | } |
duke@435 | 364 | |
duke@435 | 365 | // Known good alignment in _LP64 but unknown otherwise |
duke@435 | 366 | void InterpreterMacroAssembler::store_unaligned_long(Register l, Register r1, int offset) { |
duke@435 | 367 | assert_not_delayed(); |
duke@435 | 368 | |
duke@435 | 369 | #ifdef _LP64 |
duke@435 | 370 | stx(l, r1, offset); |
duke@435 | 371 | // store something more useful here |
twisti@1861 | 372 | debug_only(stx(G0, r1, offset+Interpreter::stackElementSize);) |
duke@435 | 373 | #else |
duke@435 | 374 | st(l, r1, offset); |
twisti@1861 | 375 | st(l->successor(), r1, offset + Interpreter::stackElementSize); |
duke@435 | 376 | #endif |
duke@435 | 377 | } |
duke@435 | 378 | |
duke@435 | 379 | void InterpreterMacroAssembler::pop_i(Register r) { |
duke@435 | 380 | assert_not_delayed(); |
duke@435 | 381 | ld(Lesp, Interpreter::expr_offset_in_bytes(0), r); |
twisti@1861 | 382 | inc(Lesp, Interpreter::stackElementSize); |
duke@435 | 383 | debug_only(verify_esp(Lesp)); |
duke@435 | 384 | } |
duke@435 | 385 | |
duke@435 | 386 | void InterpreterMacroAssembler::pop_ptr(Register r, Register scratch) { |
duke@435 | 387 | assert_not_delayed(); |
duke@435 | 388 | ld_ptr(Lesp, Interpreter::expr_offset_in_bytes(0), r); |
twisti@1861 | 389 | inc(Lesp, Interpreter::stackElementSize); |
duke@435 | 390 | debug_only(verify_esp(Lesp)); |
duke@435 | 391 | } |
duke@435 | 392 | |
duke@435 | 393 | void InterpreterMacroAssembler::pop_l(Register r) { |
duke@435 | 394 | assert_not_delayed(); |
duke@435 | 395 | load_unaligned_long(Lesp, Interpreter::expr_offset_in_bytes(0), r); |
twisti@1861 | 396 | inc(Lesp, 2*Interpreter::stackElementSize); |
duke@435 | 397 | debug_only(verify_esp(Lesp)); |
duke@435 | 398 | } |
duke@435 | 399 | |
duke@435 | 400 | |
duke@435 | 401 | void InterpreterMacroAssembler::pop_f(FloatRegister f, Register scratch) { |
duke@435 | 402 | assert_not_delayed(); |
duke@435 | 403 | ldf(FloatRegisterImpl::S, Lesp, Interpreter::expr_offset_in_bytes(0), f); |
twisti@1861 | 404 | inc(Lesp, Interpreter::stackElementSize); |
duke@435 | 405 | debug_only(verify_esp(Lesp)); |
duke@435 | 406 | } |
duke@435 | 407 | |
duke@435 | 408 | |
duke@435 | 409 | void InterpreterMacroAssembler::pop_d(FloatRegister f, Register scratch) { |
duke@435 | 410 | assert_not_delayed(); |
duke@435 | 411 | load_unaligned_double(Lesp, Interpreter::expr_offset_in_bytes(0), f); |
twisti@1861 | 412 | inc(Lesp, 2*Interpreter::stackElementSize); |
duke@435 | 413 | debug_only(verify_esp(Lesp)); |
duke@435 | 414 | } |
duke@435 | 415 | |
duke@435 | 416 | |
duke@435 | 417 | void InterpreterMacroAssembler::push_i(Register r) { |
duke@435 | 418 | assert_not_delayed(); |
duke@435 | 419 | debug_only(verify_esp(Lesp)); |
twisti@1861 | 420 | st(r, Lesp, 0); |
twisti@1861 | 421 | dec(Lesp, Interpreter::stackElementSize); |
duke@435 | 422 | } |
duke@435 | 423 | |
duke@435 | 424 | void InterpreterMacroAssembler::push_ptr(Register r) { |
duke@435 | 425 | assert_not_delayed(); |
twisti@1861 | 426 | st_ptr(r, Lesp, 0); |
twisti@1861 | 427 | dec(Lesp, Interpreter::stackElementSize); |
duke@435 | 428 | } |
duke@435 | 429 | |
duke@435 | 430 | // remember: our convention for longs in SPARC is: |
duke@435 | 431 | // O0 (Otos_l1) has high-order part in first word, |
duke@435 | 432 | // O1 (Otos_l2) has low-order part in second word |
duke@435 | 433 | |
duke@435 | 434 | void InterpreterMacroAssembler::push_l(Register r) { |
duke@435 | 435 | assert_not_delayed(); |
duke@435 | 436 | debug_only(verify_esp(Lesp)); |
twisti@1861 | 437 | // Longs are stored in memory-correct order, even if unaligned. |
twisti@1861 | 438 | int offset = -Interpreter::stackElementSize; |
duke@435 | 439 | store_unaligned_long(r, Lesp, offset); |
twisti@1861 | 440 | dec(Lesp, 2 * Interpreter::stackElementSize); |
duke@435 | 441 | } |
duke@435 | 442 | |
duke@435 | 443 | |
duke@435 | 444 | void InterpreterMacroAssembler::push_f(FloatRegister f) { |
duke@435 | 445 | assert_not_delayed(); |
duke@435 | 446 | debug_only(verify_esp(Lesp)); |
twisti@1861 | 447 | stf(FloatRegisterImpl::S, f, Lesp, 0); |
twisti@1861 | 448 | dec(Lesp, Interpreter::stackElementSize); |
duke@435 | 449 | } |
duke@435 | 450 | |
duke@435 | 451 | |
duke@435 | 452 | void InterpreterMacroAssembler::push_d(FloatRegister d) { |
duke@435 | 453 | assert_not_delayed(); |
duke@435 | 454 | debug_only(verify_esp(Lesp)); |
twisti@1861 | 455 | // Longs are stored in memory-correct order, even if unaligned. |
twisti@1861 | 456 | int offset = -Interpreter::stackElementSize; |
duke@435 | 457 | store_unaligned_double(d, Lesp, offset); |
twisti@1861 | 458 | dec(Lesp, 2 * Interpreter::stackElementSize); |
duke@435 | 459 | } |
duke@435 | 460 | |
duke@435 | 461 | |
duke@435 | 462 | void InterpreterMacroAssembler::push(TosState state) { |
duke@435 | 463 | interp_verify_oop(Otos_i, state, __FILE__, __LINE__); |
duke@435 | 464 | switch (state) { |
duke@435 | 465 | case atos: push_ptr(); break; |
duke@435 | 466 | case btos: push_i(); break; |
duke@435 | 467 | case ctos: |
duke@435 | 468 | case stos: push_i(); break; |
duke@435 | 469 | case itos: push_i(); break; |
duke@435 | 470 | case ltos: push_l(); break; |
duke@435 | 471 | case ftos: push_f(); break; |
duke@435 | 472 | case dtos: push_d(); break; |
duke@435 | 473 | case vtos: /* nothing to do */ break; |
duke@435 | 474 | default : ShouldNotReachHere(); |
duke@435 | 475 | } |
duke@435 | 476 | } |
duke@435 | 477 | |
duke@435 | 478 | |
duke@435 | 479 | void InterpreterMacroAssembler::pop(TosState state) { |
duke@435 | 480 | switch (state) { |
duke@435 | 481 | case atos: pop_ptr(); break; |
duke@435 | 482 | case btos: pop_i(); break; |
duke@435 | 483 | case ctos: |
duke@435 | 484 | case stos: pop_i(); break; |
duke@435 | 485 | case itos: pop_i(); break; |
duke@435 | 486 | case ltos: pop_l(); break; |
duke@435 | 487 | case ftos: pop_f(); break; |
duke@435 | 488 | case dtos: pop_d(); break; |
duke@435 | 489 | case vtos: /* nothing to do */ break; |
duke@435 | 490 | default : ShouldNotReachHere(); |
duke@435 | 491 | } |
duke@435 | 492 | interp_verify_oop(Otos_i, state, __FILE__, __LINE__); |
duke@435 | 493 | } |
duke@435 | 494 | |
duke@435 | 495 | |
twisti@1861 | 496 | // Helpers for swap and dup |
twisti@1861 | 497 | void InterpreterMacroAssembler::load_ptr(int n, Register val) { |
duke@435 | 498 | ld_ptr(Lesp, Interpreter::expr_offset_in_bytes(n), val); |
duke@435 | 499 | } |
twisti@1861 | 500 | void InterpreterMacroAssembler::store_ptr(int n, Register val) { |
duke@435 | 501 | st_ptr(val, Lesp, Interpreter::expr_offset_in_bytes(n)); |
duke@435 | 502 | } |
duke@435 | 503 | |
duke@435 | 504 | |
duke@435 | 505 | void InterpreterMacroAssembler::load_receiver(Register param_count, |
duke@435 | 506 | Register recv) { |
twisti@1861 | 507 | sll(param_count, Interpreter::logStackElementSize, param_count); |
duke@435 | 508 | ld_ptr(Lesp, param_count, recv); // gets receiver Oop |
duke@435 | 509 | } |
duke@435 | 510 | |
duke@435 | 511 | void InterpreterMacroAssembler::empty_expression_stack() { |
duke@435 | 512 | // Reset Lesp. |
duke@435 | 513 | sub( Lmonitors, wordSize, Lesp ); |
duke@435 | 514 | |
duke@435 | 515 | // Reset SP by subtracting more space from Lesp. |
duke@435 | 516 | Label done; |
duke@435 | 517 | verify_oop(Lmethod); |
twisti@1162 | 518 | assert(G4_scratch != Gframe_size, "Only you can prevent register aliasing!"); |
duke@435 | 519 | |
duke@435 | 520 | // A native does not need to do this, since its callee does not change SP. |
twisti@1162 | 521 | ld(Lmethod, methodOopDesc::access_flags_offset(), Gframe_size); // Load access flags. |
duke@435 | 522 | btst(JVM_ACC_NATIVE, Gframe_size); |
duke@435 | 523 | br(Assembler::notZero, false, Assembler::pt, done); |
duke@435 | 524 | delayed()->nop(); |
duke@435 | 525 | |
duke@435 | 526 | // Compute max expression stack+register save area |
twisti@1162 | 527 | lduh(Lmethod, in_bytes(methodOopDesc::max_stack_offset()), Gframe_size); // Load max stack. |
duke@435 | 528 | add( Gframe_size, frame::memory_parameter_word_sp_offset, Gframe_size ); |
duke@435 | 529 | |
duke@435 | 530 | // |
duke@435 | 531 | // now set up a stack frame with the size computed above |
duke@435 | 532 | // |
duke@435 | 533 | //round_to( Gframe_size, WordsPerLong ); // -- moved down to the "and" below |
duke@435 | 534 | sll( Gframe_size, LogBytesPerWord, Gframe_size ); |
duke@435 | 535 | sub( Lesp, Gframe_size, Gframe_size ); |
duke@435 | 536 | and3( Gframe_size, -(2 * wordSize), Gframe_size ); // align SP (downwards) to an 8/16-byte boundary |
duke@435 | 537 | debug_only(verify_sp(Gframe_size, G4_scratch)); |
duke@435 | 538 | #ifdef _LP64 |
duke@435 | 539 | sub(Gframe_size, STACK_BIAS, Gframe_size ); |
duke@435 | 540 | #endif |
duke@435 | 541 | mov(Gframe_size, SP); |
duke@435 | 542 | |
duke@435 | 543 | bind(done); |
duke@435 | 544 | } |
duke@435 | 545 | |
duke@435 | 546 | |
duke@435 | 547 | #ifdef ASSERT |
duke@435 | 548 | void InterpreterMacroAssembler::verify_sp(Register Rsp, Register Rtemp) { |
duke@435 | 549 | Label Bad, OK; |
duke@435 | 550 | |
duke@435 | 551 | // Saved SP must be aligned. |
duke@435 | 552 | #ifdef _LP64 |
duke@435 | 553 | btst(2*BytesPerWord-1, Rsp); |
duke@435 | 554 | #else |
duke@435 | 555 | btst(LongAlignmentMask, Rsp); |
duke@435 | 556 | #endif |
duke@435 | 557 | br(Assembler::notZero, false, Assembler::pn, Bad); |
duke@435 | 558 | delayed()->nop(); |
duke@435 | 559 | |
duke@435 | 560 | // Saved SP, plus register window size, must not be above FP. |
duke@435 | 561 | add(Rsp, frame::register_save_words * wordSize, Rtemp); |
duke@435 | 562 | #ifdef _LP64 |
duke@435 | 563 | sub(Rtemp, STACK_BIAS, Rtemp); // Bias Rtemp before cmp to FP |
duke@435 | 564 | #endif |
kvn@3037 | 565 | cmp_and_brx_short(Rtemp, FP, Assembler::greaterUnsigned, Assembler::pn, Bad); |
duke@435 | 566 | |
duke@435 | 567 | // Saved SP must not be ridiculously below current SP. |
duke@435 | 568 | size_t maxstack = MAX2(JavaThread::stack_size_at_create(), (size_t) 4*K*K); |
duke@435 | 569 | set(maxstack, Rtemp); |
duke@435 | 570 | sub(SP, Rtemp, Rtemp); |
duke@435 | 571 | #ifdef _LP64 |
duke@435 | 572 | add(Rtemp, STACK_BIAS, Rtemp); // Unbias Rtemp before cmp to Rsp |
duke@435 | 573 | #endif |
kvn@3037 | 574 | cmp_and_brx_short(Rsp, Rtemp, Assembler::lessUnsigned, Assembler::pn, Bad); |
kvn@3037 | 575 | |
kvn@3037 | 576 | ba_short(OK); |
duke@435 | 577 | |
duke@435 | 578 | bind(Bad); |
duke@435 | 579 | stop("on return to interpreted call, restored SP is corrupted"); |
duke@435 | 580 | |
duke@435 | 581 | bind(OK); |
duke@435 | 582 | } |
duke@435 | 583 | |
duke@435 | 584 | |
duke@435 | 585 | void InterpreterMacroAssembler::verify_esp(Register Resp) { |
duke@435 | 586 | // about to read or write Resp[0] |
duke@435 | 587 | // make sure it is not in the monitors or the register save area |
duke@435 | 588 | Label OK1, OK2; |
duke@435 | 589 | |
duke@435 | 590 | cmp(Resp, Lmonitors); |
duke@435 | 591 | brx(Assembler::lessUnsigned, true, Assembler::pt, OK1); |
duke@435 | 592 | delayed()->sub(Resp, frame::memory_parameter_word_sp_offset * wordSize, Resp); |
duke@435 | 593 | stop("too many pops: Lesp points into monitor area"); |
duke@435 | 594 | bind(OK1); |
duke@435 | 595 | #ifdef _LP64 |
duke@435 | 596 | sub(Resp, STACK_BIAS, Resp); |
duke@435 | 597 | #endif |
duke@435 | 598 | cmp(Resp, SP); |
duke@435 | 599 | brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, OK2); |
duke@435 | 600 | delayed()->add(Resp, STACK_BIAS + frame::memory_parameter_word_sp_offset * wordSize, Resp); |
duke@435 | 601 | stop("too many pushes: Lesp points into register window"); |
duke@435 | 602 | bind(OK2); |
duke@435 | 603 | } |
duke@435 | 604 | #endif // ASSERT |
duke@435 | 605 | |
duke@435 | 606 | // Load compiled (i2c) or interpreter entry when calling from interpreted and |
duke@435 | 607 | // do the call. Centralized so that all interpreter calls will do the same actions. |
duke@435 | 608 | // If jvmti single stepping is on for a thread we must not call compiled code. |
duke@435 | 609 | void InterpreterMacroAssembler::call_from_interpreter(Register target, Register scratch, Register Rret) { |
duke@435 | 610 | |
duke@435 | 611 | // Assume we want to go compiled if available |
duke@435 | 612 | |
duke@435 | 613 | ld_ptr(G5_method, in_bytes(methodOopDesc::from_interpreted_offset()), target); |
duke@435 | 614 | |
duke@435 | 615 | if (JvmtiExport::can_post_interpreter_events()) { |
duke@435 | 616 | // JVMTI events, such as single-stepping, are implemented partly by avoiding running |
duke@435 | 617 | // compiled code in threads for which the event is enabled. Check here for |
duke@435 | 618 | // interp_only_mode if these events CAN be enabled. |
duke@435 | 619 | verify_thread(); |
duke@435 | 620 | Label skip_compiled_code; |
duke@435 | 621 | |
twisti@1162 | 622 | const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset()); |
duke@435 | 623 | ld(interp_only, scratch); |
kvn@3037 | 624 | cmp_zero_and_br(Assembler::notZero, scratch, skip_compiled_code, true, Assembler::pn); |
duke@435 | 625 | delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), target); |
duke@435 | 626 | bind(skip_compiled_code); |
duke@435 | 627 | } |
duke@435 | 628 | |
duke@435 | 629 | // the i2c_adapters need methodOop in G5_method (right? %%%) |
duke@435 | 630 | // do the call |
duke@435 | 631 | #ifdef ASSERT |
duke@435 | 632 | { |
duke@435 | 633 | Label ok; |
kvn@3037 | 634 | br_notnull_short(target, Assembler::pt, ok); |
duke@435 | 635 | stop("null entry point"); |
duke@435 | 636 | bind(ok); |
duke@435 | 637 | } |
duke@435 | 638 | #endif // ASSERT |
duke@435 | 639 | |
duke@435 | 640 | // Adjust Rret first so Llast_SP can be same as Rret |
duke@435 | 641 | add(Rret, -frame::pc_return_offset, O7); |
duke@435 | 642 | add(Lesp, BytesPerWord, Gargs); // setup parameter pointer |
duke@435 | 643 | // Record SP so we can remove any stack space allocated by adapter transition |
duke@435 | 644 | jmp(target, 0); |
duke@435 | 645 | delayed()->mov(SP, Llast_SP); |
duke@435 | 646 | } |
duke@435 | 647 | |
duke@435 | 648 | void InterpreterMacroAssembler::if_cmp(Condition cc, bool ptr_compare) { |
duke@435 | 649 | assert_not_delayed(); |
duke@435 | 650 | |
duke@435 | 651 | Label not_taken; |
duke@435 | 652 | if (ptr_compare) brx(cc, false, Assembler::pn, not_taken); |
duke@435 | 653 | else br (cc, false, Assembler::pn, not_taken); |
duke@435 | 654 | delayed()->nop(); |
duke@435 | 655 | |
duke@435 | 656 | TemplateTable::branch(false,false); |
duke@435 | 657 | |
duke@435 | 658 | bind(not_taken); |
duke@435 | 659 | |
duke@435 | 660 | profile_not_taken_branch(G3_scratch); |
duke@435 | 661 | } |
duke@435 | 662 | |
duke@435 | 663 | |
duke@435 | 664 | void InterpreterMacroAssembler::get_2_byte_integer_at_bcp( |
duke@435 | 665 | int bcp_offset, |
duke@435 | 666 | Register Rtmp, |
duke@435 | 667 | Register Rdst, |
duke@435 | 668 | signedOrNot is_signed, |
duke@435 | 669 | setCCOrNot should_set_CC ) { |
duke@435 | 670 | assert(Rtmp != Rdst, "need separate temp register"); |
duke@435 | 671 | assert_not_delayed(); |
duke@435 | 672 | switch (is_signed) { |
duke@435 | 673 | default: ShouldNotReachHere(); |
duke@435 | 674 | |
duke@435 | 675 | case Signed: ldsb( Lbcp, bcp_offset, Rdst ); break; // high byte |
duke@435 | 676 | case Unsigned: ldub( Lbcp, bcp_offset, Rdst ); break; // high byte |
duke@435 | 677 | } |
duke@435 | 678 | ldub( Lbcp, bcp_offset + 1, Rtmp ); // low byte |
duke@435 | 679 | sll( Rdst, BitsPerByte, Rdst); |
duke@435 | 680 | switch (should_set_CC ) { |
duke@435 | 681 | default: ShouldNotReachHere(); |
duke@435 | 682 | |
duke@435 | 683 | case set_CC: orcc( Rdst, Rtmp, Rdst ); break; |
duke@435 | 684 | case dont_set_CC: or3( Rdst, Rtmp, Rdst ); break; |
duke@435 | 685 | } |
duke@435 | 686 | } |
duke@435 | 687 | |
duke@435 | 688 | |
duke@435 | 689 | void InterpreterMacroAssembler::get_4_byte_integer_at_bcp( |
duke@435 | 690 | int bcp_offset, |
duke@435 | 691 | Register Rtmp, |
duke@435 | 692 | Register Rdst, |
duke@435 | 693 | setCCOrNot should_set_CC ) { |
duke@435 | 694 | assert(Rtmp != Rdst, "need separate temp register"); |
duke@435 | 695 | assert_not_delayed(); |
duke@435 | 696 | add( Lbcp, bcp_offset, Rtmp); |
duke@435 | 697 | andcc( Rtmp, 3, G0); |
duke@435 | 698 | Label aligned; |
duke@435 | 699 | switch (should_set_CC ) { |
duke@435 | 700 | default: ShouldNotReachHere(); |
duke@435 | 701 | |
duke@435 | 702 | case set_CC: break; |
duke@435 | 703 | case dont_set_CC: break; |
duke@435 | 704 | } |
duke@435 | 705 | |
duke@435 | 706 | br(Assembler::zero, true, Assembler::pn, aligned); |
duke@435 | 707 | #ifdef _LP64 |
duke@435 | 708 | delayed()->ldsw(Rtmp, 0, Rdst); |
duke@435 | 709 | #else |
duke@435 | 710 | delayed()->ld(Rtmp, 0, Rdst); |
duke@435 | 711 | #endif |
duke@435 | 712 | |
duke@435 | 713 | ldub(Lbcp, bcp_offset + 3, Rdst); |
duke@435 | 714 | ldub(Lbcp, bcp_offset + 2, Rtmp); sll(Rtmp, 8, Rtmp); or3(Rtmp, Rdst, Rdst); |
duke@435 | 715 | ldub(Lbcp, bcp_offset + 1, Rtmp); sll(Rtmp, 16, Rtmp); or3(Rtmp, Rdst, Rdst); |
duke@435 | 716 | #ifdef _LP64 |
duke@435 | 717 | ldsb(Lbcp, bcp_offset + 0, Rtmp); sll(Rtmp, 24, Rtmp); |
duke@435 | 718 | #else |
duke@435 | 719 | // Unsigned load is faster than signed on some implementations |
duke@435 | 720 | ldub(Lbcp, bcp_offset + 0, Rtmp); sll(Rtmp, 24, Rtmp); |
duke@435 | 721 | #endif |
duke@435 | 722 | or3(Rtmp, Rdst, Rdst ); |
duke@435 | 723 | |
duke@435 | 724 | bind(aligned); |
duke@435 | 725 | if (should_set_CC == set_CC) tst(Rdst); |
duke@435 | 726 | } |
duke@435 | 727 | |
duke@435 | 728 | |
twisti@1858 | 729 | void InterpreterMacroAssembler::get_cache_index_at_bcp(Register cache, Register tmp, |
jrose@1920 | 730 | int bcp_offset, size_t index_size) { |
twisti@1858 | 731 | assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); |
jrose@1920 | 732 | if (index_size == sizeof(u2)) { |
twisti@1858 | 733 | get_2_byte_integer_at_bcp(bcp_offset, cache, tmp, Unsigned); |
jrose@1920 | 734 | } else if (index_size == sizeof(u4)) { |
twisti@2698 | 735 | assert(EnableInvokeDynamic, "giant index used only for JSR 292"); |
twisti@1858 | 736 | get_4_byte_integer_at_bcp(bcp_offset, cache, tmp); |
twisti@1858 | 737 | assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line"); |
twisti@1858 | 738 | xor3(tmp, -1, tmp); // convert to plain index |
jrose@1920 | 739 | } else if (index_size == sizeof(u1)) { |
twisti@2698 | 740 | assert(EnableInvokeDynamic, "tiny index used only for JSR 292"); |
jrose@1920 | 741 | ldub(Lbcp, bcp_offset, tmp); |
jrose@1920 | 742 | } else { |
jrose@1920 | 743 | ShouldNotReachHere(); |
twisti@1858 | 744 | } |
twisti@1858 | 745 | } |
twisti@1858 | 746 | |
twisti@1858 | 747 | |
twisti@1858 | 748 | void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Register tmp, |
jrose@1920 | 749 | int bcp_offset, size_t index_size) { |
duke@435 | 750 | assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); |
duke@435 | 751 | assert_different_registers(cache, tmp); |
duke@435 | 752 | assert_not_delayed(); |
jrose@1920 | 753 | get_cache_index_at_bcp(cache, tmp, bcp_offset, index_size); |
twisti@1858 | 754 | // convert from field index to ConstantPoolCacheEntry index and from |
twisti@1858 | 755 | // word index to byte offset |
duke@435 | 756 | sll(tmp, exact_log2(in_words(ConstantPoolCacheEntry::size()) * BytesPerWord), tmp); |
duke@435 | 757 | add(LcpoolCache, tmp, cache); |
duke@435 | 758 | } |
duke@435 | 759 | |
duke@435 | 760 | |
twisti@3050 | 761 | void InterpreterMacroAssembler::get_cache_and_index_and_bytecode_at_bcp(Register cache, |
twisti@3050 | 762 | Register temp, |
twisti@3050 | 763 | Register bytecode, |
twisti@3050 | 764 | int byte_no, |
twisti@3050 | 765 | int bcp_offset, |
twisti@3050 | 766 | size_t index_size) { |
twisti@3050 | 767 | get_cache_and_index_at_bcp(cache, temp, bcp_offset, index_size); |
twisti@3050 | 768 | ld_ptr(cache, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset(), bytecode); |
twisti@3050 | 769 | const int shift_count = (1 + byte_no) * BitsPerByte; |
twisti@3050 | 770 | srl( bytecode, shift_count, bytecode); |
twisti@3050 | 771 | and3(bytecode, 0xFF, bytecode); |
twisti@3050 | 772 | } |
twisti@3050 | 773 | |
twisti@3050 | 774 | |
twisti@1858 | 775 | void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, Register tmp, |
jrose@1920 | 776 | int bcp_offset, size_t index_size) { |
duke@435 | 777 | assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); |
duke@435 | 778 | assert_different_registers(cache, tmp); |
duke@435 | 779 | assert_not_delayed(); |
jrose@1920 | 780 | if (index_size == sizeof(u2)) { |
jrose@1920 | 781 | get_2_byte_integer_at_bcp(bcp_offset, cache, tmp, Unsigned); |
jrose@1920 | 782 | } else { |
jrose@1920 | 783 | ShouldNotReachHere(); // other sizes not supported here |
jrose@1920 | 784 | } |
duke@435 | 785 | // convert from field index to ConstantPoolCacheEntry index |
duke@435 | 786 | // and from word index to byte offset |
duke@435 | 787 | sll(tmp, exact_log2(in_words(ConstantPoolCacheEntry::size()) * BytesPerWord), tmp); |
duke@435 | 788 | // skip past the header |
duke@435 | 789 | add(tmp, in_bytes(constantPoolCacheOopDesc::base_offset()), tmp); |
duke@435 | 790 | // construct pointer to cache entry |
duke@435 | 791 | add(LcpoolCache, tmp, cache); |
duke@435 | 792 | } |
duke@435 | 793 | |
duke@435 | 794 | |
duke@435 | 795 | // Generate a subtype check: branch to ok_is_subtype if sub_klass is |
coleenp@548 | 796 | // a subtype of super_klass. Blows registers Rsuper_klass, Rsub_klass, tmp1, tmp2. |
duke@435 | 797 | void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass, |
duke@435 | 798 | Register Rsuper_klass, |
duke@435 | 799 | Register Rtmp1, |
duke@435 | 800 | Register Rtmp2, |
duke@435 | 801 | Register Rtmp3, |
duke@435 | 802 | Label &ok_is_subtype ) { |
jrose@1079 | 803 | Label not_subtype; |
duke@435 | 804 | |
duke@435 | 805 | // Profile the not-null value's klass. |
duke@435 | 806 | profile_typecheck(Rsub_klass, Rtmp1); |
duke@435 | 807 | |
jrose@1079 | 808 | check_klass_subtype_fast_path(Rsub_klass, Rsuper_klass, |
jrose@1079 | 809 | Rtmp1, Rtmp2, |
jrose@1079 | 810 | &ok_is_subtype, ¬_subtype, NULL); |
jrose@1079 | 811 | |
jrose@1079 | 812 | check_klass_subtype_slow_path(Rsub_klass, Rsuper_klass, |
jrose@1079 | 813 | Rtmp1, Rtmp2, Rtmp3, /*hack:*/ noreg, |
jrose@1079 | 814 | &ok_is_subtype, NULL); |
duke@435 | 815 | |
duke@435 | 816 | bind(not_subtype); |
duke@435 | 817 | profile_typecheck_failed(Rtmp1); |
duke@435 | 818 | } |
duke@435 | 819 | |
duke@435 | 820 | // Separate these two to allow for delay slot in middle |
duke@435 | 821 | // These are used to do a test and full jump to exception-throwing code. |
duke@435 | 822 | |
duke@435 | 823 | // %%%%% Could possibly reoptimize this by testing to see if could use |
duke@435 | 824 | // a single conditional branch (i.e. if span is small enough. |
duke@435 | 825 | // If you go that route, than get rid of the split and give up |
duke@435 | 826 | // on the delay-slot hack. |
duke@435 | 827 | |
duke@435 | 828 | void InterpreterMacroAssembler::throw_if_not_1_icc( Condition ok_condition, |
duke@435 | 829 | Label& ok ) { |
duke@435 | 830 | assert_not_delayed(); |
duke@435 | 831 | br(ok_condition, true, pt, ok); |
duke@435 | 832 | // DELAY SLOT |
duke@435 | 833 | } |
duke@435 | 834 | |
duke@435 | 835 | void InterpreterMacroAssembler::throw_if_not_1_xcc( Condition ok_condition, |
duke@435 | 836 | Label& ok ) { |
duke@435 | 837 | assert_not_delayed(); |
duke@435 | 838 | bp( ok_condition, true, Assembler::xcc, pt, ok); |
duke@435 | 839 | // DELAY SLOT |
duke@435 | 840 | } |
duke@435 | 841 | |
duke@435 | 842 | void InterpreterMacroAssembler::throw_if_not_1_x( Condition ok_condition, |
duke@435 | 843 | Label& ok ) { |
duke@435 | 844 | assert_not_delayed(); |
duke@435 | 845 | brx(ok_condition, true, pt, ok); |
duke@435 | 846 | // DELAY SLOT |
duke@435 | 847 | } |
duke@435 | 848 | |
duke@435 | 849 | void InterpreterMacroAssembler::throw_if_not_2( address throw_entry_point, |
duke@435 | 850 | Register Rscratch, |
duke@435 | 851 | Label& ok ) { |
duke@435 | 852 | assert(throw_entry_point != NULL, "entry point must be generated by now"); |
twisti@1162 | 853 | AddressLiteral dest(throw_entry_point); |
twisti@1162 | 854 | jump_to(dest, Rscratch); |
duke@435 | 855 | delayed()->nop(); |
duke@435 | 856 | bind(ok); |
duke@435 | 857 | } |
duke@435 | 858 | |
duke@435 | 859 | |
duke@435 | 860 | // And if you cannot use the delay slot, here is a shorthand: |
duke@435 | 861 | |
duke@435 | 862 | void InterpreterMacroAssembler::throw_if_not_icc( Condition ok_condition, |
duke@435 | 863 | address throw_entry_point, |
duke@435 | 864 | Register Rscratch ) { |
duke@435 | 865 | Label ok; |
duke@435 | 866 | if (ok_condition != never) { |
duke@435 | 867 | throw_if_not_1_icc( ok_condition, ok); |
duke@435 | 868 | delayed()->nop(); |
duke@435 | 869 | } |
duke@435 | 870 | throw_if_not_2( throw_entry_point, Rscratch, ok); |
duke@435 | 871 | } |
duke@435 | 872 | void InterpreterMacroAssembler::throw_if_not_xcc( Condition ok_condition, |
duke@435 | 873 | address throw_entry_point, |
duke@435 | 874 | Register Rscratch ) { |
duke@435 | 875 | Label ok; |
duke@435 | 876 | if (ok_condition != never) { |
duke@435 | 877 | throw_if_not_1_xcc( ok_condition, ok); |
duke@435 | 878 | delayed()->nop(); |
duke@435 | 879 | } |
duke@435 | 880 | throw_if_not_2( throw_entry_point, Rscratch, ok); |
duke@435 | 881 | } |
duke@435 | 882 | void InterpreterMacroAssembler::throw_if_not_x( Condition ok_condition, |
duke@435 | 883 | address throw_entry_point, |
duke@435 | 884 | Register Rscratch ) { |
duke@435 | 885 | Label ok; |
duke@435 | 886 | if (ok_condition != never) { |
duke@435 | 887 | throw_if_not_1_x( ok_condition, ok); |
duke@435 | 888 | delayed()->nop(); |
duke@435 | 889 | } |
duke@435 | 890 | throw_if_not_2( throw_entry_point, Rscratch, ok); |
duke@435 | 891 | } |
duke@435 | 892 | |
duke@435 | 893 | // Check that index is in range for array, then shift index by index_shift, and put arrayOop + shifted_index into res |
duke@435 | 894 | // Note: res is still shy of address by array offset into object. |
duke@435 | 895 | |
duke@435 | 896 | void InterpreterMacroAssembler::index_check_without_pop(Register array, Register index, int index_shift, Register tmp, Register res) { |
duke@435 | 897 | assert_not_delayed(); |
duke@435 | 898 | |
duke@435 | 899 | verify_oop(array); |
duke@435 | 900 | #ifdef _LP64 |
duke@435 | 901 | // sign extend since tos (index) can be a 32bit value |
duke@435 | 902 | sra(index, G0, index); |
duke@435 | 903 | #endif // _LP64 |
duke@435 | 904 | |
duke@435 | 905 | // check array |
duke@435 | 906 | Label ptr_ok; |
duke@435 | 907 | tst(array); |
duke@435 | 908 | throw_if_not_1_x( notZero, ptr_ok ); |
duke@435 | 909 | delayed()->ld( array, arrayOopDesc::length_offset_in_bytes(), tmp ); // check index |
duke@435 | 910 | throw_if_not_2( Interpreter::_throw_NullPointerException_entry, G3_scratch, ptr_ok); |
duke@435 | 911 | |
duke@435 | 912 | Label index_ok; |
duke@435 | 913 | cmp(index, tmp); |
duke@435 | 914 | throw_if_not_1_icc( lessUnsigned, index_ok ); |
duke@435 | 915 | if (index_shift > 0) delayed()->sll(index, index_shift, index); |
duke@435 | 916 | else delayed()->add(array, index, res); // addr - const offset in index |
duke@435 | 917 | // convention: move aberrant index into G3_scratch for exception message |
duke@435 | 918 | mov(index, G3_scratch); |
duke@435 | 919 | throw_if_not_2( Interpreter::_throw_ArrayIndexOutOfBoundsException_entry, G4_scratch, index_ok); |
duke@435 | 920 | |
duke@435 | 921 | // add offset if didn't do it in delay slot |
duke@435 | 922 | if (index_shift > 0) add(array, index, res); // addr - const offset in index |
duke@435 | 923 | } |
duke@435 | 924 | |
duke@435 | 925 | |
duke@435 | 926 | void InterpreterMacroAssembler::index_check(Register array, Register index, int index_shift, Register tmp, Register res) { |
duke@435 | 927 | assert_not_delayed(); |
duke@435 | 928 | |
duke@435 | 929 | // pop array |
duke@435 | 930 | pop_ptr(array); |
duke@435 | 931 | |
duke@435 | 932 | // check array |
duke@435 | 933 | index_check_without_pop(array, index, index_shift, tmp, res); |
duke@435 | 934 | } |
duke@435 | 935 | |
duke@435 | 936 | |
duke@435 | 937 | void InterpreterMacroAssembler::get_constant_pool(Register Rdst) { |
duke@435 | 938 | ld_ptr(Lmethod, in_bytes(methodOopDesc::constants_offset()), Rdst); |
duke@435 | 939 | } |
duke@435 | 940 | |
duke@435 | 941 | |
duke@435 | 942 | void InterpreterMacroAssembler::get_constant_pool_cache(Register Rdst) { |
duke@435 | 943 | get_constant_pool(Rdst); |
duke@435 | 944 | ld_ptr(Rdst, constantPoolOopDesc::cache_offset_in_bytes(), Rdst); |
duke@435 | 945 | } |
duke@435 | 946 | |
duke@435 | 947 | |
duke@435 | 948 | void InterpreterMacroAssembler::get_cpool_and_tags(Register Rcpool, Register Rtags) { |
duke@435 | 949 | get_constant_pool(Rcpool); |
duke@435 | 950 | ld_ptr(Rcpool, constantPoolOopDesc::tags_offset_in_bytes(), Rtags); |
duke@435 | 951 | } |
duke@435 | 952 | |
duke@435 | 953 | |
duke@435 | 954 | // unlock if synchronized method |
duke@435 | 955 | // |
duke@435 | 956 | // Unlock the receiver if this is a synchronized method. |
duke@435 | 957 | // Unlock any Java monitors from syncronized blocks. |
duke@435 | 958 | // |
duke@435 | 959 | // If there are locked Java monitors |
duke@435 | 960 | // If throw_monitor_exception |
duke@435 | 961 | // throws IllegalMonitorStateException |
duke@435 | 962 | // Else if install_monitor_exception |
duke@435 | 963 | // installs IllegalMonitorStateException |
duke@435 | 964 | // Else |
duke@435 | 965 | // no error processing |
duke@435 | 966 | void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state, |
duke@435 | 967 | bool throw_monitor_exception, |
duke@435 | 968 | bool install_monitor_exception) { |
duke@435 | 969 | Label unlocked, unlock, no_unlock; |
duke@435 | 970 | |
duke@435 | 971 | // get the value of _do_not_unlock_if_synchronized into G1_scratch |
twisti@1162 | 972 | const Address do_not_unlock_if_synchronized(G2_thread, |
twisti@1162 | 973 | JavaThread::do_not_unlock_if_synchronized_offset()); |
duke@435 | 974 | ldbool(do_not_unlock_if_synchronized, G1_scratch); |
duke@435 | 975 | stbool(G0, do_not_unlock_if_synchronized); // reset the flag |
duke@435 | 976 | |
duke@435 | 977 | // check if synchronized method |
twisti@1162 | 978 | const Address access_flags(Lmethod, methodOopDesc::access_flags_offset()); |
duke@435 | 979 | interp_verify_oop(Otos_i, state, __FILE__, __LINE__); |
duke@435 | 980 | push(state); // save tos |
twisti@1162 | 981 | ld(access_flags, G3_scratch); // Load access flags. |
duke@435 | 982 | btst(JVM_ACC_SYNCHRONIZED, G3_scratch); |
twisti@1162 | 983 | br(zero, false, pt, unlocked); |
duke@435 | 984 | delayed()->nop(); |
duke@435 | 985 | |
duke@435 | 986 | // Don't unlock anything if the _do_not_unlock_if_synchronized flag |
duke@435 | 987 | // is set. |
kvn@3037 | 988 | cmp_zero_and_br(Assembler::notZero, G1_scratch, no_unlock); |
duke@435 | 989 | delayed()->nop(); |
duke@435 | 990 | |
duke@435 | 991 | // BasicObjectLock will be first in list, since this is a synchronized method. However, need |
duke@435 | 992 | // to check that the object has not been unlocked by an explicit monitorexit bytecode. |
duke@435 | 993 | |
duke@435 | 994 | //Intel: if (throw_monitor_exception) ... else ... |
duke@435 | 995 | // Entry already unlocked, need to throw exception |
duke@435 | 996 | //... |
duke@435 | 997 | |
duke@435 | 998 | // pass top-most monitor elem |
duke@435 | 999 | add( top_most_monitor(), O1 ); |
duke@435 | 1000 | |
duke@435 | 1001 | ld_ptr(O1, BasicObjectLock::obj_offset_in_bytes(), G3_scratch); |
kvn@3037 | 1002 | br_notnull_short(G3_scratch, pt, unlock); |
duke@435 | 1003 | |
duke@435 | 1004 | if (throw_monitor_exception) { |
duke@435 | 1005 | // Entry already unlocked need to throw an exception |
duke@435 | 1006 | MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_illegal_monitor_state_exception)); |
duke@435 | 1007 | should_not_reach_here(); |
duke@435 | 1008 | } else { |
duke@435 | 1009 | // Monitor already unlocked during a stack unroll. |
duke@435 | 1010 | // If requested, install an illegal_monitor_state_exception. |
duke@435 | 1011 | // Continue with stack unrolling. |
duke@435 | 1012 | if (install_monitor_exception) { |
duke@435 | 1013 | MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::new_illegal_monitor_state_exception)); |
duke@435 | 1014 | } |
kvn@3037 | 1015 | ba_short(unlocked); |
duke@435 | 1016 | } |
duke@435 | 1017 | |
duke@435 | 1018 | bind(unlock); |
duke@435 | 1019 | |
duke@435 | 1020 | unlock_object(O1); |
duke@435 | 1021 | |
duke@435 | 1022 | bind(unlocked); |
duke@435 | 1023 | |
duke@435 | 1024 | // I0, I1: Might contain return value |
duke@435 | 1025 | |
duke@435 | 1026 | // Check that all monitors are unlocked |
duke@435 | 1027 | { Label loop, exception, entry, restart; |
duke@435 | 1028 | |
duke@435 | 1029 | Register Rmptr = O0; |
duke@435 | 1030 | Register Rtemp = O1; |
duke@435 | 1031 | Register Rlimit = Lmonitors; |
duke@435 | 1032 | const jint delta = frame::interpreter_frame_monitor_size() * wordSize; |
duke@435 | 1033 | assert( (delta & LongAlignmentMask) == 0, |
duke@435 | 1034 | "sizeof BasicObjectLock must be even number of doublewords"); |
duke@435 | 1035 | |
duke@435 | 1036 | #ifdef ASSERT |
duke@435 | 1037 | add(top_most_monitor(), Rmptr, delta); |
duke@435 | 1038 | { Label L; |
duke@435 | 1039 | // ensure that Rmptr starts out above (or at) Rlimit |
kvn@3037 | 1040 | cmp_and_brx_short(Rmptr, Rlimit, Assembler::greaterEqualUnsigned, pn, L); |
duke@435 | 1041 | stop("monitor stack has negative size"); |
duke@435 | 1042 | bind(L); |
duke@435 | 1043 | } |
duke@435 | 1044 | #endif |
duke@435 | 1045 | bind(restart); |
kvn@3037 | 1046 | ba(entry); |
duke@435 | 1047 | delayed()-> |
duke@435 | 1048 | add(top_most_monitor(), Rmptr, delta); // points to current entry, starting with bottom-most entry |
duke@435 | 1049 | |
duke@435 | 1050 | // Entry is still locked, need to throw exception |
duke@435 | 1051 | bind(exception); |
duke@435 | 1052 | if (throw_monitor_exception) { |
duke@435 | 1053 | MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_illegal_monitor_state_exception)); |
duke@435 | 1054 | should_not_reach_here(); |
duke@435 | 1055 | } else { |
duke@435 | 1056 | // Stack unrolling. Unlock object and if requested, install illegal_monitor_exception. |
duke@435 | 1057 | // Unlock does not block, so don't have to worry about the frame |
duke@435 | 1058 | unlock_object(Rmptr); |
duke@435 | 1059 | if (install_monitor_exception) { |
duke@435 | 1060 | MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::new_illegal_monitor_state_exception)); |
duke@435 | 1061 | } |
kvn@3037 | 1062 | ba_short(restart); |
duke@435 | 1063 | } |
duke@435 | 1064 | |
duke@435 | 1065 | bind(loop); |
duke@435 | 1066 | cmp(Rtemp, G0); // check if current entry is used |
duke@435 | 1067 | brx(Assembler::notEqual, false, pn, exception); |
duke@435 | 1068 | delayed()-> |
duke@435 | 1069 | dec(Rmptr, delta); // otherwise advance to next entry |
duke@435 | 1070 | #ifdef ASSERT |
duke@435 | 1071 | { Label L; |
duke@435 | 1072 | // ensure that Rmptr has not somehow stepped below Rlimit |
kvn@3037 | 1073 | cmp_and_brx_short(Rmptr, Rlimit, Assembler::greaterEqualUnsigned, pn, L); |
duke@435 | 1074 | stop("ran off the end of the monitor stack"); |
duke@435 | 1075 | bind(L); |
duke@435 | 1076 | } |
duke@435 | 1077 | #endif |
duke@435 | 1078 | bind(entry); |
duke@435 | 1079 | cmp(Rmptr, Rlimit); // check if bottom reached |
duke@435 | 1080 | brx(Assembler::notEqual, true, pn, loop); // if not at bottom then check this entry |
duke@435 | 1081 | delayed()-> |
duke@435 | 1082 | ld_ptr(Rmptr, BasicObjectLock::obj_offset_in_bytes() - delta, Rtemp); |
duke@435 | 1083 | } |
duke@435 | 1084 | |
duke@435 | 1085 | bind(no_unlock); |
duke@435 | 1086 | pop(state); |
duke@435 | 1087 | interp_verify_oop(Otos_i, state, __FILE__, __LINE__); |
duke@435 | 1088 | } |
duke@435 | 1089 | |
duke@435 | 1090 | |
duke@435 | 1091 | // remove activation |
duke@435 | 1092 | // |
duke@435 | 1093 | // Unlock the receiver if this is a synchronized method. |
duke@435 | 1094 | // Unlock any Java monitors from syncronized blocks. |
duke@435 | 1095 | // Remove the activation from the stack. |
duke@435 | 1096 | // |
duke@435 | 1097 | // If there are locked Java monitors |
duke@435 | 1098 | // If throw_monitor_exception |
duke@435 | 1099 | // throws IllegalMonitorStateException |
duke@435 | 1100 | // Else if install_monitor_exception |
duke@435 | 1101 | // installs IllegalMonitorStateException |
duke@435 | 1102 | // Else |
duke@435 | 1103 | // no error processing |
duke@435 | 1104 | void InterpreterMacroAssembler::remove_activation(TosState state, |
duke@435 | 1105 | bool throw_monitor_exception, |
duke@435 | 1106 | bool install_monitor_exception) { |
duke@435 | 1107 | |
duke@435 | 1108 | unlock_if_synchronized_method(state, throw_monitor_exception, install_monitor_exception); |
duke@435 | 1109 | |
duke@435 | 1110 | // save result (push state before jvmti call and pop it afterwards) and notify jvmti |
duke@435 | 1111 | notify_method_exit(false, state, NotifyJVMTI); |
duke@435 | 1112 | |
duke@435 | 1113 | interp_verify_oop(Otos_i, state, __FILE__, __LINE__); |
duke@435 | 1114 | verify_oop(Lmethod); |
duke@435 | 1115 | verify_thread(); |
duke@435 | 1116 | |
duke@435 | 1117 | // return tos |
duke@435 | 1118 | assert(Otos_l1 == Otos_i, "adjust code below"); |
duke@435 | 1119 | switch (state) { |
duke@435 | 1120 | #ifdef _LP64 |
duke@435 | 1121 | case ltos: mov(Otos_l, Otos_l->after_save()); break; // O0 -> I0 |
duke@435 | 1122 | #else |
duke@435 | 1123 | case ltos: mov(Otos_l2, Otos_l2->after_save()); // fall through // O1 -> I1 |
duke@435 | 1124 | #endif |
duke@435 | 1125 | case btos: // fall through |
duke@435 | 1126 | case ctos: |
duke@435 | 1127 | case stos: // fall through |
duke@435 | 1128 | case atos: // fall through |
duke@435 | 1129 | case itos: mov(Otos_l1, Otos_l1->after_save()); break; // O0 -> I0 |
duke@435 | 1130 | case ftos: // fall through |
duke@435 | 1131 | case dtos: // fall through |
duke@435 | 1132 | case vtos: /* nothing to do */ break; |
duke@435 | 1133 | default : ShouldNotReachHere(); |
duke@435 | 1134 | } |
duke@435 | 1135 | |
duke@435 | 1136 | #if defined(COMPILER2) && !defined(_LP64) |
duke@435 | 1137 | if (state == ltos) { |
duke@435 | 1138 | // C2 expects long results in G1 we can't tell if we're returning to interpreted |
duke@435 | 1139 | // or compiled so just be safe use G1 and O0/O1 |
duke@435 | 1140 | |
duke@435 | 1141 | // Shift bits into high (msb) of G1 |
duke@435 | 1142 | sllx(Otos_l1->after_save(), 32, G1); |
duke@435 | 1143 | // Zero extend low bits |
duke@435 | 1144 | srl (Otos_l2->after_save(), 0, Otos_l2->after_save()); |
duke@435 | 1145 | or3 (Otos_l2->after_save(), G1, G1); |
duke@435 | 1146 | } |
duke@435 | 1147 | #endif /* COMPILER2 */ |
duke@435 | 1148 | |
duke@435 | 1149 | } |
duke@435 | 1150 | #endif /* CC_INTERP */ |
duke@435 | 1151 | |
duke@435 | 1152 | |
duke@435 | 1153 | // Lock object |
duke@435 | 1154 | // |
duke@435 | 1155 | // Argument - lock_reg points to the BasicObjectLock to be used for locking, |
duke@435 | 1156 | // it must be initialized with the object to lock |
duke@435 | 1157 | void InterpreterMacroAssembler::lock_object(Register lock_reg, Register Object) { |
duke@435 | 1158 | if (UseHeavyMonitors) { |
duke@435 | 1159 | call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), lock_reg); |
duke@435 | 1160 | } |
duke@435 | 1161 | else { |
duke@435 | 1162 | Register obj_reg = Object; |
duke@435 | 1163 | Register mark_reg = G4_scratch; |
duke@435 | 1164 | Register temp_reg = G1_scratch; |
twisti@1162 | 1165 | Address lock_addr(lock_reg, BasicObjectLock::lock_offset_in_bytes()); |
twisti@1162 | 1166 | Address mark_addr(obj_reg, oopDesc::mark_offset_in_bytes()); |
duke@435 | 1167 | Label done; |
duke@435 | 1168 | |
duke@435 | 1169 | Label slow_case; |
duke@435 | 1170 | |
duke@435 | 1171 | assert_different_registers(lock_reg, obj_reg, mark_reg, temp_reg); |
duke@435 | 1172 | |
duke@435 | 1173 | // load markOop from object into mark_reg |
duke@435 | 1174 | ld_ptr(mark_addr, mark_reg); |
duke@435 | 1175 | |
duke@435 | 1176 | if (UseBiasedLocking) { |
duke@435 | 1177 | biased_locking_enter(obj_reg, mark_reg, temp_reg, done, &slow_case); |
duke@435 | 1178 | } |
duke@435 | 1179 | |
duke@435 | 1180 | // get the address of basicLock on stack that will be stored in the object |
duke@435 | 1181 | // we need a temporary register here as we do not want to clobber lock_reg |
duke@435 | 1182 | // (cas clobbers the destination register) |
duke@435 | 1183 | mov(lock_reg, temp_reg); |
duke@435 | 1184 | // set mark reg to be (markOop of object | UNLOCK_VALUE) |
duke@435 | 1185 | or3(mark_reg, markOopDesc::unlocked_value, mark_reg); |
duke@435 | 1186 | // initialize the box (Must happen before we update the object mark!) |
duke@435 | 1187 | st_ptr(mark_reg, lock_addr, BasicLock::displaced_header_offset_in_bytes()); |
duke@435 | 1188 | // compare and exchange object_addr, markOop | 1, stack address of basicLock |
duke@435 | 1189 | assert(mark_addr.disp() == 0, "cas must take a zero displacement"); |
duke@435 | 1190 | casx_under_lock(mark_addr.base(), mark_reg, temp_reg, |
duke@435 | 1191 | (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr()); |
duke@435 | 1192 | |
duke@435 | 1193 | // if the compare and exchange succeeded we are done (we saw an unlocked object) |
kvn@3037 | 1194 | cmp_and_brx_short(mark_reg, temp_reg, Assembler::equal, Assembler::pt, done); |
duke@435 | 1195 | |
duke@435 | 1196 | // We did not see an unlocked object so try the fast recursive case |
duke@435 | 1197 | |
duke@435 | 1198 | // Check if owner is self by comparing the value in the markOop of object |
duke@435 | 1199 | // with the stack pointer |
duke@435 | 1200 | sub(temp_reg, SP, temp_reg); |
duke@435 | 1201 | #ifdef _LP64 |
duke@435 | 1202 | sub(temp_reg, STACK_BIAS, temp_reg); |
duke@435 | 1203 | #endif |
duke@435 | 1204 | assert(os::vm_page_size() > 0xfff, "page size too small - change the constant"); |
duke@435 | 1205 | |
duke@435 | 1206 | // Composite "andcc" test: |
duke@435 | 1207 | // (a) %sp -vs- markword proximity check, and, |
duke@435 | 1208 | // (b) verify mark word LSBs == 0 (Stack-locked). |
duke@435 | 1209 | // |
duke@435 | 1210 | // FFFFF003/FFFFFFFFFFFF003 is (markOopDesc::lock_mask_in_place | -os::vm_page_size()) |
duke@435 | 1211 | // Note that the page size used for %sp proximity testing is arbitrary and is |
duke@435 | 1212 | // unrelated to the actual MMU page size. We use a 'logical' page size of |
duke@435 | 1213 | // 4096 bytes. F..FFF003 is designed to fit conveniently in the SIMM13 immediate |
duke@435 | 1214 | // field of the andcc instruction. |
duke@435 | 1215 | andcc (temp_reg, 0xFFFFF003, G0) ; |
duke@435 | 1216 | |
duke@435 | 1217 | // if condition is true we are done and hence we can store 0 in the displaced |
duke@435 | 1218 | // header indicating it is a recursive lock and be done |
duke@435 | 1219 | brx(Assembler::zero, true, Assembler::pt, done); |
duke@435 | 1220 | delayed()->st_ptr(G0, lock_addr, BasicLock::displaced_header_offset_in_bytes()); |
duke@435 | 1221 | |
duke@435 | 1222 | // none of the above fast optimizations worked so we have to get into the |
duke@435 | 1223 | // slow case of monitor enter |
duke@435 | 1224 | bind(slow_case); |
duke@435 | 1225 | call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), lock_reg); |
duke@435 | 1226 | |
duke@435 | 1227 | bind(done); |
duke@435 | 1228 | } |
duke@435 | 1229 | } |
duke@435 | 1230 | |
duke@435 | 1231 | // Unlocks an object. Used in monitorexit bytecode and remove_activation. |
duke@435 | 1232 | // |
duke@435 | 1233 | // Argument - lock_reg points to the BasicObjectLock for lock |
duke@435 | 1234 | // Throw IllegalMonitorException if object is not locked by current thread |
duke@435 | 1235 | void InterpreterMacroAssembler::unlock_object(Register lock_reg) { |
duke@435 | 1236 | if (UseHeavyMonitors) { |
duke@435 | 1237 | call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg); |
duke@435 | 1238 | } else { |
duke@435 | 1239 | Register obj_reg = G3_scratch; |
duke@435 | 1240 | Register mark_reg = G4_scratch; |
duke@435 | 1241 | Register displaced_header_reg = G1_scratch; |
twisti@1162 | 1242 | Address lockobj_addr(lock_reg, BasicObjectLock::obj_offset_in_bytes()); |
twisti@1162 | 1243 | Address mark_addr(obj_reg, oopDesc::mark_offset_in_bytes()); |
duke@435 | 1244 | Label done; |
duke@435 | 1245 | |
duke@435 | 1246 | if (UseBiasedLocking) { |
duke@435 | 1247 | // load the object out of the BasicObjectLock |
duke@435 | 1248 | ld_ptr(lockobj_addr, obj_reg); |
duke@435 | 1249 | biased_locking_exit(mark_addr, mark_reg, done, true); |
duke@435 | 1250 | st_ptr(G0, lockobj_addr); // free entry |
duke@435 | 1251 | } |
duke@435 | 1252 | |
duke@435 | 1253 | // Test first if we are in the fast recursive case |
twisti@1162 | 1254 | Address lock_addr(lock_reg, BasicObjectLock::lock_offset_in_bytes() + BasicLock::displaced_header_offset_in_bytes()); |
twisti@1162 | 1255 | ld_ptr(lock_addr, displaced_header_reg); |
duke@435 | 1256 | br_null(displaced_header_reg, true, Assembler::pn, done); |
duke@435 | 1257 | delayed()->st_ptr(G0, lockobj_addr); // free entry |
duke@435 | 1258 | |
duke@435 | 1259 | // See if it is still a light weight lock, if so we just unlock |
duke@435 | 1260 | // the object and we are done |
duke@435 | 1261 | |
duke@435 | 1262 | if (!UseBiasedLocking) { |
duke@435 | 1263 | // load the object out of the BasicObjectLock |
duke@435 | 1264 | ld_ptr(lockobj_addr, obj_reg); |
duke@435 | 1265 | } |
duke@435 | 1266 | |
duke@435 | 1267 | // we have the displaced header in displaced_header_reg |
duke@435 | 1268 | // we expect to see the stack address of the basicLock in case the |
duke@435 | 1269 | // lock is still a light weight lock (lock_reg) |
duke@435 | 1270 | assert(mark_addr.disp() == 0, "cas must take a zero displacement"); |
duke@435 | 1271 | casx_under_lock(mark_addr.base(), lock_reg, displaced_header_reg, |
duke@435 | 1272 | (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr()); |
duke@435 | 1273 | cmp(lock_reg, displaced_header_reg); |
duke@435 | 1274 | brx(Assembler::equal, true, Assembler::pn, done); |
duke@435 | 1275 | delayed()->st_ptr(G0, lockobj_addr); // free entry |
duke@435 | 1276 | |
duke@435 | 1277 | // The lock has been converted into a heavy lock and hence |
duke@435 | 1278 | // we need to get into the slow case |
duke@435 | 1279 | |
duke@435 | 1280 | call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg); |
duke@435 | 1281 | |
duke@435 | 1282 | bind(done); |
duke@435 | 1283 | } |
duke@435 | 1284 | } |
duke@435 | 1285 | |
duke@435 | 1286 | #ifndef CC_INTERP |
duke@435 | 1287 | |
duke@435 | 1288 | // Get the method data pointer from the methodOop and set the |
duke@435 | 1289 | // specified register to its value. |
duke@435 | 1290 | |
iveresov@2438 | 1291 | void InterpreterMacroAssembler::set_method_data_pointer() { |
duke@435 | 1292 | assert(ProfileInterpreter, "must be profiling interpreter"); |
duke@435 | 1293 | Label get_continue; |
duke@435 | 1294 | |
duke@435 | 1295 | ld_ptr(Lmethod, in_bytes(methodOopDesc::method_data_offset()), ImethodDataPtr); |
duke@435 | 1296 | test_method_data_pointer(get_continue); |
duke@435 | 1297 | add(ImethodDataPtr, in_bytes(methodDataOopDesc::data_offset()), ImethodDataPtr); |
duke@435 | 1298 | bind(get_continue); |
duke@435 | 1299 | } |
duke@435 | 1300 | |
duke@435 | 1301 | // Set the method data pointer for the current bcp. |
duke@435 | 1302 | |
duke@435 | 1303 | void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { |
duke@435 | 1304 | assert(ProfileInterpreter, "must be profiling interpreter"); |
duke@435 | 1305 | Label zero_continue; |
duke@435 | 1306 | |
duke@435 | 1307 | // Test MDO to avoid the call if it is NULL. |
iveresov@2438 | 1308 | ld_ptr(Lmethod, in_bytes(methodOopDesc::method_data_offset()), ImethodDataPtr); |
duke@435 | 1309 | test_method_data_pointer(zero_continue); |
duke@435 | 1310 | call_VM_leaf(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), Lmethod, Lbcp); |
iveresov@2438 | 1311 | add(ImethodDataPtr, in_bytes(methodDataOopDesc::data_offset()), ImethodDataPtr); |
iveresov@2438 | 1312 | add(ImethodDataPtr, O0, ImethodDataPtr); |
duke@435 | 1313 | bind(zero_continue); |
duke@435 | 1314 | } |
duke@435 | 1315 | |
duke@435 | 1316 | // Test ImethodDataPtr. If it is null, continue at the specified label |
duke@435 | 1317 | |
duke@435 | 1318 | void InterpreterMacroAssembler::test_method_data_pointer(Label& zero_continue) { |
duke@435 | 1319 | assert(ProfileInterpreter, "must be profiling interpreter"); |
kvn@3037 | 1320 | br_null_short(ImethodDataPtr, Assembler::pn, zero_continue); |
duke@435 | 1321 | } |
duke@435 | 1322 | |
duke@435 | 1323 | void InterpreterMacroAssembler::verify_method_data_pointer() { |
duke@435 | 1324 | assert(ProfileInterpreter, "must be profiling interpreter"); |
duke@435 | 1325 | #ifdef ASSERT |
duke@435 | 1326 | Label verify_continue; |
duke@435 | 1327 | test_method_data_pointer(verify_continue); |
duke@435 | 1328 | |
duke@435 | 1329 | // If the mdp is valid, it will point to a DataLayout header which is |
duke@435 | 1330 | // consistent with the bcp. The converse is highly probable also. |
duke@435 | 1331 | lduh(ImethodDataPtr, in_bytes(DataLayout::bci_offset()), G3_scratch); |
twisti@1162 | 1332 | ld_ptr(Lmethod, methodOopDesc::const_offset(), O5); |
duke@435 | 1333 | add(G3_scratch, in_bytes(constMethodOopDesc::codes_offset()), G3_scratch); |
duke@435 | 1334 | add(G3_scratch, O5, G3_scratch); |
duke@435 | 1335 | cmp(Lbcp, G3_scratch); |
duke@435 | 1336 | brx(Assembler::equal, false, Assembler::pt, verify_continue); |
duke@435 | 1337 | |
duke@435 | 1338 | Register temp_reg = O5; |
duke@435 | 1339 | delayed()->mov(ImethodDataPtr, temp_reg); |
duke@435 | 1340 | // %%% should use call_VM_leaf here? |
duke@435 | 1341 | //call_VM_leaf(noreg, ..., Lmethod, Lbcp, ImethodDataPtr); |
duke@435 | 1342 | save_frame_and_mov(sizeof(jdouble) / wordSize, Lmethod, O0, Lbcp, O1); |
twisti@1162 | 1343 | Address d_save(FP, -sizeof(jdouble) + STACK_BIAS); |
duke@435 | 1344 | stf(FloatRegisterImpl::D, Ftos_d, d_save); |
duke@435 | 1345 | mov(temp_reg->after_save(), O2); |
duke@435 | 1346 | save_thread(L7_thread_cache); |
duke@435 | 1347 | call(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp), relocInfo::none); |
duke@435 | 1348 | delayed()->nop(); |
duke@435 | 1349 | restore_thread(L7_thread_cache); |
duke@435 | 1350 | ldf(FloatRegisterImpl::D, d_save, Ftos_d); |
duke@435 | 1351 | restore(); |
duke@435 | 1352 | bind(verify_continue); |
duke@435 | 1353 | #endif // ASSERT |
duke@435 | 1354 | } |
duke@435 | 1355 | |
duke@435 | 1356 | void InterpreterMacroAssembler::test_invocation_counter_for_mdp(Register invocation_count, |
duke@435 | 1357 | Register Rtmp, |
duke@435 | 1358 | Label &profile_continue) { |
duke@435 | 1359 | assert(ProfileInterpreter, "must be profiling interpreter"); |
duke@435 | 1360 | // Control will flow to "profile_continue" if the counter is less than the |
duke@435 | 1361 | // limit or if we call profile_method() |
duke@435 | 1362 | |
duke@435 | 1363 | Label done; |
duke@435 | 1364 | |
duke@435 | 1365 | // if no method data exists, and the counter is high enough, make one |
kvn@3037 | 1366 | br_notnull_short(ImethodDataPtr, Assembler::pn, done); |
duke@435 | 1367 | |
duke@435 | 1368 | // Test to see if we should create a method data oop |
twisti@1162 | 1369 | AddressLiteral profile_limit((address) &InvocationCounter::InterpreterProfileLimit); |
twisti@1162 | 1370 | sethi(profile_limit, Rtmp); |
twisti@1162 | 1371 | ld(Rtmp, profile_limit.low10(), Rtmp); |
kvn@3037 | 1372 | cmp_and_br_short(invocation_count, Rtmp, Assembler::lessUnsigned, Assembler::pn, profile_continue); |
duke@435 | 1373 | |
duke@435 | 1374 | // Build it now. |
iveresov@2438 | 1375 | call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method)); |
iveresov@2438 | 1376 | set_method_data_pointer_for_bcp(); |
kvn@3037 | 1377 | ba_short(profile_continue); |
duke@435 | 1378 | bind(done); |
duke@435 | 1379 | } |
duke@435 | 1380 | |
duke@435 | 1381 | // Store a value at some constant offset from the method data pointer. |
duke@435 | 1382 | |
duke@435 | 1383 | void InterpreterMacroAssembler::set_mdp_data_at(int constant, Register value) { |
duke@435 | 1384 | assert(ProfileInterpreter, "must be profiling interpreter"); |
duke@435 | 1385 | st_ptr(value, ImethodDataPtr, constant); |
duke@435 | 1386 | } |
duke@435 | 1387 | |
duke@435 | 1388 | void InterpreterMacroAssembler::increment_mdp_data_at(Address counter, |
duke@435 | 1389 | Register bumped_count, |
duke@435 | 1390 | bool decrement) { |
duke@435 | 1391 | assert(ProfileInterpreter, "must be profiling interpreter"); |
duke@435 | 1392 | |
duke@435 | 1393 | // Load the counter. |
duke@435 | 1394 | ld_ptr(counter, bumped_count); |
duke@435 | 1395 | |
duke@435 | 1396 | if (decrement) { |
duke@435 | 1397 | // Decrement the register. Set condition codes. |
duke@435 | 1398 | subcc(bumped_count, DataLayout::counter_increment, bumped_count); |
duke@435 | 1399 | |
duke@435 | 1400 | // If the decrement causes the counter to overflow, stay negative |
duke@435 | 1401 | Label L; |
duke@435 | 1402 | brx(Assembler::negative, true, Assembler::pn, L); |
duke@435 | 1403 | |
duke@435 | 1404 | // Store the decremented counter, if it is still negative. |
duke@435 | 1405 | delayed()->st_ptr(bumped_count, counter); |
duke@435 | 1406 | bind(L); |
duke@435 | 1407 | } else { |
duke@435 | 1408 | // Increment the register. Set carry flag. |
duke@435 | 1409 | addcc(bumped_count, DataLayout::counter_increment, bumped_count); |
duke@435 | 1410 | |
duke@435 | 1411 | // If the increment causes the counter to overflow, pull back by 1. |
duke@435 | 1412 | assert(DataLayout::counter_increment == 1, "subc works"); |
duke@435 | 1413 | subc(bumped_count, G0, bumped_count); |
duke@435 | 1414 | |
duke@435 | 1415 | // Store the incremented counter. |
duke@435 | 1416 | st_ptr(bumped_count, counter); |
duke@435 | 1417 | } |
duke@435 | 1418 | } |
duke@435 | 1419 | |
duke@435 | 1420 | // Increment the value at some constant offset from the method data pointer. |
duke@435 | 1421 | |
duke@435 | 1422 | void InterpreterMacroAssembler::increment_mdp_data_at(int constant, |
duke@435 | 1423 | Register bumped_count, |
duke@435 | 1424 | bool decrement) { |
duke@435 | 1425 | // Locate the counter at a fixed offset from the mdp: |
twisti@1162 | 1426 | Address counter(ImethodDataPtr, constant); |
duke@435 | 1427 | increment_mdp_data_at(counter, bumped_count, decrement); |
duke@435 | 1428 | } |
duke@435 | 1429 | |
duke@435 | 1430 | // Increment the value at some non-fixed (reg + constant) offset from |
duke@435 | 1431 | // the method data pointer. |
duke@435 | 1432 | |
duke@435 | 1433 | void InterpreterMacroAssembler::increment_mdp_data_at(Register reg, |
duke@435 | 1434 | int constant, |
duke@435 | 1435 | Register bumped_count, |
duke@435 | 1436 | Register scratch2, |
duke@435 | 1437 | bool decrement) { |
duke@435 | 1438 | // Add the constant to reg to get the offset. |
duke@435 | 1439 | add(ImethodDataPtr, reg, scratch2); |
twisti@1162 | 1440 | Address counter(scratch2, constant); |
duke@435 | 1441 | increment_mdp_data_at(counter, bumped_count, decrement); |
duke@435 | 1442 | } |
duke@435 | 1443 | |
duke@435 | 1444 | // Set a flag value at the current method data pointer position. |
duke@435 | 1445 | // Updates a single byte of the header, to avoid races with other header bits. |
duke@435 | 1446 | |
duke@435 | 1447 | void InterpreterMacroAssembler::set_mdp_flag_at(int flag_constant, |
duke@435 | 1448 | Register scratch) { |
duke@435 | 1449 | assert(ProfileInterpreter, "must be profiling interpreter"); |
duke@435 | 1450 | // Load the data header |
duke@435 | 1451 | ldub(ImethodDataPtr, in_bytes(DataLayout::flags_offset()), scratch); |
duke@435 | 1452 | |
duke@435 | 1453 | // Set the flag |
duke@435 | 1454 | or3(scratch, flag_constant, scratch); |
duke@435 | 1455 | |
duke@435 | 1456 | // Store the modified header. |
duke@435 | 1457 | stb(scratch, ImethodDataPtr, in_bytes(DataLayout::flags_offset())); |
duke@435 | 1458 | } |
duke@435 | 1459 | |
duke@435 | 1460 | // Test the location at some offset from the method data pointer. |
duke@435 | 1461 | // If it is not equal to value, branch to the not_equal_continue Label. |
duke@435 | 1462 | // Set condition codes to match the nullness of the loaded value. |
duke@435 | 1463 | |
duke@435 | 1464 | void InterpreterMacroAssembler::test_mdp_data_at(int offset, |
duke@435 | 1465 | Register value, |
duke@435 | 1466 | Label& not_equal_continue, |
duke@435 | 1467 | Register scratch) { |
duke@435 | 1468 | assert(ProfileInterpreter, "must be profiling interpreter"); |
duke@435 | 1469 | ld_ptr(ImethodDataPtr, offset, scratch); |
duke@435 | 1470 | cmp(value, scratch); |
duke@435 | 1471 | brx(Assembler::notEqual, false, Assembler::pn, not_equal_continue); |
duke@435 | 1472 | delayed()->tst(scratch); |
duke@435 | 1473 | } |
duke@435 | 1474 | |
duke@435 | 1475 | // Update the method data pointer by the displacement located at some fixed |
duke@435 | 1476 | // offset from the method data pointer. |
duke@435 | 1477 | |
duke@435 | 1478 | void InterpreterMacroAssembler::update_mdp_by_offset(int offset_of_disp, |
duke@435 | 1479 | Register scratch) { |
duke@435 | 1480 | assert(ProfileInterpreter, "must be profiling interpreter"); |
duke@435 | 1481 | ld_ptr(ImethodDataPtr, offset_of_disp, scratch); |
duke@435 | 1482 | add(ImethodDataPtr, scratch, ImethodDataPtr); |
duke@435 | 1483 | } |
duke@435 | 1484 | |
duke@435 | 1485 | // Update the method data pointer by the displacement located at the |
duke@435 | 1486 | // offset (reg + offset_of_disp). |
duke@435 | 1487 | |
duke@435 | 1488 | void InterpreterMacroAssembler::update_mdp_by_offset(Register reg, |
duke@435 | 1489 | int offset_of_disp, |
duke@435 | 1490 | Register scratch) { |
duke@435 | 1491 | assert(ProfileInterpreter, "must be profiling interpreter"); |
duke@435 | 1492 | add(reg, offset_of_disp, scratch); |
duke@435 | 1493 | ld_ptr(ImethodDataPtr, scratch, scratch); |
duke@435 | 1494 | add(ImethodDataPtr, scratch, ImethodDataPtr); |
duke@435 | 1495 | } |
duke@435 | 1496 | |
duke@435 | 1497 | // Update the method data pointer by a simple constant displacement. |
duke@435 | 1498 | |
duke@435 | 1499 | void InterpreterMacroAssembler::update_mdp_by_constant(int constant) { |
duke@435 | 1500 | assert(ProfileInterpreter, "must be profiling interpreter"); |
duke@435 | 1501 | add(ImethodDataPtr, constant, ImethodDataPtr); |
duke@435 | 1502 | } |
duke@435 | 1503 | |
duke@435 | 1504 | // Update the method data pointer for a _ret bytecode whose target |
duke@435 | 1505 | // was not among our cached targets. |
duke@435 | 1506 | |
duke@435 | 1507 | void InterpreterMacroAssembler::update_mdp_for_ret(TosState state, |
duke@435 | 1508 | Register return_bci) { |
duke@435 | 1509 | assert(ProfileInterpreter, "must be profiling interpreter"); |
duke@435 | 1510 | push(state); |
duke@435 | 1511 | st_ptr(return_bci, l_tmp); // protect return_bci, in case it is volatile |
duke@435 | 1512 | call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::update_mdp_for_ret), return_bci); |
duke@435 | 1513 | ld_ptr(l_tmp, return_bci); |
duke@435 | 1514 | pop(state); |
duke@435 | 1515 | } |
duke@435 | 1516 | |
duke@435 | 1517 | // Count a taken branch in the bytecodes. |
duke@435 | 1518 | |
duke@435 | 1519 | void InterpreterMacroAssembler::profile_taken_branch(Register scratch, Register bumped_count) { |
duke@435 | 1520 | if (ProfileInterpreter) { |
duke@435 | 1521 | Label profile_continue; |
duke@435 | 1522 | |
duke@435 | 1523 | // If no method data exists, go to profile_continue. |
duke@435 | 1524 | test_method_data_pointer(profile_continue); |
duke@435 | 1525 | |
duke@435 | 1526 | // We are taking a branch. Increment the taken count. |
duke@435 | 1527 | increment_mdp_data_at(in_bytes(JumpData::taken_offset()), bumped_count); |
duke@435 | 1528 | |
duke@435 | 1529 | // The method data pointer needs to be updated to reflect the new target. |
duke@435 | 1530 | update_mdp_by_offset(in_bytes(JumpData::displacement_offset()), scratch); |
duke@435 | 1531 | bind (profile_continue); |
duke@435 | 1532 | } |
duke@435 | 1533 | } |
duke@435 | 1534 | |
duke@435 | 1535 | |
duke@435 | 1536 | // Count a not-taken branch in the bytecodes. |
duke@435 | 1537 | |
duke@435 | 1538 | void InterpreterMacroAssembler::profile_not_taken_branch(Register scratch) { |
duke@435 | 1539 | if (ProfileInterpreter) { |
duke@435 | 1540 | Label profile_continue; |
duke@435 | 1541 | |
duke@435 | 1542 | // If no method data exists, go to profile_continue. |
duke@435 | 1543 | test_method_data_pointer(profile_continue); |
duke@435 | 1544 | |
duke@435 | 1545 | // We are taking a branch. Increment the not taken count. |
duke@435 | 1546 | increment_mdp_data_at(in_bytes(BranchData::not_taken_offset()), scratch); |
duke@435 | 1547 | |
duke@435 | 1548 | // The method data pointer needs to be updated to correspond to the |
duke@435 | 1549 | // next bytecode. |
duke@435 | 1550 | update_mdp_by_constant(in_bytes(BranchData::branch_data_size())); |
duke@435 | 1551 | bind (profile_continue); |
duke@435 | 1552 | } |
duke@435 | 1553 | } |
duke@435 | 1554 | |
duke@435 | 1555 | |
duke@435 | 1556 | // Count a non-virtual call in the bytecodes. |
duke@435 | 1557 | |
duke@435 | 1558 | void InterpreterMacroAssembler::profile_call(Register scratch) { |
duke@435 | 1559 | if (ProfileInterpreter) { |
duke@435 | 1560 | Label profile_continue; |
duke@435 | 1561 | |
duke@435 | 1562 | // If no method data exists, go to profile_continue. |
duke@435 | 1563 | test_method_data_pointer(profile_continue); |
duke@435 | 1564 | |
duke@435 | 1565 | // We are making a call. Increment the count. |
duke@435 | 1566 | increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch); |
duke@435 | 1567 | |
duke@435 | 1568 | // The method data pointer needs to be updated to reflect the new target. |
duke@435 | 1569 | update_mdp_by_constant(in_bytes(CounterData::counter_data_size())); |
duke@435 | 1570 | bind (profile_continue); |
duke@435 | 1571 | } |
duke@435 | 1572 | } |
duke@435 | 1573 | |
duke@435 | 1574 | |
duke@435 | 1575 | // Count a final call in the bytecodes. |
duke@435 | 1576 | |
duke@435 | 1577 | void InterpreterMacroAssembler::profile_final_call(Register scratch) { |
duke@435 | 1578 | if (ProfileInterpreter) { |
duke@435 | 1579 | Label profile_continue; |
duke@435 | 1580 | |
duke@435 | 1581 | // If no method data exists, go to profile_continue. |
duke@435 | 1582 | test_method_data_pointer(profile_continue); |
duke@435 | 1583 | |
duke@435 | 1584 | // We are making a call. Increment the count. |
duke@435 | 1585 | increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch); |
duke@435 | 1586 | |
duke@435 | 1587 | // The method data pointer needs to be updated to reflect the new target. |
duke@435 | 1588 | update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size())); |
duke@435 | 1589 | bind (profile_continue); |
duke@435 | 1590 | } |
duke@435 | 1591 | } |
duke@435 | 1592 | |
duke@435 | 1593 | |
duke@435 | 1594 | // Count a virtual call in the bytecodes. |
duke@435 | 1595 | |
duke@435 | 1596 | void InterpreterMacroAssembler::profile_virtual_call(Register receiver, |
twisti@1858 | 1597 | Register scratch, |
twisti@1858 | 1598 | bool receiver_can_be_null) { |
duke@435 | 1599 | if (ProfileInterpreter) { |
duke@435 | 1600 | Label profile_continue; |
duke@435 | 1601 | |
duke@435 | 1602 | // If no method data exists, go to profile_continue. |
duke@435 | 1603 | test_method_data_pointer(profile_continue); |
duke@435 | 1604 | |
twisti@1858 | 1605 | |
twisti@1858 | 1606 | Label skip_receiver_profile; |
twisti@1858 | 1607 | if (receiver_can_be_null) { |
twisti@1858 | 1608 | Label not_null; |
kvn@3037 | 1609 | br_notnull_short(receiver, Assembler::pt, not_null); |
twisti@1858 | 1610 | // We are making a call. Increment the count for null receiver. |
twisti@1858 | 1611 | increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch); |
kvn@3037 | 1612 | ba_short(skip_receiver_profile); |
twisti@1858 | 1613 | bind(not_null); |
twisti@1858 | 1614 | } |
twisti@1858 | 1615 | |
duke@435 | 1616 | // Record the receiver type. |
kvn@1641 | 1617 | record_klass_in_profile(receiver, scratch, true); |
twisti@1858 | 1618 | bind(skip_receiver_profile); |
duke@435 | 1619 | |
duke@435 | 1620 | // The method data pointer needs to be updated to reflect the new target. |
duke@435 | 1621 | update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size())); |
duke@435 | 1622 | bind (profile_continue); |
duke@435 | 1623 | } |
duke@435 | 1624 | } |
duke@435 | 1625 | |
duke@435 | 1626 | void InterpreterMacroAssembler::record_klass_in_profile_helper( |
duke@435 | 1627 | Register receiver, Register scratch, |
kvn@1641 | 1628 | int start_row, Label& done, bool is_virtual_call) { |
kvn@1641 | 1629 | if (TypeProfileWidth == 0) { |
kvn@1641 | 1630 | if (is_virtual_call) { |
kvn@1641 | 1631 | increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch); |
kvn@1641 | 1632 | } |
poonam@1402 | 1633 | return; |
kvn@1641 | 1634 | } |
poonam@1402 | 1635 | |
duke@435 | 1636 | int last_row = VirtualCallData::row_limit() - 1; |
duke@435 | 1637 | assert(start_row <= last_row, "must be work left to do"); |
duke@435 | 1638 | // Test this row for both the receiver and for null. |
duke@435 | 1639 | // Take any of three different outcomes: |
duke@435 | 1640 | // 1. found receiver => increment count and goto done |
duke@435 | 1641 | // 2. found null => keep looking for case 1, maybe allocate this cell |
duke@435 | 1642 | // 3. found something else => keep looking for cases 1 and 2 |
duke@435 | 1643 | // Case 3 is handled by a recursive call. |
duke@435 | 1644 | for (int row = start_row; row <= last_row; row++) { |
duke@435 | 1645 | Label next_test; |
duke@435 | 1646 | bool test_for_null_also = (row == start_row); |
duke@435 | 1647 | |
duke@435 | 1648 | // See if the receiver is receiver[n]. |
duke@435 | 1649 | int recvr_offset = in_bytes(VirtualCallData::receiver_offset(row)); |
duke@435 | 1650 | test_mdp_data_at(recvr_offset, receiver, next_test, scratch); |
kvn@1641 | 1651 | // delayed()->tst(scratch); |
duke@435 | 1652 | |
duke@435 | 1653 | // The receiver is receiver[n]. Increment count[n]. |
duke@435 | 1654 | int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row)); |
duke@435 | 1655 | increment_mdp_data_at(count_offset, scratch); |
kvn@3037 | 1656 | ba_short(done); |
duke@435 | 1657 | bind(next_test); |
duke@435 | 1658 | |
duke@435 | 1659 | if (test_for_null_also) { |
kvn@1641 | 1660 | Label found_null; |
duke@435 | 1661 | // Failed the equality check on receiver[n]... Test for null. |
duke@435 | 1662 | if (start_row == last_row) { |
duke@435 | 1663 | // The only thing left to do is handle the null case. |
kvn@1641 | 1664 | if (is_virtual_call) { |
kvn@1641 | 1665 | brx(Assembler::zero, false, Assembler::pn, found_null); |
kvn@1641 | 1666 | delayed()->nop(); |
kvn@1641 | 1667 | // Receiver did not match any saved receiver and there is no empty row for it. |
kvn@1686 | 1668 | // Increment total counter to indicate polymorphic case. |
kvn@1641 | 1669 | increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch); |
kvn@3037 | 1670 | ba_short(done); |
kvn@1641 | 1671 | bind(found_null); |
kvn@1641 | 1672 | } else { |
kvn@1641 | 1673 | brx(Assembler::notZero, false, Assembler::pt, done); |
kvn@1641 | 1674 | delayed()->nop(); |
kvn@1641 | 1675 | } |
duke@435 | 1676 | break; |
duke@435 | 1677 | } |
duke@435 | 1678 | // Since null is rare, make it be the branch-taken case. |
duke@435 | 1679 | brx(Assembler::zero, false, Assembler::pn, found_null); |
duke@435 | 1680 | delayed()->nop(); |
duke@435 | 1681 | |
duke@435 | 1682 | // Put all the "Case 3" tests here. |
kvn@1641 | 1683 | record_klass_in_profile_helper(receiver, scratch, start_row + 1, done, is_virtual_call); |
duke@435 | 1684 | |
duke@435 | 1685 | // Found a null. Keep searching for a matching receiver, |
duke@435 | 1686 | // but remember that this is an empty (unused) slot. |
duke@435 | 1687 | bind(found_null); |
duke@435 | 1688 | } |
duke@435 | 1689 | } |
duke@435 | 1690 | |
duke@435 | 1691 | // In the fall-through case, we found no matching receiver, but we |
duke@435 | 1692 | // observed the receiver[start_row] is NULL. |
duke@435 | 1693 | |
duke@435 | 1694 | // Fill in the receiver field and increment the count. |
duke@435 | 1695 | int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row)); |
duke@435 | 1696 | set_mdp_data_at(recvr_offset, receiver); |
duke@435 | 1697 | int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row)); |
duke@435 | 1698 | mov(DataLayout::counter_increment, scratch); |
duke@435 | 1699 | set_mdp_data_at(count_offset, scratch); |
kvn@1641 | 1700 | if (start_row > 0) { |
kvn@3037 | 1701 | ba_short(done); |
kvn@1641 | 1702 | } |
duke@435 | 1703 | } |
duke@435 | 1704 | |
duke@435 | 1705 | void InterpreterMacroAssembler::record_klass_in_profile(Register receiver, |
kvn@1641 | 1706 | Register scratch, bool is_virtual_call) { |
duke@435 | 1707 | assert(ProfileInterpreter, "must be profiling"); |
duke@435 | 1708 | Label done; |
duke@435 | 1709 | |
kvn@1641 | 1710 | record_klass_in_profile_helper(receiver, scratch, 0, done, is_virtual_call); |
duke@435 | 1711 | |
duke@435 | 1712 | bind (done); |
duke@435 | 1713 | } |
duke@435 | 1714 | |
duke@435 | 1715 | |
duke@435 | 1716 | // Count a ret in the bytecodes. |
duke@435 | 1717 | |
duke@435 | 1718 | void InterpreterMacroAssembler::profile_ret(TosState state, |
duke@435 | 1719 | Register return_bci, |
duke@435 | 1720 | Register scratch) { |
duke@435 | 1721 | if (ProfileInterpreter) { |
duke@435 | 1722 | Label profile_continue; |
duke@435 | 1723 | uint row; |
duke@435 | 1724 | |
duke@435 | 1725 | // If no method data exists, go to profile_continue. |
duke@435 | 1726 | test_method_data_pointer(profile_continue); |
duke@435 | 1727 | |
duke@435 | 1728 | // Update the total ret count. |
duke@435 | 1729 | increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch); |
duke@435 | 1730 | |
duke@435 | 1731 | for (row = 0; row < RetData::row_limit(); row++) { |
duke@435 | 1732 | Label next_test; |
duke@435 | 1733 | |
duke@435 | 1734 | // See if return_bci is equal to bci[n]: |
duke@435 | 1735 | test_mdp_data_at(in_bytes(RetData::bci_offset(row)), |
duke@435 | 1736 | return_bci, next_test, scratch); |
duke@435 | 1737 | |
duke@435 | 1738 | // return_bci is equal to bci[n]. Increment the count. |
duke@435 | 1739 | increment_mdp_data_at(in_bytes(RetData::bci_count_offset(row)), scratch); |
duke@435 | 1740 | |
duke@435 | 1741 | // The method data pointer needs to be updated to reflect the new target. |
duke@435 | 1742 | update_mdp_by_offset(in_bytes(RetData::bci_displacement_offset(row)), scratch); |
kvn@3037 | 1743 | ba_short(profile_continue); |
duke@435 | 1744 | bind(next_test); |
duke@435 | 1745 | } |
duke@435 | 1746 | |
duke@435 | 1747 | update_mdp_for_ret(state, return_bci); |
duke@435 | 1748 | |
duke@435 | 1749 | bind (profile_continue); |
duke@435 | 1750 | } |
duke@435 | 1751 | } |
duke@435 | 1752 | |
duke@435 | 1753 | // Profile an unexpected null in the bytecodes. |
duke@435 | 1754 | void InterpreterMacroAssembler::profile_null_seen(Register scratch) { |
duke@435 | 1755 | if (ProfileInterpreter) { |
duke@435 | 1756 | Label profile_continue; |
duke@435 | 1757 | |
duke@435 | 1758 | // If no method data exists, go to profile_continue. |
duke@435 | 1759 | test_method_data_pointer(profile_continue); |
duke@435 | 1760 | |
duke@435 | 1761 | set_mdp_flag_at(BitData::null_seen_byte_constant(), scratch); |
duke@435 | 1762 | |
duke@435 | 1763 | // The method data pointer needs to be updated. |
duke@435 | 1764 | int mdp_delta = in_bytes(BitData::bit_data_size()); |
duke@435 | 1765 | if (TypeProfileCasts) { |
duke@435 | 1766 | mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size()); |
duke@435 | 1767 | } |
duke@435 | 1768 | update_mdp_by_constant(mdp_delta); |
duke@435 | 1769 | |
duke@435 | 1770 | bind (profile_continue); |
duke@435 | 1771 | } |
duke@435 | 1772 | } |
duke@435 | 1773 | |
duke@435 | 1774 | void InterpreterMacroAssembler::profile_typecheck(Register klass, |
duke@435 | 1775 | Register scratch) { |
duke@435 | 1776 | if (ProfileInterpreter) { |
duke@435 | 1777 | Label profile_continue; |
duke@435 | 1778 | |
duke@435 | 1779 | // If no method data exists, go to profile_continue. |
duke@435 | 1780 | test_method_data_pointer(profile_continue); |
duke@435 | 1781 | |
duke@435 | 1782 | int mdp_delta = in_bytes(BitData::bit_data_size()); |
duke@435 | 1783 | if (TypeProfileCasts) { |
duke@435 | 1784 | mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size()); |
duke@435 | 1785 | |
duke@435 | 1786 | // Record the object type. |
kvn@1641 | 1787 | record_klass_in_profile(klass, scratch, false); |
duke@435 | 1788 | } |
duke@435 | 1789 | |
duke@435 | 1790 | // The method data pointer needs to be updated. |
duke@435 | 1791 | update_mdp_by_constant(mdp_delta); |
duke@435 | 1792 | |
duke@435 | 1793 | bind (profile_continue); |
duke@435 | 1794 | } |
duke@435 | 1795 | } |
duke@435 | 1796 | |
duke@435 | 1797 | void InterpreterMacroAssembler::profile_typecheck_failed(Register scratch) { |
duke@435 | 1798 | if (ProfileInterpreter && TypeProfileCasts) { |
duke@435 | 1799 | Label profile_continue; |
duke@435 | 1800 | |
duke@435 | 1801 | // If no method data exists, go to profile_continue. |
duke@435 | 1802 | test_method_data_pointer(profile_continue); |
duke@435 | 1803 | |
duke@435 | 1804 | int count_offset = in_bytes(CounterData::count_offset()); |
duke@435 | 1805 | // Back up the address, since we have already bumped the mdp. |
duke@435 | 1806 | count_offset -= in_bytes(VirtualCallData::virtual_call_data_size()); |
duke@435 | 1807 | |
duke@435 | 1808 | // *Decrement* the counter. We expect to see zero or small negatives. |
duke@435 | 1809 | increment_mdp_data_at(count_offset, scratch, true); |
duke@435 | 1810 | |
duke@435 | 1811 | bind (profile_continue); |
duke@435 | 1812 | } |
duke@435 | 1813 | } |
duke@435 | 1814 | |
duke@435 | 1815 | // Count the default case of a switch construct. |
duke@435 | 1816 | |
duke@435 | 1817 | void InterpreterMacroAssembler::profile_switch_default(Register scratch) { |
duke@435 | 1818 | if (ProfileInterpreter) { |
duke@435 | 1819 | Label profile_continue; |
duke@435 | 1820 | |
duke@435 | 1821 | // If no method data exists, go to profile_continue. |
duke@435 | 1822 | test_method_data_pointer(profile_continue); |
duke@435 | 1823 | |
duke@435 | 1824 | // Update the default case count |
duke@435 | 1825 | increment_mdp_data_at(in_bytes(MultiBranchData::default_count_offset()), |
duke@435 | 1826 | scratch); |
duke@435 | 1827 | |
duke@435 | 1828 | // The method data pointer needs to be updated. |
duke@435 | 1829 | update_mdp_by_offset( |
duke@435 | 1830 | in_bytes(MultiBranchData::default_displacement_offset()), |
duke@435 | 1831 | scratch); |
duke@435 | 1832 | |
duke@435 | 1833 | bind (profile_continue); |
duke@435 | 1834 | } |
duke@435 | 1835 | } |
duke@435 | 1836 | |
duke@435 | 1837 | // Count the index'th case of a switch construct. |
duke@435 | 1838 | |
duke@435 | 1839 | void InterpreterMacroAssembler::profile_switch_case(Register index, |
duke@435 | 1840 | Register scratch, |
duke@435 | 1841 | Register scratch2, |
duke@435 | 1842 | Register scratch3) { |
duke@435 | 1843 | if (ProfileInterpreter) { |
duke@435 | 1844 | Label profile_continue; |
duke@435 | 1845 | |
duke@435 | 1846 | // If no method data exists, go to profile_continue. |
duke@435 | 1847 | test_method_data_pointer(profile_continue); |
duke@435 | 1848 | |
duke@435 | 1849 | // Build the base (index * per_case_size_in_bytes()) + case_array_offset_in_bytes() |
duke@435 | 1850 | set(in_bytes(MultiBranchData::per_case_size()), scratch); |
duke@435 | 1851 | smul(index, scratch, scratch); |
duke@435 | 1852 | add(scratch, in_bytes(MultiBranchData::case_array_offset()), scratch); |
duke@435 | 1853 | |
duke@435 | 1854 | // Update the case count |
duke@435 | 1855 | increment_mdp_data_at(scratch, |
duke@435 | 1856 | in_bytes(MultiBranchData::relative_count_offset()), |
duke@435 | 1857 | scratch2, |
duke@435 | 1858 | scratch3); |
duke@435 | 1859 | |
duke@435 | 1860 | // The method data pointer needs to be updated. |
duke@435 | 1861 | update_mdp_by_offset(scratch, |
duke@435 | 1862 | in_bytes(MultiBranchData::relative_displacement_offset()), |
duke@435 | 1863 | scratch2); |
duke@435 | 1864 | |
duke@435 | 1865 | bind (profile_continue); |
duke@435 | 1866 | } |
duke@435 | 1867 | } |
duke@435 | 1868 | |
duke@435 | 1869 | // add a InterpMonitorElem to stack (see frame_sparc.hpp) |
duke@435 | 1870 | |
duke@435 | 1871 | void InterpreterMacroAssembler::add_monitor_to_stack( bool stack_is_empty, |
duke@435 | 1872 | Register Rtemp, |
duke@435 | 1873 | Register Rtemp2 ) { |
duke@435 | 1874 | |
duke@435 | 1875 | Register Rlimit = Lmonitors; |
duke@435 | 1876 | const jint delta = frame::interpreter_frame_monitor_size() * wordSize; |
duke@435 | 1877 | assert( (delta & LongAlignmentMask) == 0, |
duke@435 | 1878 | "sizeof BasicObjectLock must be even number of doublewords"); |
duke@435 | 1879 | |
duke@435 | 1880 | sub( SP, delta, SP); |
duke@435 | 1881 | sub( Lesp, delta, Lesp); |
duke@435 | 1882 | sub( Lmonitors, delta, Lmonitors); |
duke@435 | 1883 | |
duke@435 | 1884 | if (!stack_is_empty) { |
duke@435 | 1885 | |
duke@435 | 1886 | // must copy stack contents down |
duke@435 | 1887 | |
duke@435 | 1888 | Label start_copying, next; |
duke@435 | 1889 | |
duke@435 | 1890 | // untested("monitor stack expansion"); |
duke@435 | 1891 | compute_stack_base(Rtemp); |
kvn@3037 | 1892 | ba(start_copying); |
kvn@3037 | 1893 | delayed()->cmp(Rtemp, Rlimit); // done? duplicated below |
duke@435 | 1894 | |
duke@435 | 1895 | // note: must copy from low memory upwards |
duke@435 | 1896 | // On entry to loop, |
duke@435 | 1897 | // Rtemp points to new base of stack, Lesp points to new end of stack (1 past TOS) |
duke@435 | 1898 | // Loop mutates Rtemp |
duke@435 | 1899 | |
duke@435 | 1900 | bind( next); |
duke@435 | 1901 | |
duke@435 | 1902 | st_ptr(Rtemp2, Rtemp, 0); |
duke@435 | 1903 | inc(Rtemp, wordSize); |
duke@435 | 1904 | cmp(Rtemp, Rlimit); // are we done? (duplicated above) |
duke@435 | 1905 | |
duke@435 | 1906 | bind( start_copying ); |
duke@435 | 1907 | |
duke@435 | 1908 | brx( notEqual, true, pn, next ); |
duke@435 | 1909 | delayed()->ld_ptr( Rtemp, delta, Rtemp2 ); |
duke@435 | 1910 | |
duke@435 | 1911 | // done copying stack |
duke@435 | 1912 | } |
duke@435 | 1913 | } |
duke@435 | 1914 | |
duke@435 | 1915 | // Locals |
duke@435 | 1916 | void InterpreterMacroAssembler::access_local_ptr( Register index, Register dst ) { |
duke@435 | 1917 | assert_not_delayed(); |
twisti@1861 | 1918 | sll(index, Interpreter::logStackElementSize, index); |
duke@435 | 1919 | sub(Llocals, index, index); |
twisti@1861 | 1920 | ld_ptr(index, 0, dst); |
duke@435 | 1921 | // Note: index must hold the effective address--the iinc template uses it |
duke@435 | 1922 | } |
duke@435 | 1923 | |
duke@435 | 1924 | // Just like access_local_ptr but the tag is a returnAddress |
duke@435 | 1925 | void InterpreterMacroAssembler::access_local_returnAddress(Register index, |
duke@435 | 1926 | Register dst ) { |
duke@435 | 1927 | assert_not_delayed(); |
twisti@1861 | 1928 | sll(index, Interpreter::logStackElementSize, index); |
duke@435 | 1929 | sub(Llocals, index, index); |
twisti@1861 | 1930 | ld_ptr(index, 0, dst); |
duke@435 | 1931 | } |
duke@435 | 1932 | |
duke@435 | 1933 | void InterpreterMacroAssembler::access_local_int( Register index, Register dst ) { |
duke@435 | 1934 | assert_not_delayed(); |
twisti@1861 | 1935 | sll(index, Interpreter::logStackElementSize, index); |
duke@435 | 1936 | sub(Llocals, index, index); |
twisti@1861 | 1937 | ld(index, 0, dst); |
duke@435 | 1938 | // Note: index must hold the effective address--the iinc template uses it |
duke@435 | 1939 | } |
duke@435 | 1940 | |
duke@435 | 1941 | |
duke@435 | 1942 | void InterpreterMacroAssembler::access_local_long( Register index, Register dst ) { |
duke@435 | 1943 | assert_not_delayed(); |
twisti@1861 | 1944 | sll(index, Interpreter::logStackElementSize, index); |
duke@435 | 1945 | sub(Llocals, index, index); |
duke@435 | 1946 | // First half stored at index n+1 (which grows down from Llocals[n]) |
duke@435 | 1947 | load_unaligned_long(index, Interpreter::local_offset_in_bytes(1), dst); |
duke@435 | 1948 | } |
duke@435 | 1949 | |
duke@435 | 1950 | |
duke@435 | 1951 | void InterpreterMacroAssembler::access_local_float( Register index, FloatRegister dst ) { |
duke@435 | 1952 | assert_not_delayed(); |
twisti@1861 | 1953 | sll(index, Interpreter::logStackElementSize, index); |
duke@435 | 1954 | sub(Llocals, index, index); |
twisti@1861 | 1955 | ldf(FloatRegisterImpl::S, index, 0, dst); |
duke@435 | 1956 | } |
duke@435 | 1957 | |
duke@435 | 1958 | |
duke@435 | 1959 | void InterpreterMacroAssembler::access_local_double( Register index, FloatRegister dst ) { |
duke@435 | 1960 | assert_not_delayed(); |
twisti@1861 | 1961 | sll(index, Interpreter::logStackElementSize, index); |
duke@435 | 1962 | sub(Llocals, index, index); |
duke@435 | 1963 | load_unaligned_double(index, Interpreter::local_offset_in_bytes(1), dst); |
duke@435 | 1964 | } |
duke@435 | 1965 | |
duke@435 | 1966 | |
duke@435 | 1967 | #ifdef ASSERT |
duke@435 | 1968 | void InterpreterMacroAssembler::check_for_regarea_stomp(Register Rindex, int offset, Register Rlimit, Register Rscratch, Register Rscratch1) { |
duke@435 | 1969 | Label L; |
duke@435 | 1970 | |
duke@435 | 1971 | assert(Rindex != Rscratch, "Registers cannot be same"); |
duke@435 | 1972 | assert(Rindex != Rscratch1, "Registers cannot be same"); |
duke@435 | 1973 | assert(Rlimit != Rscratch, "Registers cannot be same"); |
duke@435 | 1974 | assert(Rlimit != Rscratch1, "Registers cannot be same"); |
duke@435 | 1975 | assert(Rscratch1 != Rscratch, "Registers cannot be same"); |
duke@435 | 1976 | |
duke@435 | 1977 | // untested("reg area corruption"); |
duke@435 | 1978 | add(Rindex, offset, Rscratch); |
duke@435 | 1979 | add(Rlimit, 64 + STACK_BIAS, Rscratch1); |
kvn@3037 | 1980 | cmp_and_brx_short(Rscratch, Rscratch1, Assembler::greaterEqualUnsigned, pn, L); |
duke@435 | 1981 | stop("regsave area is being clobbered"); |
duke@435 | 1982 | bind(L); |
duke@435 | 1983 | } |
duke@435 | 1984 | #endif // ASSERT |
duke@435 | 1985 | |
duke@435 | 1986 | |
duke@435 | 1987 | void InterpreterMacroAssembler::store_local_int( Register index, Register src ) { |
duke@435 | 1988 | assert_not_delayed(); |
twisti@1861 | 1989 | sll(index, Interpreter::logStackElementSize, index); |
duke@435 | 1990 | sub(Llocals, index, index); |
twisti@1861 | 1991 | debug_only(check_for_regarea_stomp(index, 0, FP, G1_scratch, G4_scratch);) |
twisti@1861 | 1992 | st(src, index, 0); |
duke@435 | 1993 | } |
duke@435 | 1994 | |
twisti@1861 | 1995 | void InterpreterMacroAssembler::store_local_ptr( Register index, Register src ) { |
duke@435 | 1996 | assert_not_delayed(); |
twisti@1861 | 1997 | sll(index, Interpreter::logStackElementSize, index); |
duke@435 | 1998 | sub(Llocals, index, index); |
twisti@1861 | 1999 | #ifdef ASSERT |
twisti@1861 | 2000 | check_for_regarea_stomp(index, 0, FP, G1_scratch, G4_scratch); |
twisti@1861 | 2001 | #endif |
twisti@1861 | 2002 | st_ptr(src, index, 0); |
duke@435 | 2003 | } |
duke@435 | 2004 | |
duke@435 | 2005 | |
duke@435 | 2006 | |
twisti@1861 | 2007 | void InterpreterMacroAssembler::store_local_ptr( int n, Register src ) { |
twisti@1861 | 2008 | st_ptr(src, Llocals, Interpreter::local_offset_in_bytes(n)); |
duke@435 | 2009 | } |
duke@435 | 2010 | |
duke@435 | 2011 | void InterpreterMacroAssembler::store_local_long( Register index, Register src ) { |
duke@435 | 2012 | assert_not_delayed(); |
twisti@1861 | 2013 | sll(index, Interpreter::logStackElementSize, index); |
duke@435 | 2014 | sub(Llocals, index, index); |
twisti@1861 | 2015 | #ifdef ASSERT |
duke@435 | 2016 | check_for_regarea_stomp(index, Interpreter::local_offset_in_bytes(1), FP, G1_scratch, G4_scratch); |
twisti@1861 | 2017 | #endif |
duke@435 | 2018 | store_unaligned_long(src, index, Interpreter::local_offset_in_bytes(1)); // which is n+1 |
duke@435 | 2019 | } |
duke@435 | 2020 | |
duke@435 | 2021 | |
duke@435 | 2022 | void InterpreterMacroAssembler::store_local_float( Register index, FloatRegister src ) { |
duke@435 | 2023 | assert_not_delayed(); |
twisti@1861 | 2024 | sll(index, Interpreter::logStackElementSize, index); |
duke@435 | 2025 | sub(Llocals, index, index); |
twisti@1861 | 2026 | #ifdef ASSERT |
twisti@1861 | 2027 | check_for_regarea_stomp(index, 0, FP, G1_scratch, G4_scratch); |
twisti@1861 | 2028 | #endif |
twisti@1861 | 2029 | stf(FloatRegisterImpl::S, src, index, 0); |
duke@435 | 2030 | } |
duke@435 | 2031 | |
duke@435 | 2032 | |
duke@435 | 2033 | void InterpreterMacroAssembler::store_local_double( Register index, FloatRegister src ) { |
duke@435 | 2034 | assert_not_delayed(); |
twisti@1861 | 2035 | sll(index, Interpreter::logStackElementSize, index); |
duke@435 | 2036 | sub(Llocals, index, index); |
twisti@1861 | 2037 | #ifdef ASSERT |
duke@435 | 2038 | check_for_regarea_stomp(index, Interpreter::local_offset_in_bytes(1), FP, G1_scratch, G4_scratch); |
twisti@1861 | 2039 | #endif |
duke@435 | 2040 | store_unaligned_double(src, index, Interpreter::local_offset_in_bytes(1)); |
duke@435 | 2041 | } |
duke@435 | 2042 | |
duke@435 | 2043 | |
duke@435 | 2044 | int InterpreterMacroAssembler::top_most_monitor_byte_offset() { |
duke@435 | 2045 | const jint delta = frame::interpreter_frame_monitor_size() * wordSize; |
duke@435 | 2046 | int rounded_vm_local_words = ::round_to(frame::interpreter_frame_vm_local_words, WordsPerLong); |
duke@435 | 2047 | return ((-rounded_vm_local_words * wordSize) - delta ) + STACK_BIAS; |
duke@435 | 2048 | } |
duke@435 | 2049 | |
duke@435 | 2050 | |
duke@435 | 2051 | Address InterpreterMacroAssembler::top_most_monitor() { |
twisti@1162 | 2052 | return Address(FP, top_most_monitor_byte_offset()); |
duke@435 | 2053 | } |
duke@435 | 2054 | |
duke@435 | 2055 | |
duke@435 | 2056 | void InterpreterMacroAssembler::compute_stack_base( Register Rdest ) { |
duke@435 | 2057 | add( Lesp, wordSize, Rdest ); |
duke@435 | 2058 | } |
duke@435 | 2059 | |
duke@435 | 2060 | #endif /* CC_INTERP */ |
duke@435 | 2061 | |
duke@435 | 2062 | void InterpreterMacroAssembler::increment_invocation_counter( Register Rtmp, Register Rtmp2 ) { |
duke@435 | 2063 | assert(UseCompiler, "incrementing must be useful"); |
duke@435 | 2064 | #ifdef CC_INTERP |
twisti@1162 | 2065 | Address inv_counter(G5_method, methodOopDesc::invocation_counter_offset() + |
twisti@1162 | 2066 | InvocationCounter::counter_offset()); |
twisti@1162 | 2067 | Address be_counter (G5_method, methodOopDesc::backedge_counter_offset() + |
twisti@1162 | 2068 | InvocationCounter::counter_offset()); |
duke@435 | 2069 | #else |
twisti@1162 | 2070 | Address inv_counter(Lmethod, methodOopDesc::invocation_counter_offset() + |
twisti@1162 | 2071 | InvocationCounter::counter_offset()); |
twisti@1162 | 2072 | Address be_counter (Lmethod, methodOopDesc::backedge_counter_offset() + |
twisti@1162 | 2073 | InvocationCounter::counter_offset()); |
duke@435 | 2074 | #endif /* CC_INTERP */ |
duke@435 | 2075 | int delta = InvocationCounter::count_increment; |
duke@435 | 2076 | |
duke@435 | 2077 | // Load each counter in a register |
duke@435 | 2078 | ld( inv_counter, Rtmp ); |
duke@435 | 2079 | ld( be_counter, Rtmp2 ); |
duke@435 | 2080 | |
duke@435 | 2081 | assert( is_simm13( delta ), " delta too large."); |
duke@435 | 2082 | |
duke@435 | 2083 | // Add the delta to the invocation counter and store the result |
duke@435 | 2084 | add( Rtmp, delta, Rtmp ); |
duke@435 | 2085 | |
duke@435 | 2086 | // Mask the backedge counter |
duke@435 | 2087 | and3( Rtmp2, InvocationCounter::count_mask_value, Rtmp2 ); |
duke@435 | 2088 | |
duke@435 | 2089 | // Store value |
duke@435 | 2090 | st( Rtmp, inv_counter); |
duke@435 | 2091 | |
duke@435 | 2092 | // Add invocation counter + backedge counter |
duke@435 | 2093 | add( Rtmp, Rtmp2, Rtmp); |
duke@435 | 2094 | |
duke@435 | 2095 | // Note that this macro must leave the backedge_count + invocation_count in Rtmp! |
duke@435 | 2096 | } |
duke@435 | 2097 | |
duke@435 | 2098 | void InterpreterMacroAssembler::increment_backedge_counter( Register Rtmp, Register Rtmp2 ) { |
duke@435 | 2099 | assert(UseCompiler, "incrementing must be useful"); |
duke@435 | 2100 | #ifdef CC_INTERP |
twisti@1162 | 2101 | Address be_counter (G5_method, methodOopDesc::backedge_counter_offset() + |
twisti@1162 | 2102 | InvocationCounter::counter_offset()); |
twisti@1162 | 2103 | Address inv_counter(G5_method, methodOopDesc::invocation_counter_offset() + |
twisti@1162 | 2104 | InvocationCounter::counter_offset()); |
duke@435 | 2105 | #else |
twisti@1162 | 2106 | Address be_counter (Lmethod, methodOopDesc::backedge_counter_offset() + |
twisti@1162 | 2107 | InvocationCounter::counter_offset()); |
twisti@1162 | 2108 | Address inv_counter(Lmethod, methodOopDesc::invocation_counter_offset() + |
twisti@1162 | 2109 | InvocationCounter::counter_offset()); |
duke@435 | 2110 | #endif /* CC_INTERP */ |
duke@435 | 2111 | int delta = InvocationCounter::count_increment; |
duke@435 | 2112 | // Load each counter in a register |
duke@435 | 2113 | ld( be_counter, Rtmp ); |
duke@435 | 2114 | ld( inv_counter, Rtmp2 ); |
duke@435 | 2115 | |
duke@435 | 2116 | // Add the delta to the backedge counter |
duke@435 | 2117 | add( Rtmp, delta, Rtmp ); |
duke@435 | 2118 | |
duke@435 | 2119 | // Mask the invocation counter, add to backedge counter |
duke@435 | 2120 | and3( Rtmp2, InvocationCounter::count_mask_value, Rtmp2 ); |
duke@435 | 2121 | |
duke@435 | 2122 | // and store the result to memory |
duke@435 | 2123 | st( Rtmp, be_counter ); |
duke@435 | 2124 | |
duke@435 | 2125 | // Add backedge + invocation counter |
duke@435 | 2126 | add( Rtmp, Rtmp2, Rtmp ); |
duke@435 | 2127 | |
duke@435 | 2128 | // Note that this macro must leave backedge_count + invocation_count in Rtmp! |
duke@435 | 2129 | } |
duke@435 | 2130 | |
duke@435 | 2131 | #ifndef CC_INTERP |
duke@435 | 2132 | void InterpreterMacroAssembler::test_backedge_count_for_osr( Register backedge_count, |
duke@435 | 2133 | Register branch_bcp, |
duke@435 | 2134 | Register Rtmp ) { |
duke@435 | 2135 | Label did_not_overflow; |
duke@435 | 2136 | Label overflow_with_error; |
duke@435 | 2137 | assert_different_registers(backedge_count, Rtmp, branch_bcp); |
duke@435 | 2138 | assert(UseOnStackReplacement,"Must UseOnStackReplacement to test_backedge_count_for_osr"); |
duke@435 | 2139 | |
twisti@1162 | 2140 | AddressLiteral limit(&InvocationCounter::InterpreterBackwardBranchLimit); |
duke@435 | 2141 | load_contents(limit, Rtmp); |
kvn@3037 | 2142 | cmp_and_br_short(backedge_count, Rtmp, Assembler::lessUnsigned, Assembler::pt, did_not_overflow); |
duke@435 | 2143 | |
duke@435 | 2144 | // When ProfileInterpreter is on, the backedge_count comes from the |
duke@435 | 2145 | // methodDataOop, which value does not get reset on the call to |
duke@435 | 2146 | // frequency_counter_overflow(). To avoid excessive calls to the overflow |
duke@435 | 2147 | // routine while the method is being compiled, add a second test to make sure |
duke@435 | 2148 | // the overflow function is called only once every overflow_frequency. |
duke@435 | 2149 | if (ProfileInterpreter) { |
duke@435 | 2150 | const int overflow_frequency = 1024; |
duke@435 | 2151 | andcc(backedge_count, overflow_frequency-1, Rtmp); |
duke@435 | 2152 | brx(Assembler::notZero, false, Assembler::pt, did_not_overflow); |
duke@435 | 2153 | delayed()->nop(); |
duke@435 | 2154 | } |
duke@435 | 2155 | |
duke@435 | 2156 | // overflow in loop, pass branch bytecode |
duke@435 | 2157 | set(6,Rtmp); |
duke@435 | 2158 | call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), branch_bcp, Rtmp); |
duke@435 | 2159 | |
duke@435 | 2160 | // Was an OSR adapter generated? |
duke@435 | 2161 | // O0 = osr nmethod |
kvn@3037 | 2162 | br_null_short(O0, Assembler::pn, overflow_with_error); |
duke@435 | 2163 | |
duke@435 | 2164 | // Has the nmethod been invalidated already? |
duke@435 | 2165 | ld(O0, nmethod::entry_bci_offset(), O2); |
kvn@3037 | 2166 | cmp_and_br_short(O2, InvalidOSREntryBci, Assembler::equal, Assembler::pn, overflow_with_error); |
duke@435 | 2167 | |
duke@435 | 2168 | // migrate the interpreter frame off of the stack |
duke@435 | 2169 | |
duke@435 | 2170 | mov(G2_thread, L7); |
duke@435 | 2171 | // save nmethod |
duke@435 | 2172 | mov(O0, L6); |
duke@435 | 2173 | set_last_Java_frame(SP, noreg); |
duke@435 | 2174 | call_VM_leaf(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::OSR_migration_begin), L7); |
duke@435 | 2175 | reset_last_Java_frame(); |
duke@435 | 2176 | mov(L7, G2_thread); |
duke@435 | 2177 | |
duke@435 | 2178 | // move OSR nmethod to I1 |
duke@435 | 2179 | mov(L6, I1); |
duke@435 | 2180 | |
duke@435 | 2181 | // OSR buffer to I0 |
duke@435 | 2182 | mov(O0, I0); |
duke@435 | 2183 | |
duke@435 | 2184 | // remove the interpreter frame |
duke@435 | 2185 | restore(I5_savedSP, 0, SP); |
duke@435 | 2186 | |
duke@435 | 2187 | // Jump to the osr code. |
duke@435 | 2188 | ld_ptr(O1, nmethod::osr_entry_point_offset(), O2); |
duke@435 | 2189 | jmp(O2, G0); |
duke@435 | 2190 | delayed()->nop(); |
duke@435 | 2191 | |
duke@435 | 2192 | bind(overflow_with_error); |
duke@435 | 2193 | |
duke@435 | 2194 | bind(did_not_overflow); |
duke@435 | 2195 | } |
duke@435 | 2196 | |
duke@435 | 2197 | |
duke@435 | 2198 | |
duke@435 | 2199 | void InterpreterMacroAssembler::interp_verify_oop(Register reg, TosState state, const char * file, int line) { |
duke@435 | 2200 | if (state == atos) { MacroAssembler::_verify_oop(reg, "broken oop ", file, line); } |
duke@435 | 2201 | } |
duke@435 | 2202 | |
duke@435 | 2203 | |
duke@435 | 2204 | // local helper function for the verify_oop_or_return_address macro |
duke@435 | 2205 | static bool verify_return_address(methodOopDesc* m, int bci) { |
duke@435 | 2206 | #ifndef PRODUCT |
duke@435 | 2207 | address pc = (address)(m->constMethod()) |
duke@435 | 2208 | + in_bytes(constMethodOopDesc::codes_offset()) + bci; |
duke@435 | 2209 | // assume it is a valid return address if it is inside m and is preceded by a jsr |
duke@435 | 2210 | if (!m->contains(pc)) return false; |
duke@435 | 2211 | address jsr_pc; |
duke@435 | 2212 | jsr_pc = pc - Bytecodes::length_for(Bytecodes::_jsr); |
duke@435 | 2213 | if (*jsr_pc == Bytecodes::_jsr && jsr_pc >= m->code_base()) return true; |
duke@435 | 2214 | jsr_pc = pc - Bytecodes::length_for(Bytecodes::_jsr_w); |
duke@435 | 2215 | if (*jsr_pc == Bytecodes::_jsr_w && jsr_pc >= m->code_base()) return true; |
duke@435 | 2216 | #endif // PRODUCT |
duke@435 | 2217 | return false; |
duke@435 | 2218 | } |
duke@435 | 2219 | |
duke@435 | 2220 | |
duke@435 | 2221 | void InterpreterMacroAssembler::verify_oop_or_return_address(Register reg, Register Rtmp) { |
duke@435 | 2222 | if (!VerifyOops) return; |
duke@435 | 2223 | // the VM documentation for the astore[_wide] bytecode allows |
duke@435 | 2224 | // the TOS to be not only an oop but also a return address |
duke@435 | 2225 | Label test; |
duke@435 | 2226 | Label skip; |
duke@435 | 2227 | // See if it is an address (in the current method): |
duke@435 | 2228 | |
duke@435 | 2229 | mov(reg, Rtmp); |
duke@435 | 2230 | const int log2_bytecode_size_limit = 16; |
duke@435 | 2231 | srl(Rtmp, log2_bytecode_size_limit, Rtmp); |
kvn@3037 | 2232 | br_notnull_short( Rtmp, pt, test ); |
duke@435 | 2233 | |
duke@435 | 2234 | // %%% should use call_VM_leaf here? |
duke@435 | 2235 | save_frame_and_mov(0, Lmethod, O0, reg, O1); |
duke@435 | 2236 | save_thread(L7_thread_cache); |
duke@435 | 2237 | call(CAST_FROM_FN_PTR(address,verify_return_address), relocInfo::none); |
duke@435 | 2238 | delayed()->nop(); |
duke@435 | 2239 | restore_thread(L7_thread_cache); |
duke@435 | 2240 | br_notnull( O0, false, pt, skip ); |
duke@435 | 2241 | delayed()->restore(); |
duke@435 | 2242 | |
duke@435 | 2243 | // Perform a more elaborate out-of-line call |
duke@435 | 2244 | // Not an address; verify it: |
duke@435 | 2245 | bind(test); |
duke@435 | 2246 | verify_oop(reg); |
duke@435 | 2247 | bind(skip); |
duke@435 | 2248 | } |
duke@435 | 2249 | |
duke@435 | 2250 | |
duke@435 | 2251 | void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) { |
duke@435 | 2252 | if (state == ftos || state == dtos) MacroAssembler::verify_FPU(stack_depth); |
duke@435 | 2253 | } |
duke@435 | 2254 | #endif /* CC_INTERP */ |
duke@435 | 2255 | |
duke@435 | 2256 | // Inline assembly for: |
duke@435 | 2257 | // |
duke@435 | 2258 | // if (thread is in interp_only_mode) { |
duke@435 | 2259 | // InterpreterRuntime::post_method_entry(); |
duke@435 | 2260 | // } |
duke@435 | 2261 | // if (DTraceMethodProbes) { |
twisti@1040 | 2262 | // SharedRuntime::dtrace_method_entry(method, receiver); |
duke@435 | 2263 | // } |
dcubed@1045 | 2264 | // if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) { |
dcubed@1045 | 2265 | // SharedRuntime::rc_trace_method_entry(method, receiver); |
coleenp@857 | 2266 | // } |
duke@435 | 2267 | |
duke@435 | 2268 | void InterpreterMacroAssembler::notify_method_entry() { |
duke@435 | 2269 | |
duke@435 | 2270 | // C++ interpreter only uses this for native methods. |
duke@435 | 2271 | |
duke@435 | 2272 | // Whenever JVMTI puts a thread in interp_only_mode, method |
duke@435 | 2273 | // entry/exit events are sent for that thread to track stack |
duke@435 | 2274 | // depth. If it is possible to enter interp_only_mode we add |
duke@435 | 2275 | // the code to check if the event should be sent. |
duke@435 | 2276 | if (JvmtiExport::can_post_interpreter_events()) { |
duke@435 | 2277 | Label L; |
duke@435 | 2278 | Register temp_reg = O5; |
twisti@1162 | 2279 | const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset()); |
duke@435 | 2280 | ld(interp_only, temp_reg); |
kvn@3037 | 2281 | cmp_and_br_short(temp_reg, 0, equal, pt, L); |
duke@435 | 2282 | call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_entry)); |
duke@435 | 2283 | bind(L); |
duke@435 | 2284 | } |
duke@435 | 2285 | |
duke@435 | 2286 | { |
duke@435 | 2287 | Register temp_reg = O5; |
duke@435 | 2288 | SkipIfEqual skip_if(this, temp_reg, &DTraceMethodProbes, zero); |
duke@435 | 2289 | call_VM_leaf(noreg, |
duke@435 | 2290 | CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), |
duke@435 | 2291 | G2_thread, Lmethod); |
duke@435 | 2292 | } |
dcubed@1045 | 2293 | |
dcubed@1045 | 2294 | // RedefineClasses() tracing support for obsolete method entry |
dcubed@1045 | 2295 | if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) { |
dcubed@1045 | 2296 | call_VM_leaf(noreg, |
dcubed@1045 | 2297 | CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry), |
dcubed@1045 | 2298 | G2_thread, Lmethod); |
dcubed@1045 | 2299 | } |
duke@435 | 2300 | } |
duke@435 | 2301 | |
duke@435 | 2302 | |
duke@435 | 2303 | // Inline assembly for: |
duke@435 | 2304 | // |
duke@435 | 2305 | // if (thread is in interp_only_mode) { |
duke@435 | 2306 | // // save result |
duke@435 | 2307 | // InterpreterRuntime::post_method_exit(); |
duke@435 | 2308 | // // restore result |
duke@435 | 2309 | // } |
duke@435 | 2310 | // if (DTraceMethodProbes) { |
duke@435 | 2311 | // SharedRuntime::dtrace_method_exit(thread, method); |
duke@435 | 2312 | // } |
duke@435 | 2313 | // |
duke@435 | 2314 | // Native methods have their result stored in d_tmp and l_tmp |
duke@435 | 2315 | // Java methods have their result stored in the expression stack |
duke@435 | 2316 | |
duke@435 | 2317 | void InterpreterMacroAssembler::notify_method_exit(bool is_native_method, |
duke@435 | 2318 | TosState state, |
duke@435 | 2319 | NotifyMethodExitMode mode) { |
duke@435 | 2320 | // C++ interpreter only uses this for native methods. |
duke@435 | 2321 | |
duke@435 | 2322 | // Whenever JVMTI puts a thread in interp_only_mode, method |
duke@435 | 2323 | // entry/exit events are sent for that thread to track stack |
duke@435 | 2324 | // depth. If it is possible to enter interp_only_mode we add |
duke@435 | 2325 | // the code to check if the event should be sent. |
duke@435 | 2326 | if (mode == NotifyJVMTI && JvmtiExport::can_post_interpreter_events()) { |
duke@435 | 2327 | Label L; |
duke@435 | 2328 | Register temp_reg = O5; |
twisti@1162 | 2329 | const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset()); |
duke@435 | 2330 | ld(interp_only, temp_reg); |
kvn@3037 | 2331 | cmp_and_br_short(temp_reg, 0, equal, pt, L); |
duke@435 | 2332 | |
duke@435 | 2333 | // Note: frame::interpreter_frame_result has a dependency on how the |
duke@435 | 2334 | // method result is saved across the call to post_method_exit. For |
duke@435 | 2335 | // native methods it assumes the result registers are saved to |
duke@435 | 2336 | // l_scratch and d_scratch. If this changes then the interpreter_frame_result |
duke@435 | 2337 | // implementation will need to be updated too. |
duke@435 | 2338 | |
duke@435 | 2339 | save_return_value(state, is_native_method); |
duke@435 | 2340 | call_VM(noreg, |
duke@435 | 2341 | CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_exit)); |
duke@435 | 2342 | restore_return_value(state, is_native_method); |
duke@435 | 2343 | bind(L); |
duke@435 | 2344 | } |
duke@435 | 2345 | |
duke@435 | 2346 | { |
duke@435 | 2347 | Register temp_reg = O5; |
duke@435 | 2348 | // Dtrace notification |
duke@435 | 2349 | SkipIfEqual skip_if(this, temp_reg, &DTraceMethodProbes, zero); |
duke@435 | 2350 | save_return_value(state, is_native_method); |
duke@435 | 2351 | call_VM_leaf( |
duke@435 | 2352 | noreg, |
duke@435 | 2353 | CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), |
duke@435 | 2354 | G2_thread, Lmethod); |
duke@435 | 2355 | restore_return_value(state, is_native_method); |
duke@435 | 2356 | } |
duke@435 | 2357 | } |
duke@435 | 2358 | |
duke@435 | 2359 | void InterpreterMacroAssembler::save_return_value(TosState state, bool is_native_call) { |
duke@435 | 2360 | #ifdef CC_INTERP |
duke@435 | 2361 | // result potentially in O0/O1: save it across calls |
duke@435 | 2362 | stf(FloatRegisterImpl::D, F0, STATE(_native_fresult)); |
duke@435 | 2363 | #ifdef _LP64 |
duke@435 | 2364 | stx(O0, STATE(_native_lresult)); |
duke@435 | 2365 | #else |
duke@435 | 2366 | std(O0, STATE(_native_lresult)); |
duke@435 | 2367 | #endif |
duke@435 | 2368 | #else // CC_INTERP |
duke@435 | 2369 | if (is_native_call) { |
duke@435 | 2370 | stf(FloatRegisterImpl::D, F0, d_tmp); |
duke@435 | 2371 | #ifdef _LP64 |
duke@435 | 2372 | stx(O0, l_tmp); |
duke@435 | 2373 | #else |
duke@435 | 2374 | std(O0, l_tmp); |
duke@435 | 2375 | #endif |
duke@435 | 2376 | } else { |
duke@435 | 2377 | push(state); |
duke@435 | 2378 | } |
duke@435 | 2379 | #endif // CC_INTERP |
duke@435 | 2380 | } |
duke@435 | 2381 | |
duke@435 | 2382 | void InterpreterMacroAssembler::restore_return_value( TosState state, bool is_native_call) { |
duke@435 | 2383 | #ifdef CC_INTERP |
duke@435 | 2384 | ldf(FloatRegisterImpl::D, STATE(_native_fresult), F0); |
duke@435 | 2385 | #ifdef _LP64 |
duke@435 | 2386 | ldx(STATE(_native_lresult), O0); |
duke@435 | 2387 | #else |
duke@435 | 2388 | ldd(STATE(_native_lresult), O0); |
duke@435 | 2389 | #endif |
duke@435 | 2390 | #else // CC_INTERP |
duke@435 | 2391 | if (is_native_call) { |
duke@435 | 2392 | ldf(FloatRegisterImpl::D, d_tmp, F0); |
duke@435 | 2393 | #ifdef _LP64 |
duke@435 | 2394 | ldx(l_tmp, O0); |
duke@435 | 2395 | #else |
duke@435 | 2396 | ldd(l_tmp, O0); |
duke@435 | 2397 | #endif |
duke@435 | 2398 | } else { |
duke@435 | 2399 | pop(state); |
duke@435 | 2400 | } |
duke@435 | 2401 | #endif // CC_INTERP |
duke@435 | 2402 | } |
iveresov@2138 | 2403 | |
iveresov@2138 | 2404 | // Jump if ((*counter_addr += increment) & mask) satisfies the condition. |
iveresov@2138 | 2405 | void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr, |
iveresov@2138 | 2406 | int increment, int mask, |
iveresov@2138 | 2407 | Register scratch1, Register scratch2, |
iveresov@2138 | 2408 | Condition cond, Label *where) { |
iveresov@2138 | 2409 | ld(counter_addr, scratch1); |
iveresov@2138 | 2410 | add(scratch1, increment, scratch1); |
iveresov@2138 | 2411 | if (is_simm13(mask)) { |
iveresov@2138 | 2412 | andcc(scratch1, mask, G0); |
iveresov@2138 | 2413 | } else { |
iveresov@2138 | 2414 | set(mask, scratch2); |
iveresov@2138 | 2415 | andcc(scratch1, scratch2, G0); |
iveresov@2138 | 2416 | } |
iveresov@2138 | 2417 | br(cond, false, Assembler::pn, *where); |
iveresov@2138 | 2418 | delayed()->st(scratch1, counter_addr); |
iveresov@2138 | 2419 | } |