annotate src/cpu/x86/vm/cppInterpreter_x86.cpp @ 2368:dde920245681

6896099: Integrate CMS heap ergo with default heap sizing ergo 6627787: CMS: JVM refuses to start up with -Xms16m -Xmx16m 7000125: CMS: Anti-monotone young gen sizing with respect to maximum whole heap size specification 7027529: CMS: retire CMSUseOldDefaults flag Summary: Simplify CMS heap sizing code, relying on ergonomic initial sizing consistent with other collectors for the most part, controlling only young gen sizing to rein in pause times. Make CMS young gen sizing default statically cpu-dependant. Remove inconsistencies wrt generation sizing and policy code, allowing for the fixing for 6627787 and 7000125. For 7027529, retire the flag CMSUseOldDefaults which had been introduced as a bridge from JDK 5 to JDK 6 a number of years ago. Reviewed-by: brutisso, poonam
author ysr
date Wed, 16 Mar 2011 10:37:08 -0700
parents 638119ce7cfd
children e1162778c1c8
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
a61af66fc99e Initial load
duke
parents:
diff changeset
939 //
a61af66fc99e Initial load
duke
parents:
diff changeset
940 // C++ Interpreter stub for calling a native method.
a61af66fc99e Initial load
duke
parents:
diff changeset
941 // This sets up a somewhat different looking stack for calling the native method
a61af66fc99e Initial load
duke
parents:
diff changeset
942 // than the typical interpreter frame setup but still has the pointer to
a61af66fc99e Initial load
duke
parents:
diff changeset
943 // an interpreter state.
a61af66fc99e Initial load
duke
parents:
diff changeset
944 //
a61af66fc99e Initial load
duke
parents:
diff changeset
945
a61af66fc99e Initial load
duke
parents:
diff changeset
946 address InterpreterGenerator::generate_native_entry(bool synchronized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
947 // determine code generation flags
a61af66fc99e Initial load
duke
parents:
diff changeset
948 bool inc_counter = UseCompiler || CountCompiledCalls;
a61af66fc99e Initial load
duke
parents:
diff changeset
949
a61af66fc99e Initial load
duke
parents:
diff changeset
950 // rbx: methodOop
a61af66fc99e Initial load
duke
parents:
diff changeset
951 // rcx: receiver (unused)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
952 // 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
953 // 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
954 // to save/restore.
a61af66fc99e Initial load
duke
parents:
diff changeset
955 address entry_point = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
956
a61af66fc99e Initial load
duke
parents:
diff changeset
957 const Address size_of_parameters(rbx, methodOopDesc::size_of_parameters_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
958 const Address size_of_locals (rbx, methodOopDesc::size_of_locals_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
959 const Address invocation_counter(rbx, methodOopDesc::invocation_counter_offset() + InvocationCounter::counter_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
960 const Address access_flags (rbx, methodOopDesc::access_flags_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
961
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
962 // rsi/r13 == state/locals rdi == prevstate
0
a61af66fc99e Initial load
duke
parents:
diff changeset
963 const Register locals = rdi;
a61af66fc99e Initial load
duke
parents:
diff changeset
964
a61af66fc99e Initial load
duke
parents:
diff changeset
965 // get parameter size (always needed)
622
56aae7be60d4 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 605
diff changeset
966 __ load_unsigned_short(rcx, size_of_parameters);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
967
a61af66fc99e Initial load
duke
parents:
diff changeset
968 // rbx: methodOop
a61af66fc99e Initial load
duke
parents:
diff changeset
969 // rcx: size of parameters
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
970 __ pop(rax); // get return address
0
a61af66fc99e Initial load
duke
parents:
diff changeset
971 // for natives the size of locals is zero
a61af66fc99e Initial load
duke
parents:
diff changeset
972
a61af66fc99e Initial load
duke
parents:
diff changeset
973 // compute beginning of parameters /locals
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
974 __ lea(locals, Address(rsp, rcx, Address::times_ptr, -wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
975
a61af66fc99e Initial load
duke
parents:
diff changeset
976 // initialize fixed part of activation frame
a61af66fc99e Initial load
duke
parents:
diff changeset
977
a61af66fc99e Initial load
duke
parents:
diff changeset
978 // Assumes rax = return address
a61af66fc99e Initial load
duke
parents:
diff changeset
979
a61af66fc99e Initial load
duke
parents:
diff changeset
980 // allocate and initialize new interpreterState and method expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
981 // IN(locals) -> locals
a61af66fc99e Initial load
duke
parents:
diff changeset
982 // IN(state) -> previous frame manager state (NULL from stub/c1/c2)
a61af66fc99e Initial load
duke
parents:
diff changeset
983 // destroys rax, rcx, rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
984 // OUT (state) -> new interpreterState
a61af66fc99e Initial load
duke
parents:
diff changeset
985 // OUT(rsp) -> bottom of methods expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
986
a61af66fc99e Initial load
duke
parents:
diff changeset
987 // save sender_sp
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
988 __ mov(rcx, sender_sp_on_entry);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
989 // start with NULL previous state
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
990 __ movptr(state, (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
991 generate_compute_interpreter_state(state, locals, rcx, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
992
a61af66fc99e Initial load
duke
parents:
diff changeset
993 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
994 { Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
995 __ movptr(rax, STATE(_stack_base));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
996 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
997 // duplicate the alignment rsp got after setting stack_base
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
998 __ subptr(rax, frame::arg_reg_save_area_bytes); // windows
605
98cb887364d3 6810672: Comment typos
twisti
parents: 520
diff changeset
999 __ 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
1000 #endif // _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1001 __ cmpptr(rax, rsp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 __ stop("broken stack frame setup in interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1007
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count
a61af66fc99e Initial load
duke
parents:
diff changeset
1009
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1010 const Register unlock_thread = LP64_ONLY(r15_thread) NOT_LP64(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1011 NOT_LP64(__ movptr(unlock_thread, STATE(_thread));) // get thread
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 // Since at this point in the method invocation the exception handler
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 // would try to exit the monitor of synchronized methods which hasn't
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 // been entered yet, we set the thread local variable
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 // _do_not_unlock_if_synchronized to true. The remove_activation will
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 // check this flag.
a61af66fc99e Initial load
duke
parents:
diff changeset
1017
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1018 const Address do_not_unlock_if_synchronized(unlock_thread,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 __ movbool(do_not_unlock_if_synchronized, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1021
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 // make sure method is native & not abstract
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 __ movl(rax, access_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 __ testl(rax, JVM_ACC_NATIVE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 __ jcc(Assembler::notZero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 __ stop("tried to execute non-native method as native");
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 __ testl(rax, JVM_ACC_ABSTRACT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 __ jcc(Assembler::zero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 __ stop("tried to execute abstract method in interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1039
a61af66fc99e Initial load
duke
parents:
diff changeset
1040
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 // increment invocation count & check for overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 Label invocation_counter_overflow;
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 if (inc_counter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 generate_counter_incr(&invocation_counter_overflow, NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1046
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 Label continue_after_compile;
a61af66fc99e Initial load
duke
parents:
diff changeset
1048
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 __ bind(continue_after_compile);
a61af66fc99e Initial load
duke
parents:
diff changeset
1050
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 bang_stack_shadow_pages(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1052
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 // reset the _do_not_unlock_if_synchronized flag
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1054 NOT_LP64(__ movl(rax, STATE(_thread));) // get thread
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 __ movbool(do_not_unlock_if_synchronized, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1056
a61af66fc99e Initial load
duke
parents:
diff changeset
1057
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 // check for synchronized native methods
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 // Note: This must happen *after* invocation counter check, since
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 // when overflow happens, the method should not be locked.
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 if (synchronized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 // potentially kills rax, rcx, rdx, rdi
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 lock_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 // no synchronization necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 __ movl(rax, access_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 __ testl(rax, JVM_ACC_SYNCHRONIZED);
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 __ jcc(Assembler::zero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 __ stop("method needs synchronization");
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1077
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 // start execution
a61af66fc99e Initial load
duke
parents:
diff changeset
1079
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 // jvmti support
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 __ notify_method_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
1082
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 // work registers
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 const Register method = rbx;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1085 const Register thread = LP64_ONLY(r15_thread) NOT_LP64(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1086 const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); // rcx|rscratch1
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1087
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 // allocate space for parameters
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1089 __ movptr(method, STATE(_method));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 __ verify_oop(method);
622
56aae7be60d4 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 605
diff changeset
1091 __ load_unsigned_short(t, Address(method, methodOopDesc::size_of_parameters_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 __ shll(t, 2);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1093 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1094 __ subptr(rsp, t);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1095 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows
605
98cb887364d3 6810672: Comment typos
twisti
parents: 520
diff changeset
1096 __ 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
1097 #else
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1098 __ 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
1099 __ subptr(rsp, t);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1100 __ 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
1101 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1102
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 // get signature handler
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 Label pending_exception_present;
a61af66fc99e Initial load
duke
parents:
diff changeset
1105
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 { Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1107 __ movptr(t, Address(method, methodOopDesc::signature_handler_offset()));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1108 __ testptr(t, t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 __ jcc(Assembler::notZero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 __ 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
1111 __ movptr(method, STATE(_method));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1112 __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 __ jcc(Assembler::notEqual, pending_exception_present);
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 __ verify_oop(method);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1115 __ movptr(t, Address(method, methodOopDesc::signature_handler_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1121 __ push(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 __ get_thread(t); // get vm's javathread*
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1123 __ cmpptr(t, STATE(_thread));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 __ int3();
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 __ bind(L);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1127 __ pop(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 #endif //
a61af66fc99e Initial load
duke
parents:
diff changeset
1130
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1131 const Register from_ptr = InterpreterRuntime::SignatureHandlerGenerator::from();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 // call signature handler
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 assert(InterpreterRuntime::SignatureHandlerGenerator::to () == rsp, "adjust this code");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1134
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 // The generated handlers do not touch RBX (the method oop).
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 // However, large signatures cannot be cached and are generated
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 // each time here. The slow-path generator will blow RBX
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 // sometime, so we must reload it after the call.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1139 __ movptr(from_ptr, STATE(_locals)); // get the from pointer
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 __ call(t);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1141 __ movptr(method, STATE(_method));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 __ verify_oop(method);
a61af66fc99e Initial load
duke
parents:
diff changeset
1143
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 // result handler is in rax
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 // set result handler
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1146 __ movptr(STATE(_result_handler), rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1147
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1148
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1149 // get native function entry point
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1150 { Label L;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1151 __ movptr(rax, Address(method, methodOopDesc::native_function_offset()));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1152 __ testptr(rax, rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1153 __ jcc(Assembler::notZero, L);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1154 __ 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
1155 __ movptr(method, STATE(_method));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1156 __ verify_oop(method);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1157 __ movptr(rax, Address(method, methodOopDesc::native_function_offset()));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1158 __ bind(L);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1159 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1160
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 // pass mirror handle if static call
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 __ movl(t, Address(method, methodOopDesc::access_flags_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 __ testl(t, JVM_ACC_STATIC);
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 __ jcc(Assembler::zero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 // get mirror
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1168 __ movptr(t, Address(method, methodOopDesc:: constants_offset()));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1169 __ movptr(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes()));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1170 __ movptr(t, Address(t, mirror_offset));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 // copy mirror into activation object
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1172 __ movptr(STATE(_oop_temp), t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 // pass handle to mirror
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1174 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1175 __ lea(c_rarg1, STATE(_oop_temp));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1176 #else
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1177 __ lea(t, STATE(_oop_temp));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1178 __ movptr(Address(rsp, wordSize), t);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1179 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1185 __ push(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 __ get_thread(t); // get vm's javathread*
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1187 __ cmpptr(t, STATE(_thread));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 __ int3();
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 __ bind(L);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1191 __ pop(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 #endif //
a61af66fc99e Initial load
duke
parents:
diff changeset
1194
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 // pass JNIEnv
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1196 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1197 __ lea(c_rarg0, Address(thread, JavaThread::jni_environment_offset()));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1198 #else
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1199 __ movptr(thread, STATE(_thread)); // get thread
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1200 __ lea(t, Address(thread, JavaThread::jni_environment_offset()));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1201
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1202 __ movptr(Address(rsp, 0), t);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1203 #endif // _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1204
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1208 __ push(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 __ get_thread(t); // get vm's javathread*
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1210 __ cmpptr(t, STATE(_thread));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 __ int3();
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 __ bind(L);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1214 __ pop(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 #endif //
a61af66fc99e Initial load
duke
parents:
diff changeset
1217
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 __ movl(t, Address(thread, JavaThread::thread_state_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 __ cmpl(t, _thread_in_Java);
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 __ stop("Wrong thread state in native stub");
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1227
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 // Change state to native (we save the return address in the thread, since it might not
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 // 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
1230 // points into the right code segment. It does not have to be the correct return pc.
a61af66fc99e Initial load
duke
parents:
diff changeset
1231
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 __ set_last_Java_frame(thread, noreg, rbp, __ pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
1233
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native);
a61af66fc99e Initial load
duke
parents:
diff changeset
1235
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 __ call(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1237
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 // result potentially in rdx:rax or ST0
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1239 __ movptr(method, STATE(_method));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1240 NOT_LP64(__ movptr(thread, STATE(_thread));) // get thread
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1241
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 // The potential result is in ST(0) & rdx:rax
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 // 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
1244 // 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
1245 // 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
1246 // be destroyed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 // 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
1248 // via _last_native_pc and not via _last_jave_sp
a61af66fc99e Initial load
duke
parents:
diff changeset
1249
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1250 // 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
1251 { Label Lpush, Lskip;
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 ExternalAddress float_handler(AbstractInterpreter::result_handler(T_FLOAT));
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 ExternalAddress double_handler(AbstractInterpreter::result_handler(T_DOUBLE));
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 __ cmpptr(STATE(_result_handler), float_handler.addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 __ jcc(Assembler::equal, Lpush);
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 __ cmpptr(STATE(_result_handler), double_handler.addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 __ jcc(Assembler::notEqual, Lskip);
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 __ bind(Lpush);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1259 __ subptr(rsp, 2*wordSize);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1260 if ( UseSSE < 2 ) {
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1261 __ fstp_d(Address(rsp, 0));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1262 } else {
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1263 __ movdbl(Address(rsp, 0), xmm0);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1264 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 __ bind(Lskip);
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1267
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1268 // save rax:rdx for potential use by result handler.
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1269 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1270 #ifndef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1271 __ push(rdx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1272 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1273
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 // Either restore the MXCSR register after returning from the JNI Call
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 // or verify that it wasn't changed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 if (VM_Version::supports_sse()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 if (RestoreMXCSROnJNICalls) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 __ ldmxcsr(ExternalAddress(StubRoutines::addr_mxcsr_std()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 else if (CheckJNICalls ) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1281 __ call(RuntimeAddress(StubRoutines::x86::verify_mxcsr_entry()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1284
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1285 #ifndef _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 // Either restore the x87 floating pointer control word after returning
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 // from the JNI call or verify that it wasn't changed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 if (CheckJNICalls) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1289 __ call(RuntimeAddress(StubRoutines::x86::verify_fpu_cntrl_wrd_entry()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1291 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1292
a61af66fc99e Initial load
duke
parents:
diff changeset
1293
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 // change thread state
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native_trans);
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 if(os::is_MP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 // Write serialization page so VM thread can do a pseudo remote membar.
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 // We use the current thread pointer to calculate a thread specific
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 // offset to write to within the page. This minimizes bus traffic
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 // due to cache line collision.
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 __ serialize_memory(thread, rcx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1303
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 // check for safepoint operation in progress and/or pending suspend requests
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 { Label Continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1306
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 SafepointSynchronize::_not_synchronized);
a61af66fc99e Initial load
duke
parents:
diff changeset
1309
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 // threads running native code and they are expected to self-suspend
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 // when leaving the _thread_in_native state. We need to check for
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 // pending suspend requests here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 __ jcc(Assembler::notEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 __ cmpl(Address(thread, JavaThread::suspend_flags_offset()), 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 __ jcc(Assembler::equal, Continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1318
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 // Don't use call_VM as it will see a possible pending exception and forward it
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 // and never return here preventing us from clearing _last_native_pc down below.
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 // 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
1322 // preserved and correspond to the bcp/locals pointers.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 //
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1324
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1325 ((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
1326 thread);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 __ increment(rsp, wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1328
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1329 __ movptr(method, STATE(_method));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 __ verify_oop(method);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1331 __ movptr(thread, STATE(_thread)); // get thread
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1332
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 __ bind(Continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1335
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 // change thread state
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_Java);
a61af66fc99e Initial load
duke
parents:
diff changeset
1338
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 __ reset_last_Java_frame(thread, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1340
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 // reset handle block
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1342 __ movptr(t, Address(thread, JavaThread::active_handles_offset()));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1343 __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1344
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 // If result was an oop then unbox and save it in the frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 Label no_oop, store_result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 ExternalAddress oop_handler(AbstractInterpreter::result_handler(T_OBJECT));
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 __ cmpptr(STATE(_result_handler), oop_handler.addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 __ jcc(Assembler::notEqual, no_oop);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1351 #ifndef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1352 __ pop(rdx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1353 #endif // _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1354 __ pop(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1355 __ testptr(rax, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 __ jcc(Assembler::zero, store_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 // unbox
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1358 __ movptr(rax, Address(rax, 0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 __ bind(store_result);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1360 __ movptr(STATE(_oop_temp), rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 // 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
1362 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1363 #ifndef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1364 __ push(rdx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1365 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 __ bind(no_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1368
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 Label no_reguard;
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 __ cmpl(Address(thread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_yellow_disabled);
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 __ jcc(Assembler::notEqual, no_reguard);
a61af66fc99e Initial load
duke
parents:
diff changeset
1373
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1374 __ pusha();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 __ 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
1376 __ popa();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1377
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 __ bind(no_reguard);
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1380
a61af66fc99e Initial load
duke
parents:
diff changeset
1381
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 // QQQ Seems like for native methods we simply return and the caller will see the pending
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 // exception and do the right thing. Certainly the interpreter will, don't know about
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 // compiled methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 // 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
1386 // and forward it before doing the unlocking and notifying jvmdi that method has exited.
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 // This seems wrong need to investigate the spec.
a61af66fc99e Initial load
duke
parents:
diff changeset
1388
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 // handle exceptions (exception handling will handle unlocking!)
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 { Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1391 __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 __ jcc(Assembler::zero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 __ bind(pending_exception_present);
a61af66fc99e Initial load
duke
parents:
diff changeset
1394
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 // There are potential results on the stack (rax/rdx, ST(0)) we ignore these and simply
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 // return and let caller deal with exception. This skips the unlocking here which
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 // seems wrong but seems to be what asm interpreter did. Can't find this in the spec.
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 // Note: must preverve method in rbx
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1400
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 // remove activation
a61af66fc99e Initial load
duke
parents:
diff changeset
1402
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1403 __ movptr(t, STATE(_sender_sp));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 __ leave(); // remove frame anchor
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1405 __ pop(rdi); // get return address
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1406 __ movptr(state, STATE(_prev_link)); // get previous state for return
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1407 __ mov(rsp, t); // set sp to sender sp
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1408 __ push(rdi); // push throwing pc
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 // The skips unlocking!! This seems to be what asm interpreter does but seems
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 // very wrong. Not clear if this violates the spec.
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1414
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 // do unlocking if necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 __ movl(t, Address(method, methodOopDesc::access_flags_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 __ testl(t, JVM_ACC_SYNCHRONIZED);
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 __ jcc(Assembler::zero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 // the code below should be shared with interpreter macro assembler implementation
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 { Label unlock;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1422 const Register monitor = NOT_LP64(rdx) LP64_ONLY(c_rarg1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 // BasicObjectLock will be first in list, since this is a synchronized method. However, need
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 // 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
1425 __ movptr(monitor, STATE(_monitor_base));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1426 __ 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
1427
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1428 __ movptr(t, Address(monitor, BasicObjectLock::obj_offset_in_bytes()));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1429 __ testptr(t, t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 __ jcc(Assembler::notZero, unlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1431
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 // Entry already unlocked, need to throw exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 __ MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_illegal_monitor_state_exception));
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 __ should_not_reach_here();
a61af66fc99e Initial load
duke
parents:
diff changeset
1435
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 __ bind(unlock);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1437 __ unlock_object(monitor);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 // 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
1439 __ movptr(method, STATE(_method));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1443
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 // jvmti support
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 // Note: This must happen _after_ handling/throwing any exceptions since
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 // the exception handler code notifies the runtime of method exits
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 // too. If this happens before, method entry/exit notifications are
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 // not properly paired (was bug - gri 11/22/99).
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 __ notify_method_exit(vtos, InterpreterMacroAssembler::NotifyJVMTI);
a61af66fc99e Initial load
duke
parents:
diff changeset
1450
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 // 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
1452 #ifndef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1453 __ pop(rdx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1454 #endif // _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1455 __ pop(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1456 __ movptr(t, STATE(_result_handler)); // get result handler
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 __ call(t); // call result handler to convert to tosca form
a61af66fc99e Initial load
duke
parents:
diff changeset
1458
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 // remove activation
a61af66fc99e Initial load
duke
parents:
diff changeset
1460
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1461 __ movptr(t, STATE(_sender_sp));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1462
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 __ leave(); // remove frame anchor
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1464 __ pop(rdi); // get return address
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1465 __ 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
1466 __ mov(rsp, t); // set sp to sender sp
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 __ jmp(rdi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1468
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 // invocation counter overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 if (inc_counter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 // Handle overflow of counter and compile method
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 __ bind(invocation_counter_overflow);
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 generate_counter_overflow(&continue_after_compile);
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1475
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 return entry_point;
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1478
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 // Generate entries that will put a result type index into rcx
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 void CppInterpreterGenerator::generate_deopt_handling() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1481
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 Label return_from_deopt_common;
a61af66fc99e Initial load
duke
parents:
diff changeset
1483
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 // Generate entries that will put a result type index into rcx
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 deopt_frame_manager_return_atos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1487
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 // rax is live here
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_OBJECT)); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 __ jmp(return_from_deopt_common);
a61af66fc99e Initial load
duke
parents:
diff changeset
1491
a61af66fc99e Initial load
duke
parents:
diff changeset
1492
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 deopt_frame_manager_return_btos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1495
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 // rax is live here
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_BOOLEAN)); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 __ jmp(return_from_deopt_common);
a61af66fc99e Initial load
duke
parents:
diff changeset
1499
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 deopt_frame_manager_return_itos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1502
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 // rax is live here
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_INT)); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 __ jmp(return_from_deopt_common);
a61af66fc99e Initial load
duke
parents:
diff changeset
1506
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1508
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 deopt_frame_manager_return_ltos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 // rax,rdx are live here
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_LONG)); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 __ jmp(return_from_deopt_common);
a61af66fc99e Initial load
duke
parents:
diff changeset
1513
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1515
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 deopt_frame_manager_return_ftos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 // st(0) is live here
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_FLOAT)); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 __ jmp(return_from_deopt_common);
a61af66fc99e Initial load
duke
parents:
diff changeset
1520
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 deopt_frame_manager_return_dtos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1523
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 // st(0) is live here
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_DOUBLE)); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 __ jmp(return_from_deopt_common);
a61af66fc99e Initial load
duke
parents:
diff changeset
1527
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 // deopt needs to jump to here to enter the interpreter (return a result)
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 deopt_frame_manager_return_vtos = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1530
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 __ movl(rcx, AbstractInterpreter::BasicType_as_index(T_VOID));
a61af66fc99e Initial load
duke
parents:
diff changeset
1532
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 // Deopt return common
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 // an index is present in rcx that lets us move any possible result being
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 // return to the interpreter's stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 // Because we have a full sized interpreter frame on the youngest
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 // activation the stack is pushed too deep to share the tosca to
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 // stack converters directly. We shrink the stack to the desired
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 // amount and then push result and then re-extend the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 // We could have the code in size_activation layout a short
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 // frame for the top activation but that would look different
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 // than say sparc (which needs a full size activation because
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 // the windows are in the way. Really it could be short? QQQ
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 __ bind(return_from_deopt_common);
a61af66fc99e Initial load
duke
parents:
diff changeset
1547
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1548 __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1549
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 // setup rsp so we can push the "result" as needed.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1551 __ movptr(rsp, STATE(_stack)); // trim stack (is prepushed)
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1552 __ addptr(rsp, wordSize); // undo prepush
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1553
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 ExternalAddress tosca_to_stack((address)CppInterpreter::_tosca_to_stack);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1555 // Address index(noreg, rcx, Address::times_ptr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1556 __ 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
1557 // __ movl(rcx, Address(noreg, rcx, Address::times_ptr, int(AbstractInterpreter::_tosca_to_stack)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 __ call(rcx); // call result converter
a61af66fc99e Initial load
duke
parents:
diff changeset
1559
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 __ movl(STATE(_msg), (int)BytecodeInterpreter::deopt_resume);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1561 __ 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
1562 __ movptr(STATE(_stack), rsp); // inform interpreter of new stack depth (parameters removed,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 // result if any on stack already )
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1564 __ movptr(rsp, STATE(_stack_limit)); // restore expression stack to full depth
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1566
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 // Generate the code to handle a more_monitors message from the c++ interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 void CppInterpreterGenerator::generate_more_monitors() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1569
a61af66fc99e Initial load
duke
parents:
diff changeset
1570
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 Label entry, loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1573 // 1. compute new pointers // rsp: old expression stack top
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1574 __ movptr(rdx, STATE(_stack_base)); // rdx: old expression stack bottom
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1575 __ subptr(rsp, entry_size); // move expression stack top limit
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1576 __ subptr(STATE(_stack), entry_size); // update interpreter stack top
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1577 __ subptr(STATE(_stack_limit), entry_size); // inform interpreter
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1578 __ subptr(rdx, entry_size); // move expression stack bottom
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1579 __ movptr(STATE(_stack_base), rdx); // inform interpreter
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1580 __ movptr(rcx, STATE(_stack)); // set start value for copy loop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 __ jmp(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 // 2. move expression stack contents
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 __ bind(loop);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1584 __ 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
1585 __ movptr(Address(rcx, 0), rbx); // and store it at new location
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1586 __ addptr(rcx, wordSize); // advance to next word
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 __ bind(entry);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1588 __ cmpptr(rcx, rdx); // check if bottom reached
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1589 __ jcc(Assembler::notEqual, loop); // if not at bottom then copy next word
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 // now zero the slot so we can find it.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1591 __ movptr(Address(rdx, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 __ movl(STATE(_msg), (int)BytecodeInterpreter::got_monitors);
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1594
a61af66fc99e Initial load
duke
parents:
diff changeset
1595
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 // Initial entry to C++ interpreter from the call_stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 // This entry point is called the frame manager since it handles the generation
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 // of interpreter activation frames via requests directly from the vm (via call_stub)
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 // and via requests from the interpreter. The requests from the call_stub happen
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 // directly thru the entry point. Requests from the interpreter happen via returning
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 // from the interpreter and examining the message the interpreter has returned to
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 // the frame manager. The frame manager can take the following requests:
a61af66fc99e Initial load
duke
parents:
diff changeset
1603
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 // NO_REQUEST - error, should never happen.
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 // MORE_MONITORS - need a new monitor. Shuffle the expression stack on down and
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 // allocate a new monitor.
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 // CALL_METHOD - setup a new activation to call a new method. Very similar to what
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 // happens during entry during the entry via the call stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 // RETURN_FROM_METHOD - remove an activation. Return to interpreter or call stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 // rbx: methodOop
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 // rcx: receiver - unused (retrieved from stack as needed)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1615 // rsi/r13: previous frame manager state (NULL from the call_stub/c1/c2)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 // Stack layout at entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 // [ return address ] <--- rsp
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 // [ parameter n ]
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 // ...
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 // [ parameter 1 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 // [ expression stack ]
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 // We are free to blow any registers we like because the call_stub which brought us here
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 // initially has preserved the callee save registers already.
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1631
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 static address interpreter_frame_manager = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1633
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 address InterpreterGenerator::generate_normal_entry(bool synchronized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1635
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 // rbx: methodOop
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1637 // rsi/r13: sender sp
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1638
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 // Because we redispatch "recursive" interpreter entries thru this same entry point
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 // the "input" register usage is a little strange and not what you expect coming
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 // from the call_stub. From the call stub rsi/rdi (current/previous) interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 // state are NULL but on "recursive" dispatches they are what you'd expect.
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 // rsi: current interpreter state (C++ interpreter) must preserve (null from call_stub/c1/c2)
a61af66fc99e Initial load
duke
parents:
diff changeset
1644
a61af66fc99e Initial load
duke
parents:
diff changeset
1645
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 // A single frame manager is plenty as we don't specialize for synchronized. We could and
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 // the code is pretty much ready. Would need to change the test below and for good measure
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 // modify generate_interpreter_state to only do the (pre) sync stuff stuff for synchronized
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 // routines. Not clear this is worth it yet.
a61af66fc99e Initial load
duke
parents:
diff changeset
1650
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 if (interpreter_frame_manager) return interpreter_frame_manager;
a61af66fc99e Initial load
duke
parents:
diff changeset
1652
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 address entry_point = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1654
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 // Fast accessor methods share this entry point.
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 // This works because frame manager is in the same codelet
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 if (UseFastAccessorMethods && !synchronized) __ bind(fast_accessor_slow_entry_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
1658
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 Label dispatch_entry_2;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1660 __ movptr(rcx, sender_sp_on_entry);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1661 __ movptr(state, (int32_t)NULL_WORD); // no current activation
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1662
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 __ jmp(dispatch_entry_2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1664
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 const Register locals = rdi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1666
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 Label re_dispatch;
a61af66fc99e Initial load
duke
parents:
diff changeset
1668
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 __ bind(re_dispatch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1670
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 // save sender sp (doesn't include return address
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1672 __ lea(rcx, Address(rsp, wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1673
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 __ bind(dispatch_entry_2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1675
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 // save sender sp
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1677 __ push(rcx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1678
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 const Address size_of_parameters(rbx, methodOopDesc::size_of_parameters_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 const Address size_of_locals (rbx, methodOopDesc::size_of_locals_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 const Address access_flags (rbx, methodOopDesc::access_flags_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1682
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 // const Address monitor_block_top (rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 // const Address monitor_block_bot (rbp, frame::interpreter_frame_initial_sp_offset * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 // const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset * wordSize - (int)sizeof(BasicObjectLock));
a61af66fc99e Initial load
duke
parents:
diff changeset
1686
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 // get parameter size (always needed)
622
56aae7be60d4 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 605
diff changeset
1688 __ load_unsigned_short(rcx, size_of_parameters);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1689
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 // rbx: methodOop
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 // rcx: size of parameters
622
56aae7be60d4 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 605
diff changeset
1692 __ load_unsigned_short(rdx, size_of_locals); // get size of locals in words
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1693
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1694 __ subptr(rdx, rcx); // rdx = no. of additional locals
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1695
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 // see if we've got enough room on the stack for locals plus overhead.
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 generate_stack_overflow_check(); // C++
a61af66fc99e Initial load
duke
parents:
diff changeset
1698
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 // c++ interpreter does not use stack banging or any implicit exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 // leave for now to verify that check is proper.
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 bang_stack_shadow_pages(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1702
a61af66fc99e Initial load
duke
parents:
diff changeset
1703
a61af66fc99e Initial load
duke
parents:
diff changeset
1704
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 // compute beginning of parameters (rdi)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1706 __ lea(locals, Address(rsp, rcx, Address::times_ptr, wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1707
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 // save sender's sp
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 // __ movl(rcx, rsp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1710
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 // get sender's sp
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1712 __ pop(rcx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1713
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 // get return address
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1715 __ pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1716
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 // rdx - # of additional locals
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 // allocate space for locals
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 // explicitly initialize locals
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 Label exit, loop;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1722 __ testl(rdx, rdx); // (32bit ok)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 __ jcc(Assembler::lessEqual, exit); // do nothing if rdx <= 0
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 __ bind(loop);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1725 __ push((int32_t)NULL_WORD); // initialize local variables
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 __ decrement(rdx); // until everything initialized
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 __ jcc(Assembler::greater, loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 __ bind(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1730
a61af66fc99e Initial load
duke
parents:
diff changeset
1731
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 // Assumes rax = return address
a61af66fc99e Initial load
duke
parents:
diff changeset
1733
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 // allocate and initialize new interpreterState and method expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 // IN(locals) -> locals
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 // IN(state) -> any current interpreter activation
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 // destroys rax, rcx, rdx, rdi
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 // OUT (state) -> new interpreterState
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 // OUT(rsp) -> bottom of methods expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1740
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 generate_compute_interpreter_state(state, locals, rcx, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1742
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 // Call interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1744
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 Label call_interpreter;
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 __ bind(call_interpreter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1747
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 // c++ interpreter does not use stack banging or any implicit exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 // leave for now to verify that check is proper.
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 bang_stack_shadow_pages(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1751
a61af66fc99e Initial load
duke
parents:
diff changeset
1752
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 // Call interpreter enter here if message is
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 // set and we know stack size is valid
a61af66fc99e Initial load
duke
parents:
diff changeset
1755
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 Label call_interpreter_2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1757
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 __ bind(call_interpreter_2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1759
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1761 const Register thread = NOT_LP64(rcx) LP64_ONLY(r15_thread);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1762
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1763 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1764 __ mov(c_rarg0, state);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1765 #else
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1766 __ push(state); // push arg to interpreter
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1767 __ movptr(thread, STATE(_thread));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1768 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1769
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 // We can setup the frame anchor with everything we want at this point
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 // as we are thread_in_Java and no safepoints can occur until we go to
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 // vm mode. We do have to clear flags on return from vm but that is it
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 //
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1774 __ movptr(Address(thread, JavaThread::last_Java_fp_offset()), rbp);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1775 __ movptr(Address(thread, JavaThread::last_Java_sp_offset()), rsp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1776
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 // Call the interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1778
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 RuntimeAddress normal(CAST_FROM_FN_PTR(address, BytecodeInterpreter::run));
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 RuntimeAddress checking(CAST_FROM_FN_PTR(address, BytecodeInterpreter::runWithChecks));
a61af66fc99e Initial load
duke
parents:
diff changeset
1781
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 __ call(JvmtiExport::can_post_interpreter_events() ? checking : normal);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1783 NOT_LP64(__ pop(rax);) // discard parameter to run
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 // state is preserved since it is callee saved
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1787
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 // reset_last_Java_frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1789
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1790 NOT_LP64(__ movl(thread, STATE(_thread));)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 __ reset_last_Java_frame(thread, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1793
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 // examine msg from interpreter to determine next action
a61af66fc99e Initial load
duke
parents:
diff changeset
1795
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 __ movl(rdx, STATE(_msg)); // Get new message
a61af66fc99e Initial load
duke
parents:
diff changeset
1797
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 Label call_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 Label return_from_interpreted_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 Label throw_exception;
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 Label bad_msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 Label do_OSR;
a61af66fc99e Initial load
duke
parents:
diff changeset
1803
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1804 __ cmpl(rdx, (int32_t)BytecodeInterpreter::call_method);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 __ jcc(Assembler::equal, call_method);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1806 __ cmpl(rdx, (int32_t)BytecodeInterpreter::return_from_method);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 __ jcc(Assembler::equal, return_from_interpreted_method);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1808 __ cmpl(rdx, (int32_t)BytecodeInterpreter::do_osr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 __ jcc(Assembler::equal, do_OSR);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1810 __ cmpl(rdx, (int32_t)BytecodeInterpreter::throwing_exception);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 __ jcc(Assembler::equal, throw_exception);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1812 __ cmpl(rdx, (int32_t)BytecodeInterpreter::more_monitors);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 __ jcc(Assembler::notEqual, bad_msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1814
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 // Allocate more monitor space, shuffle expression stack....
a61af66fc99e Initial load
duke
parents:
diff changeset
1816
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 generate_more_monitors();
a61af66fc99e Initial load
duke
parents:
diff changeset
1818
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 __ jmp(call_interpreter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1820
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 // uncommon trap needs to jump to here to enter the interpreter (re-execute current bytecode)
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 unctrap_frame_manager_entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 // Load the registers we need.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1825 __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter)));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1826 __ movptr(rsp, STATE(_stack_limit)); // restore expression stack to full depth
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 __ jmp(call_interpreter_2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1828
a61af66fc99e Initial load
duke
parents:
diff changeset
1829
a61af66fc99e Initial load
duke
parents:
diff changeset
1830
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 // Returning from a compiled method into a deopted method. The bytecode at the
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 // bcp has completed. The result of the bytecode is in the native abi (the tosca
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 // for the template based interpreter). Any stack space that was used by the
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 // bytecode that has completed has been removed (e.g. parameters for an invoke)
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 // so all that we have to do is place any pending result on the expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 // and resume execution on the next bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
1838
a61af66fc99e Initial load
duke
parents:
diff changeset
1839
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 generate_deopt_handling();
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 __ jmp(call_interpreter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1842
a61af66fc99e Initial load
duke
parents:
diff changeset
1843
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 // Current frame has caught an exception we need to dispatch to the
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 // handler. We can get here because a native interpreter frame caught
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 // an exception in which case there is no handler and we must rethrow
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 // If it is a vanilla interpreted frame the we simply drop into the
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 // interpreter and let it do the lookup.
a61af66fc99e Initial load
duke
parents:
diff changeset
1849
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 Interpreter::_rethrow_exception_entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 // rax: exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 // rdx: return address/pc that threw exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1853
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 Label return_with_exception;
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 Label unwind_and_forward;
a61af66fc99e Initial load
duke
parents:
diff changeset
1856
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 // restore state pointer.
520
52a431267315 6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents: 337
diff changeset
1858 __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter)));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1859
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1860 __ movptr(rbx, STATE(_method)); // get method
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1861 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1862 __ movptr(Address(r15_thread, Thread::pending_exception_offset()), rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1863 #else
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 __ movl(rcx, STATE(_thread)); // get thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1865
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 // Store exception with interpreter will expect it
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1867 __ movptr(Address(rcx, Thread::pending_exception_offset()), rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1868 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1869
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 // is current frame vanilla or native?
a61af66fc99e Initial load
duke
parents:
diff changeset
1871
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 __ movl(rdx, access_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 __ testl(rdx, JVM_ACC_NATIVE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 __ jcc(Assembler::zero, return_with_exception); // vanilla interpreted frame, handle directly
a61af66fc99e Initial load
duke
parents:
diff changeset
1875
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 // We drop thru to unwind a native interpreted frame with a pending exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 // We jump here for the initial interpreter frame with exception pending
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 // We unwind the current acivation and forward it to our caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
1879
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 __ bind(unwind_and_forward);
a61af66fc99e Initial load
duke
parents:
diff changeset
1881
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 // unwind rbp, return stack to unextended value and re-push return address
a61af66fc99e Initial load
duke
parents:
diff changeset
1883
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1884 __ movptr(rcx, STATE(_sender_sp));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 __ leave();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1886 __ pop(rdx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1887 __ mov(rsp, rcx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1888 __ push(rdx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1890
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 // Return point from a call which returns a result in the native abi
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 // (c1/c2/jni-native). This result must be processed onto the java
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 // expression stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 // A pending exception may be present in which case there is no result present
a61af66fc99e Initial load
duke
parents:
diff changeset
1896
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 Label resume_interpreter;
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 Label do_float;
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 Label do_double;
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 Label done_conv;
a61af66fc99e Initial load
duke
parents:
diff changeset
1901
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 if (UseSSE < 2) {
520
52a431267315 6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents: 337
diff changeset
1904 __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter)));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1905 __ movptr(rbx, STATE(_result._to_call._callee)); // get method just executed
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 __ movl(rcx, Address(rbx, methodOopDesc::result_index_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 __ cmpl(rcx, AbstractInterpreter::BasicType_as_index(T_FLOAT)); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 __ jcc(Assembler::equal, do_float);
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 __ cmpl(rcx, AbstractInterpreter::BasicType_as_index(T_DOUBLE)); // Result stub address array index
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 __ jcc(Assembler::equal, do_double);
520
52a431267315 6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents: 337
diff changeset
1911 #if !defined(_LP64) || defined(COMPILER1) || !defined(COMPILER2)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 __ empty_FPU_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 #endif // COMPILER2
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 __ jmp(done_conv);
a61af66fc99e Initial load
duke
parents:
diff changeset
1915
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 __ bind(do_float);
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 #ifdef COMPILER2
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 for (int i = 1; i < 8; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 __ ffree(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 #endif // COMPILER2
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 __ jmp(done_conv);
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 __ bind(do_double);
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 #ifdef COMPILER2
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 for (int i = 1; i < 8; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 __ ffree(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 #endif // COMPILER2
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 __ jmp(done_conv);
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 __ MacroAssembler::verify_FPU(0, "generate_return_entry_for compiled");
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 __ jmp(done_conv);
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1934
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 // Return point to interpreter from compiled/native method
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 InternalAddress return_from_native_method(__ pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
1937
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 __ bind(done_conv);
a61af66fc99e Initial load
duke
parents:
diff changeset
1939
a61af66fc99e Initial load
duke
parents:
diff changeset
1940
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 // Result if any is in tosca. The java expression stack is in the state that the
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 // calling convention left it (i.e. params may or may not be present)
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 // Copy the result from tosca and place it on java expression stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1944
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1945 // Restore rsi/r13 as compiled code may not preserve it
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1946
520
52a431267315 6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents: 337
diff changeset
1947 __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1948
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 // restore stack to what we had when we left (in case i2c extended it)
a61af66fc99e Initial load
duke
parents:
diff changeset
1950
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1951 __ movptr(rsp, STATE(_stack));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1952 __ lea(rsp, Address(rsp, wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1953
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 // If there is a pending exception then we don't really have a result to process
a61af66fc99e Initial load
duke
parents:
diff changeset
1955
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1956 #ifdef _LP64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1957 __ 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
1958 #else
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1959 __ movptr(rcx, STATE(_thread)); // get thread
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1960 __ 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
1961 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 __ jcc(Assembler::notZero, return_with_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
1963
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 // get method just executed
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1965 __ movptr(rbx, STATE(_result._to_call._callee));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1966
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 // 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
1968 __ 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
1969 __ lea(rsp, Address(rsp, rcx, Address::times_ptr));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1970
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 __ movl(rcx, Address(rbx, methodOopDesc::result_index_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 ExternalAddress tosca_to_stack((address)CppInterpreter::_tosca_to_stack);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1973 // Address index(noreg, rax, Address::times_ptr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1974 __ 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
1975 // __ movl(rcx, Address(noreg, rcx, Address::times_ptr, int(AbstractInterpreter::_tosca_to_stack)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 __ call(rcx); // call result converter
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 __ jmp(resume_interpreter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1978
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 // An exception is being caught on return to a vanilla interpreter frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 // Empty the stack and resume interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1981
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 __ bind(return_with_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
1983
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 // Exception present, empty stack
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1985 __ movptr(rsp, STATE(_stack_base));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 __ jmp(resume_interpreter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1987
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 // Return from interpreted method we return result appropriate to the caller (i.e. "recursive"
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 // interpreter call, or native) and unwind this interpreter activation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 // All monitors should be unlocked.
a61af66fc99e Initial load
duke
parents:
diff changeset
1991
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 __ bind(return_from_interpreted_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
1993
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 Label return_to_initial_caller;
a61af66fc99e Initial load
duke
parents:
diff changeset
1995
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1996 __ movptr(rbx, STATE(_method)); // get method just executed
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1997 __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from "recursive" interpreter call?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 __ movl(rax, Address(rbx, methodOopDesc::result_index_offset())); // get result type index
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 __ jcc(Assembler::equal, return_to_initial_caller); // back to native code (call_stub/c1/c2)
a61af66fc99e Initial load
duke
parents:
diff changeset
2000
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 // Copy result to callers java stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 ExternalAddress stack_to_stack((address)CppInterpreter::_stack_to_stack);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2003 // Address index(noreg, rax, Address::times_ptr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2004
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2005 __ 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
2006 // __ movl(rax, Address(noreg, rax, Address::times_ptr, int(AbstractInterpreter::_stack_to_stack)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 __ call(rax); // call result converter
a61af66fc99e Initial load
duke
parents:
diff changeset
2008
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 Label unwind_recursive_activation;
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 __ bind(unwind_recursive_activation);
a61af66fc99e Initial load
duke
parents:
diff changeset
2011
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 // returning to interpreter method from "recursive" interpreter call
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 // result converter left rax pointing to top of the java stack for method we are returning
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 // to. Now all we must do is unwind the state from the completed call
a61af66fc99e Initial load
duke
parents:
diff changeset
2015
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2016 __ movptr(state, STATE(_prev_link)); // unwind state
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 __ leave(); // pop the frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2018 __ mov(rsp, rax); // unwind stack to remove args
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2019
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 // Resume the interpreter. The current frame contains the current interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 // state object.
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2023
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 __ bind(resume_interpreter);
a61af66fc99e Initial load
duke
parents:
diff changeset
2025
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 // state == interpreterState object for method we are resuming
a61af66fc99e Initial load
duke
parents:
diff changeset
2027
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 __ movl(STATE(_msg), (int)BytecodeInterpreter::method_resume);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2029 __ 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
2030 __ movptr(STATE(_stack), rsp); // inform interpreter of new stack depth (parameters removed,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 // result if any on stack already )
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2032 __ movptr(rsp, STATE(_stack_limit)); // restore expression stack to full depth
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 __ jmp(call_interpreter_2); // No need to bang
a61af66fc99e Initial load
duke
parents:
diff changeset
2034
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 // interpreter returning to native code (call_stub/c1/c2)
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 // convert result and unwind initial activation
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 // rax - result index
a61af66fc99e Initial load
duke
parents:
diff changeset
2038
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 __ bind(return_to_initial_caller);
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 ExternalAddress stack_to_native((address)CppInterpreter::_stack_to_native_abi);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2041 // Address index(noreg, rax, Address::times_ptr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2042
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2043 __ movptr(rax, ArrayAddress(stack_to_native, Address(noreg, rax, Address::times_ptr)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 __ call(rax); // call result converter
a61af66fc99e Initial load
duke
parents:
diff changeset
2045
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 Label unwind_initial_activation;
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 __ bind(unwind_initial_activation);
a61af66fc99e Initial load
duke
parents:
diff changeset
2048
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 // RETURN TO CALL_STUB/C1/C2 code (result if any in rax/rdx ST(0))
a61af66fc99e Initial load
duke
parents:
diff changeset
2050
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 /* Current stack picture
a61af66fc99e Initial load
duke
parents:
diff changeset
2052
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 [ incoming parameters ]
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 [ extra locals ]
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 [ return address to CALL_STUB/C1/C2]
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 fp -> [ CALL_STUB/C1/C2 fp ]
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 BytecodeInterpreter object
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 sp ->
a61af66fc99e Initial load
duke
parents:
diff changeset
2060
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 */
a61af66fc99e Initial load
duke
parents:
diff changeset
2062
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 // return restoring the stack to the original sender_sp value
a61af66fc99e Initial load
duke
parents:
diff changeset
2064
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2065 __ movptr(rcx, STATE(_sender_sp));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 __ leave();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2067 __ pop(rdi); // get return address
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 // set stack to sender's sp
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2069 __ mov(rsp, rcx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 __ jmp(rdi); // return to call_stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2071
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 // OSR request, adjust return address to make current frame into adapter frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 // and enter OSR nmethod
a61af66fc99e Initial load
duke
parents:
diff changeset
2074
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 __ bind(do_OSR);
a61af66fc99e Initial load
duke
parents:
diff changeset
2076
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 Label remove_initial_frame;
a61af66fc99e Initial load
duke
parents:
diff changeset
2078
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 // We are going to pop this frame. Is there another interpreter frame underneath
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 // it or is it callstub/compiled?
a61af66fc99e Initial load
duke
parents:
diff changeset
2081
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 // Move buffer to the expected parameter location
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2083 __ movptr(rcx, STATE(_result._osr._osr_buf));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2084
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2085 __ movptr(rax, STATE(_result._osr._osr_entry));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2086
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2087 __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from "recursive" interpreter call?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 __ jcc(Assembler::equal, remove_initial_frame); // back to native code (call_stub/c1/c2)
a61af66fc99e Initial load
duke
parents:
diff changeset
2089
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2090 __ movptr(sender_sp_on_entry, STATE(_sender_sp)); // get sender's sp in expected register
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 __ leave(); // pop the frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2092 __ mov(rsp, sender_sp_on_entry); // trim any stack expansion
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2093
a61af66fc99e Initial load
duke
parents:
diff changeset
2094
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 // We know we are calling compiled so push specialized return
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 // method uses specialized entry, push a return so we look like call stub setup
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 // this path will handle fact that result is returned in registers and not
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 // on the java stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
2099
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 __ pushptr(return_from_native_method.addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
2101
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 __ jmp(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2103
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 __ bind(remove_initial_frame);
a61af66fc99e Initial load
duke
parents:
diff changeset
2105
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2106 __ movptr(rdx, STATE(_sender_sp));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 __ leave();
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 // get real return
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2109 __ pop(rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 // set stack to sender's sp
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2111 __ mov(rsp, rdx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 // repush real return
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2113 __ push(rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 // Enter OSR nmethod
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 __ jmp(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2116
a61af66fc99e Initial load
duke
parents:
diff changeset
2117
a61af66fc99e Initial load
duke
parents:
diff changeset
2118
a61af66fc99e Initial load
duke
parents:
diff changeset
2119
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 // Call a new method. All we do is (temporarily) trim the expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 // push a return address to bring us back to here and leap to the new entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
2122
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 __ bind(call_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
2124
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 // stack points to next free location and not top element on expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 // method expects sp to be pointing to topmost element
a61af66fc99e Initial load
duke
parents:
diff changeset
2127
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2128 __ 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
2129 __ lea(rsp, Address(rsp, wordSize));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2130
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2131 __ movptr(rbx, STATE(_result._to_call._callee)); // get method to execute
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2132
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 // don't need a return address if reinvoking interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
2134
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 // Make it look like call_stub calling conventions
a61af66fc99e Initial load
duke
parents:
diff changeset
2136
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 // Get (potential) receiver
622
56aae7be60d4 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 605
diff changeset
2138 __ load_unsigned_short(rcx, size_of_parameters); // get size of parameters in words
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2139
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 ExternalAddress recursive(CAST_FROM_FN_PTR(address, RecursiveInterpreterActivation));
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 __ pushptr(recursive.addr()); // make it look good in the debugger
a61af66fc99e Initial load
duke
parents:
diff changeset
2142
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 InternalAddress entry(entry_point);
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 __ cmpptr(STATE(_result._to_call._callee_entry_point), entry.addr()); // returning to interpreter?
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 __ jcc(Assembler::equal, re_dispatch); // yes
a61af66fc99e Initial load
duke
parents:
diff changeset
2146
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2147 __ pop(rax); // pop dummy address
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2148
a61af66fc99e Initial load
duke
parents:
diff changeset
2149
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 // get specialized entry
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2151 __ movptr(rax, STATE(_result._to_call._callee_entry_point));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 // set sender SP
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2153 __ mov(sender_sp_on_entry, rsp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2154
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 // method uses specialized entry, push a return so we look like call stub setup
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 // this path will handle fact that result is returned in registers and not
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 // on the java stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
2158
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 __ pushptr(return_from_native_method.addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
2160
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 __ jmp(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2162
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 __ bind(bad_msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 __ stop("Bad message from interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
2165
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 // Interpreted method "returned" with an exception pass it on...
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 // Pass result, unwind activation and continue/return to interpreter/call_stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 // We handle result (if any) differently based on return to interpreter or call_stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2169
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 Label unwind_initial_with_pending_exception;
a61af66fc99e Initial load
duke
parents:
diff changeset
2171
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 __ bind(throw_exception);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2173 __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from recursive interpreter call?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 __ 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
2175 __ movptr(rax, STATE(_locals)); // pop parameters get new stack value
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2176 __ addptr(rax, wordSize); // account for prepush before we return
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 __ jmp(unwind_recursive_activation);
a61af66fc99e Initial load
duke
parents:
diff changeset
2178
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 __ bind(unwind_initial_with_pending_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
2180
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 // We will unwind the current (initial) interpreter frame and forward
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 // the exception to the caller. We must put the exception in the
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 // expected register and clear pending exception and then forward.
a61af66fc99e Initial load
duke
parents:
diff changeset
2184
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 __ jmp(unwind_and_forward);
a61af66fc99e Initial load
duke
parents:
diff changeset
2186
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 interpreter_frame_manager = entry_point;
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 return entry_point;
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2190
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 address AbstractInterpreterGenerator::generate_method_entry(AbstractInterpreter::MethodKind kind) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 // determine code generation flags
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 bool synchronized = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 address entry_point = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2195
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 switch (kind) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 case Interpreter::zerolocals : break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 case Interpreter::zerolocals_synchronized: synchronized = true; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 case Interpreter::native : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 case Interpreter::accessor : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 case Interpreter::abstract : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); break;
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 628
diff changeset
2204 case Interpreter::method_handle : entry_point = ((InterpreterGenerator*)this)->generate_method_handle_entry(); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2205
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 case Interpreter::java_lang_math_sin : // fall thru
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 case Interpreter::java_lang_math_cos : // fall thru
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 case Interpreter::java_lang_math_tan : // fall thru
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 case Interpreter::java_lang_math_abs : // fall thru
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 case Interpreter::java_lang_math_log : // fall thru
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 case Interpreter::java_lang_math_log10 : // fall thru
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 case Interpreter::java_lang_math_sqrt : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 default : ShouldNotReachHere(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2215
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 if (entry_point) return entry_point;
a61af66fc99e Initial load
duke
parents:
diff changeset
2217
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 return ((InterpreterGenerator*)this)->generate_normal_entry(synchronized);
a61af66fc99e Initial load
duke
parents:
diff changeset
2219
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2221
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 InterpreterGenerator::InterpreterGenerator(StubQueue* code)
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 : CppInterpreterGenerator(code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 generate_all(); // down here so it can be "virtual"
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2226
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 // Deoptimization helpers for C++ interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
2228
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 // How much stack a method activation needs in words.
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 int AbstractInterpreter::size_top_interpreter_activation(methodOop method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2231
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 const int stub_code = 4; // see generate_call_stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 // Save space for one monitor to get into the interpreted method in case
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 // the method is synchronized
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 int monitor_size = method->is_synchronized() ?
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 1*frame::interpreter_frame_monitor_size() : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2237
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 // total static overhead size. Account for interpreter state object, return
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 // address, saved rbp and 2 words for a "static long no_params() method" issue.
a61af66fc99e Initial load
duke
parents:
diff changeset
2240
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 const int overhead_size = sizeof(BytecodeInterpreter)/wordSize +
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 ( frame::sender_sp_offset - frame::link_offset) + 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2243
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 628
diff changeset
2244 const int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 628
diff changeset
2245 const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) *
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 Interpreter::stackElementWords();
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 return overhead_size + method_stack + stub_code;
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2249
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 // returns the activation size.
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 static int size_activation_helper(int extra_locals_size, int monitor_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 return (extra_locals_size + // the addition space for locals
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 2*BytesPerWord + // return address and saved rbp
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 2*BytesPerWord + // "static long no_params() method" issue
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 sizeof(BytecodeInterpreter) + // interpreterState
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 monitor_size); // monitors
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2258
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill,
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 frame* caller,
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 frame* current,
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 methodOop method,
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 intptr_t* locals,
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 intptr_t* stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 intptr_t* stack_base,
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 intptr_t* monitor_base,
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 intptr_t* frame_bottom,
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 bool is_top_frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 )
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 // What about any vtable?
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 to_fill->_thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 // This gets filled in later but make it something recognizable for now
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 to_fill->_bcp = method->code_base();
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 to_fill->_locals = locals;
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 to_fill->_constants = method->constants()->cache();
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 to_fill->_method = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 to_fill->_mdx = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 to_fill->_stack = stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 if (is_top_frame && JavaThread::current()->popframe_forcing_deopt_reexecution() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 to_fill->_msg = deopt_resume2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 to_fill->_msg = method_resume;
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 to_fill->_result._to_call._bcp_advance = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 to_fill->_result._to_call._callee_entry_point = NULL; // doesn't matter to anyone
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 to_fill->_result._to_call._callee = NULL; // doesn't matter to anyone
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 to_fill->_prev_link = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2290
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 to_fill->_sender_sp = caller->unextended_sp();
a61af66fc99e Initial load
duke
parents:
diff changeset
2292
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 if (caller->is_interpreted_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 interpreterState prev = caller->get_interpreterState();
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 to_fill->_prev_link = prev;
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 // *current->register_addr(GR_Iprev_state) = (intptr_t) prev;
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 // Make the prev callee look proper
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 prev->_result._to_call._callee = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 if (*prev->_bcp == Bytecodes::_invokeinterface) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 prev->_result._to_call._bcp_advance = 5;
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 prev->_result._to_call._bcp_advance = 3;
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 to_fill->_oop_temp = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 to_fill->_stack_base = stack_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 // Need +1 here because stack_base points to the word just above the first expr stack entry
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 // and stack_limit is supposed to point to the word just below the last expr stack entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 // See generate_compute_interpreter_state.
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 628
diff changeset
2310 int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 628
diff changeset
2311 to_fill->_stack_limit = stack_base - (method->max_stack() + extra_stack + 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 to_fill->_monitor_base = (BasicObjectLock*) monitor_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
2313
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 to_fill->_self_link = to_fill;
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 assert(stack >= to_fill->_stack_limit && stack < to_fill->_stack_base,
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 "Stack top out of range");
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2318
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 int AbstractInterpreter::layout_activation(methodOop method,
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 int tempcount, //
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 int popframe_extra_args,
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 int moncount,
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 int callee_param_count,
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 int callee_locals,
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 frame* caller,
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 frame* interpreter_frame,
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 bool is_top_frame) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2328
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 assert(popframe_extra_args == 0, "FIX ME");
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 // NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state()
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 // does as far as allocating an interpreter frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 // If interpreter_frame!=NULL, set up the method, locals, and monitors.
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 // The frame interpreter_frame, if not NULL, is guaranteed to be the right size,
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 // as determined by a previous call to this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 // It is also guaranteed to be walkable even though it is in a skeletal state
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 // NOTE: return size is in words not bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 // NOTE: tempcount is the current size of the java expression stack. For top most
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 // frames we will allocate a full sized expression stack and not the curback
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 // version that non-top frames have.
a61af66fc99e Initial load
duke
parents:
diff changeset
2340
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 // Calculate the amount our frame will be adjust by the callee. For top frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 // this is zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
2343
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 // NOTE: ia64 seems to do this wrong (or at least backwards) in that it
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 // calculates the extra locals based on itself. Not what the callee does
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 // to it. So it ignores last_frame_adjust value. Seems suspicious as far
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 // as getting sender_sp correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
2348
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 int extra_locals_size = (callee_locals - callee_param_count) * BytesPerWord;
a61af66fc99e Initial load
duke
parents:
diff changeset
2350 int monitor_size = sizeof(BasicObjectLock) * moncount;
a61af66fc99e Initial load
duke
parents:
diff changeset
2351
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 // First calculate the frame size without any java expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 int short_frame_size = size_activation_helper(extra_locals_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 monitor_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2355
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 // Now with full size expression stack
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 628
diff changeset
2357 int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries();
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 628
diff changeset
2358 int full_frame_size = short_frame_size + (method->max_stack() + extra_stack) * BytesPerWord;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2359
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 // and now with only live portion of the expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 short_frame_size = short_frame_size + tempcount * BytesPerWord;
a61af66fc99e Initial load
duke
parents:
diff changeset
2362
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 // the size the activation is right now. Only top frame is full size
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 int frame_size = (is_top_frame ? full_frame_size : short_frame_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2365
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 if (interpreter_frame != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2370
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 // MUCHO HACK
a61af66fc99e Initial load
duke
parents:
diff changeset
2372
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 intptr_t* frame_bottom = (intptr_t*) ((intptr_t)interpreter_frame->sp() - (full_frame_size - frame_size));
a61af66fc99e Initial load
duke
parents:
diff changeset
2374
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 /* Now fillin the interpreterState object */
a61af66fc99e Initial load
duke
parents:
diff changeset
2376
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 // The state object is the first thing on the frame and easily located
a61af66fc99e Initial load
duke
parents:
diff changeset
2378
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 interpreterState cur_state = (interpreterState) ((intptr_t)interpreter_frame->fp() - sizeof(BytecodeInterpreter));
a61af66fc99e Initial load
duke
parents:
diff changeset
2380
a61af66fc99e Initial load
duke
parents:
diff changeset
2381
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 // Find the locals pointer. This is rather simple on x86 because there is no
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 // confusing rounding at the callee to account for. We can trivially locate
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 // our locals based on the current fp().
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 // Note: the + 2 is for handling the "static long no_params() method" issue.
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 // (too bad I don't really remember that issue well...)
a61af66fc99e Initial load
duke
parents:
diff changeset
2387
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 intptr_t* locals;
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 // If the caller is interpreted we need to make sure that locals points to the first
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 // argument that the caller passed and not in an area where the stack might have been extended.
a61af66fc99e Initial load
duke
parents:
diff changeset
2391 // because the stack to stack to converter needs a proper locals value in order to remove the
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 // arguments from the caller and place the result in the proper location. Hmm maybe it'd be
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 // simpler if we simply stored the result in the BytecodeInterpreter object and let the c++ code
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 // adjust the stack?? HMMM QQQ
a61af66fc99e Initial load
duke
parents:
diff changeset
2395 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 if (caller->is_interpreted_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 // locals must agree with the caller because it will be used to set the
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 // caller's tos when we return.
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 interpreterState prev = caller->get_interpreterState();
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 // stack() is prepushed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 locals = prev->stack() + method->size_of_parameters();
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 // locals = caller->unextended_sp() + (method->size_of_parameters() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 if (locals != interpreter_frame->fp() + frame::sender_sp_offset + (method->max_locals() - 1) + 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 // os::breakpoint();
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 // this is where a c2i would have placed locals (except for the +2)
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 locals = interpreter_frame->fp() + frame::sender_sp_offset + (method->max_locals() - 1) + 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2410
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 intptr_t* monitor_base = (intptr_t*) cur_state;
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 intptr_t* stack_base = (intptr_t*) ((intptr_t) monitor_base - monitor_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 /* +1 because stack is always prepushed */
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 intptr_t* stack = (intptr_t*) ((intptr_t) stack_base - (tempcount + 1) * BytesPerWord);
a61af66fc99e Initial load
duke
parents:
diff changeset
2415
a61af66fc99e Initial load
duke
parents:
diff changeset
2416
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 BytecodeInterpreter::layout_interpreterState(cur_state,
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 caller,
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 interpreter_frame,
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 method,
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 locals,
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 stack_base,
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 monitor_base,
a61af66fc99e Initial load
duke
parents:
diff changeset
2425 frame_bottom,
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 is_top_frame);
a61af66fc99e Initial load
duke
parents:
diff changeset
2427
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 // BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address, interpreter_frame->fp());
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 return frame_size/BytesPerWord;
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2432
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 #endif // CC_INTERP (all)