annotate src/cpu/sparc/vm/interp_masm_sparc.cpp @ 2368:dde920245681

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