annotate src/cpu/sparc/vm/cppInterpreter_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
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) 2007, 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: 710
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 710
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: 710
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: 1552
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
26 #include "asm/assembler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27 #include "interpreter/bytecodeHistogram.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "interpreter/cppInterpreter.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "interpreter/interpreter.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30 #include "interpreter/interpreterGenerator.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
31 #include "interpreter/interpreterRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
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: 1552
diff changeset
35 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
36 #include "prims/jvmtiExport.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
37 #include "prims/jvmtiThreadState.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
38 #include "runtime/arguments.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
39 #include "runtime/deoptimization.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
40 #include "runtime/frame.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
41 #include "runtime/interfaceSupport.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
42 #include "runtime/sharedRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
43 #include "runtime/stubRoutines.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
44 #include "runtime/synchronizer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
45 #include "runtime/timer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
46 #include "runtime/vframeArray.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
47 #include "utilities/debug.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
48 #ifdef SHARK
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
49 #include "shark/shark_globals.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
50 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 #ifdef CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // Routine exists to make tracebacks look decent in debugger
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // while "shadow" interpreter frames are on stack. It is also
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // used to distinguish interpreter frames.
a61af66fc99e Initial load
duke
parents:
diff changeset
57
a61af66fc99e Initial load
duke
parents:
diff changeset
58 extern "C" void RecursiveInterpreterActivation(interpreterState istate) {
a61af66fc99e Initial load
duke
parents:
diff changeset
59 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
60 }
a61af66fc99e Initial load
duke
parents:
diff changeset
61
a61af66fc99e Initial load
duke
parents:
diff changeset
62 bool CppInterpreter::contains(address pc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
63 return ( _code->contains(pc) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
64 ( pc == (CAST_FROM_FN_PTR(address, RecursiveInterpreterActivation) + frame::pc_return_offset)));
a61af66fc99e Initial load
duke
parents:
diff changeset
65 }
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 #define STATE(field_name) Lstate, in_bytes(byte_offset_of(BytecodeInterpreter, field_name))
a61af66fc99e Initial load
duke
parents:
diff changeset
68 #define __ _masm->
a61af66fc99e Initial load
duke
parents:
diff changeset
69
a61af66fc99e Initial load
duke
parents:
diff changeset
70 Label frame_manager_entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 Label fast_accessor_slow_entry_path; // fast accessor methods need to be able to jmp to unsynchronized
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // c++ interpreter entry point this holds that entry point label.
a61af66fc99e Initial load
duke
parents:
diff changeset
73
a61af66fc99e Initial load
duke
parents:
diff changeset
74 static address unctrap_frame_manager_entry = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76 static address interpreter_return_address = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
77 static address deopt_frame_manager_return_atos = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
78 static address deopt_frame_manager_return_btos = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
79 static address deopt_frame_manager_return_itos = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
80 static address deopt_frame_manager_return_ltos = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
81 static address deopt_frame_manager_return_ftos = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
82 static address deopt_frame_manager_return_dtos = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
83 static address deopt_frame_manager_return_vtos = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 const Register prevState = G1_scratch;
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 void InterpreterGenerator::save_native_result(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // result potentially in O0/O1: save it across calls
a61af66fc99e Initial load
duke
parents:
diff changeset
89 __ stf(FloatRegisterImpl::D, F0, STATE(_native_fresult));
a61af66fc99e Initial load
duke
parents:
diff changeset
90 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
91 __ stx(O0, STATE(_native_lresult));
a61af66fc99e Initial load
duke
parents:
diff changeset
92 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
93 __ std(O0, STATE(_native_lresult));
a61af66fc99e Initial load
duke
parents:
diff changeset
94 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
95 }
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97 void InterpreterGenerator::restore_native_result(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
98
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // Restore any method result value
a61af66fc99e Initial load
duke
parents:
diff changeset
100 __ ldf(FloatRegisterImpl::D, STATE(_native_fresult), F0);
a61af66fc99e Initial load
duke
parents:
diff changeset
101 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
102 __ ldx(STATE(_native_lresult), O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
103 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
104 __ ldd(STATE(_native_lresult), O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
105 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
107
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // A result handler converts/unboxes a native call result into
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // a java interpreter/compiler result. The current frame is an
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // interpreter frame. The activation frame unwind code must be
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // consistent with that of TemplateTable::_return(...). In the
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // case of native methods, the caller's SP was not modified.
a61af66fc99e Initial load
duke
parents:
diff changeset
113 address CppInterpreterGenerator::generate_result_handler_for(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
114 address entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
115 Register Itos_i = Otos_i ->after_save();
a61af66fc99e Initial load
duke
parents:
diff changeset
116 Register Itos_l = Otos_l ->after_save();
a61af66fc99e Initial load
duke
parents:
diff changeset
117 Register Itos_l1 = Otos_l1->after_save();
a61af66fc99e Initial load
duke
parents:
diff changeset
118 Register Itos_l2 = Otos_l2->after_save();
a61af66fc99e Initial load
duke
parents:
diff changeset
119 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
120 case T_BOOLEAN: __ subcc(G0, O0, G0); __ addc(G0, 0, Itos_i); break; // !0 => true; 0 => false
a61af66fc99e Initial load
duke
parents:
diff changeset
121 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
122 case T_BYTE : __ sll(O0, 24, O0); __ sra(O0, 24, Itos_i); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
123 case T_SHORT : __ sll(O0, 16, O0); __ sra(O0, 16, Itos_i); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
124 case T_LONG :
a61af66fc99e Initial load
duke
parents:
diff changeset
125 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
126 __ mov(O1, Itos_l2); // move other half of long
a61af66fc99e Initial load
duke
parents:
diff changeset
127 #endif // ifdef or no ifdef, fall through to the T_INT case
a61af66fc99e Initial load
duke
parents:
diff changeset
128 case T_INT : __ mov(O0, Itos_i); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
129 case T_VOID : /* nothing to do */ break;
a61af66fc99e Initial load
duke
parents:
diff changeset
130 case T_FLOAT : assert(F0 == Ftos_f, "fix this code" ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
131 case T_DOUBLE : assert(F0 == Ftos_d, "fix this code" ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
132 case T_OBJECT :
a61af66fc99e Initial load
duke
parents:
diff changeset
133 __ ld_ptr(STATE(_oop_temp), Itos_i);
a61af66fc99e Initial load
duke
parents:
diff changeset
134 __ verify_oop(Itos_i);
a61af66fc99e Initial load
duke
parents:
diff changeset
135 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
136 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
138 __ ret(); // return from interpreter activation
a61af66fc99e Initial load
duke
parents:
diff changeset
139 __ delayed()->restore(I5_savedSP, G0, SP); // remove interpreter frame
a61af66fc99e Initial load
duke
parents:
diff changeset
140 NOT_PRODUCT(__ emit_long(0);) // marker for disassembly
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 // tosca based result to c++ interpreter stack based result.
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // Result goes to address in L1_scratch
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147 address CppInterpreterGenerator::generate_tosca_to_stack_converter(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // A result is in the native abi result register from a native method call.
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // We need to return this result to the interpreter by pushing the result on the interpreter's
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // stack. This is relatively simple the destination is in L1_scratch
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // i.e. L1_scratch is the first free element on the stack. If we "push" a return value we must
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // adjust L1_scratch
a61af66fc99e Initial load
duke
parents:
diff changeset
153 address entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
154 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
155 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // !0 => true; 0 => false
a61af66fc99e Initial load
duke
parents:
diff changeset
157 __ subcc(G0, O0, G0);
a61af66fc99e Initial load
duke
parents:
diff changeset
158 __ addc(G0, 0, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
159 __ st(O0, L1_scratch, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
160 __ sub(L1_scratch, wordSize, L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
161 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
162
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // cannot use and3, 0xFFFF too big as immediate value!
a61af66fc99e Initial load
duke
parents:
diff changeset
164 case T_CHAR :
a61af66fc99e Initial load
duke
parents:
diff changeset
165 __ sll(O0, 16, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
166 __ srl(O0, 16, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
167 __ st(O0, L1_scratch, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
168 __ sub(L1_scratch, wordSize, L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
169 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 case T_BYTE :
a61af66fc99e Initial load
duke
parents:
diff changeset
172 __ sll(O0, 24, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
173 __ sra(O0, 24, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
174 __ st(O0, L1_scratch, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
175 __ sub(L1_scratch, wordSize, L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
176 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
177
a61af66fc99e Initial load
duke
parents:
diff changeset
178 case T_SHORT :
a61af66fc99e Initial load
duke
parents:
diff changeset
179 __ sll(O0, 16, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
180 __ sra(O0, 16, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
181 __ st(O0, L1_scratch, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
182 __ sub(L1_scratch, wordSize, L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
183 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
184 case T_LONG :
a61af66fc99e Initial load
duke
parents:
diff changeset
185 #ifndef _LP64
123
9e5a7340635e 6688137: c++ interpreter fails on 64bit sparc
sgoldman
parents: 0
diff changeset
186 #if defined(COMPILER2)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // All return values are where we want them, except for Longs. C2 returns
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1.
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // Since the interpreter will return longs in G1 and O0/O1 in the 32bit
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // build even if we are returning from interpreted we just do a little
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // stupid shuffing.
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // 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
193 // do this here. Unfortunately if we did a rethrow we'd see an machepilog node
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // first which would move g1 -> O0/O1 and destroy the exception we were throwing.
a61af66fc99e Initial load
duke
parents:
diff changeset
195 __ stx(G1, L1_scratch, -wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
196 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // native result is in O0, O1
a61af66fc99e Initial load
duke
parents:
diff changeset
198 __ st(O1, L1_scratch, 0); // Low order
a61af66fc99e Initial load
duke
parents:
diff changeset
199 __ st(O0, L1_scratch, -wordSize); // High order
123
9e5a7340635e 6688137: c++ interpreter fails on 64bit sparc
sgoldman
parents: 0
diff changeset
200 #endif /* COMPILER2 */
0
a61af66fc99e Initial load
duke
parents:
diff changeset
201 #else
123
9e5a7340635e 6688137: c++ interpreter fails on 64bit sparc
sgoldman
parents: 0
diff changeset
202 __ stx(O0, L1_scratch, -wordSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
203 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
204 __ sub(L1_scratch, 2*wordSize, L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
205 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
206
a61af66fc99e Initial load
duke
parents:
diff changeset
207 case T_INT :
a61af66fc99e Initial load
duke
parents:
diff changeset
208 __ st(O0, L1_scratch, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
209 __ sub(L1_scratch, wordSize, L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
210 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 case T_VOID : /* nothing to do */
a61af66fc99e Initial load
duke
parents:
diff changeset
213 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
214
a61af66fc99e Initial load
duke
parents:
diff changeset
215 case T_FLOAT :
a61af66fc99e Initial load
duke
parents:
diff changeset
216 __ stf(FloatRegisterImpl::S, F0, L1_scratch, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
217 __ sub(L1_scratch, wordSize, L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
218 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
219
a61af66fc99e Initial load
duke
parents:
diff changeset
220 case T_DOUBLE :
a61af66fc99e Initial load
duke
parents:
diff changeset
221 // Every stack slot is aligned on 64 bit, However is this
a61af66fc99e Initial load
duke
parents:
diff changeset
222 // the correct stack slot on 64bit?? QQQ
a61af66fc99e Initial load
duke
parents:
diff changeset
223 __ stf(FloatRegisterImpl::D, F0, L1_scratch, -wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
224 __ sub(L1_scratch, 2*wordSize, L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
225 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
226 case T_OBJECT :
a61af66fc99e Initial load
duke
parents:
diff changeset
227 __ verify_oop(O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
228 __ st_ptr(O0, L1_scratch, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
229 __ sub(L1_scratch, wordSize, L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
230 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
231 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
233 __ retl(); // return from interpreter activation
a61af66fc99e Initial load
duke
parents:
diff changeset
234 __ delayed()->nop(); // schedule this better
a61af66fc99e Initial load
duke
parents:
diff changeset
235 NOT_PRODUCT(__ emit_long(0);) // marker for disassembly
a61af66fc99e Initial load
duke
parents:
diff changeset
236 return entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
238
a61af66fc99e Initial load
duke
parents:
diff changeset
239 address CppInterpreterGenerator::generate_stack_to_stack_converter(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // A result is in the java expression stack of the interpreted method that has just
a61af66fc99e Initial load
duke
parents:
diff changeset
241 // returned. Place this result on the java expression stack of the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
242 //
a61af66fc99e Initial load
duke
parents:
diff changeset
243 // The current interpreter activation in Lstate is for the method just returning its
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // result. So we know that the result of this method is on the top of the current
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // execution stack (which is pre-pushed) and will be return to the top of the caller
a61af66fc99e Initial load
duke
parents:
diff changeset
246 // stack. The top of the callers stack is the bottom of the locals of the current
a61af66fc99e Initial load
duke
parents:
diff changeset
247 // activation.
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // Because of the way activation are managed by the frame manager the value of esp is
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // below both the stack top of the current activation and naturally the stack top
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // of the calling activation. This enable this routine to leave the return address
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // to the frame manager on the stack and do a vanilla return.
a61af66fc99e Initial load
duke
parents:
diff changeset
252 //
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // On entry: O0 - points to source (callee stack top)
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // O1 - points to destination (caller stack top [i.e. free location])
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // destroys O2, O3
a61af66fc99e Initial load
duke
parents:
diff changeset
256 //
a61af66fc99e Initial load
duke
parents:
diff changeset
257
a61af66fc99e Initial load
duke
parents:
diff changeset
258 address entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
259 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
260 case T_VOID: break;
a61af66fc99e Initial load
duke
parents:
diff changeset
261 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
262 case T_FLOAT :
a61af66fc99e Initial load
duke
parents:
diff changeset
263 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
264 case T_CHAR :
a61af66fc99e Initial load
duke
parents:
diff changeset
265 case T_BYTE :
a61af66fc99e Initial load
duke
parents:
diff changeset
266 case T_SHORT :
a61af66fc99e Initial load
duke
parents:
diff changeset
267 case T_INT :
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // 1 word result
a61af66fc99e Initial load
duke
parents:
diff changeset
269 __ ld(O0, 0, O2);
a61af66fc99e Initial load
duke
parents:
diff changeset
270 __ st(O2, O1, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
271 __ sub(O1, wordSize, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
272 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
273 case T_DOUBLE :
a61af66fc99e Initial load
duke
parents:
diff changeset
274 case T_LONG :
a61af66fc99e Initial load
duke
parents:
diff changeset
275 // return top two words on current expression stack to caller's expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
276 // The caller's expression stack is adjacent to the current frame manager's intepretState
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // except we allocated one extra word for this intepretState so we won't overwrite it
a61af66fc99e Initial load
duke
parents:
diff changeset
278 // when we return a two word result.
a61af66fc99e Initial load
duke
parents:
diff changeset
279 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
280 __ ld_ptr(O0, 0, O2);
a61af66fc99e Initial load
duke
parents:
diff changeset
281 __ st_ptr(O2, O1, -wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
282 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
283 __ ld(O0, 0, O2);
a61af66fc99e Initial load
duke
parents:
diff changeset
284 __ ld(O0, wordSize, O3);
a61af66fc99e Initial load
duke
parents:
diff changeset
285 __ st(O3, O1, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
286 __ st(O2, O1, -wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
287 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
288 __ sub(O1, 2*wordSize, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
289 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
290 case T_OBJECT :
a61af66fc99e Initial load
duke
parents:
diff changeset
291 __ ld_ptr(O0, 0, O2);
a61af66fc99e Initial load
duke
parents:
diff changeset
292 __ verify_oop(O2); // verify it
a61af66fc99e Initial load
duke
parents:
diff changeset
293 __ st_ptr(O2, O1, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
294 __ sub(O1, wordSize, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
295 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
296 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
298 __ retl();
a61af66fc99e Initial load
duke
parents:
diff changeset
299 __ delayed()->nop(); // QQ schedule this better
a61af66fc99e Initial load
duke
parents:
diff changeset
300 return entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303 address CppInterpreterGenerator::generate_stack_to_native_abi_converter(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
304 // A result is in the java expression stack of the interpreted method that has just
a61af66fc99e Initial load
duke
parents:
diff changeset
305 // returned. Place this result in the native abi that the caller expects.
a61af66fc99e Initial load
duke
parents:
diff changeset
306 // We are in a new frame registers we set must be in caller (i.e. callstub) frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
307 //
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // Similar to generate_stack_to_stack_converter above. Called at a similar time from the
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // frame manager execept in this situation the caller is native code (c1/c2/call_stub)
a61af66fc99e Initial load
duke
parents:
diff changeset
310 // and so rather than return result onto caller's java expression stack we return the
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // result in the expected location based on the native abi.
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // On entry: O0 - source (stack top)
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // On exit result in expected output register
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // QQQ schedule this better
a61af66fc99e Initial load
duke
parents:
diff changeset
315
a61af66fc99e Initial load
duke
parents:
diff changeset
316 address entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
317 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
318 case T_VOID: break;
a61af66fc99e Initial load
duke
parents:
diff changeset
319 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
320 case T_FLOAT :
a61af66fc99e Initial load
duke
parents:
diff changeset
321 __ ldf(FloatRegisterImpl::S, O0, 0, F0);
a61af66fc99e Initial load
duke
parents:
diff changeset
322 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
323 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
324 case T_CHAR :
a61af66fc99e Initial load
duke
parents:
diff changeset
325 case T_BYTE :
a61af66fc99e Initial load
duke
parents:
diff changeset
326 case T_SHORT :
a61af66fc99e Initial load
duke
parents:
diff changeset
327 case T_INT :
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // 1 word result
a61af66fc99e Initial load
duke
parents:
diff changeset
329 __ ld(O0, 0, O0->after_save());
a61af66fc99e Initial load
duke
parents:
diff changeset
330 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
331 case T_DOUBLE :
a61af66fc99e Initial load
duke
parents:
diff changeset
332 __ ldf(FloatRegisterImpl::D, O0, 0, F0);
a61af66fc99e Initial load
duke
parents:
diff changeset
333 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
334 case T_LONG :
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // return top two words on current expression stack to caller's expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // The caller's expression stack is adjacent to the current frame manager's interpretState
a61af66fc99e Initial load
duke
parents:
diff changeset
337 // except we allocated one extra word for this intepretState so we won't overwrite it
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // when we return a two word result.
a61af66fc99e Initial load
duke
parents:
diff changeset
339 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
340 __ ld_ptr(O0, 0, O0->after_save());
a61af66fc99e Initial load
duke
parents:
diff changeset
341 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
342 __ ld(O0, wordSize, O1->after_save());
a61af66fc99e Initial load
duke
parents:
diff changeset
343 __ ld(O0, 0, O0->after_save());
a61af66fc99e Initial load
duke
parents:
diff changeset
344 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
345 #if defined(COMPILER2) && !defined(_LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
346 // C2 expects long results in G1 we can't tell if we're returning to interpreted
a61af66fc99e Initial load
duke
parents:
diff changeset
347 // or compiled so just be safe use G1 and O0/O1
a61af66fc99e Initial load
duke
parents:
diff changeset
348
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // Shift bits into high (msb) of G1
a61af66fc99e Initial load
duke
parents:
diff changeset
350 __ sllx(Otos_l1->after_save(), 32, G1);
a61af66fc99e Initial load
duke
parents:
diff changeset
351 // Zero extend low bits
a61af66fc99e Initial load
duke
parents:
diff changeset
352 __ srl (Otos_l2->after_save(), 0, Otos_l2->after_save());
a61af66fc99e Initial load
duke
parents:
diff changeset
353 __ or3 (Otos_l2->after_save(), G1, G1);
a61af66fc99e Initial load
duke
parents:
diff changeset
354 #endif /* COMPILER2 */
a61af66fc99e Initial load
duke
parents:
diff changeset
355 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
356 case T_OBJECT :
a61af66fc99e Initial load
duke
parents:
diff changeset
357 __ ld_ptr(O0, 0, O0->after_save());
a61af66fc99e Initial load
duke
parents:
diff changeset
358 __ verify_oop(O0->after_save()); // verify it
a61af66fc99e Initial load
duke
parents:
diff changeset
359 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
360 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
362 __ retl();
a61af66fc99e Initial load
duke
parents:
diff changeset
363 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
364 return entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
366
a61af66fc99e Initial load
duke
parents:
diff changeset
367 address CppInterpreter::return_entry(TosState state, int length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
368 // make it look good in the debugger
a61af66fc99e Initial load
duke
parents:
diff changeset
369 return CAST_FROM_FN_PTR(address, RecursiveInterpreterActivation) + frame::pc_return_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
371
a61af66fc99e Initial load
duke
parents:
diff changeset
372 address CppInterpreter::deopt_entry(TosState state, int length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
373 address ret = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
374 if (length != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
375 switch (state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
376 case atos: ret = deopt_frame_manager_return_atos; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
377 case btos: ret = deopt_frame_manager_return_btos; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
378 case ctos:
a61af66fc99e Initial load
duke
parents:
diff changeset
379 case stos:
a61af66fc99e Initial load
duke
parents:
diff changeset
380 case itos: ret = deopt_frame_manager_return_itos; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
381 case ltos: ret = deopt_frame_manager_return_ltos; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
382 case ftos: ret = deopt_frame_manager_return_ftos; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
383 case dtos: ret = deopt_frame_manager_return_dtos; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
384 case vtos: ret = deopt_frame_manager_return_vtos; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
386 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
387 ret = unctrap_frame_manager_entry; // re-execute the bytecode ( e.g. uncommon trap)
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389 assert(ret != NULL, "Not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
390 return ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
392
a61af66fc99e Initial load
duke
parents:
diff changeset
393 //
a61af66fc99e Initial load
duke
parents:
diff changeset
394 // Helpers for commoning out cases in the various type of method entries.
a61af66fc99e Initial load
duke
parents:
diff changeset
395 //
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // increment invocation count & check for overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
398 //
a61af66fc99e Initial load
duke
parents:
diff changeset
399 // Note: checking for negative value instead of overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
400 // so we have a 'sticky' overflow test
a61af66fc99e Initial load
duke
parents:
diff changeset
401 //
a61af66fc99e Initial load
duke
parents:
diff changeset
402 // Lmethod: method
a61af66fc99e Initial load
duke
parents:
diff changeset
403 // ??: invocation counter
a61af66fc99e Initial load
duke
parents:
diff changeset
404 //
a61af66fc99e Initial load
duke
parents:
diff changeset
405 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) {
a61af66fc99e Initial load
duke
parents:
diff changeset
406 // Update standard invocation counters
a61af66fc99e Initial load
duke
parents:
diff changeset
407 __ increment_invocation_counter(O0, G3_scratch);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
408 if (ProfileInterpreter) { // %%% Merge this into MethodData*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
409 __ ld_ptr(STATE(_method), G3_scratch);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
410 Address interpreter_invocation_counter(G3_scratch, 0, in_bytes(Method::interpreter_invocation_counter_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
411 __ ld(interpreter_invocation_counter, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
412 __ inc(G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
413 __ st(G3_scratch, interpreter_invocation_counter);
a61af66fc99e Initial load
duke
parents:
diff changeset
414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
415
a61af66fc99e Initial load
duke
parents:
diff changeset
416 Address invocation_limit(G3_scratch, (address)&InvocationCounter::InterpreterInvocationLimit);
a61af66fc99e Initial load
duke
parents:
diff changeset
417 __ sethi(invocation_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
418 __ ld(invocation_limit, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
419 __ cmp(O0, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
420 __ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow);
a61af66fc99e Initial load
duke
parents:
diff changeset
421 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
422
a61af66fc99e Initial load
duke
parents:
diff changeset
423 }
a61af66fc99e Initial load
duke
parents:
diff changeset
424
a61af66fc99e Initial load
duke
parents:
diff changeset
425 address InterpreterGenerator::generate_empty_entry(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
426
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // A method that does nothing but return...
a61af66fc99e Initial load
duke
parents:
diff changeset
428
a61af66fc99e Initial load
duke
parents:
diff changeset
429 address entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
430 Label slow_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
431
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // do nothing for empty methods (do not even increment invocation counter)
a61af66fc99e Initial load
duke
parents:
diff changeset
433 if ( UseFastEmptyMethods) {
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // If we need a safepoint check, generate full interpreter entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
435 Address sync_state(G3_scratch, SafepointSynchronize::address_of_state());
a61af66fc99e Initial load
duke
parents:
diff changeset
436 __ load_contents(sync_state, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
437 __ cmp(G3_scratch, SafepointSynchronize::_not_synchronized);
a61af66fc99e Initial load
duke
parents:
diff changeset
438 __ br(Assembler::notEqual, false, Assembler::pn, frame_manager_entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
439 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
440
a61af66fc99e Initial load
duke
parents:
diff changeset
441 // Code: _return
a61af66fc99e Initial load
duke
parents:
diff changeset
442 __ retl();
a61af66fc99e Initial load
duke
parents:
diff changeset
443 __ delayed()->mov(O5_savedSP, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
444 return entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
446 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
447 }
a61af66fc99e Initial load
duke
parents:
diff changeset
448
a61af66fc99e Initial load
duke
parents:
diff changeset
449 // Call an accessor method (assuming it is resolved, otherwise drop into
a61af66fc99e Initial load
duke
parents:
diff changeset
450 // vanilla (slow path) entry
a61af66fc99e Initial load
duke
parents:
diff changeset
451
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // Generates code to elide accessor methods
a61af66fc99e Initial load
duke
parents:
diff changeset
453 // Uses G3_scratch and G1_scratch as scratch
a61af66fc99e Initial load
duke
parents:
diff changeset
454 address InterpreterGenerator::generate_accessor_entry(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
455
a61af66fc99e Initial load
duke
parents:
diff changeset
456 // Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites thereof;
a61af66fc99e Initial load
duke
parents:
diff changeset
457 // parameter size = 1
a61af66fc99e Initial load
duke
parents:
diff changeset
458 // Note: We can only use this code if the getfield has been resolved
a61af66fc99e Initial load
duke
parents:
diff changeset
459 // and if we don't have a null-pointer exception => check for
a61af66fc99e Initial load
duke
parents:
diff changeset
460 // these conditions first and use slow path if necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
461 address entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
462 Label slow_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
463
a61af66fc99e Initial load
duke
parents:
diff changeset
464 if ( UseFastAccessorMethods) {
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // Check if we need to reach a safepoint and generate full interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
466 // frame if so.
a61af66fc99e Initial load
duke
parents:
diff changeset
467 Address sync_state(G3_scratch, SafepointSynchronize::address_of_state());
a61af66fc99e Initial load
duke
parents:
diff changeset
468 __ load_contents(sync_state, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
469 __ cmp(G3_scratch, SafepointSynchronize::_not_synchronized);
a61af66fc99e Initial load
duke
parents:
diff changeset
470 __ br(Assembler::notEqual, false, Assembler::pn, slow_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
471 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
472
a61af66fc99e Initial load
duke
parents:
diff changeset
473 // Check if local 0 != NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
474 __ ld_ptr(Gargs, G0, Otos_i ); // get local 0
a61af66fc99e Initial load
duke
parents:
diff changeset
475 __ tst(Otos_i); // check if local 0 == NULL and go the slow path
a61af66fc99e Initial load
duke
parents:
diff changeset
476 __ brx(Assembler::zero, false, Assembler::pn, slow_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
477 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
478
a61af66fc99e Initial load
duke
parents:
diff changeset
479
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // read first instruction word and extract bytecode @ 1 and index @ 2
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // 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
482 __ ld_ptr(Address(G5_method, 0, in_bytes(Method::const_offset())), G1_scratch);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
483 __ ld(Address(G1_scratch, 0, in_bytes(ConstMethod::codes_offset())), G1_scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
484
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // move index @ 2 far left then to the right most two bytes.
a61af66fc99e Initial load
duke
parents:
diff changeset
486 __ sll(G1_scratch, 2*BitsPerByte, G1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
487 __ srl(G1_scratch, 2*BitsPerByte - exact_log2(in_words(
a61af66fc99e Initial load
duke
parents:
diff changeset
488 ConstantPoolCacheEntry::size()) * BytesPerWord), G1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
489
a61af66fc99e Initial load
duke
parents:
diff changeset
490 // get constant pool cache
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
491 __ ld_ptr(G5_method, in_bytes(Method::const_offset()), G3_scratch);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
492 __ ld_ptr(G3_scratch, in_bytes(ConstMethod::constants_offset()), G3_scratch);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
493 __ ld_ptr(G3_scratch, ConstantPool::cache_offset_in_bytes(), G3_scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
494
a61af66fc99e Initial load
duke
parents:
diff changeset
495 // get specific constant pool cache entry
a61af66fc99e Initial load
duke
parents:
diff changeset
496 __ add(G3_scratch, G1_scratch, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498 // Check the constant Pool cache entry to see if it has been resolved.
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // If not, need the slow path.
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
500 ByteSize cp_base_offset = ConstantPoolCache::base_offset();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
501 __ ld_ptr(G3_scratch, in_bytes(cp_base_offset + ConstantPoolCacheEntry::indices_offset()), G1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
502 __ srl(G1_scratch, 2*BitsPerByte, G1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
503 __ and3(G1_scratch, 0xFF, G1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
504 __ cmp(G1_scratch, Bytecodes::_getfield);
a61af66fc99e Initial load
duke
parents:
diff changeset
505 __ br(Assembler::notEqual, false, Assembler::pn, slow_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
506 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
507
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // Get the type and return field offset from the constant pool cache
a61af66fc99e Initial load
duke
parents:
diff changeset
509 __ ld_ptr(G3_scratch, in_bytes(cp_base_offset + ConstantPoolCacheEntry::flags_offset()), G1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
510 __ ld_ptr(G3_scratch, in_bytes(cp_base_offset + ConstantPoolCacheEntry::f2_offset()), G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
511
a61af66fc99e Initial load
duke
parents:
diff changeset
512 Label xreturn_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // Need to differentiate between igetfield, agetfield, bgetfield etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // because they are different sizes.
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // 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
516 __ 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
517 // 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
518 ConstantPoolCacheEntry::verify_tos_state_shift();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
519 __ cmp(G1_scratch, atos );
a61af66fc99e Initial load
duke
parents:
diff changeset
520 __ br(Assembler::equal, true, Assembler::pt, xreturn_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
521 __ delayed()->ld_ptr(Otos_i, G3_scratch, Otos_i);
a61af66fc99e Initial load
duke
parents:
diff changeset
522 __ cmp(G1_scratch, itos);
a61af66fc99e Initial load
duke
parents:
diff changeset
523 __ br(Assembler::equal, true, Assembler::pt, xreturn_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
524 __ delayed()->ld(Otos_i, G3_scratch, Otos_i);
a61af66fc99e Initial load
duke
parents:
diff changeset
525 __ cmp(G1_scratch, stos);
a61af66fc99e Initial load
duke
parents:
diff changeset
526 __ br(Assembler::equal, true, Assembler::pt, xreturn_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
527 __ delayed()->ldsh(Otos_i, G3_scratch, Otos_i);
a61af66fc99e Initial load
duke
parents:
diff changeset
528 __ cmp(G1_scratch, ctos);
a61af66fc99e Initial load
duke
parents:
diff changeset
529 __ br(Assembler::equal, true, Assembler::pt, xreturn_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
530 __ delayed()->lduh(Otos_i, G3_scratch, Otos_i);
a61af66fc99e Initial load
duke
parents:
diff changeset
531 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
532 __ cmp(G1_scratch, btos);
a61af66fc99e Initial load
duke
parents:
diff changeset
533 __ br(Assembler::equal, true, Assembler::pt, xreturn_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
534 __ delayed()->ldsb(Otos_i, G3_scratch, Otos_i);
a61af66fc99e Initial load
duke
parents:
diff changeset
535 __ should_not_reach_here();
a61af66fc99e Initial load
duke
parents:
diff changeset
536 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
537 __ ldsb(Otos_i, G3_scratch, Otos_i);
a61af66fc99e Initial load
duke
parents:
diff changeset
538 __ bind(xreturn_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
539
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // _ireturn/_areturn
a61af66fc99e Initial load
duke
parents:
diff changeset
541 __ retl(); // return from leaf routine
a61af66fc99e Initial load
duke
parents:
diff changeset
542 __ delayed()->mov(O5_savedSP, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
543
a61af66fc99e Initial load
duke
parents:
diff changeset
544 // Generate regular method entry
a61af66fc99e Initial load
duke
parents:
diff changeset
545 __ bind(slow_path);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
546 __ ba(fast_accessor_slow_entry_path);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
547 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
548 return entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
550 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
552
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
553 address InterpreterGenerator::generate_Reference_get_entry(void) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
554 #ifndef SERIALGC
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
555 if (UseG1GC) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
556 // We need to generate have a routine that generates code to:
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
557 // * load the value in the referent field
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
558 // * passes that value to the pre-barrier.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
559 //
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
560 // In the case of G1 this will record the value of the
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
561 // referent in an SATB buffer if marking is active.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
562 // This will cause concurrent marking to mark the referent
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
563 // field as live.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
564 Unimplemented();
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
565 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
566 #endif // SERIALGC
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
567
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
568 // 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: 2357
diff changeset
569 // Reference.get is an accessor
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
570 return generate_accessor_entry();
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
571 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
572
0
a61af66fc99e Initial load
duke
parents:
diff changeset
573 //
a61af66fc99e Initial load
duke
parents:
diff changeset
574 // Interpreter stub for calling a native method. (C++ interpreter)
a61af66fc99e Initial load
duke
parents:
diff changeset
575 // This sets up a somewhat different looking stack for calling the native method
a61af66fc99e Initial load
duke
parents:
diff changeset
576 // than the typical interpreter frame setup.
a61af66fc99e Initial load
duke
parents:
diff changeset
577 //
a61af66fc99e Initial load
duke
parents:
diff changeset
578
a61af66fc99e Initial load
duke
parents:
diff changeset
579 address InterpreterGenerator::generate_native_entry(bool synchronized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
580 address entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
581
a61af66fc99e Initial load
duke
parents:
diff changeset
582 // the following temporary registers are used during frame creation
a61af66fc99e Initial load
duke
parents:
diff changeset
583 const Register Gtmp1 = G3_scratch ;
a61af66fc99e Initial load
duke
parents:
diff changeset
584 const Register Gtmp2 = G1_scratch;
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
585 const Address size_of_parameters(G5_method, 0, in_bytes(Method::size_of_parameters_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
586
a61af66fc99e Initial load
duke
parents:
diff changeset
587 bool inc_counter = UseCompiler || CountCompiledCalls;
a61af66fc99e Initial load
duke
parents:
diff changeset
588
a61af66fc99e Initial load
duke
parents:
diff changeset
589 // make sure registers are different!
a61af66fc99e Initial load
duke
parents:
diff changeset
590 assert_different_registers(G2_thread, G5_method, Gargs, Gtmp1, Gtmp2);
a61af66fc99e Initial load
duke
parents:
diff changeset
591
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
592 const Address access_flags (G5_method, 0, in_bytes(Method::access_flags_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
593
a61af66fc99e Initial load
duke
parents:
diff changeset
594 Label Lentry;
a61af66fc99e Initial load
duke
parents:
diff changeset
595 __ bind(Lentry);
a61af66fc99e Initial load
duke
parents:
diff changeset
596
a61af66fc99e Initial load
duke
parents:
diff changeset
597 const Register Glocals_size = G3;
a61af66fc99e Initial load
duke
parents:
diff changeset
598 assert_different_registers(Glocals_size, G4_scratch, Gframe_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
599
a61af66fc99e Initial load
duke
parents:
diff changeset
600 // make sure method is native & not abstract
a61af66fc99e Initial load
duke
parents:
diff changeset
601 // rethink these assertions - they can be simplified and shared (gri 2/25/2000)
a61af66fc99e Initial load
duke
parents:
diff changeset
602 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
603 __ ld(access_flags, Gtmp1);
a61af66fc99e Initial load
duke
parents:
diff changeset
604 {
a61af66fc99e Initial load
duke
parents:
diff changeset
605 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
606 __ btst(JVM_ACC_NATIVE, Gtmp1);
a61af66fc99e Initial load
duke
parents:
diff changeset
607 __ br(Assembler::notZero, false, Assembler::pt, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
608 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
609 __ stop("tried to execute non-native method as native");
a61af66fc99e Initial load
duke
parents:
diff changeset
610 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
612 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
613 __ btst(JVM_ACC_ABSTRACT, Gtmp1);
a61af66fc99e Initial load
duke
parents:
diff changeset
614 __ br(Assembler::zero, false, Assembler::pt, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
615 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
616 __ stop("tried to execute abstract method as non-abstract");
a61af66fc99e Initial load
duke
parents:
diff changeset
617 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
619 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
620
a61af66fc99e Initial load
duke
parents:
diff changeset
621 __ lduh(size_of_parameters, Gtmp1);
a61af66fc99e Initial load
duke
parents:
diff changeset
622 __ sll(Gtmp1, LogBytesPerWord, Gtmp2); // parameter size in bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
623 __ add(Gargs, Gtmp2, Gargs); // points to first local + BytesPerWord
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // NEW
a61af66fc99e Initial load
duke
parents:
diff changeset
625 __ add(Gargs, -wordSize, Gargs); // points to first local[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
626 // generate the code to allocate the interpreter stack frame
a61af66fc99e Initial load
duke
parents:
diff changeset
627 // NEW FRAME ALLOCATED HERE
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // save callers original sp
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // __ mov(SP, I5_savedSP->after_restore());
a61af66fc99e Initial load
duke
parents:
diff changeset
630
a61af66fc99e Initial load
duke
parents:
diff changeset
631 generate_compute_interpreter_state(Lstate, G0, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
632
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // At this point Lstate points to new interpreter state
a61af66fc99e Initial load
duke
parents:
diff changeset
634 //
a61af66fc99e Initial load
duke
parents:
diff changeset
635
a61af66fc99e Initial load
duke
parents:
diff changeset
636 const Address do_not_unlock_if_synchronized(G2_thread, 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
637 in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
638 // Since at this point in the method invocation the exception handler
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // would try to exit the monitor of synchronized methods which hasn't
a61af66fc99e Initial load
duke
parents:
diff changeset
640 // been entered yet, we set the thread local variable
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // _do_not_unlock_if_synchronized to true. If any exception was thrown by
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // runtime, exception handling i.e. unlock_if_synchronized_method will
a61af66fc99e Initial load
duke
parents:
diff changeset
643 // check this thread local flag.
a61af66fc99e Initial load
duke
parents:
diff changeset
644 // This flag has two effects, one is to force an unwind in the topmost
a61af66fc99e Initial load
duke
parents:
diff changeset
645 // interpreter frame and not perform an unlock while doing so.
a61af66fc99e Initial load
duke
parents:
diff changeset
646
a61af66fc99e Initial load
duke
parents:
diff changeset
647 __ movbool(true, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
648 __ stbool(G3_scratch, do_not_unlock_if_synchronized);
a61af66fc99e Initial load
duke
parents:
diff changeset
649
a61af66fc99e Initial load
duke
parents:
diff changeset
650
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // increment invocation counter and check for overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
652 //
a61af66fc99e Initial load
duke
parents:
diff changeset
653 // Note: checking for negative value instead of overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
654 // so we have a 'sticky' overflow test (may be of
a61af66fc99e Initial load
duke
parents:
diff changeset
655 // importance as soon as we have true MT/MP)
a61af66fc99e Initial load
duke
parents:
diff changeset
656 Label invocation_counter_overflow;
a61af66fc99e Initial load
duke
parents:
diff changeset
657 if (inc_counter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
658 generate_counter_incr(&invocation_counter_overflow, NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
659 }
a61af66fc99e Initial load
duke
parents:
diff changeset
660 Label Lcontinue;
a61af66fc99e Initial load
duke
parents:
diff changeset
661 __ bind(Lcontinue);
a61af66fc99e Initial load
duke
parents:
diff changeset
662
a61af66fc99e Initial load
duke
parents:
diff changeset
663 bang_stack_shadow_pages(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // reset the _do_not_unlock_if_synchronized flag
a61af66fc99e Initial load
duke
parents:
diff changeset
665 __ stbool(G0, do_not_unlock_if_synchronized);
a61af66fc99e Initial load
duke
parents:
diff changeset
666
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // check for synchronized methods
a61af66fc99e Initial load
duke
parents:
diff changeset
668 // Must happen AFTER invocation_counter check, so method is not locked
a61af66fc99e Initial load
duke
parents:
diff changeset
669 // if counter overflows.
a61af66fc99e Initial load
duke
parents:
diff changeset
670
a61af66fc99e Initial load
duke
parents:
diff changeset
671 if (synchronized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
672 lock_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
673 // Don't see how G2_thread is preserved here...
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // __ verify_thread(); QQQ destroys L0,L1 can't use
a61af66fc99e Initial load
duke
parents:
diff changeset
675 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
676 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
677 { Label ok;
a61af66fc99e Initial load
duke
parents:
diff changeset
678 __ ld_ptr(STATE(_method), G5_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
679 __ ld(access_flags, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
680 __ btst(JVM_ACC_SYNCHRONIZED, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
681 __ br( Assembler::zero, false, Assembler::pt, ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
682 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
683 __ stop("method needs synchronization");
a61af66fc99e Initial load
duke
parents:
diff changeset
684 __ bind(ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
686 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
687 }
a61af66fc99e Initial load
duke
parents:
diff changeset
688
a61af66fc99e Initial load
duke
parents:
diff changeset
689 // start execution
a61af66fc99e Initial load
duke
parents:
diff changeset
690
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // __ verify_thread(); kills L1,L2 can't use at the moment
a61af66fc99e Initial load
duke
parents:
diff changeset
692
a61af66fc99e Initial load
duke
parents:
diff changeset
693 // jvmti/jvmpi support
a61af66fc99e Initial load
duke
parents:
diff changeset
694 __ notify_method_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
695
a61af66fc99e Initial load
duke
parents:
diff changeset
696 // native call
a61af66fc99e Initial load
duke
parents:
diff changeset
697
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // (note that O0 is never an oop--at most it is a handle)
a61af66fc99e Initial load
duke
parents:
diff changeset
699 // It is important not to smash any handles created by this call,
a61af66fc99e Initial load
duke
parents:
diff changeset
700 // until any oop handle in O0 is dereferenced.
a61af66fc99e Initial load
duke
parents:
diff changeset
701
a61af66fc99e Initial load
duke
parents:
diff changeset
702 // (note that the space for outgoing params is preallocated)
a61af66fc99e Initial load
duke
parents:
diff changeset
703
a61af66fc99e Initial load
duke
parents:
diff changeset
704 // get signature handler
a61af66fc99e Initial load
duke
parents:
diff changeset
705
a61af66fc99e Initial load
duke
parents:
diff changeset
706 Label pending_exception_present;
a61af66fc99e Initial load
duke
parents:
diff changeset
707
a61af66fc99e Initial load
duke
parents:
diff changeset
708 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
709 __ ld_ptr(STATE(_method), G5_method);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
710 __ ld_ptr(Address(G5_method, 0, in_bytes(Method::signature_handler_offset())), G3_scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
711 __ tst(G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
712 __ brx(Assembler::notZero, false, Assembler::pt, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
713 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
714 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), G5_method, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
715 __ ld_ptr(STATE(_method), G5_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
716
a61af66fc99e Initial load
duke
parents:
diff changeset
717 Address exception_addr(G2_thread, 0, in_bytes(Thread::pending_exception_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
718 __ ld_ptr(exception_addr, G3_scratch);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
719 __ br_notnull_short(G3_scratch, Assembler::pn, pending_exception_present);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
720 __ ld_ptr(Address(G5_method, 0, in_bytes(Method::signature_handler_offset())), G3_scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
721 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
722 }
a61af66fc99e Initial load
duke
parents:
diff changeset
723
a61af66fc99e Initial load
duke
parents:
diff changeset
724 // Push a new frame so that the args will really be stored in
a61af66fc99e Initial load
duke
parents:
diff changeset
725 // Copy a few locals across so the new frame has the variables
a61af66fc99e Initial load
duke
parents:
diff changeset
726 // we need but these values will be dead at the jni call and
a61af66fc99e Initial load
duke
parents:
diff changeset
727 // therefore not gc volatile like the values in the current
a61af66fc99e Initial load
duke
parents:
diff changeset
728 // frame (Lstate in particular)
a61af66fc99e Initial load
duke
parents:
diff changeset
729
a61af66fc99e Initial load
duke
parents:
diff changeset
730 // Flush the state pointer to the register save area
a61af66fc99e Initial load
duke
parents:
diff changeset
731 // Which is the only register we need for a stack walk.
a61af66fc99e Initial load
duke
parents:
diff changeset
732 __ st_ptr(Lstate, SP, (Lstate->sp_offset_in_saved_window() * wordSize) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
733
a61af66fc99e Initial load
duke
parents:
diff changeset
734 __ mov(Lstate, O1); // Need to pass the state pointer across the frame
a61af66fc99e Initial load
duke
parents:
diff changeset
735
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // Calculate current frame size
a61af66fc99e Initial load
duke
parents:
diff changeset
737 __ sub(SP, FP, O3); // Calculate negative of current frame size
a61af66fc99e Initial load
duke
parents:
diff changeset
738 __ save(SP, O3, SP); // Allocate an identical sized frame
a61af66fc99e Initial load
duke
parents:
diff changeset
739
a61af66fc99e Initial load
duke
parents:
diff changeset
740 __ mov(I1, Lstate); // In the "natural" register.
a61af66fc99e Initial load
duke
parents:
diff changeset
741
a61af66fc99e Initial load
duke
parents:
diff changeset
742 // Note I7 has leftover trash. Slow signature handler will fill it in
a61af66fc99e Initial load
duke
parents:
diff changeset
743 // should we get there. Normal jni call will set reasonable last_Java_pc
a61af66fc99e Initial load
duke
parents:
diff changeset
744 // below (and fix I7 so the stack trace doesn't have a meaningless frame
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // in it).
a61af66fc99e Initial load
duke
parents:
diff changeset
746
a61af66fc99e Initial load
duke
parents:
diff changeset
747
a61af66fc99e Initial load
duke
parents:
diff changeset
748 // call signature handler
a61af66fc99e Initial load
duke
parents:
diff changeset
749 __ ld_ptr(STATE(_method), Lmethod);
a61af66fc99e Initial load
duke
parents:
diff changeset
750 __ ld_ptr(STATE(_locals), Llocals);
a61af66fc99e Initial load
duke
parents:
diff changeset
751
a61af66fc99e Initial load
duke
parents:
diff changeset
752 __ callr(G3_scratch, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
753 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
754 __ ld_ptr(STATE(_thread), G2_thread); // restore thread (shouldn't be needed)
a61af66fc99e Initial load
duke
parents:
diff changeset
755
a61af66fc99e Initial load
duke
parents:
diff changeset
756 { Label not_static;
a61af66fc99e Initial load
duke
parents:
diff changeset
757
a61af66fc99e Initial load
duke
parents:
diff changeset
758 __ ld_ptr(STATE(_method), G5_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
759 __ ld(access_flags, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
760 __ btst(JVM_ACC_STATIC, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
761 __ br( Assembler::zero, false, Assembler::pt, not_static);
a61af66fc99e Initial load
duke
parents:
diff changeset
762 __ delayed()->
a61af66fc99e Initial load
duke
parents:
diff changeset
763 // 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
764 ld_ptr(Address(G5_method, 0, in_bytes(Method::native_function_offset())), O0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
765 // 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
766 const int mirror_offset = in_bytes(Klass::java_mirror_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
767
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
768 __ ld_ptr(Address(G5_method, 0, in_bytes(Method:: const_offset())), O1);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
769 __ ld_ptr(Address(O1, 0, in_bytes(ConstMethod::constants_offset())), O1);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
770 __ ld_ptr(Address(O1, 0, ConstantPool::pool_holder_offset_in_bytes()), O1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
771 __ ld_ptr(O1, mirror_offset, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
772 // where the mirror handle body is allocated:
a61af66fc99e Initial load
duke
parents:
diff changeset
773 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
774 if (!PrintSignatureHandlers) // do not dirty the output with this
a61af66fc99e Initial load
duke
parents:
diff changeset
775 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
776 __ tst(O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
777 __ brx(Assembler::notZero, false, Assembler::pt, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
778 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
779 __ stop("mirror is missing");
a61af66fc99e Initial load
duke
parents:
diff changeset
780 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
781 }
a61af66fc99e Initial load
duke
parents:
diff changeset
782 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
783 __ st_ptr(O1, STATE(_oop_temp));
a61af66fc99e Initial load
duke
parents:
diff changeset
784 __ add(STATE(_oop_temp), O1); // this is really an LEA not an add
a61af66fc99e Initial load
duke
parents:
diff changeset
785 __ bind(not_static);
a61af66fc99e Initial load
duke
parents:
diff changeset
786 }
a61af66fc99e Initial load
duke
parents:
diff changeset
787
a61af66fc99e Initial load
duke
parents:
diff changeset
788 // At this point, arguments have been copied off of stack into
a61af66fc99e Initial load
duke
parents:
diff changeset
789 // their JNI positions, which are O1..O5 and SP[68..].
a61af66fc99e Initial load
duke
parents:
diff changeset
790 // Oops are boxed in-place on the stack, with handles copied to arguments.
a61af66fc99e Initial load
duke
parents:
diff changeset
791 // The result handler is in Lscratch. O0 will shortly hold the JNIEnv*.
a61af66fc99e Initial load
duke
parents:
diff changeset
792
a61af66fc99e Initial load
duke
parents:
diff changeset
793 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
794 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
795 __ tst(O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
796 __ brx(Assembler::notZero, false, Assembler::pt, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
797 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
798 __ stop("native entry point is missing");
a61af66fc99e Initial load
duke
parents:
diff changeset
799 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
800 }
a61af66fc99e Initial load
duke
parents:
diff changeset
801 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
802
a61af66fc99e Initial load
duke
parents:
diff changeset
803 //
a61af66fc99e Initial load
duke
parents:
diff changeset
804 // setup the java frame anchor
a61af66fc99e Initial load
duke
parents:
diff changeset
805 //
a61af66fc99e Initial load
duke
parents:
diff changeset
806 // The scavenge function only needs to know that the PC of this frame is
a61af66fc99e Initial load
duke
parents:
diff changeset
807 // in the interpreter method entry code, it doesn't need to know the exact
a61af66fc99e Initial load
duke
parents:
diff changeset
808 // PC and hence we can use O7 which points to the return address from the
a61af66fc99e Initial load
duke
parents:
diff changeset
809 // previous call in the code stream (signature handler function)
a61af66fc99e Initial load
duke
parents:
diff changeset
810 //
a61af66fc99e Initial load
duke
parents:
diff changeset
811 // The other trick is we set last_Java_sp to FP instead of the usual SP because
a61af66fc99e Initial load
duke
parents:
diff changeset
812 // we have pushed the extra frame in order to protect the volatile register(s)
a61af66fc99e Initial load
duke
parents:
diff changeset
813 // in that frame when we return from the jni call
a61af66fc99e Initial load
duke
parents:
diff changeset
814 //
a61af66fc99e Initial load
duke
parents:
diff changeset
815
a61af66fc99e Initial load
duke
parents:
diff changeset
816
a61af66fc99e Initial load
duke
parents:
diff changeset
817 __ set_last_Java_frame(FP, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
818 __ mov(O7, I7); // make dummy interpreter frame look like one above,
a61af66fc99e Initial load
duke
parents:
diff changeset
819 // not meaningless information that'll confuse me.
a61af66fc99e Initial load
duke
parents:
diff changeset
820
a61af66fc99e Initial load
duke
parents:
diff changeset
821 // flush the windows now. We don't care about the current (protection) frame
a61af66fc99e Initial load
duke
parents:
diff changeset
822 // only the outer frames
a61af66fc99e Initial load
duke
parents:
diff changeset
823
a61af66fc99e Initial load
duke
parents:
diff changeset
824 __ flush_windows();
a61af66fc99e Initial load
duke
parents:
diff changeset
825
a61af66fc99e Initial load
duke
parents:
diff changeset
826 // mark windows as flushed
a61af66fc99e Initial load
duke
parents:
diff changeset
827 Address flags(G2_thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
828 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
829 in_bytes(JavaThread::frame_anchor_offset()) + in_bytes(JavaFrameAnchor::flags_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
830 __ set(JavaFrameAnchor::flushed, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
831 __ st(G3_scratch, flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
832
a61af66fc99e Initial load
duke
parents:
diff changeset
833 // Transition from _thread_in_Java to _thread_in_native. We are already safepoint ready.
a61af66fc99e Initial load
duke
parents:
diff changeset
834
a61af66fc99e Initial load
duke
parents:
diff changeset
835 Address thread_state(G2_thread, 0, in_bytes(JavaThread::thread_state_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
836 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
837 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
838 __ ld(thread_state, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
839 __ cmp(G3_scratch, _thread_in_Java);
a61af66fc99e Initial load
duke
parents:
diff changeset
840 __ br(Assembler::equal, false, Assembler::pt, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
841 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
842 __ stop("Wrong thread state in native stub");
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 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
846 __ set(_thread_in_native, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
847 __ st(G3_scratch, thread_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
848
a61af66fc99e Initial load
duke
parents:
diff changeset
849 // Call the jni method, using the delay slot to set the JNIEnv* argument.
a61af66fc99e Initial load
duke
parents:
diff changeset
850 __ callr(O0, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
851 __ delayed()->
a61af66fc99e Initial load
duke
parents:
diff changeset
852 add(G2_thread, in_bytes(JavaThread::jni_environment_offset()), O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
853 __ ld_ptr(STATE(_thread), G2_thread); // restore thread
a61af66fc99e Initial load
duke
parents:
diff changeset
854
a61af66fc99e Initial load
duke
parents:
diff changeset
855 // must we block?
a61af66fc99e Initial load
duke
parents:
diff changeset
856
a61af66fc99e Initial load
duke
parents:
diff changeset
857 // Block, if necessary, before resuming in _thread_in_Java state.
a61af66fc99e Initial load
duke
parents:
diff changeset
858 // In order for GC to work, don't clear the last_Java_sp until after blocking.
a61af66fc99e Initial load
duke
parents:
diff changeset
859 { Label no_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
860 Address sync_state(G3_scratch, SafepointSynchronize::address_of_state());
a61af66fc99e Initial load
duke
parents:
diff changeset
861
a61af66fc99e Initial load
duke
parents:
diff changeset
862 // Switch thread to "native transition" state before reading the synchronization state.
a61af66fc99e Initial load
duke
parents:
diff changeset
863 // This additional state is necessary because reading and testing the synchronization
a61af66fc99e Initial load
duke
parents:
diff changeset
864 // state is not atomic w.r.t. GC, as this scenario demonstrates:
a61af66fc99e Initial load
duke
parents:
diff changeset
865 // Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted.
a61af66fc99e Initial load
duke
parents:
diff changeset
866 // VM thread changes sync state to synchronizing and suspends threads for GC.
a61af66fc99e Initial load
duke
parents:
diff changeset
867 // Thread A is resumed to finish this native method, but doesn't block here since it
a61af66fc99e Initial load
duke
parents:
diff changeset
868 // didn't see any synchronization is progress, and escapes.
a61af66fc99e Initial load
duke
parents:
diff changeset
869 __ set(_thread_in_native_trans, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
870 __ st(G3_scratch, thread_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
871 if(os::is_MP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
872 // Write serialization page so VM thread can do a pseudo remote membar.
a61af66fc99e Initial load
duke
parents:
diff changeset
873 // We use the current thread pointer to calculate a thread specific
a61af66fc99e Initial load
duke
parents:
diff changeset
874 // offset to write to within the page. This minimizes bus traffic
a61af66fc99e Initial load
duke
parents:
diff changeset
875 // due to cache line collision.
a61af66fc99e Initial load
duke
parents:
diff changeset
876 __ serialize_memory(G2_thread, G1_scratch, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
877 }
a61af66fc99e Initial load
duke
parents:
diff changeset
878 __ load_contents(sync_state, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
879 __ cmp(G3_scratch, SafepointSynchronize::_not_synchronized);
a61af66fc99e Initial load
duke
parents:
diff changeset
880
a61af66fc99e Initial load
duke
parents:
diff changeset
881
a61af66fc99e Initial load
duke
parents:
diff changeset
882 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
883 Address suspend_state(G2_thread, 0, in_bytes(JavaThread::suspend_flags_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
884 __ br(Assembler::notEqual, false, Assembler::pn, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
885 __ delayed()->
a61af66fc99e Initial load
duke
parents:
diff changeset
886 ld(suspend_state, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
887 __ cmp(G3_scratch, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
888 __ br(Assembler::equal, false, Assembler::pt, no_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
889 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
890 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
891
a61af66fc99e Initial load
duke
parents:
diff changeset
892 // Block. Save any potential method result value before the operation and
a61af66fc99e Initial load
duke
parents:
diff changeset
893 // use a leaf call to leave the last_Java_frame setup undisturbed.
a61af66fc99e Initial load
duke
parents:
diff changeset
894 save_native_result();
a61af66fc99e Initial load
duke
parents:
diff changeset
895 __ call_VM_leaf(noreg,
a61af66fc99e Initial load
duke
parents:
diff changeset
896 CAST_FROM_FN_PTR(address, JavaThread::check_safepoint_and_suspend_for_native_trans),
a61af66fc99e Initial load
duke
parents:
diff changeset
897 G2_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
898 __ ld_ptr(STATE(_thread), G2_thread); // restore thread
a61af66fc99e Initial load
duke
parents:
diff changeset
899 // Restore any method result value
a61af66fc99e Initial load
duke
parents:
diff changeset
900 restore_native_result();
a61af66fc99e Initial load
duke
parents:
diff changeset
901 __ bind(no_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
902 }
a61af66fc99e Initial load
duke
parents:
diff changeset
903
a61af66fc99e Initial load
duke
parents:
diff changeset
904 // Clear the frame anchor now
a61af66fc99e Initial load
duke
parents:
diff changeset
905
a61af66fc99e Initial load
duke
parents:
diff changeset
906 __ reset_last_Java_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
907
a61af66fc99e Initial load
duke
parents:
diff changeset
908 // Move the result handler address
a61af66fc99e Initial load
duke
parents:
diff changeset
909 __ mov(Lscratch, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
910 // return possible result to the outer frame
a61af66fc99e Initial load
duke
parents:
diff changeset
911 #ifndef __LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
912 __ mov(O0, I0);
a61af66fc99e Initial load
duke
parents:
diff changeset
913 __ restore(O1, G0, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
914 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
915 __ restore(O0, G0, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
916 #endif /* __LP64 */
a61af66fc99e Initial load
duke
parents:
diff changeset
917
a61af66fc99e Initial load
duke
parents:
diff changeset
918 // Move result handler to expected register
a61af66fc99e Initial load
duke
parents:
diff changeset
919 __ mov(G3_scratch, Lscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
920
a61af66fc99e Initial load
duke
parents:
diff changeset
921
a61af66fc99e Initial load
duke
parents:
diff changeset
922 // thread state is thread_in_native_trans. Any safepoint blocking has
a61af66fc99e Initial load
duke
parents:
diff changeset
923 // happened in the trampoline we are ready to switch to thread_in_Java.
a61af66fc99e Initial load
duke
parents:
diff changeset
924
a61af66fc99e Initial load
duke
parents:
diff changeset
925 __ set(_thread_in_Java, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
926 __ st(G3_scratch, thread_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
927
a61af66fc99e Initial load
duke
parents:
diff changeset
928 // If we have an oop result store it where it will be safe for any further gc
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // until we return now that we've released the handle it might be protected by
a61af66fc99e Initial load
duke
parents:
diff changeset
930
a61af66fc99e Initial load
duke
parents:
diff changeset
931 {
a61af66fc99e Initial load
duke
parents:
diff changeset
932 Label no_oop, store_result;
a61af66fc99e Initial load
duke
parents:
diff changeset
933
a61af66fc99e Initial load
duke
parents:
diff changeset
934 __ set((intptr_t)AbstractInterpreter::result_handler(T_OBJECT), G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
935 __ cmp(G3_scratch, Lscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
936 __ brx(Assembler::notEqual, false, Assembler::pt, no_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
937 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
938 __ addcc(G0, O0, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
939 __ brx(Assembler::notZero, true, Assembler::pt, store_result); // if result is not NULL:
a61af66fc99e Initial load
duke
parents:
diff changeset
940 __ delayed()->ld_ptr(O0, 0, O0); // unbox it
a61af66fc99e Initial load
duke
parents:
diff changeset
941 __ mov(G0, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
942
a61af66fc99e Initial load
duke
parents:
diff changeset
943 __ bind(store_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
944 // Store it where gc will look for it and result handler expects it.
a61af66fc99e Initial load
duke
parents:
diff changeset
945 __ st_ptr(O0, STATE(_oop_temp));
a61af66fc99e Initial load
duke
parents:
diff changeset
946
a61af66fc99e Initial load
duke
parents:
diff changeset
947 __ bind(no_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
948
a61af66fc99e Initial load
duke
parents:
diff changeset
949 }
a61af66fc99e Initial load
duke
parents:
diff changeset
950
a61af66fc99e Initial load
duke
parents:
diff changeset
951 // reset handle block
a61af66fc99e Initial load
duke
parents:
diff changeset
952 __ ld_ptr(G2_thread, in_bytes(JavaThread::active_handles_offset()), G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
953 __ st_ptr(G0, G3_scratch, JNIHandleBlock::top_offset_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
954
a61af66fc99e Initial load
duke
parents:
diff changeset
955
a61af66fc99e Initial load
duke
parents:
diff changeset
956 // handle exceptions (exception handling will handle unlocking!)
a61af66fc99e Initial load
duke
parents:
diff changeset
957 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
958 Address exception_addr (G2_thread, 0, in_bytes(Thread::pending_exception_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
959
a61af66fc99e Initial load
duke
parents:
diff changeset
960 __ ld_ptr(exception_addr, Gtemp);
a61af66fc99e Initial load
duke
parents:
diff changeset
961 __ tst(Gtemp);
a61af66fc99e Initial load
duke
parents:
diff changeset
962 __ brx(Assembler::equal, false, Assembler::pt, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
963 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
964 __ bind(pending_exception_present);
a61af66fc99e Initial load
duke
parents:
diff changeset
965 // With c++ interpreter we just leave it pending caller will do the correct thing. However...
a61af66fc99e Initial load
duke
parents:
diff changeset
966 // Like x86 we ignore the result of the native call and leave the method locked. This
a61af66fc99e Initial load
duke
parents:
diff changeset
967 // seems wrong to leave things locked.
a61af66fc99e Initial load
duke
parents:
diff changeset
968
a61af66fc99e Initial load
duke
parents:
diff changeset
969 __ br(Assembler::always, false, Assembler::pt, StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
970 __ delayed()->restore(I5_savedSP, G0, SP); // remove interpreter frame
a61af66fc99e Initial load
duke
parents:
diff changeset
971
a61af66fc99e Initial load
duke
parents:
diff changeset
972 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
973 }
a61af66fc99e Initial load
duke
parents:
diff changeset
974
a61af66fc99e Initial load
duke
parents:
diff changeset
975 // jvmdi/jvmpi support (preserves thread register)
a61af66fc99e Initial load
duke
parents:
diff changeset
976 __ notify_method_exit(true, ilgl, InterpreterMacroAssembler::NotifyJVMTI);
a61af66fc99e Initial load
duke
parents:
diff changeset
977
a61af66fc99e Initial load
duke
parents:
diff changeset
978 if (synchronized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
979 // save and restore any potential method result value around the unlocking operation
a61af66fc99e Initial load
duke
parents:
diff changeset
980 save_native_result();
a61af66fc99e Initial load
duke
parents:
diff changeset
981
a61af66fc99e Initial load
duke
parents:
diff changeset
982 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
983 // Get the initial monitor we allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
984 __ sub(Lstate, entry_size, O1); // initial monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
985 __ unlock_object(O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
986 restore_native_result();
a61af66fc99e Initial load
duke
parents:
diff changeset
987 }
a61af66fc99e Initial load
duke
parents:
diff changeset
988
a61af66fc99e Initial load
duke
parents:
diff changeset
989 #if defined(COMPILER2) && !defined(_LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
990
a61af66fc99e Initial load
duke
parents:
diff changeset
991 // C2 expects long results in G1 we can't tell if we're returning to interpreted
a61af66fc99e Initial load
duke
parents:
diff changeset
992 // or compiled so just be safe.
a61af66fc99e Initial load
duke
parents:
diff changeset
993
a61af66fc99e Initial load
duke
parents:
diff changeset
994 __ sllx(O0, 32, G1); // Shift bits into high G1
a61af66fc99e Initial load
duke
parents:
diff changeset
995 __ srl (O1, 0, O1); // Zero extend O1
a61af66fc99e Initial load
duke
parents:
diff changeset
996 __ or3 (O1, G1, G1); // OR 64 bits into G1
a61af66fc99e Initial load
duke
parents:
diff changeset
997
a61af66fc99e Initial load
duke
parents:
diff changeset
998 #endif /* COMPILER2 && !_LP64 */
a61af66fc99e Initial load
duke
parents:
diff changeset
999
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 Label ok;
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 __ cmp(I5_savedSP, FP);
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 __ stop("bad I5_savedSP value");
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 __ should_not_reach_here();
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 __ bind(ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 // Calls result handler which POPS FRAME
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 if (TraceJumps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 // Move target to register that is recordable
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 __ mov(Lscratch, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 __ JMP(G3_scratch, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 __ jmp(Lscratch, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1020
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 if (inc_counter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 // handle invocation counter overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 __ bind(invocation_counter_overflow);
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 generate_counter_overflow(Lcontinue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1026
a61af66fc99e Initial load
duke
parents:
diff changeset
1027
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 return entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1030
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 void CppInterpreterGenerator::generate_compute_interpreter_state(const Register state,
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 const Register prev_state,
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 bool native) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1034
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 // On entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 // G5_method - caller's method
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 // Gargs - points to initial parameters (i.e. locals[0])
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 // G2_thread - valid? (C1 only??)
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 // "prev_state" - contains any previous frame manager state which we must save a link
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 // On return
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 // "state" is a pointer to the newly allocated state object. We must allocate and initialize
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 // a new interpretState object and the method expression stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1044
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 assert_different_registers(state, prev_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 assert_different_registers(prev_state, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 const Register Gtmp = G3_scratch;
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1048 const Address constMethod (G5_method, 0, in_bytes(Method::const_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1049 const Address access_flags (G5_method, 0, in_bytes(Method::access_flags_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1050 const Address size_of_parameters(G5_method, 0, in_bytes(Method::size_of_parameters_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1051 const Address max_stack (G5_method, 0, in_bytes(Method::max_stack_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1052 const Address size_of_locals (G5_method, 0, in_bytes(Method::size_of_locals_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1053
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 // slop factor is two extra slots on the expression stack so that
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 // we always have room to store a result when returning from a call without parameters
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 // that returns a result.
a61af66fc99e Initial load
duke
parents:
diff changeset
1057
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 const int slop_factor = 2*wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
1059
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 const int fixed_size = ((sizeof(BytecodeInterpreter) + slop_factor) >> LogBytesPerWord) + // what is the slop factor?
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1061 //6815692//Method::extra_stack_words() + // extra push slots for MH adapters
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 frame::memory_parameter_word_sp_offset + // register save area + param window
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 (native ? frame::interpreter_frame_extra_outgoing_argument_words : 0); // JNI, class
a61af66fc99e Initial load
duke
parents:
diff changeset
1064
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 // XXX G5_method valid
a61af66fc99e Initial load
duke
parents:
diff changeset
1066
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 // Now compute new frame size
a61af66fc99e Initial load
duke
parents:
diff changeset
1068
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 if (native) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 __ lduh( size_of_parameters, Gtmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 __ calc_mem_param_words(Gtmp, Gtmp); // space for native call parameters passed on the stack in words
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 __ lduh(max_stack, Gtmp); // Full size expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 __ add(Gtmp, fixed_size, Gtmp); // plus the fixed portion
a61af66fc99e Initial load
duke
parents:
diff changeset
1076
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 __ neg(Gtmp); // negative space for stack/parameters in words
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 __ and3(Gtmp, -WordsPerLong, Gtmp); // make multiple of 2 (SP must be 2-word aligned)
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 __ sll(Gtmp, LogBytesPerWord, Gtmp); // negative space for frame in bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
1080
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 // Need to do stack size check here before we fault on large frames
a61af66fc99e Initial load
duke
parents:
diff changeset
1082
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 Label stack_ok;
a61af66fc99e Initial load
duke
parents:
diff changeset
1084
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 const int max_pages = StackShadowPages > (StackRedPages+StackYellowPages) ? StackShadowPages :
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 (StackRedPages+StackYellowPages);
a61af66fc99e Initial load
duke
parents:
diff changeset
1087
a61af66fc99e Initial load
duke
parents:
diff changeset
1088
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 __ ld_ptr(G2_thread, in_bytes(Thread::stack_base_offset()), O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 __ ld_ptr(G2_thread, in_bytes(Thread::stack_size_offset()), O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 // compute stack bottom
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 __ sub(O0, O1, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1093
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 // Avoid touching the guard pages
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 // Also a fudge for frame size of BytecodeInterpreter::run
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 // It varies from 1k->4k depending on build type
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 const int fudge = 6 * K;
a61af66fc99e Initial load
duke
parents:
diff changeset
1098
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 __ set(fudge + (max_pages * os::vm_page_size()), O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1100
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 __ add(O0, O1, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 __ sub(O0, Gtmp, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 __ cmp(SP, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 __ brx(Assembler::greaterUnsigned, false, Assembler::pt, stack_ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1106
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 // throw exception return address becomes throwing pc
a61af66fc99e Initial load
duke
parents:
diff changeset
1108
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_StackOverflowError));
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 __ stop("never reached");
a61af66fc99e Initial load
duke
parents:
diff changeset
1111
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 __ bind(stack_ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
1113
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 __ save(SP, Gtmp, SP); // setup new frame and register window
a61af66fc99e Initial load
duke
parents:
diff changeset
1115
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 // New window I7 call_stub or previous activation
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 // O6 - register save area, BytecodeInterpreter just below it, args/locals just above that
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 __ sub(FP, sizeof(BytecodeInterpreter), state); // Point to new Interpreter state
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 __ add(state, STACK_BIAS, state ); // Account for 64bit bias
a61af66fc99e Initial load
duke
parents:
diff changeset
1121
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 #define XXX_STATE(field_name) state, in_bytes(byte_offset_of(BytecodeInterpreter, field_name))
a61af66fc99e Initial load
duke
parents:
diff changeset
1123
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 // Initialize a new Interpreter state
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 // orig_sp - caller's original sp
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 // G2_thread - thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 // Gargs - &locals[0] (unbiased?)
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 // G5_method - method
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 // SP (biased) - accounts for full size java stack, BytecodeInterpreter object, register save area, and register parameter save window
a61af66fc99e Initial load
duke
parents:
diff changeset
1130
a61af66fc99e Initial load
duke
parents:
diff changeset
1131
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 __ set(0xdead0004, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1133
a61af66fc99e Initial load
duke
parents:
diff changeset
1134
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 __ st_ptr(Gargs, XXX_STATE(_locals));
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 __ st_ptr(G0, XXX_STATE(_oop_temp));
a61af66fc99e Initial load
duke
parents:
diff changeset
1137
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 __ st_ptr(state, XXX_STATE(_self_link)); // point to self
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 __ st_ptr(prev_state->after_save(), XXX_STATE(_prev_link)); // Chain interpreter states
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 __ st_ptr(G2_thread, XXX_STATE(_thread)); // Store javathread
a61af66fc99e Initial load
duke
parents:
diff changeset
1141
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 if (native) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 __ st_ptr(G0, XXX_STATE(_bcp));
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 } else {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1145 __ ld_ptr(G5_method, in_bytes(Method::const_offset()), O2); // get ConstMethod*
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1146 __ add(O2, in_bytes(ConstMethod::codes_offset()), O2); // get bcp
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 __ st_ptr(O2, XXX_STATE(_bcp));
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1149
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 __ st_ptr(G0, XXX_STATE(_mdx));
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 __ st_ptr(G5_method, XXX_STATE(_method));
a61af66fc99e Initial load
duke
parents:
diff changeset
1152
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 __ set((int) BytecodeInterpreter::method_entry, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 __ st(O1, XXX_STATE(_msg));
a61af66fc99e Initial load
duke
parents:
diff changeset
1155
6123
2fe087c3e814 7172967: Eliminate constMethod's _method backpointer to methodOop.
jiangli
parents: 5923
diff changeset
1156 __ ld_ptr(constMethod, O3);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1157 __ ld_ptr(O3, in_bytes(ConstMethod::constants_offset()), O3);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1158 __ ld_ptr(O3, ConstantPool::cache_offset_in_bytes(), O2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 __ st_ptr(O2, XXX_STATE(_constants));
a61af66fc99e Initial load
duke
parents:
diff changeset
1160
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 __ st_ptr(G0, XXX_STATE(_result._to_call._callee));
a61af66fc99e Initial load
duke
parents:
diff changeset
1162
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 // Monitor base is just start of BytecodeInterpreter object;
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 __ mov(state, O2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 __ st_ptr(O2, XXX_STATE(_monitor_base));
a61af66fc99e Initial load
duke
parents:
diff changeset
1166
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 // Do we need a monitor for synchonized method?
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 __ ld(access_flags, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 Label done;
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 Label got_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 __ btst(JVM_ACC_SYNCHRONIZED, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 __ br( Assembler::zero, false, Assembler::pt, done);
a61af66fc99e Initial load
duke
parents:
diff changeset
1174
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3839
diff changeset
1175 const int mirror_offset = in_bytes(Klass::java_mirror_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 __ delayed()->btst(JVM_ACC_STATIC, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 __ ld_ptr(XXX_STATE(_locals), O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 __ br( Assembler::zero, true, Assembler::pt, got_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 __ delayed()->ld_ptr(O1, 0, O1); // get receiver for not-static case
6123
2fe087c3e814 7172967: Eliminate constMethod's _method backpointer to methodOop.
jiangli
parents: 5923
diff changeset
1180 __ ld_ptr(constMethod, O1);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1181 __ ld_ptr( O1, in_bytes(ConstMethod::constants_offset()), O1);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1182 __ ld_ptr( O1, ConstantPool::pool_holder_offset_in_bytes(), O1);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1183 // lock the mirror, not the Klass*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 __ ld_ptr( O1, mirror_offset, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1185
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 __ bind(got_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1187
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 __ tst(O1);
5923
8a48c2906f91 7150046: SIGILL on sparcv9 fastdebug
coleenp
parents: 4762
diff changeset
1190 __ breakpoint_trap(Assembler::zero, Assembler::ptr_cc);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1192
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 __ sub(SP, entry_size, SP); // account for initial monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 __ sub(O2, entry_size, O2); // initial monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 __ st_ptr(O1, O2, BasicObjectLock::obj_offset_in_bytes()); // and allocate it for interpreter use
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 __ bind(done);
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1199
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 // Remember initial frame bottom
a61af66fc99e Initial load
duke
parents:
diff changeset
1201
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 __ st_ptr(SP, XXX_STATE(_frame_bottom));
a61af66fc99e Initial load
duke
parents:
diff changeset
1203
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 __ st_ptr(O2, XXX_STATE(_stack_base));
a61af66fc99e Initial load
duke
parents:
diff changeset
1205
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 __ sub(O2, wordSize, O2); // prepush
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 __ st_ptr(O2, XXX_STATE(_stack)); // PREPUSH
a61af66fc99e Initial load
duke
parents:
diff changeset
1208
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 __ lduh(max_stack, O3); // Full size expression stack
2416
38fea01eb669 6817525: turn on method handle functionality by default for JSR 292
twisti
parents: 2357
diff changeset
1210 guarantee(!EnableInvokeDynamic, "no support yet for java.lang.invoke.MethodHandle"); //6815692
38fea01eb669 6817525: turn on method handle functionality by default for JSR 292
twisti
parents: 2357
diff changeset
1211 //6815692//if (EnableInvokeDynamic)
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1212 //6815692// __ inc(O3, Method::extra_stack_entries());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 __ sll(O3, LogBytesPerWord, O3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 __ sub(O2, O3, O3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 // __ sub(O3, wordSize, O3); // so prepush doesn't look out of bounds
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 __ st_ptr(O3, XXX_STATE(_stack_limit));
a61af66fc99e Initial load
duke
parents:
diff changeset
1217
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 if (!native) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 // Code to initialize locals
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 Register init_value = noreg; // will be G0 if we must clear locals
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 // Now zero locals
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 if (true /* zerolocals */ || ClearInterpreterLocals) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 // explicitly initialize locals
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 init_value = G0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 // initialize locals to a garbage pattern for better debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 init_value = O3;
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 __ set( 0x0F0F0F0F, init_value );
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 if (init_value != noreg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 Label clear_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1236
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 // NOTE: If you change the frame layout, this code will need to
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 // be updated!
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 __ lduh( size_of_locals, O2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 __ lduh( size_of_parameters, O1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 __ sll( O2, LogBytesPerWord, O2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 __ sll( O1, LogBytesPerWord, O1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 __ ld_ptr(XXX_STATE(_locals), L2_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 __ sub( L2_scratch, O2, O2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 __ sub( L2_scratch, O1, O1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1246
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 __ bind( clear_loop );
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 __ inc( O2, wordSize );
a61af66fc99e Initial load
duke
parents:
diff changeset
1249
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 __ cmp( O2, O1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 __ br( Assembler::lessEqualUnsigned, true, Assembler::pt, clear_loop );
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 __ delayed()->st_ptr( init_value, O2, 0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 // Find preallocated monitor and lock method (C++ interpreter)
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 void InterpreterGenerator::lock_method(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 // Lock the current method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 // Destroys registers L2_scratch, L3_scratch, O0
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 // Find everything relative to Lstate
a61af66fc99e Initial load
duke
parents:
diff changeset
1263
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 __ ld_ptr(STATE(_method), L2_scratch);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1266 __ ld(L2_scratch, in_bytes(Method::access_flags_offset()), O0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1267
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 { Label ok;
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 __ btst(JVM_ACC_SYNCHRONIZED, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 __ br( Assembler::notZero, false, Assembler::pt, ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 __ stop("method doesn't need synchronization");
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 __ bind(ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1276
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 // monitor is already allocated at stack base
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 // and the lockee is already present
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 __ ld_ptr(STATE(_stack_base), L2_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 __ ld_ptr(L2_scratch, BasicObjectLock::obj_offset_in_bytes(), O0); // get object
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 __ lock_object(L2_scratch, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1282
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1284
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // Generate code for handling resuming a deopted method
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 void CppInterpreterGenerator::generate_deopt_handling() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1287
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 Label return_from_deopt_common;
a61af66fc99e Initial load
duke
parents:
diff changeset
1289
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 deopt_frame_manager_return_atos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1292
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 // O0/O1 live
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
1294 __ ba(return_from_deopt_common);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 __ delayed()->set(AbstractInterpreter::BasicType_as_index(T_OBJECT), L3_scratch); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1296
a61af66fc99e Initial load
duke
parents:
diff changeset
1297
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 deopt_frame_manager_return_btos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1300
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 // O0/O1 live
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
1302 __ ba(return_from_deopt_common);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 __ delayed()->set(AbstractInterpreter::BasicType_as_index(T_BOOLEAN), L3_scratch); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1304
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 deopt_frame_manager_return_itos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1307
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 // O0/O1 live
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
1309 __ ba(return_from_deopt_common);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 __ delayed()->set(AbstractInterpreter::BasicType_as_index(T_INT), L3_scratch); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1311
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1313
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 deopt_frame_manager_return_ltos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 #if !defined(_LP64) && defined(COMPILER2)
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 // All return values are where we want them, except for Longs. C2 returns
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 // longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1.
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 // Since the interpreter will return longs in G1 and O0/O1 in the 32bit
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 // build even if we are returning from interpreted we just do a little
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 // stupid shuffing.
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 // 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
1322 // do this here. Unfortunately if we did a rethrow we'd see an machepilog node
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 // first which would move g1 -> O0/O1 and destroy the exception we were throwing.
a61af66fc99e Initial load
duke
parents:
diff changeset
1324
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 __ srl (G1, 0,O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 __ srlx(G1,32,O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 #endif /* !_LP64 && COMPILER2 */
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 // O0/O1 live
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
1329 __ ba(return_from_deopt_common);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 __ delayed()->set(AbstractInterpreter::BasicType_as_index(T_LONG), L3_scratch); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1331
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1333
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 deopt_frame_manager_return_ftos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 // O0/O1 live
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
1336 __ ba(return_from_deopt_common);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 __ delayed()->set(AbstractInterpreter::BasicType_as_index(T_FLOAT), L3_scratch); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1338
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 deopt_frame_manager_return_dtos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1341
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 // O0/O1 live
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
1343 __ ba(return_from_deopt_common);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 __ delayed()->set(AbstractInterpreter::BasicType_as_index(T_DOUBLE), L3_scratch); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1345
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 deopt_frame_manager_return_vtos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1348
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 // O0/O1 live
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 __ set(AbstractInterpreter::BasicType_as_index(T_VOID), L3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1351
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 // Deopt return common
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 // an index is present that lets us move any possible result being
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 // return to the interpreter's stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 __ bind(return_from_deopt_common);
a61af66fc99e Initial load
duke
parents:
diff changeset
1357
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 // Result if any is in native abi result (O0..O1/F0..F1). The java expression
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 // stack is in the state that the calling convention left it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 // Copy the result from native abi result and place it on java expression stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1361
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 // Current interpreter state is present in Lstate
a61af66fc99e Initial load
duke
parents:
diff changeset
1363
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 // Get current pre-pushed top of interpreter stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 // Any result (if any) is in native abi
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 // result type index is in L3_scratch
a61af66fc99e Initial load
duke
parents:
diff changeset
1367
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 __ ld_ptr(STATE(_stack), L1_scratch); // get top of java expr stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1369
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 __ set((intptr_t)CppInterpreter::_tosca_to_stack, L4_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 __ sll(L3_scratch, LogBytesPerWord, L3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 __ ld_ptr(L4_scratch, L3_scratch, Lscratch); // get typed result converter address
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 __ jmpl(Lscratch, G0, O7); // and convert it
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1375
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 // L1_scratch points to top of stack (prepushed)
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 __ st_ptr(L1_scratch, STATE(_stack));
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1379
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 // Generate the code to handle a more_monitors message from the c++ interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 void CppInterpreterGenerator::generate_more_monitors() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1382
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 Label entry, loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 // 1. compute new pointers // esp: old expression stack top
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 __ delayed()->ld_ptr(STATE(_stack_base), L4_scratch); // current expression stack bottom
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 __ sub(L4_scratch, entry_size, L4_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 __ st_ptr(L4_scratch, STATE(_stack_base));
a61af66fc99e Initial load
duke
parents:
diff changeset
1389
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 __ sub(SP, entry_size, SP); // Grow stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 __ st_ptr(SP, STATE(_frame_bottom));
a61af66fc99e Initial load
duke
parents:
diff changeset
1392
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 __ ld_ptr(STATE(_stack_limit), L2_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 __ sub(L2_scratch, entry_size, L2_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 __ st_ptr(L2_scratch, STATE(_stack_limit));
a61af66fc99e Initial load
duke
parents:
diff changeset
1396
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 __ ld_ptr(STATE(_stack), L1_scratch); // Get current stack top
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 __ sub(L1_scratch, entry_size, L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 __ st_ptr(L1_scratch, STATE(_stack));
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
1400 __ ba(entry);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 __ delayed()->add(L1_scratch, wordSize, L1_scratch); // first real entry (undo prepush)
a61af66fc99e Initial load
duke
parents:
diff changeset
1402
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 // 2. move expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1404
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 __ bind(loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 __ st_ptr(L3_scratch, Address(L1_scratch, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 __ add(L1_scratch, wordSize, L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 __ bind(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 __ cmp(L1_scratch, L4_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 __ br(Assembler::notEqual, false, Assembler::pt, loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 __ delayed()->ld_ptr(L1_scratch, entry_size, L3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1412
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 // now zero the slot so we can find it.
123
9e5a7340635e 6688137: c++ interpreter fails on 64bit sparc
sgoldman
parents: 0
diff changeset
1414 __ st_ptr(G0, L4_scratch, BasicObjectLock::obj_offset_in_bytes());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1415
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1417
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 // Initial entry to C++ interpreter from the call_stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 // This entry point is called the frame manager since it handles the generation
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 // of interpreter activation frames via requests directly from the vm (via call_stub)
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 // and via requests from the interpreter. The requests from the call_stub happen
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 // directly thru the entry point. Requests from the interpreter happen via returning
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 // from the interpreter and examining the message the interpreter has returned to
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 // the frame manager. The frame manager can take the following requests:
a61af66fc99e Initial load
duke
parents:
diff changeset
1425
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 // NO_REQUEST - error, should never happen.
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 // MORE_MONITORS - need a new monitor. Shuffle the expression stack on down and
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 // allocate a new monitor.
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 // CALL_METHOD - setup a new activation to call a new method. Very similar to what
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 // happens during entry during the entry via the call stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 // RETURN_FROM_METHOD - remove an activation. Return to interpreter or call stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 //
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1435 // ebx: Method*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 // ecx: receiver - unused (retrieved from stack as needed)
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 // esi: previous frame manager state (NULL from the call_stub/c1/c2)
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 // Stack layout at entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 // [ return address ] <--- esp
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 // [ parameter n ]
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 // ...
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 // [ parameter 1 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 // [ expression stack ]
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 // We are free to blow any registers we like because the call_stub which brought us here
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 // initially has preserved the callee save registers already.
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1453
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 static address interpreter_frame_manager = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1455
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 #define VALIDATE_STATE(scratch, marker) \
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 { \
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 Label skip; \
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 __ ld_ptr(STATE(_self_link), scratch); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 __ cmp(Lstate, scratch); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 __ brx(Assembler::equal, false, Assembler::pt, skip); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 __ delayed()->nop(); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 __ breakpoint_trap(); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 __ emit_long(marker); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 __ bind(skip); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 #define VALIDATE_STATE(scratch, marker)
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 #endif /* ASSERT */
a61af66fc99e Initial load
duke
parents:
diff changeset
1471
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 void CppInterpreterGenerator::adjust_callers_stack(Register args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 // Adjust caller's stack so that all the locals can be contiguous with
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 // the parameters.
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 // Worries about stack overflow make this a pain.
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 // Destroys args, G3_scratch, G3_scratch
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 // In/Out O5_savedSP (sender's original SP)
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 // assert_different_registers(state, prev_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 const Register Gtmp = G3_scratch;
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 const Register tmp = O2;
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1484 const Address size_of_parameters(G5_method, 0, in_bytes(Method::size_of_parameters_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1485 const Address size_of_locals (G5_method, 0, in_bytes(Method::size_of_locals_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1486
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 __ lduh(size_of_parameters, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 __ sll(tmp, LogBytesPerWord, Gtmp); // parameter size in bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 __ add(args, Gtmp, Gargs); // points to first local + BytesPerWord
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 // NEW
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 __ add(Gargs, -wordSize, Gargs); // points to first local[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 // determine extra space for non-argument locals & adjust caller's SP
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 // Gtmp1: parameter size in words
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 __ lduh(size_of_locals, Gtmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 __ compute_extra_locals_size_in_bytes(tmp, Gtmp, Gtmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1496
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 #if 1
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 // c2i adapters place the final interpreter argument in the register save area for O0/I0
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 // the call_stub will place the final interpreter argument at
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 // frame::memory_parameter_word_sp_offset. This is mostly not noticable for either asm
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 // or c++ interpreter. However with the c++ interpreter when we do a recursive call
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 // and try to make it look good in the debugger we will store the argument to
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 // RecursiveInterpreterActivation in the register argument save area. Without allocating
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 // extra space for the compiler this will overwrite locals in the local array of the
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 // interpreter.
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 // QQQ still needed with frameless adapters???
a61af66fc99e Initial load
duke
parents:
diff changeset
1507
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 const int c2i_adjust_words = frame::memory_parameter_word_sp_offset - frame::callee_register_argument_save_area_sp_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
1509
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 __ add(Gtmp, c2i_adjust_words*wordSize, Gtmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 #endif // 1
a61af66fc99e Initial load
duke
parents:
diff changeset
1512
a61af66fc99e Initial load
duke
parents:
diff changeset
1513
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 __ sub(SP, Gtmp, SP); // just caller's frame for the additional space we need.
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1516
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 address InterpreterGenerator::generate_normal_entry(bool synchronized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1518
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1519 // G5_method: Method*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 // G2_thread: thread (unused)
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 // Gargs: bottom of args (sender_sp)
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 // O5: sender's sp
a61af66fc99e Initial load
duke
parents:
diff changeset
1523
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 // A single frame manager is plenty as we don't specialize for synchronized. We could and
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 // the code is pretty much ready. Would need to change the test below and for good measure
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 // modify generate_interpreter_state to only do the (pre) sync stuff stuff for synchronized
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 // routines. Not clear this is worth it yet.
a61af66fc99e Initial load
duke
parents:
diff changeset
1528
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 if (interpreter_frame_manager) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 return interpreter_frame_manager;
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1532
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 __ bind(frame_manager_entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
1534
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 // the following temporary registers are used during frame creation
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 const Register Gtmp1 = G3_scratch;
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 // const Register Lmirror = L1; // native mirror (native calls only)
a61af66fc99e Initial load
duke
parents:
diff changeset
1538
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1539 const Address constMethod (G5_method, 0, in_bytes(Method::const_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1540 const Address access_flags (G5_method, 0, in_bytes(Method::access_flags_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1541 const Address size_of_parameters(G5_method, 0, in_bytes(Method::size_of_parameters_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1542 const Address max_stack (G5_method, 0, in_bytes(Method::max_stack_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1543 const Address size_of_locals (G5_method, 0, in_bytes(Method::size_of_locals_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1544
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 address entry_point = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 __ mov(G0, prevState); // no current activation
a61af66fc99e Initial load
duke
parents:
diff changeset
1547
a61af66fc99e Initial load
duke
parents:
diff changeset
1548
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 Label re_dispatch;
a61af66fc99e Initial load
duke
parents:
diff changeset
1550
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 __ bind(re_dispatch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1552
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 // Interpreter needs to have locals completely contiguous. In order to do that
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 // We must adjust the caller's stack pointer for any locals beyond just the
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 // parameters
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 adjust_callers_stack(Gargs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1557
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 // O5_savedSP still contains sender's sp
a61af66fc99e Initial load
duke
parents:
diff changeset
1559
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 // NEW FRAME
a61af66fc99e Initial load
duke
parents:
diff changeset
1561
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 generate_compute_interpreter_state(Lstate, prevState, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1563
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 // At this point a new interpreter frame and state object are created and initialized
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 // Lstate has the pointer to the new activation
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 // Any stack banging or limit check should already be done.
a61af66fc99e Initial load
duke
parents:
diff changeset
1567
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 Label call_interpreter;
a61af66fc99e Initial load
duke
parents:
diff changeset
1569
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 __ bind(call_interpreter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1571
a61af66fc99e Initial load
duke
parents:
diff changeset
1572
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 #if 1
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 __ set(0xdead002, Lmirror);
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 __ set(0xdead002, L2_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 __ set(0xdead003, L3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 __ set(0xdead004, L4_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 __ set(0xdead005, Lscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 __ set(0xdead006, Lscratch2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 __ set(0xdead007, L7_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1581
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 __ set(0xdeaf002, O2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 __ set(0xdeaf003, O3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 __ set(0xdeaf004, O4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 __ set(0xdeaf005, O5);
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1587
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 // Call interpreter (stack bang complete) enter here if message is
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 // set and we know stack size is valid
a61af66fc99e Initial load
duke
parents:
diff changeset
1590
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 Label call_interpreter_2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1592
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 __ bind(call_interpreter_2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1594
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 Label skip;
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 __ ld_ptr(STATE(_frame_bottom), G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 __ cmp(G3_scratch, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 __ brx(Assembler::equal, false, Assembler::pt, skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 __ stop("SP not restored to frame bottom");
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 __ bind(skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1606
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 VALIDATE_STATE(G3_scratch, 4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 __ set_last_Java_frame(SP, noreg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 __ mov(Lstate, O0); // (arg) pointer to current state
a61af66fc99e Initial load
duke
parents:
diff changeset
1610
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 __ call(CAST_FROM_FN_PTR(address,
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 JvmtiExport::can_post_interpreter_events() ?
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 BytecodeInterpreter::runWithChecks
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 : BytecodeInterpreter::run),
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 relocInfo::runtime_call_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1616
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1618
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 __ ld_ptr(STATE(_thread), G2_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 __ reset_last_Java_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
1621
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 // examine msg from interpreter to determine next action
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 __ ld_ptr(STATE(_thread), G2_thread); // restore G2_thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1624
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 __ ld(STATE(_msg), L1_scratch); // Get new message
a61af66fc99e Initial load
duke
parents:
diff changeset
1626
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 Label call_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 Label return_from_interpreted_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 Label throw_exception;
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 Label do_OSR;
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 Label bad_msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 Label resume_interpreter;
a61af66fc99e Initial load
duke
parents:
diff changeset
1633
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 __ cmp(L1_scratch, (int)BytecodeInterpreter::call_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 __ br(Assembler::equal, false, Assembler::pt, call_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 __ delayed()->cmp(L1_scratch, (int)BytecodeInterpreter::return_from_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 __ br(Assembler::equal, false, Assembler::pt, return_from_interpreted_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 __ delayed()->cmp(L1_scratch, (int)BytecodeInterpreter::throwing_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 __ br(Assembler::equal, false, Assembler::pt, throw_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 __ delayed()->cmp(L1_scratch, (int)BytecodeInterpreter::do_osr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 __ br(Assembler::equal, false, Assembler::pt, do_OSR);
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 __ delayed()->cmp(L1_scratch, (int)BytecodeInterpreter::more_monitors);
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 __ br(Assembler::notEqual, false, Assembler::pt, bad_msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1644
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 // Allocate more monitor space, shuffle expression stack....
a61af66fc99e Initial load
duke
parents:
diff changeset
1646
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 generate_more_monitors();
a61af66fc99e Initial load
duke
parents:
diff changeset
1648
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 // new monitor slot allocated, resume the interpreter.
a61af66fc99e Initial load
duke
parents:
diff changeset
1650
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 __ set((int)BytecodeInterpreter::got_monitors, L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 VALIDATE_STATE(G3_scratch, 5);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
1653 __ ba(call_interpreter);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 __ delayed()->st(L1_scratch, STATE(_msg));
a61af66fc99e Initial load
duke
parents:
diff changeset
1655
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 // uncommon trap needs to jump to here to enter the interpreter (re-execute current bytecode)
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 unctrap_frame_manager_entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1658
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 // QQQ what message do we send
a61af66fc99e Initial load
duke
parents:
diff changeset
1660
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
1661 __ ba(call_interpreter);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 __ delayed()->ld_ptr(STATE(_frame_bottom), SP); // restore to full stack frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1663
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 // Returning from a compiled method into a deopted method. The bytecode at the
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 // bcp has completed. The result of the bytecode is in the native abi (the tosca
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 // for the template based interpreter). Any stack space that was used by the
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 // bytecode that has completed has been removed (e.g. parameters for an invoke)
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 // so all that we have to do is place any pending result on the expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 // and resume execution on the next bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
1671
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 generate_deopt_handling();
a61af66fc99e Initial load
duke
parents:
diff changeset
1673
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 // ready to resume the interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1675
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 __ set((int)BytecodeInterpreter::deopt_resume, L1_scratch);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
1677 __ ba(call_interpreter);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 __ delayed()->st(L1_scratch, STATE(_msg));
a61af66fc99e Initial load
duke
parents:
diff changeset
1679
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 // Current frame has caught an exception we need to dispatch to the
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 // handler. We can get here because a native interpreter frame caught
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 // an exception in which case there is no handler and we must rethrow
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 // If it is a vanilla interpreted frame the we simply drop into the
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 // interpreter and let it do the lookup.
a61af66fc99e Initial load
duke
parents:
diff changeset
1685
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 Interpreter::_rethrow_exception_entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1687
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 Label return_with_exception;
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 Label unwind_and_forward;
a61af66fc99e Initial load
duke
parents:
diff changeset
1690
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 // O0: exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 // O7: throwing pc
a61af66fc99e Initial load
duke
parents:
diff changeset
1693
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 // We want exception in the thread no matter what we ultimately decide about frame type.
a61af66fc99e Initial load
duke
parents:
diff changeset
1695
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 Address exception_addr (G2_thread, 0, in_bytes(Thread::pending_exception_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 __ verify_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 __ st_ptr(O0, exception_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1699
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1700 // get the Method*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 __ ld_ptr(STATE(_method), G5_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
1702
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 // if this current frame vanilla or native?
a61af66fc99e Initial load
duke
parents:
diff changeset
1704
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 __ ld(access_flags, Gtmp1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 __ btst(JVM_ACC_NATIVE, Gtmp1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 __ br(Assembler::zero, false, Assembler::pt, return_with_exception); // vanilla interpreted frame handle directly
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1709
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 // We drop thru to unwind a native interpreted frame with a pending exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 // We jump here for the initial interpreter frame with exception pending
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 // We unwind the current acivation and forward it to our caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
1713
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 __ bind(unwind_and_forward);
a61af66fc99e Initial load
duke
parents:
diff changeset
1715
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 // Unwind frame and jump to forward exception. unwinding will place throwing pc in O7
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 // as expected by forward_exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
1718
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 __ restore(FP, G0, SP); // unwind interpreter state frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 __ br(Assembler::always, false, Assembler::pt, StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 __ delayed()->mov(I5_savedSP->after_restore(), SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
1722
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 // Return point from a call which returns a result in the native abi
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 // (c1/c2/jni-native). This result must be processed onto the java
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 // expression stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 // A pending exception may be present in which case there is no result present
a61af66fc99e Initial load
duke
parents:
diff changeset
1728
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 address return_from_native_method = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1730
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 VALIDATE_STATE(G3_scratch, 6);
a61af66fc99e Initial load
duke
parents:
diff changeset
1732
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 // Result if any is in native abi result (O0..O1/F0..F1). The java expression
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 // stack is in the state that the calling convention left it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 // Copy the result from native abi result and place it on java expression stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1736
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 // Current interpreter state is present in Lstate
a61af66fc99e Initial load
duke
parents:
diff changeset
1738
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 // Exception pending?
a61af66fc99e Initial load
duke
parents:
diff changeset
1740
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 __ ld_ptr(STATE(_frame_bottom), SP); // restore to full stack frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 __ ld_ptr(exception_addr, Lscratch); // get any pending exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 __ tst(Lscratch); // exception pending?
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 __ brx(Assembler::notZero, false, Assembler::pt, return_with_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1746
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 // Process the native abi result to java expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1748
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 __ ld_ptr(STATE(_result._to_call._callee), L4_scratch); // called method
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 __ ld_ptr(STATE(_stack), L1_scratch); // get top of java expr stack
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1751 __ lduh(L4_scratch, in_bytes(Method::size_of_parameters_offset()), L2_scratch); // get parameter size
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 __ sll(L2_scratch, LogBytesPerWord, L2_scratch ); // parameter size in bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 __ add(L1_scratch, L2_scratch, L1_scratch); // stack destination for result
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1754 __ ld(L4_scratch, in_bytes(Method::result_index_offset()), L3_scratch); // called method result type index
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1755
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 // tosca is really just native abi
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 __ set((intptr_t)CppInterpreter::_tosca_to_stack, L4_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 __ sll(L3_scratch, LogBytesPerWord, L3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 __ ld_ptr(L4_scratch, L3_scratch, Lscratch); // get typed result converter address
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 __ jmpl(Lscratch, G0, O7); // and convert it
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1762
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 // L1_scratch points to top of stack (prepushed)
a61af66fc99e Initial load
duke
parents:
diff changeset
1764
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
1765 __ ba(resume_interpreter);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 __ delayed()->mov(L1_scratch, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1767
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 // An exception is being caught on return to a vanilla interpreter frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 // Empty the stack and resume interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1770
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 __ bind(return_with_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
1772
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 __ ld_ptr(STATE(_frame_bottom), SP); // restore to full stack frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 __ ld_ptr(STATE(_stack_base), O1); // empty java expression stack
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
1775 __ ba(resume_interpreter);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 __ delayed()->sub(O1, wordSize, O1); // account for prepush
a61af66fc99e Initial load
duke
parents:
diff changeset
1777
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 // Return from interpreted method we return result appropriate to the caller (i.e. "recursive"
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 // interpreter call, or native) and unwind this interpreter activation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 // All monitors should be unlocked.
a61af66fc99e Initial load
duke
parents:
diff changeset
1781
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 __ bind(return_from_interpreted_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
1783
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 VALIDATE_STATE(G3_scratch, 7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1785
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 Label return_to_initial_caller;
a61af66fc99e Initial load
duke
parents:
diff changeset
1787
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 // Interpreted result is on the top of the completed activation expression stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 // We must return it to the top of the callers stack if caller was interpreted
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 // otherwise we convert to native abi result and return to call_stub/c1/c2
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 // The caller's expression stack was truncated by the call however the current activation
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 // has enough stuff on the stack that we have usable space there no matter what. The
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 // other thing that makes it easy is that the top of the caller's stack is stored in STATE(_locals)
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 // for the current activation
a61af66fc99e Initial load
duke
parents:
diff changeset
1795
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 __ ld_ptr(STATE(_prev_link), L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 __ ld_ptr(STATE(_method), L2_scratch); // get method just executed
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1798 __ ld(L2_scratch, in_bytes(Method::result_index_offset()), L2_scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 __ tst(L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 __ brx(Assembler::zero, false, Assembler::pt, return_to_initial_caller);
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 __ delayed()->sll(L2_scratch, LogBytesPerWord, L2_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1802
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 // Copy result to callers java stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1804
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 __ set((intptr_t)CppInterpreter::_stack_to_stack, L4_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 __ ld_ptr(L4_scratch, L2_scratch, Lscratch); // get typed result converter address
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 __ ld_ptr(STATE(_stack), O0); // current top (prepushed)
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 __ ld_ptr(STATE(_locals), O1); // stack destination
a61af66fc99e Initial load
duke
parents:
diff changeset
1809
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 // O0 - will be source, O1 - will be destination (preserved)
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 __ jmpl(Lscratch, G0, O7); // and convert it
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 __ delayed()->add(O0, wordSize, O0); // get source (top of current expr stack)
a61af66fc99e Initial load
duke
parents:
diff changeset
1813
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 // O1 == &locals[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
1815
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 // Result is now on caller's stack. Just unwind current activation and resume
a61af66fc99e Initial load
duke
parents:
diff changeset
1817
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 Label unwind_recursive_activation;
a61af66fc99e Initial load
duke
parents:
diff changeset
1819
a61af66fc99e Initial load
duke
parents:
diff changeset
1820
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 __ bind(unwind_recursive_activation);
a61af66fc99e Initial load
duke
parents:
diff changeset
1822
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 // O1 == &locals[0] (really callers stacktop) for activation now returning
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 // returning to interpreter method from "recursive" interpreter call
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 // result converter left O1 pointing to top of the( prepushed) java stack for method we are returning
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 // to. Now all we must do is unwind the state from the completed call
a61af66fc99e Initial load
duke
parents:
diff changeset
1827
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 // Must restore stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 VALIDATE_STATE(G3_scratch, 8);
a61af66fc99e Initial load
duke
parents:
diff changeset
1830
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 // Return to interpreter method after a method call (interpreted/native/c1/c2) has completed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 // Result if any is already on the caller's stack. All we must do now is remove the now dead
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 // frame and tell interpreter to resume.
a61af66fc99e Initial load
duke
parents:
diff changeset
1834
a61af66fc99e Initial load
duke
parents:
diff changeset
1835
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 __ mov(O1, I1); // pass back new stack top across activation
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 // POP FRAME HERE ==================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 __ restore(FP, G0, SP); // unwind interpreter state frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 __ ld_ptr(STATE(_frame_bottom), SP); // restore to full stack frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1840
a61af66fc99e Initial load
duke
parents:
diff changeset
1841
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 // Resume the interpreter. The current frame contains the current interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 // state object.
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 // O1 == new java stack pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
1846
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 __ bind(resume_interpreter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 VALIDATE_STATE(G3_scratch, 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
1849
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 // A frame we have already used before so no need to bang stack so use call_interpreter_2 entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1851
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 __ set((int)BytecodeInterpreter::method_resume, L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 __ st(L1_scratch, STATE(_msg));
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
1854 __ ba(call_interpreter_2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 __ delayed()->st_ptr(O1, STATE(_stack));
a61af66fc99e Initial load
duke
parents:
diff changeset
1856
a61af66fc99e Initial load
duke
parents:
diff changeset
1857
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 // Fast accessor methods share this entry point.
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 // This works because frame manager is in the same codelet
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 // This can either be an entry via call_stub/c1/c2 or a recursive interpreter call
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 // we need to do a little register fixup here once we distinguish the two of them
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 if (UseFastAccessorMethods && !synchronized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 // Call stub_return address still in O7
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 __ bind(fast_accessor_slow_entry_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 __ set((intptr_t)return_from_native_method - 8, Gtmp1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 __ cmp(Gtmp1, O7); // returning to interpreter?
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 __ brx(Assembler::equal, true, Assembler::pt, re_dispatch); // yep
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 __ delayed()->nop();
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
1869 __ ba(re_dispatch);
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
1870 __ delayed()->mov(G0, prevState); // initial entry
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1871
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1873
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 // interpreter returning to native code (call_stub/c1/c2)
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 // convert result and unwind initial activation
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 // L2_scratch - scaled result type index
a61af66fc99e Initial load
duke
parents:
diff changeset
1877
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 __ bind(return_to_initial_caller);
a61af66fc99e Initial load
duke
parents:
diff changeset
1879
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 __ set((intptr_t)CppInterpreter::_stack_to_native_abi, L4_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 __ ld_ptr(L4_scratch, L2_scratch, Lscratch); // get typed result converter address
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 __ ld_ptr(STATE(_stack), O0); // current top (prepushed)
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 __ jmpl(Lscratch, G0, O7); // and convert it
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 __ delayed()->add(O0, wordSize, O0); // get source (top of current expr stack)
a61af66fc99e Initial load
duke
parents:
diff changeset
1885
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 Label unwind_initial_activation;
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 __ bind(unwind_initial_activation);
a61af66fc99e Initial load
duke
parents:
diff changeset
1888
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 // RETURN TO CALL_STUB/C1/C2 code (result if any in I0..I1/(F0/..F1)
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 // we can return here with an exception that wasn't handled by interpreted code
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 // how does c1/c2 see it on return?
a61af66fc99e Initial load
duke
parents:
diff changeset
1892
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 // compute resulting sp before/after args popped depending upon calling convention
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 // __ ld_ptr(STATE(_saved_sp), Gtmp1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 // POP FRAME HERE ==================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 __ restore(FP, G0, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 __ retl();
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 __ delayed()->mov(I5_savedSP->after_restore(), SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
1900
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 // OSR request, unwind the current frame and transfer to the OSR entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 // and enter OSR nmethod
a61af66fc99e Initial load
duke
parents:
diff changeset
1903
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 __ bind(do_OSR);
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 Label remove_initial_frame;
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 __ ld_ptr(STATE(_prev_link), L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 __ ld_ptr(STATE(_result._osr._osr_buf), G1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1908
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 // We are going to pop this frame. Is there another interpreter frame underneath
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 // it or is it callstub/compiled?
a61af66fc99e Initial load
duke
parents:
diff changeset
1911
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 __ tst(L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 __ brx(Assembler::zero, false, Assembler::pt, remove_initial_frame);
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 __ delayed()->ld_ptr(STATE(_result._osr._osr_entry), G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1915
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 // Frame underneath is an interpreter frame simply unwind
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 // POP FRAME HERE ==================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 __ restore(FP, G0, SP); // unwind interpreter state frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 __ mov(I5_savedSP->after_restore(), SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
1920
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 // Since we are now calling native need to change our "return address" from the
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 // dummy RecursiveInterpreterActivation to a return from native
a61af66fc99e Initial load
duke
parents:
diff changeset
1923
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 __ set((intptr_t)return_from_native_method - 8, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1925
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 __ jmpl(G3_scratch, G0, G0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 __ delayed()->mov(G1_scratch, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1928
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 __ bind(remove_initial_frame);
a61af66fc99e Initial load
duke
parents:
diff changeset
1930
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 // POP FRAME HERE ==================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 __ restore(FP, G0, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 __ mov(I5_savedSP->after_restore(), SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 __ jmpl(G3_scratch, G0, G0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 __ delayed()->mov(G1_scratch, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1936
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 // Call a new method. All we do is (temporarily) trim the expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 // push a return address to bring us back to here and leap to the new entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 // At this point we have a topmost frame that was allocated by the frame manager
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 // which contains the current method interpreted state. We trim this frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 // of excess java expression stack entries and then recurse.
a61af66fc99e Initial load
duke
parents:
diff changeset
1942
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 __ bind(call_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
1944
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 // stack points to next free location and not top element on expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 // method expects sp to be pointing to topmost element
a61af66fc99e Initial load
duke
parents:
diff changeset
1947
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 __ ld_ptr(STATE(_thread), G2_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 __ ld_ptr(STATE(_result._to_call._callee), G5_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
1950
a61af66fc99e Initial load
duke
parents:
diff changeset
1951
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 // SP already takes in to account the 2 extra words we use for slop
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 // when we call a "static long no_params()" method. So if
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 // we trim back sp by the amount of unused java expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 // there will be automagically the 2 extra words we need.
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 // We also have to worry about keeping SP aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
1957
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 __ ld_ptr(STATE(_stack), Gargs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 __ ld_ptr(STATE(_stack_limit), L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1960
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 // compute the unused java stack size
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 __ sub(Gargs, L1_scratch, L2_scratch); // compute unused space
a61af66fc99e Initial load
duke
parents:
diff changeset
1963
123
9e5a7340635e 6688137: c++ interpreter fails on 64bit sparc
sgoldman
parents: 0
diff changeset
1964 // Round down the unused space to that stack is always 16-byte aligned
9e5a7340635e 6688137: c++ interpreter fails on 64bit sparc
sgoldman
parents: 0
diff changeset
1965 // by making the unused space a multiple of the size of two longs.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1966
123
9e5a7340635e 6688137: c++ interpreter fails on 64bit sparc
sgoldman
parents: 0
diff changeset
1967 __ and3(L2_scratch, -2*BytesPerLong, L2_scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1968
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 // Now trim the stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 __ add(SP, L2_scratch, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
1971
a61af66fc99e Initial load
duke
parents:
diff changeset
1972
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 // Now point to the final argument (account for prepush)
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 __ add(Gargs, wordSize, Gargs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 // Make sure we have space for the window
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 __ sub(Gargs, SP, L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 __ cmp(L1_scratch, 16*wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 Label skip;
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 __ brx(Assembler::greaterEqual, false, Assembler::pt, skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 __ stop("killed stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 __ bind(skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1987
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 // Create a new frame where we can store values that make it look like the interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 // really recursed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1990
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 // prepare to recurse or call specialized entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1992
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 // First link the registers we need
a61af66fc99e Initial load
duke
parents:
diff changeset
1994
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 // make the pc look good in debugger
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 __ set(CAST_FROM_FN_PTR(intptr_t, RecursiveInterpreterActivation), O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 // argument too
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 __ mov(Lstate, I0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1999
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 // Record our sending SP
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 __ mov(SP, O5_savedSP);
a61af66fc99e Initial load
duke
parents:
diff changeset
2002
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 __ ld_ptr(STATE(_result._to_call._callee_entry_point), L2_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 __ set((intptr_t) entry_point, L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 __ cmp(L1_scratch, L2_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 __ brx(Assembler::equal, false, Assembler::pt, re_dispatch);
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 __ delayed()->mov(Lstate, prevState); // link activations
a61af66fc99e Initial load
duke
parents:
diff changeset
2008
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 // method uses specialized entry, push a return so we look like call stub setup
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 // this path will handle fact that result is returned in registers and not
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 // on the java stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
2012
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 __ set((intptr_t)return_from_native_method - 8, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 __ jmpl(L2_scratch, G0, G0); // Do specialized entry
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2016
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 // Bad Message from interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 __ bind(bad_msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 __ stop("Bad message from interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
2022
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 // Interpreted method "returned" with an exception pass it on...
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 // Pass result, unwind activation and continue/return to interpreter/call_stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 // We handle result (if any) differently based on return to interpreter or call_stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2026
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 __ bind(throw_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 __ ld_ptr(STATE(_prev_link), L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 __ tst(L1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 __ brx(Assembler::zero, false, Assembler::pt, unwind_and_forward);
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2032
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
2033 __ ld_ptr(STATE(_locals), O1); // get result of popping callee's args
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3369
diff changeset
2034 __ ba(unwind_recursive_activation);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2036
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 interpreter_frame_manager = entry_point;
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 return entry_point;
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2040
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 InterpreterGenerator::InterpreterGenerator(StubQueue* code)
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 : CppInterpreterGenerator(code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 generate_all(); // down here so it can be "virtual"
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2045
a61af66fc99e Initial load
duke
parents:
diff changeset
2046
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 static int size_activation_helper(int callee_extra_locals, int max_stack, int monitor_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2048
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 // Figure out the size of an interpreter frame (in words) given that we have a fully allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 // expression stack, the callee will have callee_extra_locals (so we can account for
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 // frame extension) and monitor_size for monitors. Basically we need to calculate
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 // this exactly like generate_fixed_frame/generate_compute_interpreter_state.
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 // The big complicating thing here is that we must ensure that the stack stays properly
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 // aligned. This would be even uglier if monitor size wasn't modulo what the stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 // needs to be aligned for). We are given that the sp (fp) is already aligned by
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 // the caller so we must ensure that it is properly aligned for our callee.
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 // Ths c++ interpreter always makes sure that we have a enough extra space on the
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 // stack at all times to deal with the "stack long no_params()" method issue. This
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 // is "slop_factor" here.
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 const int slop_factor = 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2064
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 const int fixed_size = sizeof(BytecodeInterpreter)/wordSize + // interpreter state object
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 frame::memory_parameter_word_sp_offset; // register save area + param window
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2067 const int extra_stack = 0; //6815692//Method::extra_stack_entries();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 return (round_to(max_stack +
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 196
diff changeset
2069 extra_stack +
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 slop_factor +
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 fixed_size +
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 monitor_size +
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2073 (callee_extra_locals * Interpreter::stackElementWords), WordsPerLong));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2074
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2076
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2077 int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2078
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 // See call_stub code
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 int call_stub_size = round_to(7 + frame::memory_parameter_word_sp_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 WordsPerLong); // 7 + register save area
a61af66fc99e Initial load
duke
parents:
diff changeset
2082
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 // Save space for one monitor to get into the interpreted method in case
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 // the method is synchronized
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 int monitor_size = method->is_synchronized() ?
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 1*frame::interpreter_frame_monitor_size() : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 return size_activation_helper(method->max_locals(), method->max_stack(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 monitor_size) + call_stub_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2090
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill,
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 frame* caller,
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 frame* current,
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2094 Method* method,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 intptr_t* locals,
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 intptr_t* stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 intptr_t* stack_base,
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 intptr_t* monitor_base,
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 intptr_t* frame_bottom,
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 bool is_top_frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 )
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 // What about any vtable?
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 to_fill->_thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 // This gets filled in later but make it something recognizable for now
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 to_fill->_bcp = method->code_base();
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 to_fill->_locals = locals;
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 to_fill->_constants = method->constants()->cache();
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 to_fill->_method = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 to_fill->_mdx = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 to_fill->_stack = stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 if (is_top_frame && JavaThread::current()->popframe_forcing_deopt_reexecution() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 to_fill->_msg = deopt_resume2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 to_fill->_msg = method_resume;
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 to_fill->_result._to_call._bcp_advance = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 to_fill->_result._to_call._callee_entry_point = NULL; // doesn't matter to anyone
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 to_fill->_result._to_call._callee = NULL; // doesn't matter to anyone
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 to_fill->_prev_link = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2122
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 // Fill in the registers for the frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2124
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 // Need to install _sender_sp. Actually not too hard in C++!
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 // When the skeletal frames are layed out we fill in a value
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 // for _sender_sp. That value is only correct for the oldest
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 // skeletal frame constructed (because there is only a single
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 // entry for "caller_adjustment". While the skeletal frames
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 // exist that is good enough. We correct that calculation
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 // here and get all the frames correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
2132
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 // to_fill->_sender_sp = locals - (method->size_of_parameters() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2134
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 *current->register_addr(Lstate) = (intptr_t) to_fill;
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 // skeletal already places a useful value here and this doesn't account
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 // for alignment so don't bother.
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 // *current->register_addr(I5_savedSP) = (intptr_t) locals - (method->size_of_parameters() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2139
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 if (caller->is_interpreted_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 interpreterState prev = caller->get_interpreterState();
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 to_fill->_prev_link = prev;
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 // Make the prev callee look proper
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 prev->_result._to_call._callee = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 if (*prev->_bcp == Bytecodes::_invokeinterface) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 prev->_result._to_call._bcp_advance = 5;
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 prev->_result._to_call._bcp_advance = 3;
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 to_fill->_oop_temp = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 to_fill->_stack_base = stack_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 // Need +1 here because stack_base points to the word just above the first expr stack entry
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 // and stack_limit is supposed to point to the word just below the last expr stack entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 // See generate_compute_interpreter_state.
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2156 int extra_stack = 0; //6815692//Method::extra_stack_entries();
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 196
diff changeset
2157 to_fill->_stack_limit = stack_base - (method->max_stack() + 1 + extra_stack);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 to_fill->_monitor_base = (BasicObjectLock*) monitor_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
2159
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 // sparc specific
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 to_fill->_frame_bottom = frame_bottom;
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 to_fill->_self_link = to_fill;
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 to_fill->_native_fresult = 123456.789;
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 to_fill->_native_lresult = CONST64(0xdeadcafedeafcafe);
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2168
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 void BytecodeInterpreter::pd_layout_interpreterState(interpreterState istate, address last_Java_pc, intptr_t* last_Java_fp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 istate->_last_Java_pc = (intptr_t*) last_Java_pc;
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2172
a61af66fc99e Initial load
duke
parents:
diff changeset
2173
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2174 int AbstractInterpreter::layout_activation(Method* method,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 int tempcount, // Number of slots on java expression stack in use
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 int popframe_extra_args,
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 int moncount, // Number of active monitors
3369
3d2ab563047a 7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents: 3252
diff changeset
2178 int caller_actual_parameters,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 int callee_param_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 int callee_locals_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 frame* caller,
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 frame* interpreter_frame,
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 bool is_top_frame) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2184
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 assert(popframe_extra_args == 0, "NEED TO FIX");
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 // NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state()
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 // does as far as allocating an interpreter frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 // If interpreter_frame!=NULL, set up the method, locals, and monitors.
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 // The frame interpreter_frame, if not NULL, is guaranteed to be the right size,
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 // as determined by a previous call to this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 // It is also guaranteed to be walkable even though it is in a skeletal state
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 // NOTE: return size is in words not bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 // NOTE: tempcount is the current size of the java expression stack. For top most
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 // frames we will allocate a full sized expression stack and not the curback
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 // version that non-top frames have.
a61af66fc99e Initial load
duke
parents:
diff changeset
2196
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 // Calculate the amount our frame will be adjust by the callee. For top frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 // this is zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
2199
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 // NOTE: ia64 seems to do this wrong (or at least backwards) in that it
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 // calculates the extra locals based on itself. Not what the callee does
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 // to it. So it ignores last_frame_adjust value. Seems suspicious as far
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 // as getting sender_sp correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
2204
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 int extra_locals_size = callee_locals_size - callee_param_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 int monitor_size = (sizeof(BasicObjectLock) * moncount) / wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 int full_frame_words = size_activation_helper(extra_locals_size, method->max_stack(), monitor_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 int short_frame_words = size_activation_helper(extra_locals_size, method->max_stack(), monitor_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 int frame_words = is_top_frame ? full_frame_words : short_frame_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
2210
a61af66fc99e Initial load
duke
parents:
diff changeset
2211
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 if we actually have a frame to layout we must now fill in all the pieces. This means both
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 the interpreterState and the registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 */
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 if (interpreter_frame != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2217
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 // MUCHO HACK
a61af66fc99e Initial load
duke
parents:
diff changeset
2219
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 intptr_t* frame_bottom = interpreter_frame->sp() - (full_frame_words - frame_words);
123
9e5a7340635e 6688137: c++ interpreter fails on 64bit sparc
sgoldman
parents: 0
diff changeset
2221 // 'interpreter_frame->sp()' is unbiased while 'frame_bottom' must be a biased value in 64bit mode.
9e5a7340635e 6688137: c++ interpreter fails on 64bit sparc
sgoldman
parents: 0
diff changeset
2222 assert(((intptr_t)frame_bottom & 0xf) == 0, "SP biased in layout_activation");
9e5a7340635e 6688137: c++ interpreter fails on 64bit sparc
sgoldman
parents: 0
diff changeset
2223 frame_bottom = (intptr_t*)((intptr_t)frame_bottom - STACK_BIAS);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2224
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 /* Now fillin the interpreterState object */
a61af66fc99e Initial load
duke
parents:
diff changeset
2226
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 interpreterState cur_state = (interpreterState) ((intptr_t)interpreter_frame->fp() - sizeof(BytecodeInterpreter));
a61af66fc99e Initial load
duke
parents:
diff changeset
2228
a61af66fc99e Initial load
duke
parents:
diff changeset
2229
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 intptr_t* locals;
a61af66fc99e Initial load
duke
parents:
diff changeset
2231
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 // Calculate the postion of locals[0]. This is painful because of
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 // stack alignment (same as ia64). The problem is that we can
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 // not compute the location of locals from fp(). fp() will account
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 // for the extra locals but it also accounts for aligning the stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 // and we can't determine if the locals[0] was misaligned but max_locals
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 // was enough to have the
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 // calculate postion of locals. fp already accounts for extra locals.
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 // +2 for the static long no_params() issue.
a61af66fc99e Initial load
duke
parents:
diff changeset
2240
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 if (caller->is_interpreted_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 // locals must agree with the caller because it will be used to set the
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 // caller's tos when we return.
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 interpreterState prev = caller->get_interpreterState();
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 // stack() is prepushed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 locals = prev->stack() + method->size_of_parameters();
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 // Lay out locals block in the caller adjacent to the register window save area.
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 // Compiled frames do not allocate a varargs area which is why this if
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 // statement is needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 intptr_t* fp = interpreter_frame->fp();
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2254 int local_words = method->max_locals() * Interpreter::stackElementWords;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2255
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 if (caller->is_compiled_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 locals = fp + frame::register_save_words + local_words - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 locals = fp + frame::memory_parameter_word_sp_offset + local_words - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2261
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 // END MUCHO HACK
a61af66fc99e Initial load
duke
parents:
diff changeset
2264
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 intptr_t* monitor_base = (intptr_t*) cur_state;
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 intptr_t* stack_base = monitor_base - monitor_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 /* +1 because stack is always prepushed */
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 intptr_t* stack = stack_base - (tempcount + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2269
a61af66fc99e Initial load
duke
parents:
diff changeset
2270
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 BytecodeInterpreter::layout_interpreterState(cur_state,
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 caller,
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 interpreter_frame,
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 method,
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 locals,
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 stack_base,
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 monitor_base,
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 frame_bottom,
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 is_top_frame);
a61af66fc99e Initial load
duke
parents:
diff changeset
2281
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address, interpreter_frame->fp());
a61af66fc99e Initial load
duke
parents:
diff changeset
2283
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 return frame_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2287
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 #endif // CC_INTERP