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