annotate src/cpu/x86/vm/cppInterpreter_x86.cpp @ 20504:6948da6d7c13

8052172: Evacuation failure handling in G1 does not evacuate all objects if -XX:-G1DeferredRSUpdate is set Summary: Remove -XX:-G1DeferredRSUpdate functionality as it is racy. During evacuation failure handling, threads where evacuation failure handling occurred may try to add remembered sets to regions which remembered sets are currently being scanned. The iterator to handle the remembered set scan does not support addition of entries during scan and so may skip valid references. Reviewed-by: iveresov, brutisso, mgerdin
author tschatzl
date Tue, 30 Sep 2014 09:44:36 +0200
parents 0bf37f737702
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
10105
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
2 * Copyright (c) 2007, 2013, 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"
7199
cd3d6a6b95d9 8003240: x86: move MacroAssembler into separate file
twisti
parents: 6740
diff changeset
26 #include "asm/macroAssembler.hpp"
1972
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"
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 7402
diff changeset
48 #include "utilities/macros.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
49 #ifdef SHARK
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
50 #include "shark/shark_globals.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
51 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53 #ifdef CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // Routine exists to make tracebacks look decent in debugger
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // while we are recursed in the frame manager/c++ interpreter.
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // We could use an address in the frame manager but having
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // frames look natural in the debugger is a plus.
a61af66fc99e Initial load
duke
parents:
diff changeset
59 extern "C" void RecursiveInterpreterActivation(interpreterState istate )
a61af66fc99e Initial load
duke
parents:
diff changeset
60 {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 //
a61af66fc99e Initial load
duke
parents:
diff changeset
62 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
63 }
a61af66fc99e Initial load
duke
parents:
diff changeset
64
a61af66fc99e Initial load
duke
parents:
diff changeset
65
a61af66fc99e Initial load
duke
parents:
diff changeset
66 #define __ _masm->
a61af66fc99e Initial load
duke
parents:
diff changeset
67 #define STATE(field_name) (Address(state, byte_offset_of(BytecodeInterpreter, field_name)))
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 Label fast_accessor_slow_entry_path; // fast accessor methods need to be able to jmp to unsynchronized
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // c++ interpreter entry point this holds that entry point label.
a61af66fc99e Initial load
duke
parents:
diff changeset
71
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
72 // default registers for state and sender_sp
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
73 // state and sender_sp are the same on 32bit because we have no choice.
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
74 // state could be rsi on 64bit but it is an arg reg and not callee save
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
75 // so r13 is better choice.
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
76
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
77 const Register state = NOT_LP64(rsi) LP64_ONLY(r13);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
78 const Register sender_sp_on_entry = NOT_LP64(rsi) LP64_ONLY(r13);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
79
0
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // NEEDED for JVMTI?
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // address AbstractInterpreter::_remove_activation_preserving_args_entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 static address unctrap_frame_manager_entry = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 static address deopt_frame_manager_return_atos = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
86 static address deopt_frame_manager_return_btos = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
87 static address deopt_frame_manager_return_itos = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
88 static address deopt_frame_manager_return_ltos = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
89 static address deopt_frame_manager_return_ftos = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
90 static address deopt_frame_manager_return_dtos = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
91 static address deopt_frame_manager_return_vtos = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 int AbstractInterpreter::BasicType_as_index(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
94 int i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
95 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
96 case T_BOOLEAN: i = 0; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
97 case T_CHAR : i = 1; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
98 case T_BYTE : i = 2; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
99 case T_SHORT : i = 3; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
100 case T_INT : i = 4; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
101 case T_VOID : i = 5; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
102 case T_FLOAT : i = 8; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
103 case T_LONG : i = 9; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 case T_DOUBLE : i = 6; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
105 case T_OBJECT : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
106 case T_ARRAY : i = 7; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
107 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
109 assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, "index out of bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
110 return i;
a61af66fc99e Initial load
duke
parents:
diff changeset
111 }
a61af66fc99e Initial load
duke
parents:
diff changeset
112
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // Is this pc anywhere within code owned by the interpreter?
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // This only works for pc that might possibly be exposed to frame
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // walkers. It clearly misses all of the actual c++ interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // implementation
a61af66fc99e Initial load
duke
parents:
diff changeset
117 bool CppInterpreter::contains(address pc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 return (_code->contains(pc) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
119 pc == CAST_FROM_FN_PTR(address, RecursiveInterpreterActivation));
a61af66fc99e Initial load
duke
parents:
diff changeset
120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122
a61af66fc99e Initial load
duke
parents:
diff changeset
123 address CppInterpreterGenerator::generate_result_handler_for(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 address entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
125 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
126 case T_BOOLEAN: __ c2bool(rax); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
127 case T_CHAR : __ andl(rax, 0xFFFF); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
128 case T_BYTE : __ sign_extend_byte (rax); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
129 case T_SHORT : __ sign_extend_short(rax); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
130 case T_VOID : // fall thru
a61af66fc99e Initial load
duke
parents:
diff changeset
131 case T_LONG : // fall thru
a61af66fc99e Initial load
duke
parents:
diff changeset
132 case T_INT : /* nothing to do */ break;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
133
0
a61af66fc99e Initial load
duke
parents:
diff changeset
134 case T_DOUBLE :
a61af66fc99e Initial load
duke
parents:
diff changeset
135 case T_FLOAT :
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
136 {
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
137 const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
138 __ pop(t); // remove return address first
0
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // Must return a result for interpreter or compiler. In SSE
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // mode, results are returned in xmm0 and the FPU stack must
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // be empty.
a61af66fc99e Initial load
duke
parents:
diff changeset
142 if (type == T_FLOAT && UseSSE >= 1) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
143 #ifndef _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // Load ST0
a61af66fc99e Initial load
duke
parents:
diff changeset
145 __ fld_d(Address(rsp, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // Store as float and empty fpu stack
a61af66fc99e Initial load
duke
parents:
diff changeset
147 __ fstp_s(Address(rsp, 0));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
148 #endif // !_LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // and reload
a61af66fc99e Initial load
duke
parents:
diff changeset
150 __ movflt(xmm0, Address(rsp, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
151 } else if (type == T_DOUBLE && UseSSE >= 2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
152 __ movdbl(xmm0, Address(rsp, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
153 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // restore ST0
a61af66fc99e Initial load
duke
parents:
diff changeset
155 __ fld_d(Address(rsp, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // and pop the temp
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
158 __ addptr(rsp, 2 * wordSize);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
159 __ push(t); // restore return address
0
a61af66fc99e Initial load
duke
parents:
diff changeset
160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
161 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
162 case T_OBJECT :
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // retrieve result from frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
164 __ movptr(rax, STATE(_oop_temp));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // and verify it
a61af66fc99e Initial load
duke
parents:
diff changeset
166 __ verify_oop(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
167 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
169 }
a61af66fc99e Initial load
duke
parents:
diff changeset
170 __ ret(0); // return from result handler
a61af66fc99e Initial load
duke
parents:
diff changeset
171 return entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
173
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // tosca based result to c++ interpreter stack based result.
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // Result goes to top of native stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
176
a61af66fc99e Initial load
duke
parents:
diff changeset
177 #undef EXTEND // SHOULD NOT BE NEEDED
a61af66fc99e Initial load
duke
parents:
diff changeset
178 address CppInterpreterGenerator::generate_tosca_to_stack_converter(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // A result is in the tosca (abi result) from either a native method call or compiled
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // code. Place this result on the java expression stack so C++ interpreter can use it.
a61af66fc99e Initial load
duke
parents:
diff changeset
181 address entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
182
a61af66fc99e Initial load
duke
parents:
diff changeset
183 const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
184 __ pop(t); // remove return address first
0
a61af66fc99e Initial load
duke
parents:
diff changeset
185 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
186 case T_VOID:
a61af66fc99e Initial load
duke
parents:
diff changeset
187 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
188 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
189 #ifdef EXTEND
a61af66fc99e Initial load
duke
parents:
diff changeset
190 __ c2bool(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
191 #endif
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
192 __ push(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
193 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
194 case T_CHAR :
a61af66fc99e Initial load
duke
parents:
diff changeset
195 #ifdef EXTEND
a61af66fc99e Initial load
duke
parents:
diff changeset
196 __ andl(rax, 0xFFFF);
a61af66fc99e Initial load
duke
parents:
diff changeset
197 #endif
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
198 __ push(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
199 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
200 case T_BYTE :
a61af66fc99e Initial load
duke
parents:
diff changeset
201 #ifdef EXTEND
a61af66fc99e Initial load
duke
parents:
diff changeset
202 __ sign_extend_byte (rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
203 #endif
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
204 __ push(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
205 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
206 case T_SHORT :
a61af66fc99e Initial load
duke
parents:
diff changeset
207 #ifdef EXTEND
a61af66fc99e Initial load
duke
parents:
diff changeset
208 __ sign_extend_short(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
209 #endif
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
210 __ push(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
211 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
212 case T_LONG :
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
213 __ push(rdx); // pushes useless junk on 64bit
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
214 __ push(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
215 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 case T_INT :
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
217 __ push(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
218 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
219 case T_FLOAT :
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
220 // Result is in ST(0)/xmm0
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
221 __ subptr(rsp, wordSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
222 if ( UseSSE < 1) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
223 __ fstp_s(Address(rsp, 0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
224 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
225 __ movflt(Address(rsp, 0), xmm0);
a61af66fc99e Initial load
duke
parents:
diff changeset
226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
227 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
228 case T_DOUBLE :
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
229 __ subptr(rsp, 2*wordSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
230 if ( UseSSE < 2 ) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
231 __ fstp_d(Address(rsp, 0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
232 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
233 __ movdbl(Address(rsp, 0), xmm0);
a61af66fc99e Initial load
duke
parents:
diff changeset
234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
235 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
236 case T_OBJECT :
a61af66fc99e Initial load
duke
parents:
diff changeset
237 __ verify_oop(rax); // verify it
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
238 __ push(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
239 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
240 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
242 __ jmp(t); // return from result handler
a61af66fc99e Initial load
duke
parents:
diff changeset
243 return entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
245
a61af66fc99e Initial load
duke
parents:
diff changeset
246 address CppInterpreterGenerator::generate_stack_to_stack_converter(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
247 // A result is in the java expression stack of the interpreted method that has just
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // returned. Place this result on the java expression stack of the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
249 //
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
250 // The current interpreter activation in rsi/r13 is for the method just returning its
0
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // result. So we know that the result of this method is on the top of the current
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // execution stack (which is pre-pushed) and will be return to the top of the caller
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // stack. The top of the callers stack is the bottom of the locals of the current
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // activation.
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // Because of the way activation are managed by the frame manager the value of rsp is
a61af66fc99e Initial load
duke
parents:
diff changeset
256 // below both the stack top of the current activation and naturally the stack top
a61af66fc99e Initial load
duke
parents:
diff changeset
257 // of the calling activation. This enable this routine to leave the return address
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // to the frame manager on the stack and do a vanilla return.
a61af66fc99e Initial load
duke
parents:
diff changeset
259 //
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
260 // On entry: rsi/r13 - interpreter state of activation returning a (potential) result
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
261 // On Return: rsi/r13 - unchanged
0
a61af66fc99e Initial load
duke
parents:
diff changeset
262 // rax - new stack top for caller activation (i.e. activation in _prev_link)
a61af66fc99e Initial load
duke
parents:
diff changeset
263 //
a61af66fc99e Initial load
duke
parents:
diff changeset
264 // Can destroy rdx, rcx.
a61af66fc99e Initial load
duke
parents:
diff changeset
265 //
a61af66fc99e Initial load
duke
parents:
diff changeset
266
a61af66fc99e Initial load
duke
parents:
diff changeset
267 address entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
268 const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp();
a61af66fc99e Initial load
duke
parents:
diff changeset
269 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
270 case T_VOID:
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
271 __ movptr(rax, STATE(_locals)); // pop parameters get new stack value
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
272 __ addptr(rax, wordSize); // account for prepush before we return
0
a61af66fc99e Initial load
duke
parents:
diff changeset
273 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
274 case T_FLOAT :
a61af66fc99e Initial load
duke
parents:
diff changeset
275 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
276 case T_CHAR :
a61af66fc99e Initial load
duke
parents:
diff changeset
277 case T_BYTE :
a61af66fc99e Initial load
duke
parents:
diff changeset
278 case T_SHORT :
a61af66fc99e Initial load
duke
parents:
diff changeset
279 case T_INT :
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // 1 word result
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
281 __ movptr(rdx, STATE(_stack));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
282 __ movptr(rax, STATE(_locals)); // address for result
0
a61af66fc99e Initial load
duke
parents:
diff changeset
283 __ movl(rdx, Address(rdx, wordSize)); // get result
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
284 __ movptr(Address(rax, 0), rdx); // and store it
0
a61af66fc99e Initial load
duke
parents:
diff changeset
285 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
286 case T_LONG :
a61af66fc99e Initial load
duke
parents:
diff changeset
287 case T_DOUBLE :
a61af66fc99e Initial load
duke
parents:
diff changeset
288 // return top two words on current expression stack to caller's expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
289 // The caller's expression stack is adjacent to the current frame manager's intepretState
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // except we allocated one extra word for this intepretState so we won't overwrite it
a61af66fc99e Initial load
duke
parents:
diff changeset
291 // when we return a two word result.
a61af66fc99e Initial load
duke
parents:
diff changeset
292
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
293 __ movptr(rax, STATE(_locals)); // address for result
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
294 __ movptr(rcx, STATE(_stack));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
295 __ subptr(rax, wordSize); // need addition word besides locals[0]
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
296 __ movptr(rdx, Address(rcx, 2*wordSize)); // get result word (junk in 64bit)
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
297 __ movptr(Address(rax, wordSize), rdx); // and store it
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
298 __ movptr(rdx, Address(rcx, wordSize)); // get result word
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
299 __ movptr(Address(rax, 0), rdx); // and store it
0
a61af66fc99e Initial load
duke
parents:
diff changeset
300 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
301 case T_OBJECT :
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
302 __ movptr(rdx, STATE(_stack));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
303 __ movptr(rax, STATE(_locals)); // address for result
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
304 __ movptr(rdx, Address(rdx, wordSize)); // get result
0
a61af66fc99e Initial load
duke
parents:
diff changeset
305 __ verify_oop(rdx); // verify it
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
306 __ movptr(Address(rax, 0), rdx); // and store it
0
a61af66fc99e Initial load
duke
parents:
diff changeset
307 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
308 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
310 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
311 return entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
313
a61af66fc99e Initial load
duke
parents:
diff changeset
314 address CppInterpreterGenerator::generate_stack_to_native_abi_converter(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // A result is in the java expression stack of the interpreted method that has just
a61af66fc99e Initial load
duke
parents:
diff changeset
316 // returned. Place this result in the native abi that the caller expects.
a61af66fc99e Initial load
duke
parents:
diff changeset
317 //
a61af66fc99e Initial load
duke
parents:
diff changeset
318 // Similar to generate_stack_to_stack_converter above. Called at a similar time from the
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // frame manager execept in this situation the caller is native code (c1/c2/call_stub)
a61af66fc99e Initial load
duke
parents:
diff changeset
320 // and so rather than return result onto caller's java expression stack we return the
a61af66fc99e Initial load
duke
parents:
diff changeset
321 // result in the expected location based on the native abi.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
322 // On entry: rsi/r13 - interpreter state of activation returning a (potential) result
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
323 // On Return: rsi/r13 - unchanged
0
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // Other registers changed [rax/rdx/ST(0) as needed for the result returned]
a61af66fc99e Initial load
duke
parents:
diff changeset
325
a61af66fc99e Initial load
duke
parents:
diff changeset
326 address entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
327 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
328 case T_VOID:
a61af66fc99e Initial load
duke
parents:
diff changeset
329 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
330 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
331 case T_CHAR :
a61af66fc99e Initial load
duke
parents:
diff changeset
332 case T_BYTE :
a61af66fc99e Initial load
duke
parents:
diff changeset
333 case T_SHORT :
a61af66fc99e Initial load
duke
parents:
diff changeset
334 case T_INT :
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
335 __ movptr(rdx, STATE(_stack)); // get top of stack
0
a61af66fc99e Initial load
duke
parents:
diff changeset
336 __ movl(rax, Address(rdx, wordSize)); // get result word 1
a61af66fc99e Initial load
duke
parents:
diff changeset
337 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
338 case T_LONG :
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
339 __ movptr(rdx, STATE(_stack)); // get top of stack
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
340 __ movptr(rax, Address(rdx, wordSize)); // get result low word
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
341 NOT_LP64(__ movl(rdx, Address(rdx, 2*wordSize));) // get result high word
0
a61af66fc99e Initial load
duke
parents:
diff changeset
342 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
343 case T_FLOAT :
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
344 __ movptr(rdx, STATE(_stack)); // get top of stack
0
a61af66fc99e Initial load
duke
parents:
diff changeset
345 if ( UseSSE >= 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
346 __ movflt(xmm0, Address(rdx, wordSize));
a61af66fc99e Initial load
duke
parents:
diff changeset
347 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
348 __ fld_s(Address(rdx, wordSize)); // pushd float result
a61af66fc99e Initial load
duke
parents:
diff changeset
349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
350 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
351 case T_DOUBLE :
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
352 __ movptr(rdx, STATE(_stack)); // get top of stack
0
a61af66fc99e Initial load
duke
parents:
diff changeset
353 if ( UseSSE > 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
354 __ movdbl(xmm0, Address(rdx, wordSize));
a61af66fc99e Initial load
duke
parents:
diff changeset
355 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
356 __ fld_d(Address(rdx, wordSize)); // push double result
a61af66fc99e Initial load
duke
parents:
diff changeset
357 }
a61af66fc99e Initial load
duke
parents:
diff changeset
358 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
359 case T_OBJECT :
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
360 __ movptr(rdx, STATE(_stack)); // get top of stack
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
361 __ movptr(rax, Address(rdx, wordSize)); // get result word 1
0
a61af66fc99e Initial load
duke
parents:
diff changeset
362 __ verify_oop(rax); // verify it
a61af66fc99e Initial load
duke
parents:
diff changeset
363 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
364 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
366 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
367 return entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
369
13010
bd3237e0e18d 8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents: 10393
diff changeset
370 address CppInterpreter::return_entry(TosState state, int length, Bytecodes::Code code) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
371 // make it look good in the debugger
a61af66fc99e Initial load
duke
parents:
diff changeset
372 return CAST_FROM_FN_PTR(address, RecursiveInterpreterActivation);
a61af66fc99e Initial load
duke
parents:
diff changeset
373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
374
a61af66fc99e Initial load
duke
parents:
diff changeset
375 address CppInterpreter::deopt_entry(TosState state, int length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
376 address ret = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
377 if (length != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
378 switch (state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 case atos: ret = deopt_frame_manager_return_atos; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
380 case btos: ret = deopt_frame_manager_return_btos; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
381 case ctos:
a61af66fc99e Initial load
duke
parents:
diff changeset
382 case stos:
a61af66fc99e Initial load
duke
parents:
diff changeset
383 case itos: ret = deopt_frame_manager_return_itos; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
384 case ltos: ret = deopt_frame_manager_return_ltos; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
385 case ftos: ret = deopt_frame_manager_return_ftos; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
386 case dtos: ret = deopt_frame_manager_return_dtos; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
387 case vtos: ret = deopt_frame_manager_return_vtos; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
390 ret = unctrap_frame_manager_entry; // re-execute the bytecode ( e.g. uncommon trap)
a61af66fc99e Initial load
duke
parents:
diff changeset
391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
392 assert(ret != NULL, "Not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
393 return ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
395
a61af66fc99e Initial load
duke
parents:
diff changeset
396 // C++ Interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
397 void CppInterpreterGenerator::generate_compute_interpreter_state(const Register state,
a61af66fc99e Initial load
duke
parents:
diff changeset
398 const Register locals,
a61af66fc99e Initial load
duke
parents:
diff changeset
399 const Register sender_sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
400 bool native) {
a61af66fc99e Initial load
duke
parents:
diff changeset
401
a61af66fc99e Initial load
duke
parents:
diff changeset
402 // On entry the "locals" argument points to locals[0] (or where it would be in case no locals in
a61af66fc99e Initial load
duke
parents:
diff changeset
403 // a static method). "state" contains any previous frame manager state which we must save a link
a61af66fc99e Initial load
duke
parents:
diff changeset
404 // to in the newly generated state object. On return "state" is a pointer to the newly allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // state object. We must allocate and initialize a new interpretState object and the method
a61af66fc99e Initial load
duke
parents:
diff changeset
406 // expression stack. Because the returned result (if any) of the method will be placed on the caller's
a61af66fc99e Initial load
duke
parents:
diff changeset
407 // expression stack and this will overlap with locals[0] (and locals[1] if double/long) we must
a61af66fc99e Initial load
duke
parents:
diff changeset
408 // be sure to leave space on the caller's stack so that this result will not overwrite values when
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // locals[0] and locals[1] do not exist (and in fact are return address and saved rbp). So when
a61af66fc99e Initial load
duke
parents:
diff changeset
410 // we are non-native we in essence ensure that locals[0-1] exist. We play an extra trick in
a61af66fc99e Initial load
duke
parents:
diff changeset
411 // non-product builds and initialize this last local with the previous interpreterState as
a61af66fc99e Initial load
duke
parents:
diff changeset
412 // this makes things look real nice in the debugger.
a61af66fc99e Initial load
duke
parents:
diff changeset
413
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // State on entry
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // Assumes locals == &locals[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // Assumes state == any previous frame manager state (assuming call path from c++ interpreter)
a61af66fc99e Initial load
duke
parents:
diff changeset
417 // Assumes rax = return address
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // rcx == senders_sp
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // rbx == method
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // Modifies rcx, rdx, rax
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // Returns:
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // state == address of new interpreterState
a61af66fc99e Initial load
duke
parents:
diff changeset
423 // rsp == bottom of method's expression stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
424
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
425 const Address const_offset (rbx, Method::const_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
426
a61af66fc99e Initial load
duke
parents:
diff changeset
427
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // On entry sp is the sender's sp. This includes the space for the arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
429 // that the sender pushed. If the sender pushed no args (a static) and the
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // caller returns a long then we need two words on the sender's stack which
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // are not present (although when we return a restore full size stack the
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // space will be present). If we didn't allocate two words here then when
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // we "push" the result of the caller's stack we would overwrite the return
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // address and the saved rbp. Not good. So simply allocate 2 words now
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // just to be safe. This is the "static long no_params() method" issue.
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // See Lo.java for a testcase.
a61af66fc99e Initial load
duke
parents:
diff changeset
437 // We don't need this for native calls because they return result in
a61af66fc99e Initial load
duke
parents:
diff changeset
438 // register and the stack is expanded in the caller before we store
a61af66fc99e Initial load
duke
parents:
diff changeset
439 // the results on the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
440
a61af66fc99e Initial load
duke
parents:
diff changeset
441 if (!native) {
a61af66fc99e Initial load
duke
parents:
diff changeset
442 #ifdef PRODUCT
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
443 __ subptr(rsp, 2*wordSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
444 #else /* PRODUCT */
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
445 __ push((int32_t)NULL_WORD);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
446 __ push(state); // make it look like a real argument
0
a61af66fc99e Initial load
duke
parents:
diff changeset
447 #endif /* PRODUCT */
a61af66fc99e Initial load
duke
parents:
diff changeset
448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
449
a61af66fc99e Initial load
duke
parents:
diff changeset
450 // Now that we are assure of space for stack result, setup typical linkage
a61af66fc99e Initial load
duke
parents:
diff changeset
451
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
452 __ push(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
453 __ enter();
a61af66fc99e Initial load
duke
parents:
diff changeset
454
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
455 __ mov(rax, state); // save current state
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
456
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
457 __ lea(rsp, Address(rsp, -(int)sizeof(BytecodeInterpreter)));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
458 __ mov(state, rsp);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
459
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
460 // rsi/r13 == state/locals rax == prevstate
0
a61af66fc99e Initial load
duke
parents:
diff changeset
461
a61af66fc99e Initial load
duke
parents:
diff changeset
462 // initialize the "shadow" frame so that use since C++ interpreter not directly
a61af66fc99e Initial load
duke
parents:
diff changeset
463 // recursive. Simpler to recurse but we can't trim expression stack as we call
a61af66fc99e Initial load
duke
parents:
diff changeset
464 // new methods.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
465 __ movptr(STATE(_locals), locals); // state->_locals = locals()
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
466 __ movptr(STATE(_self_link), state); // point to self
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
467 __ movptr(STATE(_prev_link), rax); // state->_link = state on entry (NULL or previous state)
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
468 __ movptr(STATE(_sender_sp), sender_sp); // state->_sender_sp = sender_sp
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
469 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
470 __ movptr(STATE(_thread), r15_thread); // state->_bcp = codes()
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
471 #else
0
a61af66fc99e Initial load
duke
parents:
diff changeset
472 __ get_thread(rax); // get vm's javathread*
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
473 __ movptr(STATE(_thread), rax); // state->_bcp = codes()
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
474 #endif // _LP64
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
475 __ movptr(rdx, Address(rbx, Method::const_offset())); // get constantMethodOop
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
476 __ lea(rdx, Address(rdx, ConstMethod::codes_offset())); // get code base
0
a61af66fc99e Initial load
duke
parents:
diff changeset
477 if (native) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
478 __ movptr(STATE(_bcp), (int32_t)NULL_WORD); // state->_bcp = NULL
0
a61af66fc99e Initial load
duke
parents:
diff changeset
479 } else {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
480 __ movptr(STATE(_bcp), rdx); // state->_bcp = codes()
0
a61af66fc99e Initial load
duke
parents:
diff changeset
481 }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
482 __ xorptr(rdx, rdx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
483 __ movptr(STATE(_oop_temp), rdx); // state->_oop_temp = NULL (only really needed for native)
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
484 __ movptr(STATE(_mdx), rdx); // state->_mdx = NULL
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
485 __ movptr(rdx, Address(rbx, Method::const_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
486 __ movptr(rdx, Address(rdx, ConstMethod::constants_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
487 __ movptr(rdx, Address(rdx, ConstantPool::cache_offset_in_bytes()));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
488 __ movptr(STATE(_constants), rdx); // state->_constants = constants()
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
489
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
490 __ movptr(STATE(_method), rbx); // state->_method = method()
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
491 __ movl(STATE(_msg), (int32_t) BytecodeInterpreter::method_entry); // state->_msg = initial method entry
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
492 __ movptr(STATE(_result._to_call._callee), (int32_t) NULL_WORD); // state->_result._to_call._callee_callee = NULL
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
493
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
494
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
495 __ movptr(STATE(_monitor_base), rsp); // set monitor block bottom (grows down) this would point to entry [0]
0
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // entries run from -1..x where &monitor[x] ==
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498 {
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // Must not attempt to lock method until we enter interpreter as gc won't be able to find the
a61af66fc99e Initial load
duke
parents:
diff changeset
500 // initial frame. However we allocate a free monitor so we don't have to shuffle the expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
501 // immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
502
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // synchronize method
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
504 const Address access_flags (rbx, Method::access_flags_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
505 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
506 Label not_synced;
a61af66fc99e Initial load
duke
parents:
diff changeset
507
a61af66fc99e Initial load
duke
parents:
diff changeset
508 __ movl(rax, access_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
509 __ testl(rax, JVM_ACC_SYNCHRONIZED);
a61af66fc99e Initial load
duke
parents:
diff changeset
510 __ jcc(Assembler::zero, not_synced);
a61af66fc99e Initial load
duke
parents:
diff changeset
511
a61af66fc99e Initial load
duke
parents:
diff changeset
512 // Allocate initial monitor and pre initialize it
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // get synchronization object
a61af66fc99e Initial load
duke
parents:
diff changeset
514
a61af66fc99e Initial load
duke
parents:
diff changeset
515 Label done;
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3369
diff changeset
516 const int mirror_offset = in_bytes(Klass::java_mirror_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
517 __ movl(rax, access_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
518 __ testl(rax, JVM_ACC_STATIC);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
519 __ movptr(rax, Address(locals, 0)); // get receiver (assume this is frequent case)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
520 __ jcc(Assembler::zero, done);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
521 __ movptr(rax, Address(rbx, Method::const_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
522 __ movptr(rax, Address(rax, ConstMethod::constants_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
523 __ movptr(rax, Address(rax, ConstantPool::pool_holder_offset_in_bytes()));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
524 __ movptr(rax, Address(rax, mirror_offset));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
525 __ bind(done);
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // add space for monitor & lock
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
527 __ subptr(rsp, entry_size); // add space for a monitor entry
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
528 __ movptr(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); // store object
0
a61af66fc99e Initial load
duke
parents:
diff changeset
529 __ bind(not_synced);
a61af66fc99e Initial load
duke
parents:
diff changeset
530 }
a61af66fc99e Initial load
duke
parents:
diff changeset
531
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
532 __ movptr(STATE(_stack_base), rsp); // set expression stack base ( == &monitors[-count])
0
a61af66fc99e Initial load
duke
parents:
diff changeset
533 if (native) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
534 __ movptr(STATE(_stack), rsp); // set current expression stack tos
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
535 __ movptr(STATE(_stack_limit), rsp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
536 } else {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
537 __ subptr(rsp, wordSize); // pre-push stack
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
538 __ movptr(STATE(_stack), rsp); // set current expression stack tos
0
a61af66fc99e Initial load
duke
parents:
diff changeset
539
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // compute full expression stack limit
a61af66fc99e Initial load
duke
parents:
diff changeset
541
7183
b2dbd323c668 8003848: Make ConstMethod::generic_signature_index optional and move Method::_max_stack to ConstMethod.
jiangli
parents: 6740
diff changeset
542 __ movptr(rdx, Address(rbx, Method::const_offset()));
b2dbd323c668 8003848: Make ConstMethod::generic_signature_index optional and move Method::_max_stack to ConstMethod.
jiangli
parents: 6740
diff changeset
543 __ load_unsigned_short(rdx, Address(rdx, ConstMethod::max_stack_offset())); // get size of expression stack in words
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
544 __ negptr(rdx); // so we can subtract in next step
0
a61af66fc99e Initial load
duke
parents:
diff changeset
545 // Allocate expression stack
10393
603ca7e51354 8010460: Interpreter on some platforms loads ConstMethod::_max_stack and misses extra stack slots for JSR 292
roland
parents: 10105
diff changeset
546 __ lea(rsp, Address(rsp, rdx, Address::times_ptr, -Method::extra_stack_words()));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
547 __ movptr(STATE(_stack_limit), rsp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
549
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
550 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
551 // Make sure stack is properly aligned and sized for the abi
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
552 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows
605
98cb887364d3 6810672: Comment typos
twisti
parents: 520
diff changeset
553 __ andptr(rsp, -16); // must be 16 byte boundary (see amd64 ABI)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
554 #endif // _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
555
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
556
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
557
0
a61af66fc99e Initial load
duke
parents:
diff changeset
558 }
a61af66fc99e Initial load
duke
parents:
diff changeset
559
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // Helpers for commoning out cases in the various type of method entries.
a61af66fc99e Initial load
duke
parents:
diff changeset
561 //
a61af66fc99e Initial load
duke
parents:
diff changeset
562
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // increment invocation count & check for overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
564 //
a61af66fc99e Initial load
duke
parents:
diff changeset
565 // Note: checking for negative value instead of overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // so we have a 'sticky' overflow test
a61af66fc99e Initial load
duke
parents:
diff changeset
567 //
a61af66fc99e Initial load
duke
parents:
diff changeset
568 // rbx,: method
a61af66fc99e Initial load
duke
parents:
diff changeset
569 // rcx: invocation counter
a61af66fc99e Initial load
duke
parents:
diff changeset
570 //
a61af66fc99e Initial load
duke
parents:
diff changeset
571 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) {
10105
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
572 Label done;
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
573 const Address invocation_counter(rax,
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
574 MethodCounters::invocation_counter_offset() +
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
575 InvocationCounter::counter_offset());
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
576 const Address backedge_counter (rax,
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
577 MethodCounter::backedge_counter_offset() +
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
578 InvocationCounter::counter_offset());
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
579
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
580 __ get_method_counters(rbx, rax, done);
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
581
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
582 if (ProfileInterpreter) {
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
583 __ incrementl(Address(rax,
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
584 MethodCounters::interpreter_invocation_counter_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
586 // Update standard invocation counters
10105
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
587 __ movl(rcx, invocation_counter);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
588 __ increment(rcx, InvocationCounter::count_increment);
10105
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
589 __ movl(invocation_counter, rcx); // save invocation count
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
590
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
591 __ movl(rax, backedge_counter); // load backedge counter
0
a61af66fc99e Initial load
duke
parents:
diff changeset
592 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits
a61af66fc99e Initial load
duke
parents:
diff changeset
593
a61af66fc99e Initial load
duke
parents:
diff changeset
594 __ addl(rcx, rax); // add both counters
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596 // profile_method is non-null only for interpreted method so
a61af66fc99e Initial load
duke
parents:
diff changeset
597 // profile_method != NULL == !native_call
a61af66fc99e Initial load
duke
parents:
diff changeset
598 // BytecodeInterpreter only calls for native so code is elided.
a61af66fc99e Initial load
duke
parents:
diff changeset
599
a61af66fc99e Initial load
duke
parents:
diff changeset
600 __ cmp32(rcx,
a61af66fc99e Initial load
duke
parents:
diff changeset
601 ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit));
a61af66fc99e Initial load
duke
parents:
diff changeset
602 __ jcc(Assembler::aboveEqual, *overflow);
10105
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8873
diff changeset
603 __ bind(done);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
605
a61af66fc99e Initial load
duke
parents:
diff changeset
606 void InterpreterGenerator::generate_counter_overflow(Label* do_continue) {
a61af66fc99e Initial load
duke
parents:
diff changeset
607
a61af66fc99e Initial load
duke
parents:
diff changeset
608 // C++ interpreter on entry
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
609 // rsi/r13 - new interpreter state pointer
0
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // rbp - interpreter frame pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
611 // rbx - method
a61af66fc99e Initial load
duke
parents:
diff changeset
612
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // On return (i.e. jump to entry_point) [ back to invocation of interpreter ]
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // rbx, - method
a61af66fc99e Initial load
duke
parents:
diff changeset
615 // rcx - rcvr (assuming there is one)
a61af66fc99e Initial load
duke
parents:
diff changeset
616 // top of stack return address of interpreter caller
a61af66fc99e Initial load
duke
parents:
diff changeset
617 // rsp - sender_sp
a61af66fc99e Initial load
duke
parents:
diff changeset
618
a61af66fc99e Initial load
duke
parents:
diff changeset
619 // C++ interpreter only
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
620 // rsi/r13 - previous interpreter state pointer
0
a61af66fc99e Initial load
duke
parents:
diff changeset
621
a61af66fc99e Initial load
duke
parents:
diff changeset
622 // InterpreterRuntime::frequency_counter_overflow takes one argument
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // indicating if the counter overflow occurs at a backwards branch (non-NULL bcp).
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // The call returns the address of the verified entry point for the method or NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // if the compilation did not complete (either went background or bailed out).
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
626 __ movptr(rax, (int32_t)false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
627 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
628
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // for c++ interpreter can rsi really be munged?
520
52a431267315 6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents: 337
diff changeset
630 __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); // restore state
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
631 __ movptr(rbx, Address(state, byte_offset_of(BytecodeInterpreter, _method))); // restore method
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
632 __ movptr(rdi, Address(state, byte_offset_of(BytecodeInterpreter, _locals))); // get locals pointer
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
633
0
a61af66fc99e Initial load
duke
parents:
diff changeset
634 __ jmp(*do_continue, relocInfo::none);
a61af66fc99e Initial load
duke
parents:
diff changeset
635
a61af66fc99e Initial load
duke
parents:
diff changeset
636 }
a61af66fc99e Initial load
duke
parents:
diff changeset
637
a61af66fc99e Initial load
duke
parents:
diff changeset
638 void InterpreterGenerator::generate_stack_overflow_check(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // see if we've got enough room on the stack for locals plus overhead.
a61af66fc99e Initial load
duke
parents:
diff changeset
640 // the expression stack grows down incrementally, so the normal guard
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // page mechanism will work for that.
a61af66fc99e Initial load
duke
parents:
diff changeset
642 //
a61af66fc99e Initial load
duke
parents:
diff changeset
643 // Registers live on entry:
a61af66fc99e Initial load
duke
parents:
diff changeset
644 //
a61af66fc99e Initial load
duke
parents:
diff changeset
645 // Asm interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
646 // rdx: number of additional locals this frame needs (what we must check)
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
647 // rbx,: Method*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
648
a61af66fc99e Initial load
duke
parents:
diff changeset
649 // C++ Interpreter
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
650 // rsi/r13: previous interpreter frame state object
0
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // rdi: &locals[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
652 // rcx: # of locals
a61af66fc99e Initial load
duke
parents:
diff changeset
653 // rdx: number of additional locals this frame needs (what we must check)
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
654 // rbx: Method*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
655
a61af66fc99e Initial load
duke
parents:
diff changeset
656 // destroyed on exit
a61af66fc99e Initial load
duke
parents:
diff changeset
657 // rax,
a61af66fc99e Initial load
duke
parents:
diff changeset
658
a61af66fc99e Initial load
duke
parents:
diff changeset
659 // NOTE: since the additional locals are also always pushed (wasn't obvious in
a61af66fc99e Initial load
duke
parents:
diff changeset
660 // generate_method_entry) so the guard should work for them too.
a61af66fc99e Initial load
duke
parents:
diff changeset
661 //
a61af66fc99e Initial load
duke
parents:
diff changeset
662
a61af66fc99e Initial load
duke
parents:
diff changeset
663 // monitor entry size: see picture of stack set (generate_method_entry) and frame_i486.hpp
a61af66fc99e Initial load
duke
parents:
diff changeset
664 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
665
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // total overhead size: entry_size + (saved rbp, thru expr stack bottom).
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // be sure to change this if you add/subtract anything to/from the overhead area
a61af66fc99e Initial load
duke
parents:
diff changeset
668 const int overhead_size = (int)sizeof(BytecodeInterpreter);
a61af66fc99e Initial load
duke
parents:
diff changeset
669
a61af66fc99e Initial load
duke
parents:
diff changeset
670 const int page_size = os::vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
671
a61af66fc99e Initial load
duke
parents:
diff changeset
672 Label after_frame_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
673
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // compute rsp as if this were going to be the last frame on
a61af66fc99e Initial load
duke
parents:
diff changeset
675 // the stack before the red zone
a61af66fc99e Initial load
duke
parents:
diff changeset
676
a61af66fc99e Initial load
duke
parents:
diff changeset
677 Label after_frame_check_pop;
a61af66fc99e Initial load
duke
parents:
diff changeset
678
a61af66fc99e Initial load
duke
parents:
diff changeset
679 // save rsi == caller's bytecode ptr (c++ previous interp. state)
a61af66fc99e Initial load
duke
parents:
diff changeset
680 // QQQ problem here?? rsi overload????
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
681 __ push(state);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
682
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
683 const Register thread = LP64_ONLY(r15_thread) NOT_LP64(rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
684
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
685 NOT_LP64(__ get_thread(thread));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
686
a61af66fc99e Initial load
duke
parents:
diff changeset
687 const Address stack_base(thread, Thread::stack_base_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
688 const Address stack_size(thread, Thread::stack_size_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
689
a61af66fc99e Initial load
duke
parents:
diff changeset
690 // locals + overhead, in bytes
7183
b2dbd323c668 8003848: Make ConstMethod::generic_signature_index optional and move Method::_max_stack to ConstMethod.
jiangli
parents: 6740
diff changeset
691 // Always give one monitor to allow us to start interp if sync method.
b2dbd323c668 8003848: Make ConstMethod::generic_signature_index optional and move Method::_max_stack to ConstMethod.
jiangli
parents: 6740
diff changeset
692 // Any additional monitors need a check when moving the expression stack
b2dbd323c668 8003848: Make ConstMethod::generic_signature_index optional and move Method::_max_stack to ConstMethod.
jiangli
parents: 6740
diff changeset
693 const int one_monitor = frame::interpreter_frame_monitor_size() * wordSize;
b2dbd323c668 8003848: Make ConstMethod::generic_signature_index optional and move Method::_max_stack to ConstMethod.
jiangli
parents: 6740
diff changeset
694 __ movptr(rax, Address(rbx, Method::const_offset()));
b2dbd323c668 8003848: Make ConstMethod::generic_signature_index optional and move Method::_max_stack to ConstMethod.
jiangli
parents: 6740
diff changeset
695 __ load_unsigned_short(rax, Address(rax, ConstMethod::max_stack_offset())); // get size of expression stack in words
10393
603ca7e51354 8010460: Interpreter on some platforms loads ConstMethod::_max_stack and misses extra stack slots for JSR 292
roland
parents: 10105
diff changeset
696 __ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), one_monitor+Method::extra_stack_words()));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
697 __ lea(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
698
a61af66fc99e Initial load
duke
parents:
diff changeset
699 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
700 Label stack_base_okay, stack_size_okay;
a61af66fc99e Initial load
duke
parents:
diff changeset
701 // verify that thread stack base is non-zero
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
702 __ cmpptr(stack_base, (int32_t)0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
703 __ jcc(Assembler::notEqual, stack_base_okay);
a61af66fc99e Initial load
duke
parents:
diff changeset
704 __ stop("stack base is zero");
a61af66fc99e Initial load
duke
parents:
diff changeset
705 __ bind(stack_base_okay);
a61af66fc99e Initial load
duke
parents:
diff changeset
706 // verify that thread stack size is non-zero
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
707 __ cmpptr(stack_size, (int32_t)0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
708 __ jcc(Assembler::notEqual, stack_size_okay);
a61af66fc99e Initial load
duke
parents:
diff changeset
709 __ stop("stack size is zero");
a61af66fc99e Initial load
duke
parents:
diff changeset
710 __ bind(stack_size_okay);
a61af66fc99e Initial load
duke
parents:
diff changeset
711 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
712
a61af66fc99e Initial load
duke
parents:
diff changeset
713 // Add stack base to locals and subtract stack size
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
714 __ addptr(rax, stack_base);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
715 __ subptr(rax, stack_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
716
a61af66fc99e Initial load
duke
parents:
diff changeset
717 // We should have a magic number here for the size of the c++ interpreter frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
718 // We can't actually tell this ahead of time. The debug version size is around 3k
a61af66fc99e Initial load
duke
parents:
diff changeset
719 // product is 1k and fastdebug is 4k
a61af66fc99e Initial load
duke
parents:
diff changeset
720 const int slop = 6 * K;
a61af66fc99e Initial load
duke
parents:
diff changeset
721
a61af66fc99e Initial load
duke
parents:
diff changeset
722 // Use the maximum number of pages we might bang.
a61af66fc99e Initial load
duke
parents:
diff changeset
723 const int max_pages = StackShadowPages > (StackRedPages+StackYellowPages) ? StackShadowPages :
a61af66fc99e Initial load
duke
parents:
diff changeset
724 (StackRedPages+StackYellowPages);
a61af66fc99e Initial load
duke
parents:
diff changeset
725 // Only need this if we are stack banging which is temporary while
a61af66fc99e Initial load
duke
parents:
diff changeset
726 // we're debugging.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
727 __ addptr(rax, slop + 2*max_pages * page_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
728
a61af66fc99e Initial load
duke
parents:
diff changeset
729 // check against the current stack bottom
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
730 __ cmpptr(rsp, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
731 __ jcc(Assembler::above, after_frame_check_pop);
a61af66fc99e Initial load
duke
parents:
diff changeset
732
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
733 __ pop(state); // get c++ prev state.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
734
a61af66fc99e Initial load
duke
parents:
diff changeset
735 // throw exception return address becomes throwing pc
a61af66fc99e Initial load
duke
parents:
diff changeset
736 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_StackOverflowError));
a61af66fc99e Initial load
duke
parents:
diff changeset
737
a61af66fc99e Initial load
duke
parents:
diff changeset
738 // all done with frame size check
a61af66fc99e Initial load
duke
parents:
diff changeset
739 __ bind(after_frame_check_pop);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
740 __ pop(state);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
741
a61af66fc99e Initial load
duke
parents:
diff changeset
742 __ bind(after_frame_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
743 }
a61af66fc99e Initial load
duke
parents:
diff changeset
744
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // Find preallocated monitor and lock method (C++ interpreter)
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
746 // rbx - Method*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
747 //
a61af66fc99e Initial load
duke
parents:
diff changeset
748 void InterpreterGenerator::lock_method(void) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
749 // assumes state == rsi/r13 == pointer to current interpreterState
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
750 // minimally destroys rax, rdx|c_rarg1, rdi
0
a61af66fc99e Initial load
duke
parents:
diff changeset
751 //
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // synchronize method
a61af66fc99e Initial load
duke
parents:
diff changeset
753 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
754 const Address access_flags (rbx, Method::access_flags_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
755
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
756 const Register monitor = NOT_LP64(rdx) LP64_ONLY(c_rarg1);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
757
0
a61af66fc99e Initial load
duke
parents:
diff changeset
758 // find initial monitor i.e. monitors[-1]
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
759 __ movptr(monitor, STATE(_monitor_base)); // get monitor bottom limit
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
760 __ subptr(monitor, entry_size); // point to initial monitor
0
a61af66fc99e Initial load
duke
parents:
diff changeset
761
a61af66fc99e Initial load
duke
parents:
diff changeset
762 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
763 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
764 __ movl(rax, access_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
765 __ testl(rax, JVM_ACC_SYNCHRONIZED);
a61af66fc99e Initial load
duke
parents:
diff changeset
766 __ jcc(Assembler::notZero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
767 __ stop("method doesn't need synchronization");
a61af66fc99e Initial load
duke
parents:
diff changeset
768 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
769 }
a61af66fc99e Initial load
duke
parents:
diff changeset
770 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
771 // get synchronization object
a61af66fc99e Initial load
duke
parents:
diff changeset
772 { Label done;
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3369
diff changeset
773 const int mirror_offset = in_bytes(Klass::java_mirror_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
774 __ movl(rax, access_flags);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
775 __ movptr(rdi, STATE(_locals)); // prepare to get receiver (assume common case)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
776 __ testl(rax, JVM_ACC_STATIC);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
777 __ movptr(rax, Address(rdi, 0)); // get receiver (assume this is frequent case)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
778 __ jcc(Assembler::zero, done);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
779 __ movptr(rax, Address(rbx, Method::const_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
780 __ movptr(rax, Address(rax, ConstMethod::constants_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
781 __ movptr(rax, Address(rax, ConstantPool::pool_holder_offset_in_bytes()));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
782 __ movptr(rax, Address(rax, mirror_offset));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
783 __ bind(done);
a61af66fc99e Initial load
duke
parents:
diff changeset
784 }
a61af66fc99e Initial load
duke
parents:
diff changeset
785 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
786 { Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
787 __ cmpptr(rax, Address(monitor, BasicObjectLock::obj_offset_in_bytes())); // correct object?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
788 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
789 __ stop("wrong synchronization lobject");
a61af66fc99e Initial load
duke
parents:
diff changeset
790 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
792 #endif // ASSERT
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
793 // can destroy rax, rdx|c_rarg1, rcx, and (via call_VM) rdi!
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
794 __ lock_object(monitor);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
795 }
a61af66fc99e Initial load
duke
parents:
diff changeset
796
a61af66fc99e Initial load
duke
parents:
diff changeset
797 // Call an accessor method (assuming it is resolved, otherwise drop into vanilla (slow path) entry
a61af66fc99e Initial load
duke
parents:
diff changeset
798
a61af66fc99e Initial load
duke
parents:
diff changeset
799 address InterpreterGenerator::generate_accessor_entry(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
800
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
801 // rbx: Method*
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
802
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
803 // rsi/r13: senderSP must preserved for slow path, set SP to it on fast path
0
a61af66fc99e Initial load
duke
parents:
diff changeset
804
a61af66fc99e Initial load
duke
parents:
diff changeset
805 Label xreturn_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
806
a61af66fc99e Initial load
duke
parents:
diff changeset
807 // do fastpath for resolved accessor methods
a61af66fc99e Initial load
duke
parents:
diff changeset
808 if (UseFastAccessorMethods) {
a61af66fc99e Initial load
duke
parents:
diff changeset
809
a61af66fc99e Initial load
duke
parents:
diff changeset
810 address entry_point = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
811
a61af66fc99e Initial load
duke
parents:
diff changeset
812 Label slow_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
813 // If we need a safepoint check, generate full interpreter entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
814 ExternalAddress state(SafepointSynchronize::address_of_state());
a61af66fc99e Initial load
duke
parents:
diff changeset
815 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
a61af66fc99e Initial load
duke
parents:
diff changeset
816 SafepointSynchronize::_not_synchronized);
a61af66fc99e Initial load
duke
parents:
diff changeset
817
a61af66fc99e Initial load
duke
parents:
diff changeset
818 __ jcc(Assembler::notEqual, slow_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
819 // ASM/C++ Interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
820 // Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites thereof; parameter size = 1
a61af66fc99e Initial load
duke
parents:
diff changeset
821 // Note: We can only use this code if the getfield has been resolved
a61af66fc99e Initial load
duke
parents:
diff changeset
822 // and if we don't have a null-pointer exception => check for
a61af66fc99e Initial load
duke
parents:
diff changeset
823 // these conditions first and use slow path if necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
824 // rbx,: method
a61af66fc99e Initial load
duke
parents:
diff changeset
825 // rcx: receiver
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
826 __ movptr(rax, Address(rsp, wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
827
a61af66fc99e Initial load
duke
parents:
diff changeset
828 // check if local 0 != NULL and read field
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
829 __ testptr(rax, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
830 __ jcc(Assembler::zero, slow_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
831
a61af66fc99e Initial load
duke
parents:
diff changeset
832 // read first instruction word and extract bytecode @ 1 and index @ 2
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
833 __ movptr(rdx, Address(rbx, Method::const_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
834 __ movptr(rdi, Address(rdx, ConstMethod::constants_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
835 __ movl(rdx, Address(rdx, ConstMethod::codes_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
836 // Shift codes right to get the index on the right.
a61af66fc99e Initial load
duke
parents:
diff changeset
837 // The bytecode fetched looks like <index><0xb4><0x2a>
a61af66fc99e Initial load
duke
parents:
diff changeset
838 __ shrl(rdx, 2*BitsPerByte);
a61af66fc99e Initial load
duke
parents:
diff changeset
839 __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size())));
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
840 __ movptr(rdi, Address(rdi, ConstantPool::cache_offset_in_bytes()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
841
a61af66fc99e Initial load
duke
parents:
diff changeset
842 // rax,: local 0
a61af66fc99e Initial load
duke
parents:
diff changeset
843 // rbx,: method
a61af66fc99e Initial load
duke
parents:
diff changeset
844 // rcx: receiver - do not destroy since it is needed for slow path!
a61af66fc99e Initial load
duke
parents:
diff changeset
845 // rcx: scratch
a61af66fc99e Initial load
duke
parents:
diff changeset
846 // rdx: constant pool cache index
a61af66fc99e Initial load
duke
parents:
diff changeset
847 // rdi: constant pool cache
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
848 // rsi/r13: sender sp
0
a61af66fc99e Initial load
duke
parents:
diff changeset
849
a61af66fc99e Initial load
duke
parents:
diff changeset
850 // check if getfield has been resolved and read constant pool cache entry
a61af66fc99e Initial load
duke
parents:
diff changeset
851 // check the validity of the cache entry by testing whether _indices field
a61af66fc99e Initial load
duke
parents:
diff changeset
852 // contains Bytecode::_getfield in b1 byte.
a61af66fc99e Initial load
duke
parents:
diff changeset
853 assert(in_words(ConstantPoolCacheEntry::size()) == 4, "adjust shift below");
a61af66fc99e Initial load
duke
parents:
diff changeset
854 __ movl(rcx,
a61af66fc99e Initial load
duke
parents:
diff changeset
855 Address(rdi,
a61af66fc99e Initial load
duke
parents:
diff changeset
856 rdx,
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
857 Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
858 __ shrl(rcx, 2*BitsPerByte);
a61af66fc99e Initial load
duke
parents:
diff changeset
859 __ andl(rcx, 0xFF);
a61af66fc99e Initial load
duke
parents:
diff changeset
860 __ cmpl(rcx, Bytecodes::_getfield);
a61af66fc99e Initial load
duke
parents:
diff changeset
861 __ jcc(Assembler::notEqual, slow_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
862
a61af66fc99e Initial load
duke
parents:
diff changeset
863 // Note: constant pool entry is not valid before bytecode is resolved
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
864 __ movptr(rcx,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
865 Address(rdi,
a61af66fc99e Initial load
duke
parents:
diff changeset
866 rdx,
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
867 Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f2_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
868 __ movl(rdx,
a61af66fc99e Initial load
duke
parents:
diff changeset
869 Address(rdi,
a61af66fc99e Initial load
duke
parents:
diff changeset
870 rdx,
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
871 Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
872
a61af66fc99e Initial load
duke
parents:
diff changeset
873 Label notByte, notShort, notChar;
a61af66fc99e Initial load
duke
parents:
diff changeset
874 const Address field_address (rax, rcx, Address::times_1);
a61af66fc99e Initial load
duke
parents:
diff changeset
875
a61af66fc99e Initial load
duke
parents:
diff changeset
876 // Need to differentiate between igetfield, agetfield, bgetfield etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
877 // because they are different sizes.
a61af66fc99e Initial load
duke
parents:
diff changeset
878 // Use 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
879 __ shrl(rdx, ConstantPoolCacheEntry::tos_state_shift);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6123
diff changeset
880 // Make sure we don't need to mask rdx after the above shift
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6123
diff changeset
881 ConstantPoolCacheEntry::verify_tos_state_shift();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
882 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
883 Label notObj;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
884 __ cmpl(rdx, atos);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
885 __ jcc(Assembler::notEqual, notObj);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
886 // atos
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
887 __ movptr(rax, field_address);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
888 __ jmp(xreturn_path);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
889
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
890 __ bind(notObj);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
891 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
892 __ cmpl(rdx, btos);
a61af66fc99e Initial load
duke
parents:
diff changeset
893 __ jcc(Assembler::notEqual, notByte);
a61af66fc99e Initial load
duke
parents:
diff changeset
894 __ load_signed_byte(rax, field_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
895 __ jmp(xreturn_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
896
a61af66fc99e Initial load
duke
parents:
diff changeset
897 __ bind(notByte);
a61af66fc99e Initial load
duke
parents:
diff changeset
898 __ cmpl(rdx, stos);
a61af66fc99e Initial load
duke
parents:
diff changeset
899 __ jcc(Assembler::notEqual, notShort);
622
56aae7be60d4 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 605
diff changeset
900 __ load_signed_short(rax, field_address);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
901 __ jmp(xreturn_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
902
a61af66fc99e Initial load
duke
parents:
diff changeset
903 __ bind(notShort);
a61af66fc99e Initial load
duke
parents:
diff changeset
904 __ cmpl(rdx, ctos);
a61af66fc99e Initial load
duke
parents:
diff changeset
905 __ jcc(Assembler::notEqual, notChar);
622
56aae7be60d4 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 605
diff changeset
906 __ load_unsigned_short(rax, field_address);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
907 __ jmp(xreturn_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
908
a61af66fc99e Initial load
duke
parents:
diff changeset
909 __ bind(notChar);
a61af66fc99e Initial load
duke
parents:
diff changeset
910 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
911 Label okay;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
912 #ifndef _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
913 __ cmpl(rdx, atos);
a61af66fc99e Initial load
duke
parents:
diff changeset
914 __ jcc(Assembler::equal, okay);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
915 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
916 __ cmpl(rdx, itos);
a61af66fc99e Initial load
duke
parents:
diff changeset
917 __ jcc(Assembler::equal, okay);
a61af66fc99e Initial load
duke
parents:
diff changeset
918 __ stop("what type is this?");
a61af66fc99e Initial load
duke
parents:
diff changeset
919 __ bind(okay);
a61af66fc99e Initial load
duke
parents:
diff changeset
920 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
921 // All the rest are a 32 bit wordsize
a61af66fc99e Initial load
duke
parents:
diff changeset
922 __ movl(rax, field_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
923
a61af66fc99e Initial load
duke
parents:
diff changeset
924 __ bind(xreturn_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
925
a61af66fc99e Initial load
duke
parents:
diff changeset
926 // _ireturn/_areturn
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
927 __ pop(rdi); // get return address
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
928 __ mov(rsp, sender_sp_on_entry); // set sp to sender sp
0
a61af66fc99e Initial load
duke
parents:
diff changeset
929 __ jmp(rdi);
a61af66fc99e Initial load
duke
parents:
diff changeset
930
a61af66fc99e Initial load
duke
parents:
diff changeset
931 // generate a vanilla interpreter entry as the slow path
a61af66fc99e Initial load
duke
parents:
diff changeset
932 __ bind(slow_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
933 // We will enter c++ interpreter looking like it was
a61af66fc99e Initial load
duke
parents:
diff changeset
934 // called by the call_stub this will cause it to return
a61af66fc99e Initial load
duke
parents:
diff changeset
935 // a tosca result to the invoker which might have been
a61af66fc99e Initial load
duke
parents:
diff changeset
936 // the c++ interpreter itself.
a61af66fc99e Initial load
duke
parents:
diff changeset
937
a61af66fc99e Initial load
duke
parents:
diff changeset
938 __ jmp(fast_accessor_slow_entry_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
939 return entry_point;
a61af66fc99e Initial load
duke
parents:
diff changeset
940
a61af66fc99e Initial load
duke
parents:
diff changeset
941 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
942 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
943 }
a61af66fc99e Initial load
duke
parents:
diff changeset
944
a61af66fc99e Initial load
duke
parents:
diff changeset
945 }
a61af66fc99e Initial load
duke
parents:
diff changeset
946
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
947 address InterpreterGenerator::generate_Reference_get_entry(void) {
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 7402
diff changeset
948 #if INCLUDE_ALL_GCS
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
949 if (UseG1GC) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
950 // 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: 2245
diff changeset
951 // * load the value in the referent field
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
952 // * passes that value to the pre-barrier.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
953 //
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
954 // 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: 2245
diff changeset
955 // referent in an SATB buffer if marking is active.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
956 // This will cause concurrent marking to mark the referent
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
957 // field as live.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
958 Unimplemented();
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
959 }
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 7402
diff changeset
960 #endif // INCLUDE_ALL_GCS
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
961
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
962 // 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: 2245
diff changeset
963 // Reference.get is an accessor
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
964 return generate_accessor_entry();
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
965 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
966
0
a61af66fc99e Initial load
duke
parents:
diff changeset
967 //
a61af66fc99e Initial load
duke
parents:
diff changeset
968 // C++ Interpreter stub for calling a native method.
a61af66fc99e Initial load
duke
parents:
diff changeset
969 // This sets up a somewhat different looking stack for calling the native method
a61af66fc99e Initial load
duke
parents:
diff changeset
970 // than the typical interpreter frame setup but still has the pointer to
a61af66fc99e Initial load
duke
parents:
diff changeset
971 // an interpreter state.
a61af66fc99e Initial load
duke
parents:
diff changeset
972 //
a61af66fc99e Initial load
duke
parents:
diff changeset
973
a61af66fc99e Initial load
duke
parents:
diff changeset
974 address InterpreterGenerator::generate_native_entry(bool synchronized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
975 // determine code generation flags
a61af66fc99e Initial load
duke
parents:
diff changeset
976 bool inc_counter = UseCompiler || CountCompiledCalls;
a61af66fc99e Initial load
duke
parents:
diff changeset
977
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
978 // rbx: Method*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
979 // rcx: receiver (unused)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
980 // rsi/r13: previous interpreter state (if called from C++ interpreter) must preserve
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
981 // in any case. If called via c1/c2/call_stub rsi/r13 is junk (to use) but harmless
0
a61af66fc99e Initial load
duke
parents:
diff changeset
982 // to save/restore.
a61af66fc99e Initial load
duke
parents:
diff changeset
983 address entry_point = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
984
7402
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
985 const Address constMethod (rbx, Method::const_offset());
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
986 const Address access_flags (rbx, Method::access_flags_offset());
7402
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
987 const Address size_of_parameters(rcx, ConstMethod::size_of_parameters_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
988
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
989 // rsi/r13 == state/locals rdi == prevstate
0
a61af66fc99e Initial load
duke
parents:
diff changeset
990 const Register locals = rdi;
a61af66fc99e Initial load
duke
parents:
diff changeset
991
a61af66fc99e Initial load
duke
parents:
diff changeset
992 // get parameter size (always needed)
7402
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
993 __ movptr(rcx, constMethod);
622
56aae7be60d4 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 605
diff changeset
994 __ load_unsigned_short(rcx, size_of_parameters);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
995
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
996 // rbx: Method*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
997 // rcx: size of parameters
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
998 __ pop(rax); // get return address
0
a61af66fc99e Initial load
duke
parents:
diff changeset
999 // for natives the size of locals is zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1000
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 // compute beginning of parameters /locals
7402
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
1002
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1003 __ lea(locals, Address(rsp, rcx, Address::times_ptr, -wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1004
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 // initialize fixed part of activation frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1006
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 // Assumes rax = return address
a61af66fc99e Initial load
duke
parents:
diff changeset
1008
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 // allocate and initialize new interpreterState and method expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 // IN(locals) -> locals
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 // IN(state) -> previous frame manager state (NULL from stub/c1/c2)
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 // destroys rax, rcx, rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 // OUT (state) -> new interpreterState
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 // OUT(rsp) -> bottom of methods expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1015
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 // save sender_sp
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1017 __ mov(rcx, sender_sp_on_entry);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 // start with NULL previous state
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1019 __ movptr(state, (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 generate_compute_interpreter_state(state, locals, rcx, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1021
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 { Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1024 __ movptr(rax, STATE(_stack_base));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1025 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1026 // duplicate the alignment rsp got after setting stack_base
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1027 __ subptr(rax, frame::arg_reg_save_area_bytes); // windows
605
98cb887364d3 6810672: Comment typos
twisti
parents: 520
diff changeset
1028 __ andptr(rax, -16); // must be 16 byte boundary (see amd64 ABI)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1029 #endif // _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1030 __ cmpptr(rax, rsp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 __ stop("broken stack frame setup in interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1036
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1037 const Register unlock_thread = LP64_ONLY(r15_thread) NOT_LP64(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1038 NOT_LP64(__ movptr(unlock_thread, STATE(_thread));) // get thread
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 // Since at this point in the method invocation the exception handler
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 // would try to exit the monitor of synchronized methods which hasn't
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 // been entered yet, we set the thread local variable
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 // _do_not_unlock_if_synchronized to true. The remove_activation will
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 // check this flag.
a61af66fc99e Initial load
duke
parents:
diff changeset
1044
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1045 const Address do_not_unlock_if_synchronized(unlock_thread,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 __ movbool(do_not_unlock_if_synchronized, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1048
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 // make sure method is native & not abstract
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 __ movl(rax, access_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 __ testl(rax, JVM_ACC_NATIVE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 __ jcc(Assembler::notZero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 __ stop("tried to execute non-native method as native");
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 __ testl(rax, JVM_ACC_ABSTRACT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 __ jcc(Assembler::zero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 __ stop("tried to execute abstract method in interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1066
a61af66fc99e Initial load
duke
parents:
diff changeset
1067
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 // increment invocation count & check for overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 Label invocation_counter_overflow;
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 if (inc_counter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 generate_counter_incr(&invocation_counter_overflow, NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1073
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 Label continue_after_compile;
a61af66fc99e Initial load
duke
parents:
diff changeset
1075
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 __ bind(continue_after_compile);
a61af66fc99e Initial load
duke
parents:
diff changeset
1077
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 bang_stack_shadow_pages(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1079
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 // reset the _do_not_unlock_if_synchronized flag
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1081 NOT_LP64(__ movl(rax, STATE(_thread));) // get thread
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 __ movbool(do_not_unlock_if_synchronized, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1083
a61af66fc99e Initial load
duke
parents:
diff changeset
1084
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 // check for synchronized native methods
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 // Note: This must happen *after* invocation counter check, since
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 // when overflow happens, the method should not be locked.
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 if (synchronized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 // potentially kills rax, rcx, rdx, rdi
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 lock_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 // no synchronization necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 __ movl(rax, access_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 __ testl(rax, JVM_ACC_SYNCHRONIZED);
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 __ jcc(Assembler::zero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 __ stop("method needs synchronization");
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1104
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 // start execution
a61af66fc99e Initial load
duke
parents:
diff changeset
1106
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 // jvmti support
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 __ notify_method_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
1109
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 // work registers
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 const Register method = rbx;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1112 const Register thread = LP64_ONLY(r15_thread) NOT_LP64(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1113 const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); // rcx|rscratch1
7402
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
1114 const Address constMethod (method, Method::const_offset());
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
1115 const Address size_of_parameters(t, ConstMethod::size_of_parameters_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1116
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 // allocate space for parameters
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1118 __ movptr(method, STATE(_method));
6740
75f33eecc1b3 7196681: NPG: Some JSR 292 tests crash in Windows exception handler
coleenp
parents: 6725
diff changeset
1119 __ verify_method_ptr(method);
7402
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
1120 __ movptr(t, constMethod);
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
1121 __ load_unsigned_short(t, size_of_parameters);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 __ shll(t, 2);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1123 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1124 __ subptr(rsp, t);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1125 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows
605
98cb887364d3 6810672: Comment typos
twisti
parents: 520
diff changeset
1126 __ andptr(rsp, -16); // must be 16 byte boundary (see amd64 ABI)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1127 #else
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1128 __ addptr(t, 2*wordSize); // allocate two more slots for JNIEnv and possible mirror
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1129 __ subptr(rsp, t);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1130 __ andptr(rsp, -(StackAlignmentInBytes)); // gcc needs 16 byte aligned stacks to do XMM intrinsics
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1131 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1132
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 // get signature handler
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 Label pending_exception_present;
a61af66fc99e Initial load
duke
parents:
diff changeset
1135
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 { Label L;
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1137 __ movptr(t, Address(method, Method::signature_handler_offset()));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1138 __ testptr(t, t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 __ jcc(Assembler::notZero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method, false);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1141 __ movptr(method, STATE(_method));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1142 __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 __ jcc(Assembler::notEqual, pending_exception_present);
6740
75f33eecc1b3 7196681: NPG: Some JSR 292 tests crash in Windows exception handler
coleenp
parents: 6725
diff changeset
1144 __ verify_method_ptr(method);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1145 __ movptr(t, Address(method, Method::signature_handler_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1151 __ push(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 __ get_thread(t); // get vm's javathread*
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1153 __ cmpptr(t, STATE(_thread));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 __ int3();
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 __ bind(L);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1157 __ pop(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 #endif //
a61af66fc99e Initial load
duke
parents:
diff changeset
1160
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1161 const Register from_ptr = InterpreterRuntime::SignatureHandlerGenerator::from();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 // call signature handler
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 assert(InterpreterRuntime::SignatureHandlerGenerator::to () == rsp, "adjust this code");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1164
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 // The generated handlers do not touch RBX (the method oop).
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 // However, large signatures cannot be cached and are generated
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 // each time here. The slow-path generator will blow RBX
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 // sometime, so we must reload it after the call.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1169 __ movptr(from_ptr, STATE(_locals)); // get the from pointer
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 __ call(t);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1171 __ movptr(method, STATE(_method));
6740
75f33eecc1b3 7196681: NPG: Some JSR 292 tests crash in Windows exception handler
coleenp
parents: 6725
diff changeset
1172 __ verify_method_ptr(method);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1173
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 // result handler is in rax
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 // set result handler
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1176 __ movptr(STATE(_result_handler), rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1177
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1178
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1179 // get native function entry point
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1180 { Label L;
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1181 __ movptr(rax, Address(method, Method::native_function_offset()));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1182 __ testptr(rax, rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1183 __ jcc(Assembler::notZero, L);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1184 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1185 __ movptr(method, STATE(_method));
6740
75f33eecc1b3 7196681: NPG: Some JSR 292 tests crash in Windows exception handler
coleenp
parents: 6725
diff changeset
1186 __ verify_method_ptr(method);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1187 __ movptr(rax, Address(method, Method::native_function_offset()));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1188 __ bind(L);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1189 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1190
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 // pass mirror handle if static call
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 { Label L;
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3369
diff changeset
1193 const int mirror_offset = in_bytes(Klass::java_mirror_offset());
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1194 __ movl(t, Address(method, Method::access_flags_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 __ testl(t, JVM_ACC_STATIC);
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 __ jcc(Assembler::zero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 // get mirror
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1198 __ movptr(t, Address(method, Method:: const_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1199 __ movptr(t, Address(t, ConstMethod::constants_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1200 __ movptr(t, Address(t, ConstantPool::pool_holder_offset_in_bytes()));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1201 __ movptr(t, Address(t, mirror_offset));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 // copy mirror into activation object
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1203 __ movptr(STATE(_oop_temp), t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 // pass handle to mirror
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1205 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1206 __ lea(c_rarg1, STATE(_oop_temp));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1207 #else
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1208 __ lea(t, STATE(_oop_temp));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1209 __ movptr(Address(rsp, wordSize), t);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1210 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1216 __ push(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 __ get_thread(t); // get vm's javathread*
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1218 __ cmpptr(t, STATE(_thread));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 __ int3();
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 __ bind(L);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1222 __ pop(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 #endif //
a61af66fc99e Initial load
duke
parents:
diff changeset
1225
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 // pass JNIEnv
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1227 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1228 __ lea(c_rarg0, Address(thread, JavaThread::jni_environment_offset()));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1229 #else
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1230 __ movptr(thread, STATE(_thread)); // get thread
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1231 __ lea(t, Address(thread, JavaThread::jni_environment_offset()));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1232
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1233 __ movptr(Address(rsp, 0), t);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1234 #endif // _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1235
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1239 __ push(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 __ get_thread(t); // get vm's javathread*
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1241 __ cmpptr(t, STATE(_thread));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 __ int3();
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 __ bind(L);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1245 __ pop(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 #endif //
a61af66fc99e Initial load
duke
parents:
diff changeset
1248
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 __ movl(t, Address(thread, JavaThread::thread_state_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 __ cmpl(t, _thread_in_Java);
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 __ stop("Wrong thread state in native stub");
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1258
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 // Change state to native (we save the return address in the thread, since it might not
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 // be pushed on the stack when we do a a stack traversal). It is enough that the pc()
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 // points into the right code segment. It does not have to be the correct return pc.
a61af66fc99e Initial load
duke
parents:
diff changeset
1262
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 __ set_last_Java_frame(thread, noreg, rbp, __ pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
1264
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native);
a61af66fc99e Initial load
duke
parents:
diff changeset
1266
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 __ call(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1268
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 // result potentially in rdx:rax or ST0
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1270 __ movptr(method, STATE(_method));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1271 NOT_LP64(__ movptr(thread, STATE(_thread));) // get thread
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1272
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 // The potential result is in ST(0) & rdx:rax
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 // With C++ interpreter we leave any possible result in ST(0) until we are in result handler and then
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 // we do the appropriate stuff for returning the result. rdx:rax must always be saved because just about
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 // anything we do here will destroy it, st(0) is only saved if we re-enter the vm where it would
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 // be destroyed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 // It is safe to do these pushes because state is _thread_in_native and return address will be found
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 // via _last_native_pc and not via _last_jave_sp
a61af66fc99e Initial load
duke
parents:
diff changeset
1280
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1281 // Must save the value of ST(0)/xmm0 since it could be destroyed before we get to result handler
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 { Label Lpush, Lskip;
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 ExternalAddress float_handler(AbstractInterpreter::result_handler(T_FLOAT));
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 ExternalAddress double_handler(AbstractInterpreter::result_handler(T_DOUBLE));
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 __ cmpptr(STATE(_result_handler), float_handler.addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 __ jcc(Assembler::equal, Lpush);
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 __ cmpptr(STATE(_result_handler), double_handler.addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 __ jcc(Assembler::notEqual, Lskip);
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 __ bind(Lpush);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1290 __ subptr(rsp, 2*wordSize);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1291 if ( UseSSE < 2 ) {
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1292 __ fstp_d(Address(rsp, 0));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1293 } else {
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1294 __ movdbl(Address(rsp, 0), xmm0);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1295 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 __ bind(Lskip);
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1298
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1299 // save rax:rdx for potential use by result handler.
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1300 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1301 #ifndef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1302 __ push(rdx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1303 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1304
8873
e961c11b85fe 8011102: Clear AVX registers after return from JNI call
kvn
parents: 8727
diff changeset
1305 // Verify or restore cpu control state after JNI call
e961c11b85fe 8011102: Clear AVX registers after return from JNI call
kvn
parents: 8727
diff changeset
1306 __ restore_cpu_control_state_after_jni();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1307
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 // change thread state
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native_trans);
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 if(os::is_MP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 // Write serialization page so VM thread can do a pseudo remote membar.
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 // We use the current thread pointer to calculate a thread specific
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 // offset to write to within the page. This minimizes bus traffic
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 // due to cache line collision.
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 __ serialize_memory(thread, rcx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1317
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 // check for safepoint operation in progress and/or pending suspend requests
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 { Label Continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1320
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 SafepointSynchronize::_not_synchronized);
a61af66fc99e Initial load
duke
parents:
diff changeset
1323
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 // threads running native code and they are expected to self-suspend
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 // when leaving the _thread_in_native state. We need to check for
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 // pending suspend requests here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 __ jcc(Assembler::notEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 __ cmpl(Address(thread, JavaThread::suspend_flags_offset()), 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 __ jcc(Assembler::equal, Continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1332
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 // Don't use call_VM as it will see a possible pending exception and forward it
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 // and never return here preventing us from clearing _last_native_pc down below.
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 // Also can't use call_VM_leaf either as it will check to see if rsi & rdi are
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1336 // preserved and correspond to the bcp/locals pointers.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 //
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1338
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1339 ((MacroAssembler*)_masm)->call_VM_leaf(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans),
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1340 thread);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 __ increment(rsp, wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1342
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1343 __ movptr(method, STATE(_method));
6740
75f33eecc1b3 7196681: NPG: Some JSR 292 tests crash in Windows exception handler
coleenp
parents: 6725
diff changeset
1344 __ verify_method_ptr(method);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1345 __ movptr(thread, STATE(_thread)); // get thread
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1346
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 __ bind(Continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1349
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 // change thread state
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_Java);
a61af66fc99e Initial load
duke
parents:
diff changeset
1352
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 __ reset_last_Java_frame(thread, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1354
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 // reset handle block
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1356 __ movptr(t, Address(thread, JavaThread::active_handles_offset()));
17850
2100bf712e2a 8039146: Fix 64-bit store to int JNIHandleBlock::_top
goetz
parents: 13010
diff changeset
1357 __ movl(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1358
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 // If result was an oop then unbox and save it in the frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 Label no_oop, store_result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 ExternalAddress oop_handler(AbstractInterpreter::result_handler(T_OBJECT));
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 __ cmpptr(STATE(_result_handler), oop_handler.addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 __ jcc(Assembler::notEqual, no_oop);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1365 #ifndef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1366 __ pop(rdx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1367 #endif // _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1368 __ pop(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1369 __ testptr(rax, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 __ jcc(Assembler::zero, store_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 // unbox
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1372 __ movptr(rax, Address(rax, 0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 __ bind(store_result);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1374 __ movptr(STATE(_oop_temp), rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 // keep stack depth as expected by pushing oop which will eventually be discarded
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1376 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1377 #ifndef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1378 __ push(rdx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1379 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 __ bind(no_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1382
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 Label no_reguard;
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 __ cmpl(Address(thread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_yellow_disabled);
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 __ jcc(Assembler::notEqual, no_reguard);
a61af66fc99e Initial load
duke
parents:
diff changeset
1387
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1388 __ pusha();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages)));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1390 __ popa();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1391
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 __ bind(no_reguard);
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1394
a61af66fc99e Initial load
duke
parents:
diff changeset
1395
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 // QQQ Seems like for native methods we simply return and the caller will see the pending
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 // exception and do the right thing. Certainly the interpreter will, don't know about
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 // compiled methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 // Seems that the answer to above is no this is wrong. The old code would see the exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 // and forward it before doing the unlocking and notifying jvmdi that method has exited.
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 // This seems wrong need to investigate the spec.
a61af66fc99e Initial load
duke
parents:
diff changeset
1402
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 // handle exceptions (exception handling will handle unlocking!)
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 { Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1405 __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 __ jcc(Assembler::zero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 __ bind(pending_exception_present);
a61af66fc99e Initial load
duke
parents:
diff changeset
1408
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 // There are potential results on the stack (rax/rdx, ST(0)) we ignore these and simply
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 // return and let caller deal with exception. This skips the unlocking here which
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 // seems wrong but seems to be what asm interpreter did. Can't find this in the spec.
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 // Note: must preverve method in rbx
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1414
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 // remove activation
a61af66fc99e Initial load
duke
parents:
diff changeset
1416
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1417 __ movptr(t, STATE(_sender_sp));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 __ leave(); // remove frame anchor
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1419 __ pop(rdi); // get return address
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1420 __ movptr(state, STATE(_prev_link)); // get previous state for return
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1421 __ mov(rsp, t); // set sp to sender sp
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1422 __ push(rdi); // push throwing pc
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 // The skips unlocking!! This seems to be what asm interpreter does but seems
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 // very wrong. Not clear if this violates the spec.
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1428
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 // do unlocking if necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 { Label L;
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1431 __ movl(t, Address(method, Method::access_flags_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 __ testl(t, JVM_ACC_SYNCHRONIZED);
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 __ jcc(Assembler::zero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 // the code below should be shared with interpreter macro assembler implementation
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 { Label unlock;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1436 const Register monitor = NOT_LP64(rdx) LP64_ONLY(c_rarg1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 // BasicObjectLock will be first in list, since this is a synchronized method. However, need
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 // to check that the object has not been unlocked by an explicit monitorexit bytecode.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1439 __ movptr(monitor, STATE(_monitor_base));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1440 __ subptr(monitor, frame::interpreter_frame_monitor_size() * wordSize); // address of initial monitor
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1441
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1442 __ movptr(t, Address(monitor, BasicObjectLock::obj_offset_in_bytes()));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1443 __ testptr(t, t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 __ jcc(Assembler::notZero, unlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1445
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 // Entry already unlocked, need to throw exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 __ MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_illegal_monitor_state_exception));
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 __ should_not_reach_here();
a61af66fc99e Initial load
duke
parents:
diff changeset
1449
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 __ bind(unlock);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1451 __ unlock_object(monitor);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 // unlock can blow rbx so restore it for path that needs it below
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1453 __ movptr(method, STATE(_method));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1457
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 // jvmti support
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 // Note: This must happen _after_ handling/throwing any exceptions since
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 // the exception handler code notifies the runtime of method exits
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 // too. If this happens before, method entry/exit notifications are
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 // not properly paired (was bug - gri 11/22/99).
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 __ notify_method_exit(vtos, InterpreterMacroAssembler::NotifyJVMTI);
a61af66fc99e Initial load
duke
parents:
diff changeset
1464
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 // restore potential result in rdx:rax, call result handler to restore potential result in ST0 & handle result
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1466 #ifndef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1467 __ pop(rdx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1468 #endif // _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1469 __ pop(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1470 __ movptr(t, STATE(_result_handler)); // get result handler
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 __ call(t); // call result handler to convert to tosca form
a61af66fc99e Initial load
duke
parents:
diff changeset
1472
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 // remove activation
a61af66fc99e Initial load
duke
parents:
diff changeset
1474
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1475 __ movptr(t, STATE(_sender_sp));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1476
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 __ leave(); // remove frame anchor
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1478 __ pop(rdi); // get return address
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1479 __ movptr(state, STATE(_prev_link)); // get previous state for return (if c++ interpreter was caller)
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1480 __ mov(rsp, t); // set sp to sender sp
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 __ jmp(rdi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1482
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 // invocation counter overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 if (inc_counter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 // Handle overflow of counter and compile method
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 __ bind(invocation_counter_overflow);
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 generate_counter_overflow(&continue_after_compile);
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1489
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 return entry_point;
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1492
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 // Generate entries that will put a result type index into rcx
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 void CppInterpreterGenerator::generate_deopt_handling() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1495
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 Label return_from_deopt_common;
a61af66fc99e Initial load
duke
parents:
diff changeset
1497
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 // Generate entries that will put a result type index into rcx
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 deopt_frame_manager_return_atos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1501
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 // rax is live here
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_OBJECT)); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 __ jmp(return_from_deopt_common);
a61af66fc99e Initial load
duke
parents:
diff changeset
1505
a61af66fc99e Initial load
duke
parents:
diff changeset
1506
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 deopt_frame_manager_return_btos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1509
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 // rax is live here
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_BOOLEAN)); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 __ jmp(return_from_deopt_common);
a61af66fc99e Initial load
duke
parents:
diff changeset
1513
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 deopt_frame_manager_return_itos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1516
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 // rax is live here
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_INT)); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 __ jmp(return_from_deopt_common);
a61af66fc99e Initial load
duke
parents:
diff changeset
1520
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1522
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 deopt_frame_manager_return_ltos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 // rax,rdx are live here
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_LONG)); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 __ jmp(return_from_deopt_common);
a61af66fc99e Initial load
duke
parents:
diff changeset
1527
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1529
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 deopt_frame_manager_return_ftos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 // st(0) is live here
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_FLOAT)); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 __ jmp(return_from_deopt_common);
a61af66fc99e Initial load
duke
parents:
diff changeset
1534
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 deopt_frame_manager_return_dtos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1537
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 // st(0) is live here
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_DOUBLE)); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 __ jmp(return_from_deopt_common);
a61af66fc99e Initial load
duke
parents:
diff changeset
1541
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 deopt_frame_manager_return_vtos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1544
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_VOID));
a61af66fc99e Initial load
duke
parents:
diff changeset
1546
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 // Deopt return common
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 // an index is present in rcx that lets us move any possible result being
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 // return to the interpreter's stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 // Because we have a full sized interpreter frame on the youngest
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 // activation the stack is pushed too deep to share the tosca to
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 // stack converters directly. We shrink the stack to the desired
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 // amount and then push result and then re-extend the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 // We could have the code in size_activation layout a short
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 // frame for the top activation but that would look different
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 // than say sparc (which needs a full size activation because
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 // the windows are in the way. Really it could be short? QQQ
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 __ bind(return_from_deopt_common);
a61af66fc99e Initial load
duke
parents:
diff changeset
1561
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1562 __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1563
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 // setup rsp so we can push the "result" as needed.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1565 __ movptr(rsp, STATE(_stack)); // trim stack (is prepushed)
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1566 __ addptr(rsp, wordSize); // undo prepush
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1567
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 ExternalAddress tosca_to_stack((address)CppInterpreter::_tosca_to_stack);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1569 // Address index(noreg, rcx, Address::times_ptr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1570 __ movptr(rcx, ArrayAddress(tosca_to_stack, Address(noreg, rcx, Address::times_ptr)));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1571 // __ movl(rcx, Address(noreg, rcx, Address::times_ptr, int(AbstractInterpreter::_tosca_to_stack)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 __ call(rcx); // call result converter
a61af66fc99e Initial load
duke
parents:
diff changeset
1573
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 __ movl(STATE(_msg), (int)BytecodeInterpreter::deopt_resume);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1575 __ lea(rsp, Address(rsp, -wordSize)); // prepush stack (result if any already present)
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1576 __ movptr(STATE(_stack), rsp); // inform interpreter of new stack depth (parameters removed,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 // result if any on stack already )
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1578 __ movptr(rsp, STATE(_stack_limit)); // restore expression stack to full depth
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1580
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 // Generate the code to handle a more_monitors message from the c++ interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 void CppInterpreterGenerator::generate_more_monitors() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1583
a61af66fc99e Initial load
duke
parents:
diff changeset
1584
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 Label entry, loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1587 // 1. compute new pointers // rsp: old expression stack top
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1588 __ movptr(rdx, STATE(_stack_base)); // rdx: old expression stack bottom
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1589 __ subptr(rsp, entry_size); // move expression stack top limit
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1590 __ subptr(STATE(_stack), entry_size); // update interpreter stack top
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1591 __ subptr(STATE(_stack_limit), entry_size); // inform interpreter
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1592 __ subptr(rdx, entry_size); // move expression stack bottom
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1593 __ movptr(STATE(_stack_base), rdx); // inform interpreter
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1594 __ movptr(rcx, STATE(_stack)); // set start value for copy loop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 __ jmp(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 // 2. move expression stack contents
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 __ bind(loop);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1598 __ movptr(rbx, Address(rcx, entry_size)); // load expression stack word from old location
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1599 __ movptr(Address(rcx, 0), rbx); // and store it at new location
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1600 __ addptr(rcx, wordSize); // advance to next word
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 __ bind(entry);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1602 __ cmpptr(rcx, rdx); // check if bottom reached
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1603 __ jcc(Assembler::notEqual, loop); // if not at bottom then copy next word
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 // now zero the slot so we can find it.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1605 __ movptr(Address(rdx, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 __ movl(STATE(_msg), (int)BytecodeInterpreter::got_monitors);
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1608
a61af66fc99e Initial load
duke
parents:
diff changeset
1609
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 // Initial entry to C++ interpreter from the call_stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 // This entry point is called the frame manager since it handles the generation
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 // of interpreter activation frames via requests directly from the vm (via call_stub)
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 // and via requests from the interpreter. The requests from the call_stub happen
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 // directly thru the entry point. Requests from the interpreter happen via returning
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 // from the interpreter and examining the message the interpreter has returned to
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 // the frame manager. The frame manager can take the following requests:
a61af66fc99e Initial load
duke
parents:
diff changeset
1617
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 // NO_REQUEST - error, should never happen.
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 // MORE_MONITORS - need a new monitor. Shuffle the expression stack on down and
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 // allocate a new monitor.
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 // CALL_METHOD - setup a new activation to call a new method. Very similar to what
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 // happens during entry during the entry via the call stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 // RETURN_FROM_METHOD - remove an activation. Return to interpreter or call stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 //
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1627 // rbx: Method*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 // rcx: receiver - unused (retrieved from stack as needed)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1629 // rsi/r13: previous frame manager state (NULL from the call_stub/c1/c2)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 // Stack layout at entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 // [ return address ] <--- rsp
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 // [ parameter n ]
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 // ...
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 // [ parameter 1 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 // [ expression stack ]
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 // We are free to blow any registers we like because the call_stub which brought us here
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 // initially has preserved the callee save registers already.
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1645
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 static address interpreter_frame_manager = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1647
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 address InterpreterGenerator::generate_normal_entry(bool synchronized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1649
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1650 // rbx: Method*
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1651 // rsi/r13: sender sp
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1652
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 // Because we redispatch "recursive" interpreter entries thru this same entry point
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 // the "input" register usage is a little strange and not what you expect coming
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 // from the call_stub. From the call stub rsi/rdi (current/previous) interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 // state are NULL but on "recursive" dispatches they are what you'd expect.
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 // rsi: current interpreter state (C++ interpreter) must preserve (null from call_stub/c1/c2)
a61af66fc99e Initial load
duke
parents:
diff changeset
1658
a61af66fc99e Initial load
duke
parents:
diff changeset
1659
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 // A single frame manager is plenty as we don't specialize for synchronized. We could and
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 // the code is pretty much ready. Would need to change the test below and for good measure
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 // modify generate_interpreter_state to only do the (pre) sync stuff stuff for synchronized
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 // routines. Not clear this is worth it yet.
a61af66fc99e Initial load
duke
parents:
diff changeset
1664
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 if (interpreter_frame_manager) return interpreter_frame_manager;
a61af66fc99e Initial load
duke
parents:
diff changeset
1666
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 address entry_point = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1668
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 // Fast accessor methods share this entry point.
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 // This works because frame manager is in the same codelet
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 if (UseFastAccessorMethods && !synchronized) __ bind(fast_accessor_slow_entry_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
1672
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 Label dispatch_entry_2;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1674 __ movptr(rcx, sender_sp_on_entry);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1675 __ movptr(state, (int32_t)NULL_WORD); // no current activation
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1676
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 __ jmp(dispatch_entry_2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1678
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 const Register locals = rdi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1680
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 Label re_dispatch;
a61af66fc99e Initial load
duke
parents:
diff changeset
1682
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 __ bind(re_dispatch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1684
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 // save sender sp (doesn't include return address
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1686 __ lea(rcx, Address(rsp, wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1687
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 __ bind(dispatch_entry_2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1689
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 // save sender sp
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1691 __ push(rcx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1692
7402
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
1693 const Address constMethod (rbx, Method::const_offset());
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1694 const Address access_flags (rbx, Method::access_flags_offset());
7402
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
1695 const Address size_of_parameters(rdx, ConstMethod::size_of_parameters_offset());
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
1696 const Address size_of_locals (rdx, ConstMethod::size_of_locals_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1697
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 // const Address monitor_block_top (rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 // const Address monitor_block_bot (rbp, frame::interpreter_frame_initial_sp_offset * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 // const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset * wordSize - (int)sizeof(BasicObjectLock));
a61af66fc99e Initial load
duke
parents:
diff changeset
1701
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 // get parameter size (always needed)
7402
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
1703 __ movptr(rdx, constMethod);
622
56aae7be60d4 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 605
diff changeset
1704 __ load_unsigned_short(rcx, size_of_parameters);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1705
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1706 // rbx: Method*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 // rcx: size of parameters
622
56aae7be60d4 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 605
diff changeset
1708 __ load_unsigned_short(rdx, size_of_locals); // get size of locals in words
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1709
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1710 __ subptr(rdx, rcx); // rdx = no. of additional locals
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1711
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 // see if we've got enough room on the stack for locals plus overhead.
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 generate_stack_overflow_check(); // C++
a61af66fc99e Initial load
duke
parents:
diff changeset
1714
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 // c++ interpreter does not use stack banging or any implicit exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 // leave for now to verify that check is proper.
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 bang_stack_shadow_pages(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1718
a61af66fc99e Initial load
duke
parents:
diff changeset
1719
a61af66fc99e Initial load
duke
parents:
diff changeset
1720
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 // compute beginning of parameters (rdi)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1722 __ lea(locals, Address(rsp, rcx, Address::times_ptr, wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1723
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 // save sender's sp
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 // __ movl(rcx, rsp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1726
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 // get sender's sp
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1728 __ pop(rcx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1729
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 // get return address
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1731 __ pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1732
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 // rdx - # of additional locals
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 // allocate space for locals
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 // explicitly initialize locals
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 Label exit, loop;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1738 __ testl(rdx, rdx); // (32bit ok)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 __ jcc(Assembler::lessEqual, exit); // do nothing if rdx <= 0
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 __ bind(loop);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1741 __ push((int32_t)NULL_WORD); // initialize local variables
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 __ decrement(rdx); // until everything initialized
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 __ jcc(Assembler::greater, loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 __ bind(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1746
a61af66fc99e Initial load
duke
parents:
diff changeset
1747
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 // Assumes rax = return address
a61af66fc99e Initial load
duke
parents:
diff changeset
1749
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 // allocate and initialize new interpreterState and method expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 // IN(locals) -> locals
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 // IN(state) -> any current interpreter activation
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 // destroys rax, rcx, rdx, rdi
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 // OUT (state) -> new interpreterState
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 // OUT(rsp) -> bottom of methods expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1756
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 generate_compute_interpreter_state(state, locals, rcx, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1758
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 // Call interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1760
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 Label call_interpreter;
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 __ bind(call_interpreter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1763
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 // c++ interpreter does not use stack banging or any implicit exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 // leave for now to verify that check is proper.
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 bang_stack_shadow_pages(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1767
a61af66fc99e Initial load
duke
parents:
diff changeset
1768
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 // Call interpreter enter here if message is
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 // set and we know stack size is valid
a61af66fc99e Initial load
duke
parents:
diff changeset
1771
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 Label call_interpreter_2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1773
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 __ bind(call_interpreter_2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1775
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1777 const Register thread = NOT_LP64(rcx) LP64_ONLY(r15_thread);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1778
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1779 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1780 __ mov(c_rarg0, state);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1781 #else
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1782 __ push(state); // push arg to interpreter
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1783 __ movptr(thread, STATE(_thread));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1784 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1785
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 // We can setup the frame anchor with everything we want at this point
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 // as we are thread_in_Java and no safepoints can occur until we go to
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 // vm mode. We do have to clear flags on return from vm but that is it
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 //
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1790 __ movptr(Address(thread, JavaThread::last_Java_fp_offset()), rbp);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1791 __ movptr(Address(thread, JavaThread::last_Java_sp_offset()), rsp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1792
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 // Call the interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1794
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 RuntimeAddress normal(CAST_FROM_FN_PTR(address, BytecodeInterpreter::run));
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 RuntimeAddress checking(CAST_FROM_FN_PTR(address, BytecodeInterpreter::runWithChecks));
a61af66fc99e Initial load
duke
parents:
diff changeset
1797
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 __ call(JvmtiExport::can_post_interpreter_events() ? checking : normal);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1799 NOT_LP64(__ pop(rax);) // discard parameter to run
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 // state is preserved since it is callee saved
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1803
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 // reset_last_Java_frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1805
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1806 NOT_LP64(__ movl(thread, STATE(_thread));)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 __ reset_last_Java_frame(thread, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1809
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 // examine msg from interpreter to determine next action
a61af66fc99e Initial load
duke
parents:
diff changeset
1811
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 __ movl(rdx, STATE(_msg)); // Get new message
a61af66fc99e Initial load
duke
parents:
diff changeset
1813
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 Label call_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 Label return_from_interpreted_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 Label throw_exception;
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 Label bad_msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 Label do_OSR;
a61af66fc99e Initial load
duke
parents:
diff changeset
1819
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1820 __ cmpl(rdx, (int32_t)BytecodeInterpreter::call_method);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 __ jcc(Assembler::equal, call_method);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1822 __ cmpl(rdx, (int32_t)BytecodeInterpreter::return_from_method);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 __ jcc(Assembler::equal, return_from_interpreted_method);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1824 __ cmpl(rdx, (int32_t)BytecodeInterpreter::do_osr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 __ jcc(Assembler::equal, do_OSR);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1826 __ cmpl(rdx, (int32_t)BytecodeInterpreter::throwing_exception);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 __ jcc(Assembler::equal, throw_exception);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1828 __ cmpl(rdx, (int32_t)BytecodeInterpreter::more_monitors);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 __ jcc(Assembler::notEqual, bad_msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1830
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 // Allocate more monitor space, shuffle expression stack....
a61af66fc99e Initial load
duke
parents:
diff changeset
1832
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 generate_more_monitors();
a61af66fc99e Initial load
duke
parents:
diff changeset
1834
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 __ jmp(call_interpreter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1836
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 // uncommon trap needs to jump to here to enter the interpreter (re-execute current bytecode)
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 unctrap_frame_manager_entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 // Load the registers we need.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1841 __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter)));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1842 __ movptr(rsp, STATE(_stack_limit)); // restore expression stack to full depth
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 __ jmp(call_interpreter_2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1844
a61af66fc99e Initial load
duke
parents:
diff changeset
1845
a61af66fc99e Initial load
duke
parents:
diff changeset
1846
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 // Returning from a compiled method into a deopted method. The bytecode at the
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 // bcp has completed. The result of the bytecode is in the native abi (the tosca
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 // for the template based interpreter). Any stack space that was used by the
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 // bytecode that has completed has been removed (e.g. parameters for an invoke)
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 // so all that we have to do is place any pending result on the expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 // and resume execution on the next bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
1854
a61af66fc99e Initial load
duke
parents:
diff changeset
1855
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 generate_deopt_handling();
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 __ jmp(call_interpreter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1858
a61af66fc99e Initial load
duke
parents:
diff changeset
1859
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 // Current frame has caught an exception we need to dispatch to the
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 // handler. We can get here because a native interpreter frame caught
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 // an exception in which case there is no handler and we must rethrow
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 // If it is a vanilla interpreted frame the we simply drop into the
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 // interpreter and let it do the lookup.
a61af66fc99e Initial load
duke
parents:
diff changeset
1865
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 Interpreter::_rethrow_exception_entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 // rax: exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 // rdx: return address/pc that threw exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1869
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 Label return_with_exception;
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 Label unwind_and_forward;
a61af66fc99e Initial load
duke
parents:
diff changeset
1872
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 // restore state pointer.
520
52a431267315 6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents: 337
diff changeset
1874 __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter)));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1875
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1876 __ movptr(rbx, STATE(_method)); // get method
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1877 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1878 __ movptr(Address(r15_thread, Thread::pending_exception_offset()), rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1879 #else
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 __ movl(rcx, STATE(_thread)); // get thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1881
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 // Store exception with interpreter will expect it
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1883 __ movptr(Address(rcx, Thread::pending_exception_offset()), rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1884 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1885
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 // is current frame vanilla or native?
a61af66fc99e Initial load
duke
parents:
diff changeset
1887
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 __ movl(rdx, access_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 __ testl(rdx, JVM_ACC_NATIVE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 __ jcc(Assembler::zero, return_with_exception); // vanilla interpreted frame, handle directly
a61af66fc99e Initial load
duke
parents:
diff changeset
1891
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 // We drop thru to unwind a native interpreted frame with a pending exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 // We jump here for the initial interpreter frame with exception pending
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 // We unwind the current acivation and forward it to our caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
1895
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 __ bind(unwind_and_forward);
a61af66fc99e Initial load
duke
parents:
diff changeset
1897
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 // unwind rbp, return stack to unextended value and re-push return address
a61af66fc99e Initial load
duke
parents:
diff changeset
1899
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1900 __ movptr(rcx, STATE(_sender_sp));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 __ leave();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1902 __ pop(rdx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1903 __ mov(rsp, rcx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1904 __ push(rdx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1906
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 // Return point from a call which returns a result in the native abi
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 // (c1/c2/jni-native). This result must be processed onto the java
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 // expression stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 // A pending exception may be present in which case there is no result present
a61af66fc99e Initial load
duke
parents:
diff changeset
1912
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 Label resume_interpreter;
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 Label do_float;
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 Label do_double;
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 Label done_conv;
a61af66fc99e Initial load
duke
parents:
diff changeset
1917
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 if (UseSSE < 2) {
520
52a431267315 6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents: 337
diff changeset
1920 __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter)));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1921 __ movptr(rbx, STATE(_result._to_call._callee)); // get method just executed
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1922 __ movl(rcx, Address(rbx, Method::result_index_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 __ cmpl(rcx, AbstractInterpreter::BasicType_as_index(T_FLOAT)); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 __ jcc(Assembler::equal, do_float);
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 __ cmpl(rcx, AbstractInterpreter::BasicType_as_index(T_DOUBLE)); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 __ jcc(Assembler::equal, do_double);
520
52a431267315 6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents: 337
diff changeset
1927 #if !defined(_LP64) || defined(COMPILER1) || !defined(COMPILER2)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 __ empty_FPU_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 #endif // COMPILER2
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 __ jmp(done_conv);
a61af66fc99e Initial load
duke
parents:
diff changeset
1931
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 __ bind(do_float);
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 #ifdef COMPILER2
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 for (int i = 1; i < 8; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 __ ffree(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 #endif // COMPILER2
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 __ jmp(done_conv);
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 __ bind(do_double);
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 #ifdef COMPILER2
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 for (int i = 1; i < 8; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 __ ffree(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 #endif // COMPILER2
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 __ jmp(done_conv);
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 __ MacroAssembler::verify_FPU(0, "generate_return_entry_for compiled");
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 __ jmp(done_conv);
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1950
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 // Return point to interpreter from compiled/native method
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 InternalAddress return_from_native_method(__ pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
1953
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 __ bind(done_conv);
a61af66fc99e Initial load
duke
parents:
diff changeset
1955
a61af66fc99e Initial load
duke
parents:
diff changeset
1956
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 // Result if any is in tosca. The java expression stack is in the state that the
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 // calling convention left it (i.e. params may or may not be present)
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 // Copy the result from tosca and place it on java expression stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1960
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1961 // Restore rsi/r13 as compiled code may not preserve it
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1962
520
52a431267315 6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents: 337
diff changeset
1963 __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1964
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 // restore stack to what we had when we left (in case i2c extended it)
a61af66fc99e Initial load
duke
parents:
diff changeset
1966
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1967 __ movptr(rsp, STATE(_stack));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1968 __ lea(rsp, Address(rsp, wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1969
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 // If there is a pending exception then we don't really have a result to process
a61af66fc99e Initial load
duke
parents:
diff changeset
1971
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1972 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1973 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1974 #else
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1975 __ movptr(rcx, STATE(_thread)); // get thread
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1976 __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
520
52a431267315 6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents: 337
diff changeset
1977 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 __ jcc(Assembler::notZero, return_with_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
1979
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 // get method just executed
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1981 __ movptr(rbx, STATE(_result._to_call._callee));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1982
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 // callee left args on top of expression stack, remove them
7402
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
1984 __ movptr(rcx, constMethod);
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
1985 __ load_unsigned_short(rcx, Address(rcx, ConstMethod::size_of_parameters_offset()));
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
1986
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1987 __ lea(rsp, Address(rsp, rcx, Address::times_ptr));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1988
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1989 __ movl(rcx, Address(rbx, Method::result_index_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 ExternalAddress tosca_to_stack((address)CppInterpreter::_tosca_to_stack);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1991 // Address index(noreg, rax, Address::times_ptr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1992 __ movptr(rcx, ArrayAddress(tosca_to_stack, Address(noreg, rcx, Address::times_ptr)));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1993 // __ movl(rcx, Address(noreg, rcx, Address::times_ptr, int(AbstractInterpreter::_tosca_to_stack)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 __ call(rcx); // call result converter
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 __ jmp(resume_interpreter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1996
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 // An exception is being caught on return to a vanilla interpreter frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 // Empty the stack and resume interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1999
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 __ bind(return_with_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
2001
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 // Exception present, empty stack
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2003 __ movptr(rsp, STATE(_stack_base));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 __ jmp(resume_interpreter);
a61af66fc99e Initial load
duke
parents:
diff changeset
2005
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 // Return from interpreted method we return result appropriate to the caller (i.e. "recursive"
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 // interpreter call, or native) and unwind this interpreter activation.
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 // All monitors should be unlocked.
a61af66fc99e Initial load
duke
parents:
diff changeset
2009
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 __ bind(return_from_interpreted_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
2011
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 Label return_to_initial_caller;
a61af66fc99e Initial load
duke
parents:
diff changeset
2013
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2014 __ movptr(rbx, STATE(_method)); // get method just executed
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2015 __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from "recursive" interpreter call?
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2016 __ movl(rax, Address(rbx, Method::result_index_offset())); // get result type index
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 __ jcc(Assembler::equal, return_to_initial_caller); // back to native code (call_stub/c1/c2)
a61af66fc99e Initial load
duke
parents:
diff changeset
2018
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 // Copy result to callers java stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 ExternalAddress stack_to_stack((address)CppInterpreter::_stack_to_stack);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2021 // Address index(noreg, rax, Address::times_ptr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2022
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2023 __ movptr(rax, ArrayAddress(stack_to_stack, Address(noreg, rax, Address::times_ptr)));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2024 // __ movl(rax, Address(noreg, rax, Address::times_ptr, int(AbstractInterpreter::_stack_to_stack)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 __ call(rax); // call result converter
a61af66fc99e Initial load
duke
parents:
diff changeset
2026
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 Label unwind_recursive_activation;
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 __ bind(unwind_recursive_activation);
a61af66fc99e Initial load
duke
parents:
diff changeset
2029
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 // returning to interpreter method from "recursive" interpreter call
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 // result converter left rax pointing to top of the java stack for method we are returning
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 // to. Now all we must do is unwind the state from the completed call
a61af66fc99e Initial load
duke
parents:
diff changeset
2033
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2034 __ movptr(state, STATE(_prev_link)); // unwind state
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 __ leave(); // pop the frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2036 __ mov(rsp, rax); // unwind stack to remove args
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2037
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 // Resume the interpreter. The current frame contains the current interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 // state object.
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2041
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 __ bind(resume_interpreter);
a61af66fc99e Initial load
duke
parents:
diff changeset
2043
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 // state == interpreterState object for method we are resuming
a61af66fc99e Initial load
duke
parents:
diff changeset
2045
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 __ movl(STATE(_msg), (int)BytecodeInterpreter::method_resume);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2047 __ lea(rsp, Address(rsp, -wordSize)); // prepush stack (result if any already present)
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2048 __ movptr(STATE(_stack), rsp); // inform interpreter of new stack depth (parameters removed,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 // result if any on stack already )
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2050 __ movptr(rsp, STATE(_stack_limit)); // restore expression stack to full depth
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 __ jmp(call_interpreter_2); // No need to bang
a61af66fc99e Initial load
duke
parents:
diff changeset
2052
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 // interpreter returning to native code (call_stub/c1/c2)
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 // convert result and unwind initial activation
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 // rax - result index
a61af66fc99e Initial load
duke
parents:
diff changeset
2056
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 __ bind(return_to_initial_caller);
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 ExternalAddress stack_to_native((address)CppInterpreter::_stack_to_native_abi);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2059 // Address index(noreg, rax, Address::times_ptr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2060
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2061 __ movptr(rax, ArrayAddress(stack_to_native, Address(noreg, rax, Address::times_ptr)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 __ call(rax); // call result converter
a61af66fc99e Initial load
duke
parents:
diff changeset
2063
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 Label unwind_initial_activation;
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 __ bind(unwind_initial_activation);
a61af66fc99e Initial load
duke
parents:
diff changeset
2066
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 // RETURN TO CALL_STUB/C1/C2 code (result if any in rax/rdx ST(0))
a61af66fc99e Initial load
duke
parents:
diff changeset
2068
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 /* Current stack picture
a61af66fc99e Initial load
duke
parents:
diff changeset
2070
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 [ incoming parameters ]
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 [ extra locals ]
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 [ return address to CALL_STUB/C1/C2]
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 fp -> [ CALL_STUB/C1/C2 fp ]
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 BytecodeInterpreter object
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 sp ->
a61af66fc99e Initial load
duke
parents:
diff changeset
2078
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 */
a61af66fc99e Initial load
duke
parents:
diff changeset
2080
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 // return restoring the stack to the original sender_sp value
a61af66fc99e Initial load
duke
parents:
diff changeset
2082
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2083 __ movptr(rcx, STATE(_sender_sp));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 __ leave();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2085 __ pop(rdi); // get return address
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 // set stack to sender's sp
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2087 __ mov(rsp, rcx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 __ jmp(rdi); // return to call_stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2089
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 // OSR request, adjust return address to make current frame into adapter frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 // and enter OSR nmethod
a61af66fc99e Initial load
duke
parents:
diff changeset
2092
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 __ bind(do_OSR);
a61af66fc99e Initial load
duke
parents:
diff changeset
2094
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 Label remove_initial_frame;
a61af66fc99e Initial load
duke
parents:
diff changeset
2096
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 // We are going to pop this frame. Is there another interpreter frame underneath
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 // it or is it callstub/compiled?
a61af66fc99e Initial load
duke
parents:
diff changeset
2099
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 // Move buffer to the expected parameter location
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2101 __ movptr(rcx, STATE(_result._osr._osr_buf));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2102
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2103 __ movptr(rax, STATE(_result._osr._osr_entry));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2104
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2105 __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from "recursive" interpreter call?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 __ jcc(Assembler::equal, remove_initial_frame); // back to native code (call_stub/c1/c2)
a61af66fc99e Initial load
duke
parents:
diff changeset
2107
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2108 __ movptr(sender_sp_on_entry, STATE(_sender_sp)); // get sender's sp in expected register
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 __ leave(); // pop the frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2110 __ mov(rsp, sender_sp_on_entry); // trim any stack expansion
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2111
a61af66fc99e Initial load
duke
parents:
diff changeset
2112
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 // We know we are calling compiled so push specialized return
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 // method uses specialized entry, push a return so we look like call stub setup
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 // this path will handle fact that result is returned in registers and not
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 // on the java stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
2117
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 __ pushptr(return_from_native_method.addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
2119
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 __ jmp(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2121
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 __ bind(remove_initial_frame);
a61af66fc99e Initial load
duke
parents:
diff changeset
2123
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2124 __ movptr(rdx, STATE(_sender_sp));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 __ leave();
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 // get real return
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2127 __ pop(rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 // set stack to sender's sp
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2129 __ mov(rsp, rdx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 // repush real return
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2131 __ push(rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 // Enter OSR nmethod
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 __ jmp(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2134
a61af66fc99e Initial load
duke
parents:
diff changeset
2135
a61af66fc99e Initial load
duke
parents:
diff changeset
2136
a61af66fc99e Initial load
duke
parents:
diff changeset
2137
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 // Call a new method. All we do is (temporarily) trim the expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 // push a return address to bring us back to here and leap to the new entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
2140
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 __ bind(call_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
2142
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 // stack points to next free location and not top element on expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 // method expects sp to be pointing to topmost element
a61af66fc99e Initial load
duke
parents:
diff changeset
2145
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2146 __ movptr(rsp, STATE(_stack)); // pop args to c++ interpreter, set sp to java stack top
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2147 __ lea(rsp, Address(rsp, wordSize));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2148
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2149 __ movptr(rbx, STATE(_result._to_call._callee)); // get method to execute
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2150
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 // don't need a return address if reinvoking interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
2152
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 // Make it look like call_stub calling conventions
a61af66fc99e Initial load
duke
parents:
diff changeset
2154
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 // Get (potential) receiver
7402
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
2156 // get size of parameters in words
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
2157 __ movptr(rcx, constMethod);
fd74228fd5ca 8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents: 7206
diff changeset
2158 __ load_unsigned_short(rcx, Address(rcx, ConstMethod::size_of_parameters_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2159
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 ExternalAddress recursive(CAST_FROM_FN_PTR(address, RecursiveInterpreterActivation));
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 __ pushptr(recursive.addr()); // make it look good in the debugger
a61af66fc99e Initial load
duke
parents:
diff changeset
2162
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 InternalAddress entry(entry_point);
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 __ cmpptr(STATE(_result._to_call._callee_entry_point), entry.addr()); // returning to interpreter?
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 __ jcc(Assembler::equal, re_dispatch); // yes
a61af66fc99e Initial load
duke
parents:
diff changeset
2166
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2167 __ pop(rax); // pop dummy address
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2168
a61af66fc99e Initial load
duke
parents:
diff changeset
2169
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 // get specialized entry
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2171 __ movptr(rax, STATE(_result._to_call._callee_entry_point));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 // set sender SP
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2173 __ mov(sender_sp_on_entry, rsp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2174
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 // method uses specialized entry, push a return so we look like call stub setup
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 // this path will handle fact that result is returned in registers and not
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 // on the java stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
2178
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 __ pushptr(return_from_native_method.addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
2180
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 __ jmp(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2182
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 __ bind(bad_msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 __ stop("Bad message from interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
2185
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 // Interpreted method "returned" with an exception pass it on...
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 // Pass result, unwind activation and continue/return to interpreter/call_stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 // We handle result (if any) differently based on return to interpreter or call_stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2189
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 Label unwind_initial_with_pending_exception;
a61af66fc99e Initial load
duke
parents:
diff changeset
2191
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 __ bind(throw_exception);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2193 __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from recursive interpreter call?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 __ jcc(Assembler::equal, unwind_initial_with_pending_exception); // no, back to native code (call_stub/c1/c2)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2195 __ movptr(rax, STATE(_locals)); // pop parameters get new stack value
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2196 __ addptr(rax, wordSize); // account for prepush before we return
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 __ jmp(unwind_recursive_activation);
a61af66fc99e Initial load
duke
parents:
diff changeset
2198
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 __ bind(unwind_initial_with_pending_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
2200
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 // We will unwind the current (initial) interpreter frame and forward
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 // the exception to the caller. We must put the exception in the
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 // expected register and clear pending exception and then forward.
a61af66fc99e Initial load
duke
parents:
diff changeset
2204
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 __ jmp(unwind_and_forward);
a61af66fc99e Initial load
duke
parents:
diff changeset
2206
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 interpreter_frame_manager = entry_point;
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 return entry_point;
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2210
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 address AbstractInterpreterGenerator::generate_method_entry(AbstractInterpreter::MethodKind kind) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 // determine code generation flags
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 bool synchronized = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 address entry_point = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2215
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 switch (kind) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 case Interpreter::zerolocals : break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 case Interpreter::zerolocals_synchronized: synchronized = true; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 case Interpreter::native : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 case Interpreter::accessor : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 case Interpreter::abstract : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); break;
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 628
diff changeset
2224 case Interpreter::method_handle : entry_point = ((InterpreterGenerator*)this)->generate_method_handle_entry(); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2225
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 case Interpreter::java_lang_math_sin : // fall thru
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 case Interpreter::java_lang_math_cos : // fall thru
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 case Interpreter::java_lang_math_tan : // fall thru
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 case Interpreter::java_lang_math_abs : // fall thru
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 case Interpreter::java_lang_math_log : // fall thru
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 case Interpreter::java_lang_math_log10 : // fall thru
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 case Interpreter::java_lang_math_sqrt : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind); break;
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
2233 case Interpreter::java_lang_ref_reference_get
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2245
diff changeset
2234 : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 default : ShouldNotReachHere(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2237
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 if (entry_point) return entry_point;
a61af66fc99e Initial load
duke
parents:
diff changeset
2239
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 return ((InterpreterGenerator*)this)->generate_normal_entry(synchronized);
a61af66fc99e Initial load
duke
parents:
diff changeset
2241
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2243
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 InterpreterGenerator::InterpreterGenerator(StubQueue* code)
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 : CppInterpreterGenerator(code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 generate_all(); // down here so it can be "virtual"
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2248
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 // Deoptimization helpers for C++ interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
2250
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 // How much stack a method activation needs in words.
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2252 int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2253
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 const int stub_code = 4; // see generate_call_stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 // Save space for one monitor to get into the interpreted method in case
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 // the method is synchronized
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 int monitor_size = method->is_synchronized() ?
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 1*frame::interpreter_frame_monitor_size() : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2259
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 // total static overhead size. Account for interpreter state object, return
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 // address, saved rbp and 2 words for a "static long no_params() method" issue.
a61af66fc99e Initial load
duke
parents:
diff changeset
2262
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 const int overhead_size = sizeof(BytecodeInterpreter)/wordSize +
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 ( frame::sender_sp_offset - frame::link_offset) + 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2265
10393
603ca7e51354 8010460: Interpreter on some platforms loads ConstMethod::_max_stack and misses extra stack slots for JSR 292
roland
parents: 10105
diff changeset
2266 const int method_stack = (method->max_locals() + method->max_stack()) *
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2267 Interpreter::stackElementWords;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 return overhead_size + method_stack + stub_code;
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2270
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 // returns the activation size.
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 static int size_activation_helper(int extra_locals_size, int monitor_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 return (extra_locals_size + // the addition space for locals
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 2*BytesPerWord + // return address and saved rbp
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 2*BytesPerWord + // "static long no_params() method" issue
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 sizeof(BytecodeInterpreter) + // interpreterState
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 monitor_size); // monitors
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2279
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill,
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 frame* caller,
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 frame* current,
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2283 Method* method,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 intptr_t* locals,
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 intptr_t* stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 intptr_t* stack_base,
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 intptr_t* monitor_base,
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 intptr_t* frame_bottom,
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 bool is_top_frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 )
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 // What about any vtable?
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 to_fill->_thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 // This gets filled in later but make it something recognizable for now
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 to_fill->_bcp = method->code_base();
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 to_fill->_locals = locals;
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 to_fill->_constants = method->constants()->cache();
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 to_fill->_method = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 to_fill->_mdx = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 to_fill->_stack = stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 if (is_top_frame && JavaThread::current()->popframe_forcing_deopt_reexecution() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 to_fill->_msg = deopt_resume2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 to_fill->_msg = method_resume;
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 to_fill->_result._to_call._bcp_advance = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 to_fill->_result._to_call._callee_entry_point = NULL; // doesn't matter to anyone
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 to_fill->_result._to_call._callee = NULL; // doesn't matter to anyone
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 to_fill->_prev_link = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2311
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 to_fill->_sender_sp = caller->unextended_sp();
a61af66fc99e Initial load
duke
parents:
diff changeset
2313
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 if (caller->is_interpreted_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 interpreterState prev = caller->get_interpreterState();
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 to_fill->_prev_link = prev;
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 // *current->register_addr(GR_Iprev_state) = (intptr_t) prev;
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 // Make the prev callee look proper
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 prev->_result._to_call._callee = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 if (*prev->_bcp == Bytecodes::_invokeinterface) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 prev->_result._to_call._bcp_advance = 5;
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 prev->_result._to_call._bcp_advance = 3;
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 to_fill->_oop_temp = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 to_fill->_stack_base = stack_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 // Need +1 here because stack_base points to the word just above the first expr stack entry
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 // and stack_limit is supposed to point to the word just below the last expr stack entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 // See generate_compute_interpreter_state.
10393
603ca7e51354 8010460: Interpreter on some platforms loads ConstMethod::_max_stack and misses extra stack slots for JSR 292
roland
parents: 10105
diff changeset
2331 to_fill->_stack_limit = stack_base - (method->max_stack() + 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 to_fill->_monitor_base = (BasicObjectLock*) monitor_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
2333
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 to_fill->_self_link = to_fill;
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 assert(stack >= to_fill->_stack_limit && stack < to_fill->_stack_base,
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 "Stack top out of range");
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2338
17980
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2339
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2340 static int frame_size_helper(int max_stack,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2341 int tempcount,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2342 int moncount,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2343 int callee_param_count,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2344 int callee_locals,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2345 bool is_top_frame,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2346 int& monitor_size,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2347 int& full_frame_size) {
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2348 int extra_locals_size = (callee_locals - callee_param_count) * BytesPerWord;
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2349 monitor_size = sizeof(BasicObjectLock) * moncount;
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2350
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2351 // First calculate the frame size without any java expression stack
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2352 int short_frame_size = size_activation_helper(extra_locals_size,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2353 monitor_size);
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2354
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2355 // Now with full size expression stack
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2356 full_frame_size = short_frame_size + max_stack * BytesPerWord;
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2357
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2358 // and now with only live portion of the expression stack
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2359 short_frame_size = short_frame_size + tempcount * BytesPerWord;
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2360
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2361 // the size the activation is right now. Only top frame is full size
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2362 int frame_size = (is_top_frame ? full_frame_size : short_frame_size);
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2363 return frame_size;
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2364 }
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2365
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2366 int AbstractInterpreter::size_activation(int max_stack,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2367 int tempcount,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2368 int extra_args,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2369 int moncount,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2370 int callee_param_count,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2371 int callee_locals,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2372 bool is_top_frame) {
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2373 assert(extra_args == 0, "FIX ME");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 // NOTE: return size is in words not bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
2375
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 // Calculate the amount our frame will be adjust by the callee. For top frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 // this is zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
2378
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 // NOTE: ia64 seems to do this wrong (or at least backwards) in that it
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 // calculates the extra locals based on itself. Not what the callee does
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 // to it. So it ignores last_frame_adjust value. Seems suspicious as far
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 // as getting sender_sp correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
2383
17980
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2384 int unused_monitor_size = 0;
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2385 int unused_full_frame_size = 0;
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2386 return frame_size_helper(max_stack, tempcount, moncount, callee_param_count, callee_locals,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2387 is_top_frame, unused_monitor_size, unused_full_frame_size)/BytesPerWord;
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2388 }
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2389
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2390 void AbstractInterpreter::layout_activation(Method* method,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2391 int tempcount, //
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2392 int popframe_extra_args,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2393 int moncount,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2394 int caller_actual_parameters,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2395 int callee_param_count,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2396 int callee_locals,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2397 frame* caller,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2398 frame* interpreter_frame,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2399 bool is_top_frame,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2400 bool is_bottom_frame) {
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2401
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2402 assert(popframe_extra_args == 0, "FIX ME");
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2403 // NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state()
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2404 // does as far as allocating an interpreter frame.
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2405 // Set up the method, locals, and monitors.
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2406 // The frame interpreter_frame is guaranteed to be the right size,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2407 // as determined by a previous call to the size_activation() method.
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2408 // It is also guaranteed to be walkable even though it is in a skeletal state
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2409 // NOTE: tempcount is the current size of the java expression stack. For top most
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2410 // frames we will allocate a full sized expression stack and not the curback
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2411 // version that non-top frames have.
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2412
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2413 int monitor_size = 0;
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2414 int full_frame_size = 0;
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2415 int frame_size = frame_size_helper(method->max_stack(), tempcount, moncount, callee_param_count, callee_locals,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2416 is_top_frame, monitor_size, full_frame_size);
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2417
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 #ifdef ASSERT
17980
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2419 assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2421
17980
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2422 // MUCHO HACK
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2423
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2424 intptr_t* frame_bottom = (intptr_t*) ((intptr_t)interpreter_frame->sp() - (full_frame_size - frame_size));
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2425
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2426 /* Now fillin the interpreterState object */
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2427
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2428 // The state object is the first thing on the frame and easily located
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2429
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2430 interpreterState cur_state = (interpreterState) ((intptr_t)interpreter_frame->fp() - sizeof(BytecodeInterpreter));
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2431
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2432
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2433 // Find the locals pointer. This is rather simple on x86 because there is no
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2434 // confusing rounding at the callee to account for. We can trivially locate
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2435 // our locals based on the current fp().
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2436 // Note: the + 2 is for handling the "static long no_params() method" issue.
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2437 // (too bad I don't really remember that issue well...)
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2438
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2439 intptr_t* locals;
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2440 // If the caller is interpreted we need to make sure that locals points to the first
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2441 // argument that the caller passed and not in an area where the stack might have been extended.
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2442 // because the stack to stack to converter needs a proper locals value in order to remove the
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2443 // arguments from the caller and place the result in the proper location. Hmm maybe it'd be
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2444 // simpler if we simply stored the result in the BytecodeInterpreter object and let the c++ code
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2445 // adjust the stack?? HMMM QQQ
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2446 //
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2447 if (caller->is_interpreted_frame()) {
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2448 // locals must agree with the caller because it will be used to set the
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2449 // caller's tos when we return.
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2450 interpreterState prev = caller->get_interpreterState();
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2451 // stack() is prepushed.
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2452 locals = prev->stack() + method->size_of_parameters();
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2453 // locals = caller->unextended_sp() + (method->size_of_parameters() - 1);
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2454 if (locals != interpreter_frame->fp() + frame::sender_sp_offset + (method->max_locals() - 1) + 2) {
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2455 // os::breakpoint();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 }
17980
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2457 } else {
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2458 // this is where a c2i would have placed locals (except for the +2)
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2459 locals = interpreter_frame->fp() + frame::sender_sp_offset + (method->max_locals() - 1) + 2;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 }
17980
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2461
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2462 intptr_t* monitor_base = (intptr_t*) cur_state;
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2463 intptr_t* stack_base = (intptr_t*) ((intptr_t) monitor_base - monitor_size);
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2464 /* +1 because stack is always prepushed */
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2465 intptr_t* stack = (intptr_t*) ((intptr_t) stack_base - (tempcount + 1) * BytesPerWord);
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2466
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2467
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2468 BytecodeInterpreter::layout_interpreterState(cur_state,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2469 caller,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2470 interpreter_frame,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2471 method,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2472 locals,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2473 stack,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2474 stack_base,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2475 monitor_base,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2476 frame_bottom,
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2477 is_top_frame);
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2478
0bf37f737702 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 17850
diff changeset
2479 // BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address, interpreter_frame->fp());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2481
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 #endif // CC_INTERP (all)