annotate src/cpu/sparc/vm/interp_masm_sparc.cpp @ 6812:988bf00cc564

7200261: G1: Liveness counting inconsistencies during marking verification Summary: The clipping code in the routine that sets the bits for a range of cards, in the liveness accounting verification code was incorrect. It set all the bits in the card bitmap from the given starting index which would lead to spurious marking verification failures. Reviewed-by: brutisso, jwilhelm, jmasa
author johnc
date Thu, 27 Sep 2012 15:44:01 -0700
parents da91efe96a93
children 69fb89ec6fa7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
6123
2fe087c3e814 7172967: Eliminate constMethod's _method backpointer to methodOop.
jiangli
parents: 3852
diff changeset
2 * Copyright (c) 1997, 2012, 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"
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
31 #include "oops/methodData.hpp"
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
32 #include "oops/method.hpp"
1972
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);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
239 br_null_short(thr_state, pt, L); // if (thread->jvmti_thread_state() == NULL) exit;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
240
a61af66fc99e Initial load
duke
parents:
diff changeset
241 // Initiate earlyret handling only if it is not already being processed.
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // If the flag has the earlyret_processing bit set, it means that this code
a61af66fc99e Initial load
duke
parents:
diff changeset
243 // is called *during* earlyret handling - we don't want to reenter.
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
244 ld(thr_state, JvmtiThreadState::earlyret_state_offset(), G4_scratch);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
245 cmp_and_br_short(G4_scratch, JvmtiThreadState::earlyret_pending, Assembler::notEqual, pt, L);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 // Call Interpreter::remove_activation_early_entry() to get the address of the
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // same-named entrypoint in the generated interpreter code
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
249 ld(thr_state, JvmtiThreadState::earlyret_tos_offset(), Otos_l1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
250 call_VM_leaf(noreg, CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), Otos_l1);
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // Jump to Interpreter::_remove_activation_early_entry
a61af66fc99e Initial load
duke
parents:
diff changeset
253 jmpl(O0, G0, G0);
a61af66fc99e Initial load
duke
parents:
diff changeset
254 delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
255 bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258
a61af66fc99e Initial load
duke
parents:
diff changeset
259
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1251
diff changeset
260 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
261 mov(arg_1, O0);
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1251
diff changeset
262 mov(arg_2, O1);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1251
diff changeset
263 MacroAssembler::call_VM_leaf_base(thread_cache, entry_point, 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
265 #endif /* CC_INTERP */
a61af66fc99e Initial load
duke
parents:
diff changeset
266
a61af66fc99e Initial load
duke
parents:
diff changeset
267
a61af66fc99e Initial load
duke
parents:
diff changeset
268 #ifndef CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
269
a61af66fc99e Initial load
duke
parents:
diff changeset
270 void InterpreterMacroAssembler::dispatch_base(TosState state, address* table) {
a61af66fc99e Initial load
duke
parents:
diff changeset
271 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
272 dispatch_Lbyte_code(state, table);
a61af66fc99e Initial load
duke
parents:
diff changeset
273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
274
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 void InterpreterMacroAssembler::dispatch_normal(TosState state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
277 dispatch_base(state, Interpreter::normal_table(state));
a61af66fc99e Initial load
duke
parents:
diff changeset
278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
279
a61af66fc99e Initial load
duke
parents:
diff changeset
280
a61af66fc99e Initial load
duke
parents:
diff changeset
281 void InterpreterMacroAssembler::dispatch_only(TosState state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
282 dispatch_base(state, Interpreter::dispatch_table(state));
a61af66fc99e Initial load
duke
parents:
diff changeset
283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
284
a61af66fc99e Initial load
duke
parents:
diff changeset
285
a61af66fc99e Initial load
duke
parents:
diff changeset
286 // common code to dispatch and dispatch_only
a61af66fc99e Initial load
duke
parents:
diff changeset
287 // dispatch value in Lbyte_code and increment Lbcp
a61af66fc99e Initial load
duke
parents:
diff changeset
288
a61af66fc99e Initial load
duke
parents:
diff changeset
289 void InterpreterMacroAssembler::dispatch_Lbyte_code(TosState state, address* table, int bcp_incr, bool verify) {
a61af66fc99e Initial load
duke
parents:
diff changeset
290 verify_FPU(1, state);
a61af66fc99e Initial load
duke
parents:
diff changeset
291 // %%%%% maybe implement +VerifyActivationFrameSize here
a61af66fc99e Initial load
duke
parents:
diff changeset
292 //verify_thread(); //too slow; we will just verify on method entry & exit
a61af66fc99e Initial load
duke
parents:
diff changeset
293 if (verify) interp_verify_oop(Otos_i, state, __FILE__, __LINE__);
a61af66fc99e Initial load
duke
parents:
diff changeset
294 #ifdef FAST_DISPATCH
a61af66fc99e Initial load
duke
parents:
diff changeset
295 if (table == Interpreter::dispatch_table(state)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
296 // use IdispatchTables
a61af66fc99e Initial load
duke
parents:
diff changeset
297 add(Lbyte_code, Interpreter::distance_from_dispatch_table(state), Lbyte_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // add offset to correct dispatch table
a61af66fc99e Initial load
duke
parents:
diff changeset
299 sll(Lbyte_code, LogBytesPerWord, Lbyte_code); // multiply by wordSize
a61af66fc99e Initial load
duke
parents:
diff changeset
300 ld_ptr(IdispatchTables, Lbyte_code, G3_scratch); // get entry addr
a61af66fc99e Initial load
duke
parents:
diff changeset
301 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
302 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
303 // dispatch table to use
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
304 AddressLiteral tbl(table);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
305 sll(Lbyte_code, LogBytesPerWord, Lbyte_code); // multiply by wordSize
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
306 set(tbl, G3_scratch); // compute addr of table
0
a61af66fc99e Initial load
duke
parents:
diff changeset
307 ld_ptr(G3_scratch, Lbyte_code, G3_scratch); // get entry addr
a61af66fc99e Initial load
duke
parents:
diff changeset
308 #ifdef FAST_DISPATCH
a61af66fc99e Initial load
duke
parents:
diff changeset
309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
310 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
311 jmp( G3_scratch, 0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
312 if (bcp_incr != 0) delayed()->inc(Lbcp, bcp_incr);
a61af66fc99e Initial load
duke
parents:
diff changeset
313 else delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
315
a61af66fc99e Initial load
duke
parents:
diff changeset
316
a61af66fc99e Initial load
duke
parents:
diff changeset
317 // Helpers for expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // Longs and doubles are Category 2 computational types in the
a61af66fc99e Initial load
duke
parents:
diff changeset
320 // JVM specification (section 3.11.1) and take 2 expression stack or
a61af66fc99e Initial load
duke
parents:
diff changeset
321 // local slots.
a61af66fc99e Initial load
duke
parents:
diff changeset
322 // Aligning them on 32 bit with tagged stacks is hard because the code generated
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // for the dup* bytecodes depends on what types are already on the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // If the types are split into the two stack/local slots, that is much easier
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // (and we can use 0 for non-reference tags).
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // Known good alignment in _LP64 but unknown otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
328 void InterpreterMacroAssembler::load_unaligned_double(Register r1, int offset, FloatRegister d) {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
330
a61af66fc99e Initial load
duke
parents:
diff changeset
331 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
332 ldf(FloatRegisterImpl::D, r1, offset, d);
a61af66fc99e Initial load
duke
parents:
diff changeset
333 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
334 ldf(FloatRegisterImpl::S, r1, offset, d);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
335 ldf(FloatRegisterImpl::S, r1, offset + Interpreter::stackElementSize, d->successor());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
336 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
338
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // Known good alignment in _LP64 but unknown otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
340 void InterpreterMacroAssembler::store_unaligned_double(FloatRegister d, Register r1, int offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
341 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
342
a61af66fc99e Initial load
duke
parents:
diff changeset
343 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
344 stf(FloatRegisterImpl::D, d, r1, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
345 // store something more useful here
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
346 debug_only(stx(G0, r1, offset+Interpreter::stackElementSize);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
347 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
348 stf(FloatRegisterImpl::S, d, r1, offset);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
349 stf(FloatRegisterImpl::S, d->successor(), r1, offset + Interpreter::stackElementSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
350 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
352
a61af66fc99e Initial load
duke
parents:
diff changeset
353
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // Known good alignment in _LP64 but unknown otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
355 void InterpreterMacroAssembler::load_unaligned_long(Register r1, int offset, Register rd) {
a61af66fc99e Initial load
duke
parents:
diff changeset
356 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
357 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
358 ldx(r1, offset, rd);
a61af66fc99e Initial load
duke
parents:
diff changeset
359 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
360 ld(r1, offset, rd);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
361 ld(r1, offset + Interpreter::stackElementSize, rd->successor());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
362 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
364
a61af66fc99e Initial load
duke
parents:
diff changeset
365 // Known good alignment in _LP64 but unknown otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
366 void InterpreterMacroAssembler::store_unaligned_long(Register l, Register r1, int offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
367 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
368
a61af66fc99e Initial load
duke
parents:
diff changeset
369 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
370 stx(l, r1, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
371 // store something more useful here
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
372 debug_only(stx(G0, r1, offset+Interpreter::stackElementSize);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
373 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
374 st(l, r1, offset);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
375 st(l->successor(), r1, offset + Interpreter::stackElementSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
376 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
378
a61af66fc99e Initial load
duke
parents:
diff changeset
379 void InterpreterMacroAssembler::pop_i(Register r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
380 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
381 ld(Lesp, Interpreter::expr_offset_in_bytes(0), r);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
382 inc(Lesp, Interpreter::stackElementSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
383 debug_only(verify_esp(Lesp));
a61af66fc99e Initial load
duke
parents:
diff changeset
384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
385
a61af66fc99e Initial load
duke
parents:
diff changeset
386 void InterpreterMacroAssembler::pop_ptr(Register r, Register scratch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
387 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
388 ld_ptr(Lesp, Interpreter::expr_offset_in_bytes(0), r);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
389 inc(Lesp, Interpreter::stackElementSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
390 debug_only(verify_esp(Lesp));
a61af66fc99e Initial load
duke
parents:
diff changeset
391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
392
a61af66fc99e Initial load
duke
parents:
diff changeset
393 void InterpreterMacroAssembler::pop_l(Register r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
395 load_unaligned_long(Lesp, Interpreter::expr_offset_in_bytes(0), r);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
396 inc(Lesp, 2*Interpreter::stackElementSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
397 debug_only(verify_esp(Lesp));
a61af66fc99e Initial load
duke
parents:
diff changeset
398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400
a61af66fc99e Initial load
duke
parents:
diff changeset
401 void InterpreterMacroAssembler::pop_f(FloatRegister f, Register scratch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
402 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
403 ldf(FloatRegisterImpl::S, Lesp, Interpreter::expr_offset_in_bytes(0), f);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
404 inc(Lesp, Interpreter::stackElementSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
405 debug_only(verify_esp(Lesp));
a61af66fc99e Initial load
duke
parents:
diff changeset
406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
407
a61af66fc99e Initial load
duke
parents:
diff changeset
408
a61af66fc99e Initial load
duke
parents:
diff changeset
409 void InterpreterMacroAssembler::pop_d(FloatRegister f, Register scratch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
410 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
411 load_unaligned_double(Lesp, Interpreter::expr_offset_in_bytes(0), f);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
412 inc(Lesp, 2*Interpreter::stackElementSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
413 debug_only(verify_esp(Lesp));
a61af66fc99e Initial load
duke
parents:
diff changeset
414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
415
a61af66fc99e Initial load
duke
parents:
diff changeset
416
a61af66fc99e Initial load
duke
parents:
diff changeset
417 void InterpreterMacroAssembler::push_i(Register r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
418 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
419 debug_only(verify_esp(Lesp));
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
420 st(r, Lesp, 0);
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
421 dec(Lesp, Interpreter::stackElementSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
423
a61af66fc99e Initial load
duke
parents:
diff changeset
424 void InterpreterMacroAssembler::push_ptr(Register r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
425 assert_not_delayed();
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
426 st_ptr(r, Lesp, 0);
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
427 dec(Lesp, Interpreter::stackElementSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
429
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // remember: our convention for longs in SPARC is:
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // O0 (Otos_l1) has high-order part in first word,
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // O1 (Otos_l2) has low-order part in second word
a61af66fc99e Initial load
duke
parents:
diff changeset
433
a61af66fc99e Initial load
duke
parents:
diff changeset
434 void InterpreterMacroAssembler::push_l(Register r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
435 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
436 debug_only(verify_esp(Lesp));
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
437 // Longs are stored in memory-correct order, even if unaligned.
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
438 int offset = -Interpreter::stackElementSize;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
439 store_unaligned_long(r, Lesp, offset);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
440 dec(Lesp, 2 * Interpreter::stackElementSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
442
a61af66fc99e Initial load
duke
parents:
diff changeset
443
a61af66fc99e Initial load
duke
parents:
diff changeset
444 void InterpreterMacroAssembler::push_f(FloatRegister f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
445 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
446 debug_only(verify_esp(Lesp));
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
447 stf(FloatRegisterImpl::S, f, Lesp, 0);
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
448 dec(Lesp, Interpreter::stackElementSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
449 }
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451
a61af66fc99e Initial load
duke
parents:
diff changeset
452 void InterpreterMacroAssembler::push_d(FloatRegister d) {
a61af66fc99e Initial load
duke
parents:
diff changeset
453 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
454 debug_only(verify_esp(Lesp));
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
455 // Longs are stored in memory-correct order, even if unaligned.
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
456 int offset = -Interpreter::stackElementSize;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
457 store_unaligned_double(d, Lesp, offset);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
458 dec(Lesp, 2 * Interpreter::stackElementSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461
a61af66fc99e Initial load
duke
parents:
diff changeset
462 void InterpreterMacroAssembler::push(TosState state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
463 interp_verify_oop(Otos_i, state, __FILE__, __LINE__);
a61af66fc99e Initial load
duke
parents:
diff changeset
464 switch (state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
465 case atos: push_ptr(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
466 case btos: push_i(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
467 case ctos:
a61af66fc99e Initial load
duke
parents:
diff changeset
468 case stos: push_i(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
469 case itos: push_i(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
470 case ltos: push_l(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
471 case ftos: push_f(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
472 case dtos: push_d(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
473 case vtos: /* nothing to do */ break;
a61af66fc99e Initial load
duke
parents:
diff changeset
474 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
475 }
a61af66fc99e Initial load
duke
parents:
diff changeset
476 }
a61af66fc99e Initial load
duke
parents:
diff changeset
477
a61af66fc99e Initial load
duke
parents:
diff changeset
478
a61af66fc99e Initial load
duke
parents:
diff changeset
479 void InterpreterMacroAssembler::pop(TosState state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
480 switch (state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
481 case atos: pop_ptr(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
482 case btos: pop_i(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
483 case ctos:
a61af66fc99e Initial load
duke
parents:
diff changeset
484 case stos: pop_i(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
485 case itos: pop_i(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
486 case ltos: pop_l(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
487 case ftos: pop_f(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
488 case dtos: pop_d(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
489 case vtos: /* nothing to do */ break;
a61af66fc99e Initial load
duke
parents:
diff changeset
490 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
492 interp_verify_oop(Otos_i, state, __FILE__, __LINE__);
a61af66fc99e Initial load
duke
parents:
diff changeset
493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
494
a61af66fc99e Initial load
duke
parents:
diff changeset
495
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
496 // Helpers for swap and dup
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
497 void InterpreterMacroAssembler::load_ptr(int n, Register val) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
498 ld_ptr(Lesp, Interpreter::expr_offset_in_bytes(n), val);
a61af66fc99e Initial load
duke
parents:
diff changeset
499 }
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
500 void InterpreterMacroAssembler::store_ptr(int n, Register val) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
501 st_ptr(val, Lesp, Interpreter::expr_offset_in_bytes(n));
a61af66fc99e Initial load
duke
parents:
diff changeset
502 }
a61af66fc99e Initial load
duke
parents:
diff changeset
503
a61af66fc99e Initial load
duke
parents:
diff changeset
504
a61af66fc99e Initial load
duke
parents:
diff changeset
505 void InterpreterMacroAssembler::load_receiver(Register param_count,
a61af66fc99e Initial load
duke
parents:
diff changeset
506 Register recv) {
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
507 sll(param_count, Interpreter::logStackElementSize, param_count);
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6123
diff changeset
508 ld_ptr(Lesp, param_count, recv); // gets receiver oop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
510
a61af66fc99e Initial load
duke
parents:
diff changeset
511 void InterpreterMacroAssembler::empty_expression_stack() {
a61af66fc99e Initial load
duke
parents:
diff changeset
512 // Reset Lesp.
a61af66fc99e Initial load
duke
parents:
diff changeset
513 sub( Lmonitors, wordSize, Lesp );
a61af66fc99e Initial load
duke
parents:
diff changeset
514
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // Reset SP by subtracting more space from Lesp.
a61af66fc99e Initial load
duke
parents:
diff changeset
516 Label done;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
517 assert(G4_scratch != Gframe_size, "Only you can prevent register aliasing!");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
518
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // A native does not need to do this, since its callee does not change SP.
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
520 ld(Lmethod, Method::access_flags_offset(), Gframe_size); // Load access flags.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
521 btst(JVM_ACC_NATIVE, Gframe_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
522 br(Assembler::notZero, false, Assembler::pt, done);
a61af66fc99e Initial load
duke
parents:
diff changeset
523 delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
524
a61af66fc99e Initial load
duke
parents:
diff changeset
525 // Compute max expression stack+register save area
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
526 lduh(Lmethod, in_bytes(Method::max_stack_offset()), Gframe_size); // Load max stack.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
527 add( Gframe_size, frame::memory_parameter_word_sp_offset, Gframe_size );
a61af66fc99e Initial load
duke
parents:
diff changeset
528
a61af66fc99e Initial load
duke
parents:
diff changeset
529 //
a61af66fc99e Initial load
duke
parents:
diff changeset
530 // now set up a stack frame with the size computed above
a61af66fc99e Initial load
duke
parents:
diff changeset
531 //
a61af66fc99e Initial load
duke
parents:
diff changeset
532 //round_to( Gframe_size, WordsPerLong ); // -- moved down to the "and" below
a61af66fc99e Initial load
duke
parents:
diff changeset
533 sll( Gframe_size, LogBytesPerWord, Gframe_size );
a61af66fc99e Initial load
duke
parents:
diff changeset
534 sub( Lesp, Gframe_size, Gframe_size );
a61af66fc99e Initial load
duke
parents:
diff changeset
535 and3( Gframe_size, -(2 * wordSize), Gframe_size ); // align SP (downwards) to an 8/16-byte boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
536 debug_only(verify_sp(Gframe_size, G4_scratch));
a61af66fc99e Initial load
duke
parents:
diff changeset
537 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
538 sub(Gframe_size, STACK_BIAS, Gframe_size );
a61af66fc99e Initial load
duke
parents:
diff changeset
539 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
540 mov(Gframe_size, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 bind(done);
a61af66fc99e Initial load
duke
parents:
diff changeset
543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
544
a61af66fc99e Initial load
duke
parents:
diff changeset
545
a61af66fc99e Initial load
duke
parents:
diff changeset
546 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
547 void InterpreterMacroAssembler::verify_sp(Register Rsp, Register Rtemp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
548 Label Bad, OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
549
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // Saved SP must be aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
551 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
552 btst(2*BytesPerWord-1, Rsp);
a61af66fc99e Initial load
duke
parents:
diff changeset
553 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
554 btst(LongAlignmentMask, Rsp);
a61af66fc99e Initial load
duke
parents:
diff changeset
555 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
556 br(Assembler::notZero, false, Assembler::pn, Bad);
a61af66fc99e Initial load
duke
parents:
diff changeset
557 delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
558
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // Saved SP, plus register window size, must not be above FP.
a61af66fc99e Initial load
duke
parents:
diff changeset
560 add(Rsp, frame::register_save_words * wordSize, Rtemp);
a61af66fc99e Initial load
duke
parents:
diff changeset
561 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
562 sub(Rtemp, STACK_BIAS, Rtemp); // Bias Rtemp before cmp to FP
a61af66fc99e Initial load
duke
parents:
diff changeset
563 #endif
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
564 cmp_and_brx_short(Rtemp, FP, Assembler::greaterUnsigned, Assembler::pn, Bad);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
565
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // Saved SP must not be ridiculously below current SP.
a61af66fc99e Initial load
duke
parents:
diff changeset
567 size_t maxstack = MAX2(JavaThread::stack_size_at_create(), (size_t) 4*K*K);
a61af66fc99e Initial load
duke
parents:
diff changeset
568 set(maxstack, Rtemp);
a61af66fc99e Initial load
duke
parents:
diff changeset
569 sub(SP, Rtemp, Rtemp);
a61af66fc99e Initial load
duke
parents:
diff changeset
570 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
571 add(Rtemp, STACK_BIAS, Rtemp); // Unbias Rtemp before cmp to Rsp
a61af66fc99e Initial load
duke
parents:
diff changeset
572 #endif
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
573 cmp_and_brx_short(Rsp, Rtemp, Assembler::lessUnsigned, Assembler::pn, Bad);
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
574
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
575 ba_short(OK);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
576
a61af66fc99e Initial load
duke
parents:
diff changeset
577 bind(Bad);
a61af66fc99e Initial load
duke
parents:
diff changeset
578 stop("on return to interpreted call, restored SP is corrupted");
a61af66fc99e Initial load
duke
parents:
diff changeset
579
a61af66fc99e Initial load
duke
parents:
diff changeset
580 bind(OK);
a61af66fc99e Initial load
duke
parents:
diff changeset
581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
582
a61af66fc99e Initial load
duke
parents:
diff changeset
583
a61af66fc99e Initial load
duke
parents:
diff changeset
584 void InterpreterMacroAssembler::verify_esp(Register Resp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // about to read or write Resp[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
586 // make sure it is not in the monitors or the register save area
a61af66fc99e Initial load
duke
parents:
diff changeset
587 Label OK1, OK2;
a61af66fc99e Initial load
duke
parents:
diff changeset
588
a61af66fc99e Initial load
duke
parents:
diff changeset
589 cmp(Resp, Lmonitors);
a61af66fc99e Initial load
duke
parents:
diff changeset
590 brx(Assembler::lessUnsigned, true, Assembler::pt, OK1);
a61af66fc99e Initial load
duke
parents:
diff changeset
591 delayed()->sub(Resp, frame::memory_parameter_word_sp_offset * wordSize, Resp);
a61af66fc99e Initial load
duke
parents:
diff changeset
592 stop("too many pops: Lesp points into monitor area");
a61af66fc99e Initial load
duke
parents:
diff changeset
593 bind(OK1);
a61af66fc99e Initial load
duke
parents:
diff changeset
594 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
595 sub(Resp, STACK_BIAS, Resp);
a61af66fc99e Initial load
duke
parents:
diff changeset
596 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
597 cmp(Resp, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
598 brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, OK2);
a61af66fc99e Initial load
duke
parents:
diff changeset
599 delayed()->add(Resp, STACK_BIAS + frame::memory_parameter_word_sp_offset * wordSize, Resp);
a61af66fc99e Initial load
duke
parents:
diff changeset
600 stop("too many pushes: Lesp points into register window");
a61af66fc99e Initial load
duke
parents:
diff changeset
601 bind(OK2);
a61af66fc99e Initial load
duke
parents:
diff changeset
602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
603 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
604
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // Load compiled (i2c) or interpreter entry when calling from interpreted and
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // do the call. Centralized so that all interpreter calls will do the same actions.
a61af66fc99e Initial load
duke
parents:
diff changeset
607 // If jvmti single stepping is on for a thread we must not call compiled code.
a61af66fc99e Initial load
duke
parents:
diff changeset
608 void InterpreterMacroAssembler::call_from_interpreter(Register target, Register scratch, Register Rret) {
a61af66fc99e Initial load
duke
parents:
diff changeset
609
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // Assume we want to go compiled if available
a61af66fc99e Initial load
duke
parents:
diff changeset
611
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
612 ld_ptr(G5_method, in_bytes(Method::from_interpreted_offset()), target);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
613
a61af66fc99e Initial load
duke
parents:
diff changeset
614 if (JvmtiExport::can_post_interpreter_events()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
615 // JVMTI events, such as single-stepping, are implemented partly by avoiding running
a61af66fc99e Initial load
duke
parents:
diff changeset
616 // compiled code in threads for which the event is enabled. Check here for
a61af66fc99e Initial load
duke
parents:
diff changeset
617 // interp_only_mode if these events CAN be enabled.
a61af66fc99e Initial load
duke
parents:
diff changeset
618 verify_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
619 Label skip_compiled_code;
a61af66fc99e Initial load
duke
parents:
diff changeset
620
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
621 const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
622 ld(interp_only, scratch);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
623 cmp_zero_and_br(Assembler::notZero, scratch, skip_compiled_code, true, Assembler::pn);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
624 delayed()->ld_ptr(G5_method, in_bytes(Method::interpreter_entry_offset()), target);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
625 bind(skip_compiled_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
627
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
628 // the i2c_adapters need Method* in G5_method (right? %%%)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // do the call
a61af66fc99e Initial load
duke
parents:
diff changeset
630 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
631 {
a61af66fc99e Initial load
duke
parents:
diff changeset
632 Label ok;
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
633 br_notnull_short(target, Assembler::pt, ok);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
634 stop("null entry point");
a61af66fc99e Initial load
duke
parents:
diff changeset
635 bind(ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
636 }
a61af66fc99e Initial load
duke
parents:
diff changeset
637 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
638
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // Adjust Rret first so Llast_SP can be same as Rret
a61af66fc99e Initial load
duke
parents:
diff changeset
640 add(Rret, -frame::pc_return_offset, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
641 add(Lesp, BytesPerWord, Gargs); // setup parameter pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // Record SP so we can remove any stack space allocated by adapter transition
a61af66fc99e Initial load
duke
parents:
diff changeset
643 jmp(target, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
644 delayed()->mov(SP, Llast_SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
646
a61af66fc99e Initial load
duke
parents:
diff changeset
647 void InterpreterMacroAssembler::if_cmp(Condition cc, bool ptr_compare) {
a61af66fc99e Initial load
duke
parents:
diff changeset
648 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
649
a61af66fc99e Initial load
duke
parents:
diff changeset
650 Label not_taken;
a61af66fc99e Initial load
duke
parents:
diff changeset
651 if (ptr_compare) brx(cc, false, Assembler::pn, not_taken);
a61af66fc99e Initial load
duke
parents:
diff changeset
652 else br (cc, false, Assembler::pn, not_taken);
a61af66fc99e Initial load
duke
parents:
diff changeset
653 delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
654
a61af66fc99e Initial load
duke
parents:
diff changeset
655 TemplateTable::branch(false,false);
a61af66fc99e Initial load
duke
parents:
diff changeset
656
a61af66fc99e Initial load
duke
parents:
diff changeset
657 bind(not_taken);
a61af66fc99e Initial load
duke
parents:
diff changeset
658
a61af66fc99e Initial load
duke
parents:
diff changeset
659 profile_not_taken_branch(G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
661
a61af66fc99e Initial load
duke
parents:
diff changeset
662
a61af66fc99e Initial load
duke
parents:
diff changeset
663 void InterpreterMacroAssembler::get_2_byte_integer_at_bcp(
a61af66fc99e Initial load
duke
parents:
diff changeset
664 int bcp_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
665 Register Rtmp,
a61af66fc99e Initial load
duke
parents:
diff changeset
666 Register Rdst,
a61af66fc99e Initial load
duke
parents:
diff changeset
667 signedOrNot is_signed,
a61af66fc99e Initial load
duke
parents:
diff changeset
668 setCCOrNot should_set_CC ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
669 assert(Rtmp != Rdst, "need separate temp register");
a61af66fc99e Initial load
duke
parents:
diff changeset
670 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
671 switch (is_signed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
672 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
673
a61af66fc99e Initial load
duke
parents:
diff changeset
674 case Signed: ldsb( Lbcp, bcp_offset, Rdst ); break; // high byte
a61af66fc99e Initial load
duke
parents:
diff changeset
675 case Unsigned: ldub( Lbcp, bcp_offset, Rdst ); break; // high byte
a61af66fc99e Initial load
duke
parents:
diff changeset
676 }
a61af66fc99e Initial load
duke
parents:
diff changeset
677 ldub( Lbcp, bcp_offset + 1, Rtmp ); // low byte
a61af66fc99e Initial load
duke
parents:
diff changeset
678 sll( Rdst, BitsPerByte, Rdst);
a61af66fc99e Initial load
duke
parents:
diff changeset
679 switch (should_set_CC ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
680 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
681
a61af66fc99e Initial load
duke
parents:
diff changeset
682 case set_CC: orcc( Rdst, Rtmp, Rdst ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
683 case dont_set_CC: or3( Rdst, Rtmp, Rdst ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
684 }
a61af66fc99e Initial load
duke
parents:
diff changeset
685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
686
a61af66fc99e Initial load
duke
parents:
diff changeset
687
a61af66fc99e Initial load
duke
parents:
diff changeset
688 void InterpreterMacroAssembler::get_4_byte_integer_at_bcp(
a61af66fc99e Initial load
duke
parents:
diff changeset
689 int bcp_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
690 Register Rtmp,
a61af66fc99e Initial load
duke
parents:
diff changeset
691 Register Rdst,
a61af66fc99e Initial load
duke
parents:
diff changeset
692 setCCOrNot should_set_CC ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
693 assert(Rtmp != Rdst, "need separate temp register");
a61af66fc99e Initial load
duke
parents:
diff changeset
694 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
695 add( Lbcp, bcp_offset, Rtmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
696 andcc( Rtmp, 3, G0);
a61af66fc99e Initial load
duke
parents:
diff changeset
697 Label aligned;
a61af66fc99e Initial load
duke
parents:
diff changeset
698 switch (should_set_CC ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
699 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
700
a61af66fc99e Initial load
duke
parents:
diff changeset
701 case set_CC: break;
a61af66fc99e Initial load
duke
parents:
diff changeset
702 case dont_set_CC: break;
a61af66fc99e Initial load
duke
parents:
diff changeset
703 }
a61af66fc99e Initial load
duke
parents:
diff changeset
704
a61af66fc99e Initial load
duke
parents:
diff changeset
705 br(Assembler::zero, true, Assembler::pn, aligned);
a61af66fc99e Initial load
duke
parents:
diff changeset
706 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
707 delayed()->ldsw(Rtmp, 0, Rdst);
a61af66fc99e Initial load
duke
parents:
diff changeset
708 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
709 delayed()->ld(Rtmp, 0, Rdst);
a61af66fc99e Initial load
duke
parents:
diff changeset
710 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
711
a61af66fc99e Initial load
duke
parents:
diff changeset
712 ldub(Lbcp, bcp_offset + 3, Rdst);
a61af66fc99e Initial load
duke
parents:
diff changeset
713 ldub(Lbcp, bcp_offset + 2, Rtmp); sll(Rtmp, 8, Rtmp); or3(Rtmp, Rdst, Rdst);
a61af66fc99e Initial load
duke
parents:
diff changeset
714 ldub(Lbcp, bcp_offset + 1, Rtmp); sll(Rtmp, 16, Rtmp); or3(Rtmp, Rdst, Rdst);
a61af66fc99e Initial load
duke
parents:
diff changeset
715 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
716 ldsb(Lbcp, bcp_offset + 0, Rtmp); sll(Rtmp, 24, Rtmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
717 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
718 // Unsigned load is faster than signed on some implementations
a61af66fc99e Initial load
duke
parents:
diff changeset
719 ldub(Lbcp, bcp_offset + 0, Rtmp); sll(Rtmp, 24, Rtmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
720 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
721 or3(Rtmp, Rdst, Rdst );
a61af66fc99e Initial load
duke
parents:
diff changeset
722
a61af66fc99e Initial load
duke
parents:
diff changeset
723 bind(aligned);
a61af66fc99e Initial load
duke
parents:
diff changeset
724 if (should_set_CC == set_CC) tst(Rdst);
a61af66fc99e Initial load
duke
parents:
diff changeset
725 }
a61af66fc99e Initial load
duke
parents:
diff changeset
726
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
727 void InterpreterMacroAssembler::get_cache_index_at_bcp(Register temp, Register index,
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
728 int bcp_offset, size_t index_size) {
1503
c640000b7cc1 6829193: JSR 292 needs to support SPARC
twisti
parents: 1295
diff changeset
729 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
730 if (index_size == sizeof(u2)) {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
731 get_2_byte_integer_at_bcp(bcp_offset, temp, index, Unsigned);
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
732 } else if (index_size == sizeof(u4)) {
2416
38fea01eb669 6817525: turn on method handle functionality by default for JSR 292
twisti
parents: 2118
diff changeset
733 assert(EnableInvokeDynamic, "giant index used only for JSR 292");
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
734 get_4_byte_integer_at_bcp(bcp_offset, temp, index);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
735 assert(ConstantPool::decode_invokedynamic_index(~123) == 123, "else change next line");
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
736 xor3(index, -1, index); // convert to plain index
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
737 } else if (index_size == sizeof(u1)) {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
738 ldub(Lbcp, bcp_offset, index);
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
739 } else {
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
740 ShouldNotReachHere();
1503
c640000b7cc1 6829193: JSR 292 needs to support SPARC
twisti
parents: 1295
diff changeset
741 }
c640000b7cc1 6829193: JSR 292 needs to support SPARC
twisti
parents: 1295
diff changeset
742 }
c640000b7cc1 6829193: JSR 292 needs to support SPARC
twisti
parents: 1295
diff changeset
743
c640000b7cc1 6829193: JSR 292 needs to support SPARC
twisti
parents: 1295
diff changeset
744
c640000b7cc1 6829193: JSR 292 needs to support SPARC
twisti
parents: 1295
diff changeset
745 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
746 int bcp_offset, size_t index_size) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
747 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
a61af66fc99e Initial load
duke
parents:
diff changeset
748 assert_different_registers(cache, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
749 assert_not_delayed();
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
750 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
751 // convert from field index to ConstantPoolCacheEntry index and from
c640000b7cc1 6829193: JSR 292 needs to support SPARC
twisti
parents: 1295
diff changeset
752 // word index to byte offset
0
a61af66fc99e Initial load
duke
parents:
diff changeset
753 sll(tmp, exact_log2(in_words(ConstantPoolCacheEntry::size()) * BytesPerWord), tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
754 add(LcpoolCache, tmp, cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
755 }
a61af66fc99e Initial load
duke
parents:
diff changeset
756
a61af66fc99e Initial load
duke
parents:
diff changeset
757
3852
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3839
diff changeset
758 void InterpreterMacroAssembler::get_cache_and_index_and_bytecode_at_bcp(Register cache,
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3839
diff changeset
759 Register temp,
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3839
diff changeset
760 Register bytecode,
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3839
diff changeset
761 int byte_no,
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3839
diff changeset
762 int bcp_offset,
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3839
diff changeset
763 size_t index_size) {
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3839
diff changeset
764 get_cache_and_index_at_bcp(cache, temp, bcp_offset, index_size);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
765 ld_ptr(cache, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset(), bytecode);
3852
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3839
diff changeset
766 const int shift_count = (1 + byte_no) * BitsPerByte;
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6123
diff changeset
767 assert((byte_no == TemplateTable::f1_byte && shift_count == ConstantPoolCacheEntry::bytecode_1_shift) ||
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6123
diff changeset
768 (byte_no == TemplateTable::f2_byte && shift_count == ConstantPoolCacheEntry::bytecode_2_shift),
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6123
diff changeset
769 "correct shift count");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6123
diff changeset
770 srl(bytecode, shift_count, bytecode);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6123
diff changeset
771 assert(ConstantPoolCacheEntry::bytecode_1_mask == ConstantPoolCacheEntry::bytecode_2_mask, "common mask");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6123
diff changeset
772 and3(bytecode, ConstantPoolCacheEntry::bytecode_1_mask, bytecode);
3852
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3839
diff changeset
773 }
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3839
diff changeset
774
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3839
diff changeset
775
1503
c640000b7cc1 6829193: JSR 292 needs to support SPARC
twisti
parents: 1295
diff changeset
776 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
777 int bcp_offset, size_t index_size) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
778 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
a61af66fc99e Initial load
duke
parents:
diff changeset
779 assert_different_registers(cache, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
780 assert_not_delayed();
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
781 if (index_size == sizeof(u2)) {
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
782 get_2_byte_integer_at_bcp(bcp_offset, cache, tmp, Unsigned);
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
783 } else {
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
784 ShouldNotReachHere(); // other sizes not supported here
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
785 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
786 // convert from field index to ConstantPoolCacheEntry index
a61af66fc99e Initial load
duke
parents:
diff changeset
787 // and from word index to byte offset
a61af66fc99e Initial load
duke
parents:
diff changeset
788 sll(tmp, exact_log2(in_words(ConstantPoolCacheEntry::size()) * BytesPerWord), tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
789 // skip past the header
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
790 add(tmp, in_bytes(ConstantPoolCache::base_offset()), tmp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
791 // construct pointer to cache entry
a61af66fc99e Initial load
duke
parents:
diff changeset
792 add(LcpoolCache, tmp, cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
793 }
a61af66fc99e Initial load
duke
parents:
diff changeset
794
a61af66fc99e Initial load
duke
parents:
diff changeset
795
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
796 // Load object from cpool->resolved_references(index)
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
797 void InterpreterMacroAssembler::load_resolved_reference_at_index(
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
798 Register result, Register index) {
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
799 assert_different_registers(result, index);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
800 assert_not_delayed();
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
801 // convert from field index to resolved_references() index and from
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
802 // word index to byte offset. Since this is a java object, it can be compressed
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
803 Register tmp = index; // reuse
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
804 sll(index, LogBytesPerHeapOop, tmp);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
805 get_constant_pool(result);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
806 // load pointer for resolved_references[] objArray
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
807 ld_ptr(result, ConstantPool::resolved_references_offset_in_bytes(), result);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
808 // JNIHandles::resolve(result)
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
809 ld_ptr(result, 0, result);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
810 // Add in the index
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
811 add(result, tmp, result);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
812 load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
813 }
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
814
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
815
0
a61af66fc99e Initial load
duke
parents:
diff changeset
816 // 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
817 // a subtype of super_klass. Blows registers Rsuper_klass, Rsub_klass, tmp1, tmp2.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
818 void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
819 Register Rsuper_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
820 Register Rtmp1,
a61af66fc99e Initial load
duke
parents:
diff changeset
821 Register Rtmp2,
a61af66fc99e Initial load
duke
parents:
diff changeset
822 Register Rtmp3,
a61af66fc99e Initial load
duke
parents:
diff changeset
823 Label &ok_is_subtype ) {
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 614
diff changeset
824 Label not_subtype;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
825
a61af66fc99e Initial load
duke
parents:
diff changeset
826 // Profile the not-null value's klass.
a61af66fc99e Initial load
duke
parents:
diff changeset
827 profile_typecheck(Rsub_klass, Rtmp1);
a61af66fc99e Initial load
duke
parents:
diff changeset
828
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 614
diff changeset
829 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
830 Rtmp1, Rtmp2,
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 614
diff changeset
831 &ok_is_subtype, &not_subtype, NULL);
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 614
diff changeset
832
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 614
diff changeset
833 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
834 Rtmp1, Rtmp2, Rtmp3, /*hack:*/ noreg,
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 614
diff changeset
835 &ok_is_subtype, NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
836
a61af66fc99e Initial load
duke
parents:
diff changeset
837 bind(not_subtype);
a61af66fc99e Initial load
duke
parents:
diff changeset
838 profile_typecheck_failed(Rtmp1);
a61af66fc99e Initial load
duke
parents:
diff changeset
839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
840
a61af66fc99e Initial load
duke
parents:
diff changeset
841 // Separate these two to allow for delay slot in middle
a61af66fc99e Initial load
duke
parents:
diff changeset
842 // These are used to do a test and full jump to exception-throwing code.
a61af66fc99e Initial load
duke
parents:
diff changeset
843
a61af66fc99e Initial load
duke
parents:
diff changeset
844 // %%%%% Could possibly reoptimize this by testing to see if could use
a61af66fc99e Initial load
duke
parents:
diff changeset
845 // a single conditional branch (i.e. if span is small enough.
a61af66fc99e Initial load
duke
parents:
diff changeset
846 // If you go that route, than get rid of the split and give up
a61af66fc99e Initial load
duke
parents:
diff changeset
847 // on the delay-slot hack.
a61af66fc99e Initial load
duke
parents:
diff changeset
848
a61af66fc99e Initial load
duke
parents:
diff changeset
849 void InterpreterMacroAssembler::throw_if_not_1_icc( Condition ok_condition,
a61af66fc99e Initial load
duke
parents:
diff changeset
850 Label& ok ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
851 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
852 br(ok_condition, true, pt, ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
853 // DELAY SLOT
a61af66fc99e Initial load
duke
parents:
diff changeset
854 }
a61af66fc99e Initial load
duke
parents:
diff changeset
855
a61af66fc99e Initial load
duke
parents:
diff changeset
856 void InterpreterMacroAssembler::throw_if_not_1_xcc( Condition ok_condition,
a61af66fc99e Initial load
duke
parents:
diff changeset
857 Label& ok ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
858 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
859 bp( ok_condition, true, Assembler::xcc, pt, ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
860 // DELAY SLOT
a61af66fc99e Initial load
duke
parents:
diff changeset
861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
862
a61af66fc99e Initial load
duke
parents:
diff changeset
863 void InterpreterMacroAssembler::throw_if_not_1_x( Condition ok_condition,
a61af66fc99e Initial load
duke
parents:
diff changeset
864 Label& ok ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
865 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
866 brx(ok_condition, true, pt, ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
867 // DELAY SLOT
a61af66fc99e Initial load
duke
parents:
diff changeset
868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
869
a61af66fc99e Initial load
duke
parents:
diff changeset
870 void InterpreterMacroAssembler::throw_if_not_2( 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 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
874 AddressLiteral dest(throw_entry_point);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
875 jump_to(dest, Rscratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
876 delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
877 bind(ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
878 }
a61af66fc99e Initial load
duke
parents:
diff changeset
879
a61af66fc99e Initial load
duke
parents:
diff changeset
880
a61af66fc99e Initial load
duke
parents:
diff changeset
881 // And if you cannot use the delay slot, here is a shorthand:
a61af66fc99e Initial load
duke
parents:
diff changeset
882
a61af66fc99e Initial load
duke
parents:
diff changeset
883 void InterpreterMacroAssembler::throw_if_not_icc( Condition ok_condition,
a61af66fc99e Initial load
duke
parents:
diff changeset
884 address throw_entry_point,
a61af66fc99e Initial load
duke
parents:
diff changeset
885 Register Rscratch ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
886 Label ok;
a61af66fc99e Initial load
duke
parents:
diff changeset
887 if (ok_condition != never) {
a61af66fc99e Initial load
duke
parents:
diff changeset
888 throw_if_not_1_icc( ok_condition, ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
889 delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
890 }
a61af66fc99e Initial load
duke
parents:
diff changeset
891 throw_if_not_2( throw_entry_point, Rscratch, ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
892 }
a61af66fc99e Initial load
duke
parents:
diff changeset
893 void InterpreterMacroAssembler::throw_if_not_xcc( Condition ok_condition,
a61af66fc99e Initial load
duke
parents:
diff changeset
894 address throw_entry_point,
a61af66fc99e Initial load
duke
parents:
diff changeset
895 Register Rscratch ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
896 Label ok;
a61af66fc99e Initial load
duke
parents:
diff changeset
897 if (ok_condition != never) {
a61af66fc99e Initial load
duke
parents:
diff changeset
898 throw_if_not_1_xcc( ok_condition, ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
899 delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
900 }
a61af66fc99e Initial load
duke
parents:
diff changeset
901 throw_if_not_2( throw_entry_point, Rscratch, ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
902 }
a61af66fc99e Initial load
duke
parents:
diff changeset
903 void InterpreterMacroAssembler::throw_if_not_x( Condition ok_condition,
a61af66fc99e Initial load
duke
parents:
diff changeset
904 address throw_entry_point,
a61af66fc99e Initial load
duke
parents:
diff changeset
905 Register Rscratch ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
906 Label ok;
a61af66fc99e Initial load
duke
parents:
diff changeset
907 if (ok_condition != never) {
a61af66fc99e Initial load
duke
parents:
diff changeset
908 throw_if_not_1_x( ok_condition, ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
909 delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
911 throw_if_not_2( throw_entry_point, Rscratch, ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
912 }
a61af66fc99e Initial load
duke
parents:
diff changeset
913
a61af66fc99e Initial load
duke
parents:
diff changeset
914 // 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
915 // Note: res is still shy of address by array offset into object.
a61af66fc99e Initial load
duke
parents:
diff changeset
916
a61af66fc99e Initial load
duke
parents:
diff changeset
917 void InterpreterMacroAssembler::index_check_without_pop(Register array, Register index, int index_shift, Register tmp, Register res) {
a61af66fc99e Initial load
duke
parents:
diff changeset
918 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
919
a61af66fc99e Initial load
duke
parents:
diff changeset
920 verify_oop(array);
a61af66fc99e Initial load
duke
parents:
diff changeset
921 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
922 // sign extend since tos (index) can be a 32bit value
a61af66fc99e Initial load
duke
parents:
diff changeset
923 sra(index, G0, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
924 #endif // _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
925
a61af66fc99e Initial load
duke
parents:
diff changeset
926 // check array
a61af66fc99e Initial load
duke
parents:
diff changeset
927 Label ptr_ok;
a61af66fc99e Initial load
duke
parents:
diff changeset
928 tst(array);
a61af66fc99e Initial load
duke
parents:
diff changeset
929 throw_if_not_1_x( notZero, ptr_ok );
a61af66fc99e Initial load
duke
parents:
diff changeset
930 delayed()->ld( array, arrayOopDesc::length_offset_in_bytes(), tmp ); // check index
a61af66fc99e Initial load
duke
parents:
diff changeset
931 throw_if_not_2( Interpreter::_throw_NullPointerException_entry, G3_scratch, ptr_ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
932
a61af66fc99e Initial load
duke
parents:
diff changeset
933 Label index_ok;
a61af66fc99e Initial load
duke
parents:
diff changeset
934 cmp(index, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
935 throw_if_not_1_icc( lessUnsigned, index_ok );
a61af66fc99e Initial load
duke
parents:
diff changeset
936 if (index_shift > 0) delayed()->sll(index, index_shift, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
937 else delayed()->add(array, index, res); // addr - const offset in index
a61af66fc99e Initial load
duke
parents:
diff changeset
938 // convention: move aberrant index into G3_scratch for exception message
a61af66fc99e Initial load
duke
parents:
diff changeset
939 mov(index, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
940 throw_if_not_2( Interpreter::_throw_ArrayIndexOutOfBoundsException_entry, G4_scratch, index_ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
941
a61af66fc99e Initial load
duke
parents:
diff changeset
942 // add offset if didn't do it in delay slot
a61af66fc99e Initial load
duke
parents:
diff changeset
943 if (index_shift > 0) add(array, index, res); // addr - const offset in index
a61af66fc99e Initial load
duke
parents:
diff changeset
944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
945
a61af66fc99e Initial load
duke
parents:
diff changeset
946
a61af66fc99e Initial load
duke
parents:
diff changeset
947 void InterpreterMacroAssembler::index_check(Register array, Register index, int index_shift, Register tmp, Register res) {
a61af66fc99e Initial load
duke
parents:
diff changeset
948 assert_not_delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
949
a61af66fc99e Initial load
duke
parents:
diff changeset
950 // pop array
a61af66fc99e Initial load
duke
parents:
diff changeset
951 pop_ptr(array);
a61af66fc99e Initial load
duke
parents:
diff changeset
952
a61af66fc99e Initial load
duke
parents:
diff changeset
953 // check array
a61af66fc99e Initial load
duke
parents:
diff changeset
954 index_check_without_pop(array, index, index_shift, tmp, res);
a61af66fc99e Initial load
duke
parents:
diff changeset
955 }
a61af66fc99e Initial load
duke
parents:
diff changeset
956
a61af66fc99e Initial load
duke
parents:
diff changeset
957
6123
2fe087c3e814 7172967: Eliminate constMethod's _method backpointer to methodOop.
jiangli
parents: 3852
diff changeset
958 void InterpreterMacroAssembler::get_const(Register Rdst) {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
959 ld_ptr(Lmethod, in_bytes(Method::const_offset()), Rdst);
6123
2fe087c3e814 7172967: Eliminate constMethod's _method backpointer to methodOop.
jiangli
parents: 3852
diff changeset
960 }
2fe087c3e814 7172967: Eliminate constMethod's _method backpointer to methodOop.
jiangli
parents: 3852
diff changeset
961
2fe087c3e814 7172967: Eliminate constMethod's _method backpointer to methodOop.
jiangli
parents: 3852
diff changeset
962
0
a61af66fc99e Initial load
duke
parents:
diff changeset
963 void InterpreterMacroAssembler::get_constant_pool(Register Rdst) {
6123
2fe087c3e814 7172967: Eliminate constMethod's _method backpointer to methodOop.
jiangli
parents: 3852
diff changeset
964 get_const(Rdst);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
965 ld_ptr(Rdst, in_bytes(ConstMethod::constants_offset()), Rdst);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
967
a61af66fc99e Initial load
duke
parents:
diff changeset
968
a61af66fc99e Initial load
duke
parents:
diff changeset
969 void InterpreterMacroAssembler::get_constant_pool_cache(Register Rdst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
970 get_constant_pool(Rdst);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
971 ld_ptr(Rdst, ConstantPool::cache_offset_in_bytes(), Rdst);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
972 }
a61af66fc99e Initial load
duke
parents:
diff changeset
973
a61af66fc99e Initial load
duke
parents:
diff changeset
974
a61af66fc99e Initial load
duke
parents:
diff changeset
975 void InterpreterMacroAssembler::get_cpool_and_tags(Register Rcpool, Register Rtags) {
a61af66fc99e Initial load
duke
parents:
diff changeset
976 get_constant_pool(Rcpool);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
977 ld_ptr(Rcpool, ConstantPool::tags_offset_in_bytes(), Rtags);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
978 }
a61af66fc99e Initial load
duke
parents:
diff changeset
979
a61af66fc99e Initial load
duke
parents:
diff changeset
980
a61af66fc99e Initial load
duke
parents:
diff changeset
981 // unlock if synchronized method
a61af66fc99e Initial load
duke
parents:
diff changeset
982 //
a61af66fc99e Initial load
duke
parents:
diff changeset
983 // Unlock the receiver if this is a synchronized method.
a61af66fc99e Initial load
duke
parents:
diff changeset
984 // Unlock any Java monitors from syncronized blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
985 //
a61af66fc99e Initial load
duke
parents:
diff changeset
986 // If there are locked Java monitors
a61af66fc99e Initial load
duke
parents:
diff changeset
987 // If throw_monitor_exception
a61af66fc99e Initial load
duke
parents:
diff changeset
988 // throws IllegalMonitorStateException
a61af66fc99e Initial load
duke
parents:
diff changeset
989 // Else if install_monitor_exception
a61af66fc99e Initial load
duke
parents:
diff changeset
990 // installs IllegalMonitorStateException
a61af66fc99e Initial load
duke
parents:
diff changeset
991 // Else
a61af66fc99e Initial load
duke
parents:
diff changeset
992 // no error processing
a61af66fc99e Initial load
duke
parents:
diff changeset
993 void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
a61af66fc99e Initial load
duke
parents:
diff changeset
994 bool throw_monitor_exception,
a61af66fc99e Initial load
duke
parents:
diff changeset
995 bool install_monitor_exception) {
a61af66fc99e Initial load
duke
parents:
diff changeset
996 Label unlocked, unlock, no_unlock;
a61af66fc99e Initial load
duke
parents:
diff changeset
997
a61af66fc99e Initial load
duke
parents:
diff changeset
998 // 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
999 const Address do_not_unlock_if_synchronized(G2_thread,
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
1000 JavaThread::do_not_unlock_if_synchronized_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 ldbool(do_not_unlock_if_synchronized, G1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 stbool(G0, do_not_unlock_if_synchronized); // reset the flag
a61af66fc99e Initial load
duke
parents:
diff changeset
1003
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 // check if synchronized method
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1005 const Address access_flags(Lmethod, Method::access_flags_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 interp_verify_oop(Otos_i, state, __FILE__, __LINE__);
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 push(state); // save tos
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
1008 ld(access_flags, G3_scratch); // Load access flags.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 btst(JVM_ACC_SYNCHRONIZED, G3_scratch);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
1010 br(zero, false, pt, unlocked);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1012
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 // Don't unlock anything if the _do_not_unlock_if_synchronized flag
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 // is set.
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1015 cmp_zero_and_br(Assembler::notZero, G1_scratch, no_unlock);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1017
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 // BasicObjectLock will be first in list, since this is a synchronized method. However, need
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 // to check that the object has not been unlocked by an explicit monitorexit bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
1020
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 //Intel: if (throw_monitor_exception) ... else ...
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 // Entry already unlocked, need to throw exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 //...
a61af66fc99e Initial load
duke
parents:
diff changeset
1024
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 // pass top-most monitor elem
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 add( top_most_monitor(), O1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1027
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 ld_ptr(O1, BasicObjectLock::obj_offset_in_bytes(), G3_scratch);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1029 br_notnull_short(G3_scratch, pt, unlock);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1030
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 if (throw_monitor_exception) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 // Entry already unlocked need to throw an exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_illegal_monitor_state_exception));
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 should_not_reach_here();
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 // Monitor already unlocked during a stack unroll.
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 // If requested, install an illegal_monitor_state_exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 // Continue with stack unrolling.
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 if (install_monitor_exception) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::new_illegal_monitor_state_exception));
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 }
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1042 ba_short(unlocked);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1044
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 bind(unlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1046
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 unlock_object(O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1048
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 bind(unlocked);
a61af66fc99e Initial load
duke
parents:
diff changeset
1050
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 // I0, I1: Might contain return value
a61af66fc99e Initial load
duke
parents:
diff changeset
1052
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 // Check that all monitors are unlocked
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 { Label loop, exception, entry, restart;
a61af66fc99e Initial load
duke
parents:
diff changeset
1055
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 Register Rmptr = O0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 Register Rtemp = O1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 Register Rlimit = Lmonitors;
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 const jint delta = frame::interpreter_frame_monitor_size() * wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 assert( (delta & LongAlignmentMask) == 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 "sizeof BasicObjectLock must be even number of doublewords");
a61af66fc99e Initial load
duke
parents:
diff changeset
1062
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 add(top_most_monitor(), Rmptr, delta);
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 // ensure that Rmptr starts out above (or at) Rlimit
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1067 cmp_and_brx_short(Rmptr, Rlimit, Assembler::greaterEqualUnsigned, pn, L);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 stop("monitor stack has negative size");
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 bind(restart);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1073 ba(entry);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 delayed()->
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 add(top_most_monitor(), Rmptr, delta); // points to current entry, starting with bottom-most entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1076
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 // Entry is still locked, need to throw exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 bind(exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 if (throw_monitor_exception) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_illegal_monitor_state_exception));
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 should_not_reach_here();
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 // Stack unrolling. Unlock object and if requested, install illegal_monitor_exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 // Unlock does not block, so don't have to worry about the frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 unlock_object(Rmptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 if (install_monitor_exception) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::new_illegal_monitor_state_exception));
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 }
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1089 ba_short(restart);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1091
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 bind(loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 cmp(Rtemp, G0); // check if current entry is used
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 brx(Assembler::notEqual, false, pn, exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 delayed()->
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 dec(Rmptr, delta); // otherwise advance to next entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 // ensure that Rmptr has not somehow stepped below Rlimit
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1100 cmp_and_brx_short(Rmptr, Rlimit, Assembler::greaterEqualUnsigned, pn, L);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 stop("ran off the end of the monitor stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 bind(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 cmp(Rmptr, Rlimit); // check if bottom reached
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 brx(Assembler::notEqual, true, pn, loop); // if not at bottom then check this entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 delayed()->
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 ld_ptr(Rmptr, BasicObjectLock::obj_offset_in_bytes() - delta, Rtemp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1111
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 bind(no_unlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 pop(state);
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 interp_verify_oop(Otos_i, state, __FILE__, __LINE__);
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1116
a61af66fc99e Initial load
duke
parents:
diff changeset
1117
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 // remove activation
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 // Unlock the receiver if this is a synchronized method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 // Unlock any Java monitors from syncronized blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 // Remove the activation from the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 // If there are locked Java monitors
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 // If throw_monitor_exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 // throws IllegalMonitorStateException
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 // Else if install_monitor_exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 // installs IllegalMonitorStateException
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 // Else
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 // no error processing
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 void InterpreterMacroAssembler::remove_activation(TosState state,
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 bool throw_monitor_exception,
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 bool install_monitor_exception) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1134
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 unlock_if_synchronized_method(state, throw_monitor_exception, install_monitor_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
1136
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 // save result (push state before jvmti call and pop it afterwards) and notify jvmti
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 notify_method_exit(false, state, NotifyJVMTI);
a61af66fc99e Initial load
duke
parents:
diff changeset
1139
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 interp_verify_oop(Otos_i, state, __FILE__, __LINE__);
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 verify_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
1142
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 // return tos
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 assert(Otos_l1 == Otos_i, "adjust code below");
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 switch (state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 case ltos: mov(Otos_l, Otos_l->after_save()); break; // O0 -> I0
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 case ltos: mov(Otos_l2, Otos_l2->after_save()); // fall through // O1 -> I1
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 case btos: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 case ctos:
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 case stos: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 case atos: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 case itos: mov(Otos_l1, Otos_l1->after_save()); break; // O0 -> I0
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 case ftos: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 case dtos: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 case vtos: /* nothing to do */ break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1161
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 #if defined(COMPILER2) && !defined(_LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 if (state == ltos) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 // C2 expects long results in G1 we can't tell if we're returning to interpreted
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 // or compiled so just be safe use G1 and O0/O1
a61af66fc99e Initial load
duke
parents:
diff changeset
1166
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 // Shift bits into high (msb) of G1
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 sllx(Otos_l1->after_save(), 32, G1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 // Zero extend low bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 srl (Otos_l2->after_save(), 0, Otos_l2->after_save());
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 or3 (Otos_l2->after_save(), G1, G1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 #endif /* COMPILER2 */
a61af66fc99e Initial load
duke
parents:
diff changeset
1174
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 #endif /* CC_INTERP */
a61af66fc99e Initial load
duke
parents:
diff changeset
1177
a61af66fc99e Initial load
duke
parents:
diff changeset
1178
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 // Lock object
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 // Argument - lock_reg points to the BasicObjectLock to be used for locking,
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 // it must be initialized with the object to lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 void InterpreterMacroAssembler::lock_object(Register lock_reg, Register Object) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 if (UseHeavyMonitors) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), lock_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 Register obj_reg = Object;
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 Register mark_reg = G4_scratch;
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 Register temp_reg = G1_scratch;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
1191 Address lock_addr(lock_reg, BasicObjectLock::lock_offset_in_bytes());
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
1192 Address mark_addr(obj_reg, oopDesc::mark_offset_in_bytes());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 Label done;
a61af66fc99e Initial load
duke
parents:
diff changeset
1194
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 Label slow_case;
a61af66fc99e Initial load
duke
parents:
diff changeset
1196
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 assert_different_registers(lock_reg, obj_reg, mark_reg, temp_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1198
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 // load markOop from object into mark_reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 ld_ptr(mark_addr, mark_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1201
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 if (UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 biased_locking_enter(obj_reg, mark_reg, temp_reg, done, &slow_case);
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1205
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 // get the address of basicLock on stack that will be stored in the object
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 // we need a temporary register here as we do not want to clobber lock_reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 // (cas clobbers the destination register)
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 mov(lock_reg, temp_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 // set mark reg to be (markOop of object | UNLOCK_VALUE)
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 or3(mark_reg, markOopDesc::unlocked_value, mark_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 // initialize the box (Must happen before we update the object mark!)
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 st_ptr(mark_reg, lock_addr, BasicLock::displaced_header_offset_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 // compare and exchange object_addr, markOop | 1, stack address of basicLock
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 assert(mark_addr.disp() == 0, "cas must take a zero displacement");
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 casx_under_lock(mark_addr.base(), mark_reg, temp_reg,
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
1218
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 // if the compare and exchange succeeded we are done (we saw an unlocked object)
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1220 cmp_and_brx_short(mark_reg, temp_reg, Assembler::equal, Assembler::pt, done);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1221
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 // We did not see an unlocked object so try the fast recursive case
a61af66fc99e Initial load
duke
parents:
diff changeset
1223
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 // Check if owner is self by comparing the value in the markOop of object
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 // with the stack pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 sub(temp_reg, SP, temp_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 sub(temp_reg, STACK_BIAS, temp_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 assert(os::vm_page_size() > 0xfff, "page size too small - change the constant");
a61af66fc99e Initial load
duke
parents:
diff changeset
1231
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 // Composite "andcc" test:
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 // (a) %sp -vs- markword proximity check, and,
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 // (b) verify mark word LSBs == 0 (Stack-locked).
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 // FFFFF003/FFFFFFFFFFFF003 is (markOopDesc::lock_mask_in_place | -os::vm_page_size())
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 // Note that the page size used for %sp proximity testing is arbitrary and is
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 // unrelated to the actual MMU page size. We use a 'logical' page size of
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 // 4096 bytes. F..FFF003 is designed to fit conveniently in the SIMM13 immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 // field of the andcc instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 andcc (temp_reg, 0xFFFFF003, G0) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1242
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 // if condition is true we are done and hence we can store 0 in the displaced
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 // header indicating it is a recursive lock and be done
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 brx(Assembler::zero, true, Assembler::pt, done);
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 delayed()->st_ptr(G0, lock_addr, BasicLock::displaced_header_offset_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
1247
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 // none of the above fast optimizations worked so we have to get into the
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 // slow case of monitor enter
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 bind(slow_case);
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), lock_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1252
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 bind(done);
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1256
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 // Unlocks an object. Used in monitorexit bytecode and remove_activation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 // Argument - lock_reg points to the BasicObjectLock for lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 // Throw IllegalMonitorException if object is not locked by current thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 void InterpreterMacroAssembler::unlock_object(Register lock_reg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 if (UseHeavyMonitors) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 Register obj_reg = G3_scratch;
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 Register mark_reg = G4_scratch;
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 Register displaced_header_reg = G1_scratch;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
1268 Address lockobj_addr(lock_reg, BasicObjectLock::obj_offset_in_bytes());
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
1269 Address mark_addr(obj_reg, oopDesc::mark_offset_in_bytes());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 Label done;
a61af66fc99e Initial load
duke
parents:
diff changeset
1271
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 if (UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 // load the object out of the BasicObjectLock
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 ld_ptr(lockobj_addr, obj_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 biased_locking_exit(mark_addr, mark_reg, done, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 st_ptr(G0, lockobj_addr); // free entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1278
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 // Test first if we are in the fast recursive case
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
1280 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
1281 ld_ptr(lock_addr, displaced_header_reg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 br_null(displaced_header_reg, true, Assembler::pn, done);
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 delayed()->st_ptr(G0, lockobj_addr); // free entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1284
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // See if it is still a light weight lock, if so we just unlock
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 // the object and we are done
a61af66fc99e Initial load
duke
parents:
diff changeset
1287
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 if (!UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 // load the object out of the BasicObjectLock
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 ld_ptr(lockobj_addr, obj_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1292
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 // we have the displaced header in displaced_header_reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 // we expect to see the stack address of the basicLock in case the
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 // lock is still a light weight lock (lock_reg)
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 assert(mark_addr.disp() == 0, "cas must take a zero displacement");
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 casx_under_lock(mark_addr.base(), lock_reg, displaced_header_reg,
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 cmp(lock_reg, displaced_header_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 brx(Assembler::equal, true, Assembler::pn, done);
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 delayed()->st_ptr(G0, lockobj_addr); // free entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1302
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 // The lock has been converted into a heavy lock and hence
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 // we need to get into the slow case
a61af66fc99e Initial load
duke
parents:
diff changeset
1305
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1307
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 bind(done);
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1311
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 #ifndef CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
1313
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1314 // Get the method data pointer from the Method* and set the
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 // specified register to its value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1316
2118
dd031b2226de 4930919: race condition in MDO creation at back branch locations
iveresov
parents: 1972
diff changeset
1317 void InterpreterMacroAssembler::set_method_data_pointer() {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 assert(ProfileInterpreter, "must be profiling interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 Label get_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1320
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1321 ld_ptr(Lmethod, in_bytes(Method::method_data_offset()), ImethodDataPtr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 test_method_data_pointer(get_continue);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1323 add(ImethodDataPtr, in_bytes(MethodData::data_offset()), ImethodDataPtr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 bind(get_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1326
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 // Set the method data pointer for the current bcp.
a61af66fc99e Initial load
duke
parents:
diff changeset
1328
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 assert(ProfileInterpreter, "must be profiling interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 Label zero_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1332
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 // Test MDO to avoid the call if it is NULL.
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1334 ld_ptr(Lmethod, in_bytes(Method::method_data_offset()), ImethodDataPtr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 test_method_data_pointer(zero_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 call_VM_leaf(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), Lmethod, Lbcp);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1337 add(ImethodDataPtr, in_bytes(MethodData::data_offset()), ImethodDataPtr);
2118
dd031b2226de 4930919: race condition in MDO creation at back branch locations
iveresov
parents: 1972
diff changeset
1338 add(ImethodDataPtr, O0, ImethodDataPtr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 bind(zero_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1341
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 // Test ImethodDataPtr. If it is null, continue at the specified label
a61af66fc99e Initial load
duke
parents:
diff changeset
1343
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 void InterpreterMacroAssembler::test_method_data_pointer(Label& zero_continue) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 assert(ProfileInterpreter, "must be profiling interpreter");
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1346 br_null_short(ImethodDataPtr, Assembler::pn, zero_continue);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1348
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 void InterpreterMacroAssembler::verify_method_data_pointer() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 assert(ProfileInterpreter, "must be profiling interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 Label verify_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 test_method_data_pointer(verify_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1354
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 // If the mdp is valid, it will point to a DataLayout header which is
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 // consistent with the bcp. The converse is highly probable also.
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 lduh(ImethodDataPtr, in_bytes(DataLayout::bci_offset()), G3_scratch);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1358 ld_ptr(Lmethod, Method::const_offset(), O5);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1359 add(G3_scratch, in_bytes(ConstMethod::codes_offset()), G3_scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 add(G3_scratch, O5, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 cmp(Lbcp, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 brx(Assembler::equal, false, Assembler::pt, verify_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1363
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 Register temp_reg = O5;
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 delayed()->mov(ImethodDataPtr, temp_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 // %%% should use call_VM_leaf here?
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 //call_VM_leaf(noreg, ..., Lmethod, Lbcp, ImethodDataPtr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 save_frame_and_mov(sizeof(jdouble) / wordSize, Lmethod, O0, Lbcp, O1);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
1369 Address d_save(FP, -sizeof(jdouble) + STACK_BIAS);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 stf(FloatRegisterImpl::D, Ftos_d, d_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 mov(temp_reg->after_save(), O2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 save_thread(L7_thread_cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 call(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp), relocInfo::none);
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 restore_thread(L7_thread_cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 ldf(FloatRegisterImpl::D, d_save, Ftos_d);
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 bind(verify_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1381
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 void InterpreterMacroAssembler::test_invocation_counter_for_mdp(Register invocation_count,
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 Register Rtmp,
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 Label &profile_continue) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 assert(ProfileInterpreter, "must be profiling interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 // Control will flow to "profile_continue" if the counter is less than the
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 // limit or if we call profile_method()
a61af66fc99e Initial load
duke
parents:
diff changeset
1388
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 Label done;
a61af66fc99e Initial load
duke
parents:
diff changeset
1390
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 // if no method data exists, and the counter is high enough, make one
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1392 br_notnull_short(ImethodDataPtr, Assembler::pn, done);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1393
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 // Test to see if we should create a method data oop
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
1395 AddressLiteral profile_limit((address) &InvocationCounter::InterpreterProfileLimit);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
1396 sethi(profile_limit, Rtmp);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
1397 ld(Rtmp, profile_limit.low10(), Rtmp);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1398 cmp_and_br_short(invocation_count, Rtmp, Assembler::lessUnsigned, Assembler::pn, profile_continue);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1399
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 // Build it now.
2118
dd031b2226de 4930919: race condition in MDO creation at back branch locations
iveresov
parents: 1972
diff changeset
1401 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
1402 set_method_data_pointer_for_bcp();
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1403 ba_short(profile_continue);
0
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;
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1635 br_notnull_short(receiver, Assembler::pt, not_null);
1503
c640000b7cc1 6829193: JSR 292 needs to support SPARC
twisti
parents: 1295
diff changeset
1636 // We are making a call. Increment the count for null receiver.
c640000b7cc1 6829193: JSR 292 needs to support SPARC
twisti
parents: 1295
diff changeset
1637 increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1638 ba_short(skip_receiver_profile);
1503
c640000b7cc1 6829193: JSR 292 needs to support SPARC
twisti
parents: 1295
diff changeset
1639 bind(not_null);
c640000b7cc1 6829193: JSR 292 needs to support SPARC
twisti
parents: 1295
diff changeset
1640 }
c640000b7cc1 6829193: JSR 292 needs to support SPARC
twisti
parents: 1295
diff changeset
1641
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 // Record the receiver type.
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1643 record_klass_in_profile(receiver, scratch, true);
1503
c640000b7cc1 6829193: JSR 292 needs to support SPARC
twisti
parents: 1295
diff changeset
1644 bind(skip_receiver_profile);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1645
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 // The method data pointer needs to be updated to reflect the new target.
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 bind (profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1651
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 void InterpreterMacroAssembler::record_klass_in_profile_helper(
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 Register receiver, Register scratch,
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1654 int start_row, Label& done, bool is_virtual_call) {
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1655 if (TypeProfileWidth == 0) {
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1656 if (is_virtual_call) {
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1657 increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1658 }
967
6918603297f7 6858208: jvm crash when specifying TypeProfileWidth=0 on jdk 6.0
poonam
parents: 727
diff changeset
1659 return;
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1660 }
967
6918603297f7 6858208: jvm crash when specifying TypeProfileWidth=0 on jdk 6.0
poonam
parents: 727
diff changeset
1661
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 int last_row = VirtualCallData::row_limit() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 assert(start_row <= last_row, "must be work left to do");
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 // Test this row for both the receiver and for null.
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 // Take any of three different outcomes:
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 // 1. found receiver => increment count and goto done
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 // 2. found null => keep looking for case 1, maybe allocate this cell
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 // 3. found something else => keep looking for cases 1 and 2
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 // Case 3 is handled by a recursive call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 for (int row = start_row; row <= last_row; row++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 Label next_test;
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 bool test_for_null_also = (row == start_row);
a61af66fc99e Initial load
duke
parents:
diff changeset
1673
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 // See if the receiver is receiver[n].
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 int recvr_offset = in_bytes(VirtualCallData::receiver_offset(row));
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 test_mdp_data_at(recvr_offset, receiver, next_test, scratch);
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1677 // delayed()->tst(scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1678
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 // The receiver is receiver[n]. Increment count[n].
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row));
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 increment_mdp_data_at(count_offset, scratch);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1682 ba_short(done);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 bind(next_test);
a61af66fc99e Initial load
duke
parents:
diff changeset
1684
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 if (test_for_null_also) {
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1686 Label found_null;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 // Failed the equality check on receiver[n]... Test for null.
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 if (start_row == last_row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 // 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
1690 if (is_virtual_call) {
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1691 brx(Assembler::zero, false, Assembler::pn, found_null);
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1692 delayed()->nop();
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1693 // 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
1694 // Increment total counter to indicate polymorphic case.
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1695 increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1696 ba_short(done);
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1697 bind(found_null);
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1698 } else {
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1699 brx(Assembler::notZero, false, Assembler::pt, done);
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1700 delayed()->nop();
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1701 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 // Since null is rare, make it be the branch-taken case.
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 brx(Assembler::zero, false, Assembler::pn, found_null);
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1707
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 // Put all the "Case 3" tests here.
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1709 record_klass_in_profile_helper(receiver, scratch, start_row + 1, done, is_virtual_call);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1710
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 // Found a null. Keep searching for a matching receiver,
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 // but remember that this is an empty (unused) slot.
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 bind(found_null);
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1716
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 // In the fall-through case, we found no matching receiver, but we
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 // observed the receiver[start_row] is NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
1719
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 // Fill in the receiver field and increment the count.
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row));
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 set_mdp_data_at(recvr_offset, receiver);
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row));
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 mov(DataLayout::counter_increment, scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 set_mdp_data_at(count_offset, scratch);
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1726 if (start_row > 0) {
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1727 ba_short(done);
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1728 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1730
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 void InterpreterMacroAssembler::record_klass_in_profile(Register receiver,
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1732 Register scratch, bool is_virtual_call) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 assert(ProfileInterpreter, "must be profiling");
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 Label done;
a61af66fc99e Initial load
duke
parents:
diff changeset
1735
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1736 record_klass_in_profile_helper(receiver, scratch, 0, done, is_virtual_call);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1737
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 bind (done);
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1740
a61af66fc99e Initial load
duke
parents:
diff changeset
1741
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 // Count a ret in the bytecodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1743
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 void InterpreterMacroAssembler::profile_ret(TosState state,
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 Register return_bci,
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 Register scratch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 uint row;
a61af66fc99e Initial load
duke
parents:
diff changeset
1750
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 test_method_data_pointer(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1753
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 // Update the total ret count.
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1756
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 for (row = 0; row < RetData::row_limit(); row++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 Label next_test;
a61af66fc99e Initial load
duke
parents:
diff changeset
1759
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 // See if return_bci is equal to bci[n]:
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 test_mdp_data_at(in_bytes(RetData::bci_offset(row)),
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 return_bci, next_test, scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1763
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 // return_bci is equal to bci[n]. Increment the count.
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 increment_mdp_data_at(in_bytes(RetData::bci_count_offset(row)), scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1766
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 // The method data pointer needs to be updated to reflect the new target.
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 update_mdp_by_offset(in_bytes(RetData::bci_displacement_offset(row)), scratch);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1769 ba_short(profile_continue);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 bind(next_test);
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1772
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 update_mdp_for_ret(state, return_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
1774
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 bind (profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1778
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 // Profile an unexpected null in the bytecodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 void InterpreterMacroAssembler::profile_null_seen(Register scratch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1783
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 test_method_data_pointer(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1786
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 set_mdp_flag_at(BitData::null_seen_byte_constant(), scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1788
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 // The method data pointer needs to be updated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 int mdp_delta = in_bytes(BitData::bit_data_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 if (TypeProfileCasts) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 update_mdp_by_constant(mdp_delta);
a61af66fc99e Initial load
duke
parents:
diff changeset
1795
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 bind (profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1799
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 void InterpreterMacroAssembler::profile_typecheck(Register klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 Register scratch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1804
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 test_method_data_pointer(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1807
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 int mdp_delta = in_bytes(BitData::bit_data_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 if (TypeProfileCasts) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1811
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 // Record the object type.
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 967
diff changeset
1813 record_klass_in_profile(klass, scratch, false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1815
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 // The method data pointer needs to be updated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 update_mdp_by_constant(mdp_delta);
a61af66fc99e Initial load
duke
parents:
diff changeset
1818
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 bind (profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1822
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 void InterpreterMacroAssembler::profile_typecheck_failed(Register scratch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 if (ProfileInterpreter && TypeProfileCasts) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1826
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 test_method_data_pointer(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1829
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 int count_offset = in_bytes(CounterData::count_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 // Back up the address, since we have already bumped the mdp.
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 count_offset -= in_bytes(VirtualCallData::virtual_call_data_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1833
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 // *Decrement* the counter. We expect to see zero or small negatives.
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 increment_mdp_data_at(count_offset, scratch, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1836
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 bind (profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1840
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 // Count the default case of a switch construct.
a61af66fc99e Initial load
duke
parents:
diff changeset
1842
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 void InterpreterMacroAssembler::profile_switch_default(Register scratch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1846
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 test_method_data_pointer(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1849
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 // Update the default case count
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 increment_mdp_data_at(in_bytes(MultiBranchData::default_count_offset()),
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1853
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 // The method data pointer needs to be updated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 update_mdp_by_offset(
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 in_bytes(MultiBranchData::default_displacement_offset()),
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1858
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 bind (profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1862
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 // Count the index'th case of a switch construct.
a61af66fc99e Initial load
duke
parents:
diff changeset
1864
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 void InterpreterMacroAssembler::profile_switch_case(Register index,
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 Register scratch,
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 Register scratch2,
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 Register scratch3) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1871
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 test_method_data_pointer(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1874
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 // Build the base (index * per_case_size_in_bytes()) + case_array_offset_in_bytes()
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 set(in_bytes(MultiBranchData::per_case_size()), scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 smul(index, scratch, scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 add(scratch, in_bytes(MultiBranchData::case_array_offset()), scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1879
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 // Update the case count
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 increment_mdp_data_at(scratch,
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 in_bytes(MultiBranchData::relative_count_offset()),
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 scratch2,
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 scratch3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1885
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 // The method data pointer needs to be updated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 update_mdp_by_offset(scratch,
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 in_bytes(MultiBranchData::relative_displacement_offset()),
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 scratch2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1890
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 bind (profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1894
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 // add a InterpMonitorElem to stack (see frame_sparc.hpp)
a61af66fc99e Initial load
duke
parents:
diff changeset
1896
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 void InterpreterMacroAssembler::add_monitor_to_stack( bool stack_is_empty,
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 Register Rtemp,
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 Register Rtemp2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1900
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 Register Rlimit = Lmonitors;
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 const jint delta = frame::interpreter_frame_monitor_size() * wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 assert( (delta & LongAlignmentMask) == 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 "sizeof BasicObjectLock must be even number of doublewords");
a61af66fc99e Initial load
duke
parents:
diff changeset
1905
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 sub( SP, delta, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 sub( Lesp, delta, Lesp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 sub( Lmonitors, delta, Lmonitors);
a61af66fc99e Initial load
duke
parents:
diff changeset
1909
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 if (!stack_is_empty) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1911
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 // must copy stack contents down
a61af66fc99e Initial load
duke
parents:
diff changeset
1913
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 Label start_copying, next;
a61af66fc99e Initial load
duke
parents:
diff changeset
1915
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 // untested("monitor stack expansion");
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 compute_stack_base(Rtemp);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1918 ba(start_copying);
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
1919 delayed()->cmp(Rtemp, Rlimit); // done? duplicated below
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1920
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 // note: must copy from low memory upwards
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 // On entry to loop,
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 // Rtemp points to new base of stack, Lesp points to new end of stack (1 past TOS)
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 // Loop mutates Rtemp
a61af66fc99e Initial load
duke
parents:
diff changeset
1925
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 bind( next);
a61af66fc99e Initial load
duke
parents:
diff changeset
1927
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 st_ptr(Rtemp2, Rtemp, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 inc(Rtemp, wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 cmp(Rtemp, Rlimit); // are we done? (duplicated above)
a61af66fc99e Initial load
duke
parents:
diff changeset
1931
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 bind( start_copying );
a61af66fc99e Initial load
duke
parents:
diff changeset
1933
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 brx( notEqual, true, pn, next );
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 delayed()->ld_ptr( Rtemp, delta, Rtemp2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1936
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 // done copying stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1940
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 // Locals
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 void InterpreterMacroAssembler::access_local_ptr( Register index, Register dst ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 assert_not_delayed();
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
1944 sll(index, Interpreter::logStackElementSize, index);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 sub(Llocals, index, index);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
1946 ld_ptr(index, 0, dst);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 // Note: index must hold the effective address--the iinc template uses it
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1949
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 // Just like access_local_ptr but the tag is a returnAddress
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 void InterpreterMacroAssembler::access_local_returnAddress(Register index,
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 Register dst ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 assert_not_delayed();
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
1954 sll(index, Interpreter::logStackElementSize, index);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 sub(Llocals, index, index);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
1956 ld_ptr(index, 0, dst);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1958
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 void InterpreterMacroAssembler::access_local_int( Register index, 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(index, 0, dst);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 // Note: index must hold the effective address--the iinc template uses it
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1966
a61af66fc99e Initial load
duke
parents:
diff changeset
1967
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 void InterpreterMacroAssembler::access_local_long( Register index, Register dst ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 assert_not_delayed();
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
1970 sll(index, Interpreter::logStackElementSize, index);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 sub(Llocals, index, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 // First half stored at index n+1 (which grows down from Llocals[n])
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 load_unaligned_long(index, Interpreter::local_offset_in_bytes(1), dst);
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1975
a61af66fc99e Initial load
duke
parents:
diff changeset
1976
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 void InterpreterMacroAssembler::access_local_float( Register index, FloatRegister dst ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 assert_not_delayed();
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
1979 sll(index, Interpreter::logStackElementSize, index);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 sub(Llocals, index, index);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
1981 ldf(FloatRegisterImpl::S, index, 0, dst);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1983
a61af66fc99e Initial load
duke
parents:
diff changeset
1984
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 void InterpreterMacroAssembler::access_local_double( Register index, FloatRegister dst ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 assert_not_delayed();
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
1987 sll(index, Interpreter::logStackElementSize, index);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 sub(Llocals, index, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 load_unaligned_double(index, Interpreter::local_offset_in_bytes(1), dst);
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1991
a61af66fc99e Initial load
duke
parents:
diff changeset
1992
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 void InterpreterMacroAssembler::check_for_regarea_stomp(Register Rindex, int offset, Register Rlimit, Register Rscratch, Register Rscratch1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1996
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 assert(Rindex != Rscratch, "Registers cannot be same");
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 assert(Rindex != Rscratch1, "Registers cannot be same");
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 assert(Rlimit != Rscratch, "Registers cannot be same");
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 assert(Rlimit != Rscratch1, "Registers cannot be same");
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 assert(Rscratch1 != Rscratch, "Registers cannot be same");
a61af66fc99e Initial load
duke
parents:
diff changeset
2002
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 // untested("reg area corruption");
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 add(Rindex, offset, Rscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 add(Rlimit, 64 + STACK_BIAS, Rscratch1);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
2006 cmp_and_brx_short(Rscratch, Rscratch1, Assembler::greaterEqualUnsigned, pn, L);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 stop("regsave area is being clobbered");
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2011
a61af66fc99e Initial load
duke
parents:
diff changeset
2012
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 void InterpreterMacroAssembler::store_local_int( Register index, Register src ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 assert_not_delayed();
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2015 sll(index, Interpreter::logStackElementSize, index);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 sub(Llocals, index, index);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2017 debug_only(check_for_regarea_stomp(index, 0, FP, G1_scratch, G4_scratch);)
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2018 st(src, index, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2020
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2021 void InterpreterMacroAssembler::store_local_ptr( Register index, Register src ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 assert_not_delayed();
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2023 sll(index, Interpreter::logStackElementSize, index);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 sub(Llocals, index, index);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2025 #ifdef ASSERT
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2026 check_for_regarea_stomp(index, 0, FP, G1_scratch, G4_scratch);
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2027 #endif
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2028 st_ptr(src, index, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2030
a61af66fc99e Initial load
duke
parents:
diff changeset
2031
a61af66fc99e Initial load
duke
parents:
diff changeset
2032
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2033 void InterpreterMacroAssembler::store_local_ptr( int n, Register src ) {
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2034 st_ptr(src, Llocals, Interpreter::local_offset_in_bytes(n));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2036
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 void InterpreterMacroAssembler::store_local_long( Register index, Register src ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 assert_not_delayed();
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2039 sll(index, Interpreter::logStackElementSize, index);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 sub(Llocals, index, index);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2041 #ifdef ASSERT
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 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
2043 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 store_unaligned_long(src, index, Interpreter::local_offset_in_bytes(1)); // which is n+1
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2046
a61af66fc99e Initial load
duke
parents:
diff changeset
2047
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 void InterpreterMacroAssembler::store_local_float( Register index, FloatRegister src ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 assert_not_delayed();
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2050 sll(index, Interpreter::logStackElementSize, index);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 sub(Llocals, index, index);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2052 #ifdef ASSERT
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2053 check_for_regarea_stomp(index, 0, FP, G1_scratch, G4_scratch);
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2054 #endif
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2055 stf(FloatRegisterImpl::S, src, index, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2057
a61af66fc99e Initial load
duke
parents:
diff changeset
2058
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 void InterpreterMacroAssembler::store_local_double( Register index, FloatRegister src ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 assert_not_delayed();
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2061 sll(index, Interpreter::logStackElementSize, index);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 sub(Llocals, index, index);
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1503
diff changeset
2063 #ifdef ASSERT
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 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
2065 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 store_unaligned_double(src, index, Interpreter::local_offset_in_bytes(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2068
a61af66fc99e Initial load
duke
parents:
diff changeset
2069
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 int InterpreterMacroAssembler::top_most_monitor_byte_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 const jint delta = frame::interpreter_frame_monitor_size() * wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 int rounded_vm_local_words = ::round_to(frame::interpreter_frame_vm_local_words, WordsPerLong);
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 return ((-rounded_vm_local_words * wordSize) - delta ) + STACK_BIAS;
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2075
a61af66fc99e Initial load
duke
parents:
diff changeset
2076
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 Address InterpreterMacroAssembler::top_most_monitor() {
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
2078 return Address(FP, top_most_monitor_byte_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2080
a61af66fc99e Initial load
duke
parents:
diff changeset
2081
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 void InterpreterMacroAssembler::compute_stack_base( Register Rdest ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 add( Lesp, wordSize, Rdest );
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2085
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 #endif /* CC_INTERP */
a61af66fc99e Initial load
duke
parents:
diff changeset
2087
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 void InterpreterMacroAssembler::increment_invocation_counter( Register Rtmp, Register Rtmp2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 assert(UseCompiler, "incrementing must be useful");
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 #ifdef CC_INTERP
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2091 Address inv_counter(G5_method, Method::invocation_counter_offset() +
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
2092 InvocationCounter::counter_offset());
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2093 Address be_counter (G5_method, Method::backedge_counter_offset() +
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
2094 InvocationCounter::counter_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 #else
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2096 Address inv_counter(Lmethod, Method::invocation_counter_offset() +
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
2097 InvocationCounter::counter_offset());
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2098 Address be_counter (Lmethod, Method::backedge_counter_offset() +
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
2099 InvocationCounter::counter_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 #endif /* CC_INTERP */
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 int delta = InvocationCounter::count_increment;
a61af66fc99e Initial load
duke
parents:
diff changeset
2102
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 // Load each counter in a register
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 ld( inv_counter, Rtmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 ld( be_counter, Rtmp2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2106
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 assert( is_simm13( delta ), " delta too large.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2108
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 // Add the delta to the invocation counter and store the result
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 add( Rtmp, delta, Rtmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
2111
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 // Mask the backedge counter
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 and3( Rtmp2, InvocationCounter::count_mask_value, Rtmp2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2114
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 // Store value
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 st( Rtmp, inv_counter);
a61af66fc99e Initial load
duke
parents:
diff changeset
2117
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 // Add invocation counter + backedge counter
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 add( Rtmp, Rtmp2, Rtmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2120
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 // Note that this macro must leave the backedge_count + invocation_count in Rtmp!
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2123
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 void InterpreterMacroAssembler::increment_backedge_counter( Register Rtmp, Register Rtmp2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 assert(UseCompiler, "incrementing must be useful");
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 #ifdef CC_INTERP
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2127 Address be_counter (G5_method, Method::backedge_counter_offset() +
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
2128 InvocationCounter::counter_offset());
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2129 Address inv_counter(G5_method, Method::invocation_counter_offset() +
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
2130 InvocationCounter::counter_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 #else
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2132 Address be_counter (Lmethod, Method::backedge_counter_offset() +
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
2133 InvocationCounter::counter_offset());
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2134 Address inv_counter(Lmethod, Method::invocation_counter_offset() +
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
2135 InvocationCounter::counter_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 #endif /* CC_INTERP */
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 int delta = InvocationCounter::count_increment;
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 // Load each counter in a register
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 ld( be_counter, Rtmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 ld( inv_counter, Rtmp2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2141
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 // Add the delta to the backedge counter
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 add( Rtmp, delta, Rtmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
2144
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 // Mask the invocation counter, add to backedge counter
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 and3( Rtmp2, InvocationCounter::count_mask_value, Rtmp2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2147
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 // and store the result to memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 st( Rtmp, be_counter );
a61af66fc99e Initial load
duke
parents:
diff changeset
2150
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 // Add backedge + invocation counter
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 add( Rtmp, Rtmp2, Rtmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
2153
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 // Note that this macro must leave backedge_count + invocation_count in Rtmp!
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2156
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 #ifndef CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 void InterpreterMacroAssembler::test_backedge_count_for_osr( Register backedge_count,
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 Register branch_bcp,
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 Register Rtmp ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 Label did_not_overflow;
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 Label overflow_with_error;
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 assert_different_registers(backedge_count, Rtmp, branch_bcp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 assert(UseOnStackReplacement,"Must UseOnStackReplacement to test_backedge_count_for_osr");
a61af66fc99e Initial load
duke
parents:
diff changeset
2165
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
2166 AddressLiteral limit(&InvocationCounter::InterpreterBackwardBranchLimit);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 load_contents(limit, Rtmp);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
2168 cmp_and_br_short(backedge_count, Rtmp, Assembler::lessUnsigned, Assembler::pt, did_not_overflow);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2169
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 // When ProfileInterpreter is on, the backedge_count comes from the
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2171 // MethodData*, which value does not get reset on the call to
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 // frequency_counter_overflow(). To avoid excessive calls to the overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 // routine while the method is being compiled, add a second test to make sure
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 // the overflow function is called only once every overflow_frequency.
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 const int overflow_frequency = 1024;
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 andcc(backedge_count, overflow_frequency-1, Rtmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 brx(Assembler::notZero, 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
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 // overflow in loop, pass branch bytecode
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 set(6,Rtmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), branch_bcp, Rtmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2185
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 // Was an OSR adapter generated?
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 // O0 = osr nmethod
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
2188 br_null_short(O0, Assembler::pn, overflow_with_error);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2189
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 // Has the nmethod been invalidated already?
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 ld(O0, nmethod::entry_bci_offset(), O2);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
2192 cmp_and_br_short(O2, InvalidOSREntryBci, Assembler::equal, Assembler::pn, overflow_with_error);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2193
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 // migrate the interpreter frame off of the stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2195
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 mov(G2_thread, L7);
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 // save nmethod
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 mov(O0, L6);
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 set_last_Java_frame(SP, noreg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 call_VM_leaf(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::OSR_migration_begin), L7);
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 reset_last_Java_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 mov(L7, G2_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
2203
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 // move OSR nmethod to I1
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 mov(L6, I1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2206
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 // OSR buffer to I0
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 mov(O0, I0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2209
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 // remove the interpreter frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 restore(I5_savedSP, 0, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
2212
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 // Jump to the osr code.
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 ld_ptr(O1, nmethod::osr_entry_point_offset(), O2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 jmp(O2, G0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2217
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 bind(overflow_with_error);
a61af66fc99e Initial load
duke
parents:
diff changeset
2219
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 bind(did_not_overflow);
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2222
a61af66fc99e Initial load
duke
parents:
diff changeset
2223
a61af66fc99e Initial load
duke
parents:
diff changeset
2224
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 void InterpreterMacroAssembler::interp_verify_oop(Register reg, TosState state, const char * file, int line) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 if (state == atos) { MacroAssembler::_verify_oop(reg, "broken oop ", file, line); }
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2228
a61af66fc99e Initial load
duke
parents:
diff changeset
2229
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 // local helper function for the verify_oop_or_return_address macro
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2231 static bool verify_return_address(Method* m, int bci) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 address pc = (address)(m->constMethod())
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2234 + in_bytes(ConstMethod::codes_offset()) + bci;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 // 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
2236 if (!m->contains(pc)) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 address jsr_pc;
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 jsr_pc = pc - Bytecodes::length_for(Bytecodes::_jsr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 if (*jsr_pc == Bytecodes::_jsr && jsr_pc >= m->code_base()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 jsr_pc = pc - Bytecodes::length_for(Bytecodes::_jsr_w);
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 if (*jsr_pc == Bytecodes::_jsr_w && jsr_pc >= m->code_base()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2245
a61af66fc99e Initial load
duke
parents:
diff changeset
2246
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 void InterpreterMacroAssembler::verify_oop_or_return_address(Register reg, Register Rtmp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 if (!VerifyOops) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 // the VM documentation for the astore[_wide] bytecode allows
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 // the TOS to be not only an oop but also a return address
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 Label test;
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 Label skip;
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 // See if it is an address (in the current method):
a61af66fc99e Initial load
duke
parents:
diff changeset
2254
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 mov(reg, Rtmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 const int log2_bytecode_size_limit = 16;
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 srl(Rtmp, log2_bytecode_size_limit, Rtmp);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
2258 br_notnull_short( Rtmp, pt, test );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2259
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 // %%% should use call_VM_leaf here?
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 save_frame_and_mov(0, Lmethod, O0, reg, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 save_thread(L7_thread_cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 call(CAST_FROM_FN_PTR(address,verify_return_address), relocInfo::none);
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 restore_thread(L7_thread_cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 br_notnull( O0, false, pt, skip );
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 delayed()->restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
2268
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 // Perform a more elaborate out-of-line call
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 // Not an address; verify it:
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 bind(test);
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 verify_oop(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 bind(skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2275
a61af66fc99e Initial load
duke
parents:
diff changeset
2276
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 if (state == ftos || state == dtos) MacroAssembler::verify_FPU(stack_depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 #endif /* CC_INTERP */
a61af66fc99e Initial load
duke
parents:
diff changeset
2281
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 // Inline assembly for:
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 // if (thread is in interp_only_mode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 // InterpreterRuntime::post_method_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 // if (DTraceMethodProbes) {
605
98cb887364d3 6810672: Comment typos
twisti
parents: 422
diff changeset
2288 // SharedRuntime::dtrace_method_entry(method, receiver);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 // }
610
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 422
diff changeset
2290 // 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
2291 // SharedRuntime::rc_trace_method_entry(method, receiver);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
2293
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 void InterpreterMacroAssembler::notify_method_entry() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2295
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 // C++ interpreter only uses this for native methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
2297
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 // Whenever JVMTI puts a thread in interp_only_mode, method
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 // entry/exit events are sent for that thread to track stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 // depth. If it is possible to enter interp_only_mode we add
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 // the code to check if the event should be sent.
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 if (JvmtiExport::can_post_interpreter_events()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 Register temp_reg = O5;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
2305 const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 ld(interp_only, temp_reg);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
2307 cmp_and_br_short(temp_reg, 0, equal, pt, L);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2311
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 Register temp_reg = O5;
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 SkipIfEqual skip_if(this, temp_reg, &DTraceMethodProbes, zero);
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 call_VM_leaf(noreg,
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry),
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 G2_thread, Lmethod);
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 }
610
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 422
diff changeset
2319
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 422
diff changeset
2320 // 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
2321 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
2322 call_VM_leaf(noreg,
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 422
diff changeset
2323 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
2324 G2_thread, Lmethod);
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 422
diff changeset
2325 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2327
a61af66fc99e Initial load
duke
parents:
diff changeset
2328
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 // Inline assembly for:
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 // if (thread is in interp_only_mode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 // // save result
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 // InterpreterRuntime::post_method_exit();
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 // // restore result
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 // if (DTraceMethodProbes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 // SharedRuntime::dtrace_method_exit(thread, method);
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 // Native methods have their result stored in d_tmp and l_tmp
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 // Java methods have their result stored in the expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2342
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 void InterpreterMacroAssembler::notify_method_exit(bool is_native_method,
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 TosState state,
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 NotifyMethodExitMode mode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 // C++ interpreter only uses this for native methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
2347
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 // Whenever JVMTI puts a thread in interp_only_mode, method
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 // entry/exit events are sent for that thread to track stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2350 // depth. If it is possible to enter interp_only_mode we add
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 // the code to check if the event should be sent.
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 if (mode == NotifyJVMTI && JvmtiExport::can_post_interpreter_events()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 Register temp_reg = O5;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 644
diff changeset
2355 const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 ld(interp_only, temp_reg);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2416
diff changeset
2357 cmp_and_br_short(temp_reg, 0, equal, pt, L);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2358
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 // Note: frame::interpreter_frame_result has a dependency on how the
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 // method result is saved across the call to post_method_exit. For
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 // native methods it assumes the result registers are saved to
a61af66fc99e Initial load
duke
parents:
diff changeset
2362 // l_scratch and d_scratch. If this changes then the interpreter_frame_result
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 // implementation will need to be updated too.
a61af66fc99e Initial load
duke
parents:
diff changeset
2364
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 save_return_value(state, is_native_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 call_VM(noreg,
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_exit));
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 restore_return_value(state, is_native_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2371
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 Register temp_reg = O5;
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 // Dtrace notification
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 SkipIfEqual skip_if(this, temp_reg, &DTraceMethodProbes, zero);
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 save_return_value(state, is_native_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 call_VM_leaf(
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 noreg,
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit),
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 G2_thread, Lmethod);
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 restore_return_value(state, is_native_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2384
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 void InterpreterMacroAssembler::save_return_value(TosState state, bool is_native_call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 #ifdef CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 // result potentially in O0/O1: save it across calls
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 stf(FloatRegisterImpl::D, F0, STATE(_native_fresult));
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 stx(O0, STATE(_native_lresult));
a61af66fc99e Initial load
duke
parents:
diff changeset
2391 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 std(O0, STATE(_native_lresult));
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 #else // CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
2395 if (is_native_call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 stf(FloatRegisterImpl::D, F0, d_tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 stx(O0, l_tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 std(O0, l_tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 push(state);
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 #endif // CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2407
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 void InterpreterMacroAssembler::restore_return_value( TosState state, bool is_native_call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 #ifdef CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 ldf(FloatRegisterImpl::D, STATE(_native_fresult), F0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 ldx(STATE(_native_lresult), O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 ldd(STATE(_native_lresult), O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 #else // CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 if (is_native_call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 ldf(FloatRegisterImpl::D, d_tmp, F0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 ldx(l_tmp, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 ldd(l_tmp, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2425 pop(state);
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 #endif // CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 }
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2429
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2430 // Jump if ((*counter_addr += increment) & mask) satisfies the condition.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2431 void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2432 int increment, int mask,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2433 Register scratch1, Register scratch2,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2434 Condition cond, Label *where) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2435 ld(counter_addr, scratch1);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2436 add(scratch1, increment, scratch1);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2437 if (is_simm13(mask)) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2438 andcc(scratch1, mask, G0);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2439 } else {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2440 set(mask, scratch2);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2441 andcc(scratch1, scratch2, G0);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2442 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2443 br(cond, false, Assembler::pn, *where);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2444 delayed()->st(scratch1, counter_addr);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2445 }