annotate src/cpu/x86/vm/cppInterpreter_x86.cpp @ 4582:b24386206122

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