Mercurial > hg > graal-jvmci-8
annotate src/share/vm/interpreter/templateInterpreter.cpp @ 24145:2f2299c68571 jvmci-0.27
change default of UseJVMCICompiler based on jvmci.Compiler property (which can now be set from <java.home>/jre/lib/jvmci/compiler-name)
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Thu, 15 Jun 2017 21:38:21 +0200 |
parents | f13e777eb255 |
children |
rev | line source |
---|---|
0 | 1 /* |
23614 | 2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
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:
1489
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "interpreter/interpreter.hpp" | |
27 #include "interpreter/interpreterGenerator.hpp" | |
28 #include "interpreter/interpreterRuntime.hpp" | |
29 #include "interpreter/templateTable.hpp" | |
0 | 30 |
31 #ifndef CC_INTERP | |
32 | |
33 # define __ _masm-> | |
34 | |
35 void TemplateInterpreter::initialize() { | |
36 if (_code != NULL) return; | |
37 // assertions | |
38 assert((int)Bytecodes::number_of_codes <= (int)DispatchTable::length, | |
39 "dispatch table too small"); | |
40 | |
41 AbstractInterpreter::initialize(); | |
42 | |
43 TemplateTable::initialize(); | |
44 | |
45 // generate interpreter | |
46 { ResourceMark rm; | |
47 TraceTime timer("Interpreter generation", TraceStartupTime); | |
48 int code_size = InterpreterCodeSize; | |
49 NOT_PRODUCT(code_size *= 4;) // debug uses extra interpreter code space | |
50 _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL, | |
51 "Interpreter"); | |
52 InterpreterGenerator g(_code); | |
53 if (PrintInterpreter) print(); | |
54 } | |
55 | |
56 // initialize dispatch table | |
57 _active_table = _normal_table; | |
58 } | |
59 | |
60 //------------------------------------------------------------------------------------------------------------------------ | |
61 // Implementation of EntryPoint | |
62 | |
63 EntryPoint::EntryPoint() { | |
23614 | 64 assert(number_of_states == 10, "check the code below"); |
0 | 65 _entry[btos] = NULL; |
23614 | 66 _entry[ztos] = NULL; |
0 | 67 _entry[ctos] = NULL; |
68 _entry[stos] = NULL; | |
69 _entry[atos] = NULL; | |
70 _entry[itos] = NULL; | |
71 _entry[ltos] = NULL; | |
72 _entry[ftos] = NULL; | |
73 _entry[dtos] = NULL; | |
74 _entry[vtos] = NULL; | |
75 } | |
76 | |
77 | |
23614 | 78 EntryPoint::EntryPoint(address bentry, address zentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) { |
79 assert(number_of_states == 10, "check the code below"); | |
0 | 80 _entry[btos] = bentry; |
23614 | 81 _entry[ztos] = zentry; |
0 | 82 _entry[ctos] = centry; |
83 _entry[stos] = sentry; | |
84 _entry[atos] = aentry; | |
85 _entry[itos] = ientry; | |
86 _entry[ltos] = lentry; | |
87 _entry[ftos] = fentry; | |
88 _entry[dtos] = dentry; | |
89 _entry[vtos] = ventry; | |
90 } | |
91 | |
92 | |
93 void EntryPoint::set_entry(TosState state, address entry) { | |
94 assert(0 <= state && state < number_of_states, "state out of bounds"); | |
95 _entry[state] = entry; | |
96 } | |
97 | |
98 | |
99 address EntryPoint::entry(TosState state) const { | |
100 assert(0 <= state && state < number_of_states, "state out of bounds"); | |
101 return _entry[state]; | |
102 } | |
103 | |
104 | |
105 void EntryPoint::print() { | |
106 tty->print("["); | |
107 for (int i = 0; i < number_of_states; i++) { | |
108 if (i > 0) tty->print(", "); | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
13010
diff
changeset
|
109 tty->print(INTPTR_FORMAT, p2i(_entry[i])); |
0 | 110 } |
111 tty->print("]"); | |
112 } | |
113 | |
114 | |
115 bool EntryPoint::operator == (const EntryPoint& y) { | |
116 int i = number_of_states; | |
117 while (i-- > 0) { | |
118 if (_entry[i] != y._entry[i]) return false; | |
119 } | |
120 return true; | |
121 } | |
122 | |
123 | |
124 //------------------------------------------------------------------------------------------------------------------------ | |
125 // Implementation of DispatchTable | |
126 | |
127 EntryPoint DispatchTable::entry(int i) const { | |
128 assert(0 <= i && i < length, "index out of bounds"); | |
129 return | |
130 EntryPoint( | |
131 _table[btos][i], | |
23614 | 132 _table[ztos][i], |
0 | 133 _table[ctos][i], |
134 _table[stos][i], | |
135 _table[atos][i], | |
136 _table[itos][i], | |
137 _table[ltos][i], | |
138 _table[ftos][i], | |
139 _table[dtos][i], | |
140 _table[vtos][i] | |
141 ); | |
142 } | |
143 | |
144 | |
145 void DispatchTable::set_entry(int i, EntryPoint& entry) { | |
146 assert(0 <= i && i < length, "index out of bounds"); | |
23614 | 147 assert(number_of_states == 10, "check the code below"); |
0 | 148 _table[btos][i] = entry.entry(btos); |
23614 | 149 _table[ztos][i] = entry.entry(ztos); |
0 | 150 _table[ctos][i] = entry.entry(ctos); |
151 _table[stos][i] = entry.entry(stos); | |
152 _table[atos][i] = entry.entry(atos); | |
153 _table[itos][i] = entry.entry(itos); | |
154 _table[ltos][i] = entry.entry(ltos); | |
155 _table[ftos][i] = entry.entry(ftos); | |
156 _table[dtos][i] = entry.entry(dtos); | |
157 _table[vtos][i] = entry.entry(vtos); | |
158 } | |
159 | |
160 | |
161 bool DispatchTable::operator == (DispatchTable& y) { | |
162 int i = length; | |
163 while (i-- > 0) { | |
164 EntryPoint t = y.entry(i); // for compiler compatibility (BugId 4150096) | |
165 if (!(entry(i) == t)) return false; | |
166 } | |
167 return true; | |
168 } | |
169 | |
170 address TemplateInterpreter::_remove_activation_entry = NULL; | |
171 address TemplateInterpreter::_remove_activation_preserving_args_entry = NULL; | |
172 | |
173 | |
174 address TemplateInterpreter::_throw_ArrayIndexOutOfBoundsException_entry = NULL; | |
175 address TemplateInterpreter::_throw_ArrayStoreException_entry = NULL; | |
176 address TemplateInterpreter::_throw_ArithmeticException_entry = NULL; | |
177 address TemplateInterpreter::_throw_ClassCastException_entry = NULL; | |
178 address TemplateInterpreter::_throw_NullPointerException_entry = NULL; | |
179 address TemplateInterpreter::_throw_StackOverflowError_entry = NULL; | |
180 address TemplateInterpreter::_throw_exception_entry = NULL; | |
181 | |
182 #ifndef PRODUCT | |
183 EntryPoint TemplateInterpreter::_trace_code; | |
184 #endif // !PRODUCT | |
185 EntryPoint TemplateInterpreter::_return_entry[TemplateInterpreter::number_of_return_entries]; | |
186 EntryPoint TemplateInterpreter::_earlyret_entry; | |
187 EntryPoint TemplateInterpreter::_deopt_entry [TemplateInterpreter::number_of_deopt_entries ]; | |
188 EntryPoint TemplateInterpreter::_continuation_entry; | |
189 EntryPoint TemplateInterpreter::_safept_entry; | |
190 | |
13010
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
191 address TemplateInterpreter::_invoke_return_entry[TemplateInterpreter::number_of_return_addrs]; |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
192 address TemplateInterpreter::_invokeinterface_return_entry[TemplateInterpreter::number_of_return_addrs]; |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
193 address TemplateInterpreter::_invokedynamic_return_entry[TemplateInterpreter::number_of_return_addrs]; |
0 | 194 |
195 DispatchTable TemplateInterpreter::_active_table; | |
196 DispatchTable TemplateInterpreter::_normal_table; | |
197 DispatchTable TemplateInterpreter::_safept_table; | |
198 address TemplateInterpreter::_wentry_point[DispatchTable::length]; | |
199 | |
200 TemplateInterpreterGenerator::TemplateInterpreterGenerator(StubQueue* _code): AbstractInterpreterGenerator(_code) { | |
201 _unimplemented_bytecode = NULL; | |
202 _illegal_bytecode_sequence = NULL; | |
203 } | |
204 | |
205 static const BasicType types[Interpreter::number_of_result_handlers] = { | |
206 T_BOOLEAN, | |
207 T_CHAR , | |
208 T_BYTE , | |
209 T_SHORT , | |
210 T_INT , | |
211 T_LONG , | |
212 T_VOID , | |
213 T_FLOAT , | |
214 T_DOUBLE , | |
215 T_OBJECT | |
216 }; | |
217 | |
218 void TemplateInterpreterGenerator::generate_all() { | |
219 AbstractInterpreterGenerator::generate_all(); | |
220 | |
221 { CodeletMark cm(_masm, "error exits"); | |
222 _unimplemented_bytecode = generate_error_exit("unimplemented bytecode"); | |
223 _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified"); | |
224 } | |
225 | |
226 #ifndef PRODUCT | |
227 if (TraceBytecodes) { | |
228 CodeletMark cm(_masm, "bytecode tracing support"); | |
229 Interpreter::_trace_code = | |
230 EntryPoint( | |
231 generate_trace_code(btos), | |
23614 | 232 generate_trace_code(ztos), |
0 | 233 generate_trace_code(ctos), |
234 generate_trace_code(stos), | |
235 generate_trace_code(atos), | |
236 generate_trace_code(itos), | |
237 generate_trace_code(ltos), | |
238 generate_trace_code(ftos), | |
239 generate_trace_code(dtos), | |
240 generate_trace_code(vtos) | |
241 ); | |
242 } | |
243 #endif // !PRODUCT | |
244 | |
245 { CodeletMark cm(_masm, "return entry points"); | |
13010
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
246 const int index_size = sizeof(u2); |
0 | 247 for (int i = 0; i < Interpreter::number_of_return_entries; i++) { |
248 Interpreter::_return_entry[i] = | |
249 EntryPoint( | |
13010
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
250 generate_return_entry_for(itos, i, index_size), |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
251 generate_return_entry_for(itos, i, index_size), |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
252 generate_return_entry_for(itos, i, index_size), |
23614 | 253 generate_return_entry_for(itos, i, index_size), |
13010
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
254 generate_return_entry_for(atos, i, index_size), |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
255 generate_return_entry_for(itos, i, index_size), |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
256 generate_return_entry_for(ltos, i, index_size), |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
257 generate_return_entry_for(ftos, i, index_size), |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
258 generate_return_entry_for(dtos, i, index_size), |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
259 generate_return_entry_for(vtos, i, index_size) |
0 | 260 ); |
261 } | |
262 } | |
263 | |
13010
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
264 { CodeletMark cm(_masm, "invoke return entry points"); |
23614 | 265 // These states are in order specified in TosState, except btos/ztos/ctos/stos are |
266 // really the same as itos since there is no top of stack optimization for these types | |
267 const TosState states[] = {itos, itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos, ilgl}; | |
13010
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
268 const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic); |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
269 const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface); |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
270 const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic); |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
271 |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
272 for (int i = 0; i < Interpreter::number_of_return_addrs; i++) { |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
273 TosState state = states[i]; |
23614 | 274 assert(state != ilgl, "states array is wrong above"); |
13010
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
275 Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2)); |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
276 Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2)); |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
277 Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4)); |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
278 } |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
279 } |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
280 |
0 | 281 { CodeletMark cm(_masm, "earlyret entry points"); |
282 Interpreter::_earlyret_entry = | |
283 EntryPoint( | |
284 generate_earlyret_entry_for(btos), | |
23614 | 285 generate_earlyret_entry_for(ztos), |
0 | 286 generate_earlyret_entry_for(ctos), |
287 generate_earlyret_entry_for(stos), | |
288 generate_earlyret_entry_for(atos), | |
289 generate_earlyret_entry_for(itos), | |
290 generate_earlyret_entry_for(ltos), | |
291 generate_earlyret_entry_for(ftos), | |
292 generate_earlyret_entry_for(dtos), | |
293 generate_earlyret_entry_for(vtos) | |
294 ); | |
295 } | |
296 | |
297 { CodeletMark cm(_masm, "deoptimization entry points"); | |
298 for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) { | |
299 Interpreter::_deopt_entry[i] = | |
300 EntryPoint( | |
11173
6b0fd0964b87
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
Doug Simon <doug.simon@oracle.com>
diff
changeset
|
301 ((InterpreterGenerator*)this)->generate_deopt_entry_for(itos, i), |
6b0fd0964b87
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
Doug Simon <doug.simon@oracle.com>
diff
changeset
|
302 ((InterpreterGenerator*)this)->generate_deopt_entry_for(itos, i), |
6b0fd0964b87
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
Doug Simon <doug.simon@oracle.com>
diff
changeset
|
303 ((InterpreterGenerator*)this)->generate_deopt_entry_for(itos, i), |
23660 | 304 ((InterpreterGenerator*)this)->generate_deopt_entry_for(itos, i), |
11173
6b0fd0964b87
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
Doug Simon <doug.simon@oracle.com>
diff
changeset
|
305 ((InterpreterGenerator*)this)->generate_deopt_entry_for(atos, i), |
6b0fd0964b87
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
Doug Simon <doug.simon@oracle.com>
diff
changeset
|
306 ((InterpreterGenerator*)this)->generate_deopt_entry_for(itos, i), |
6b0fd0964b87
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
Doug Simon <doug.simon@oracle.com>
diff
changeset
|
307 ((InterpreterGenerator*)this)->generate_deopt_entry_for(ltos, i), |
6b0fd0964b87
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
Doug Simon <doug.simon@oracle.com>
diff
changeset
|
308 ((InterpreterGenerator*)this)->generate_deopt_entry_for(ftos, i), |
6b0fd0964b87
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
Doug Simon <doug.simon@oracle.com>
diff
changeset
|
309 ((InterpreterGenerator*)this)->generate_deopt_entry_for(dtos, i), |
6b0fd0964b87
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
Doug Simon <doug.simon@oracle.com>
diff
changeset
|
310 ((InterpreterGenerator*)this)->generate_deopt_entry_for(vtos, i) |
0 | 311 ); |
312 } | |
313 } | |
314 | |
315 { CodeletMark cm(_masm, "result handlers for native calls"); | |
316 // The various result converter stublets. | |
317 int is_generated[Interpreter::number_of_result_handlers]; | |
318 memset(is_generated, 0, sizeof(is_generated)); | |
319 | |
320 for (int i = 0; i < Interpreter::number_of_result_handlers; i++) { | |
321 BasicType type = types[i]; | |
322 if (!is_generated[Interpreter::BasicType_as_index(type)]++) { | |
323 Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type); | |
324 } | |
325 } | |
326 } | |
327 | |
328 { CodeletMark cm(_masm, "continuation entry points"); | |
329 Interpreter::_continuation_entry = | |
330 EntryPoint( | |
331 generate_continuation_for(btos), | |
23614 | 332 generate_continuation_for(ztos), |
0 | 333 generate_continuation_for(ctos), |
334 generate_continuation_for(stos), | |
335 generate_continuation_for(atos), | |
336 generate_continuation_for(itos), | |
337 generate_continuation_for(ltos), | |
338 generate_continuation_for(ftos), | |
339 generate_continuation_for(dtos), | |
340 generate_continuation_for(vtos) | |
341 ); | |
342 } | |
343 | |
344 { CodeletMark cm(_masm, "safepoint entry points"); | |
345 Interpreter::_safept_entry = | |
346 EntryPoint( | |
347 generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), | |
23614 | 348 generate_safept_entry_for(ztos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
0 | 349 generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
350 generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), | |
351 generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), | |
352 generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), | |
353 generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), | |
354 generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), | |
355 generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), | |
356 generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)) | |
357 ); | |
358 } | |
359 | |
360 { CodeletMark cm(_masm, "exception handling"); | |
361 // (Note: this is not safepoint safe because thread may return to compiled code) | |
362 generate_throw_exception(); | |
363 } | |
364 | |
365 { CodeletMark cm(_masm, "throw exception entrypoints"); | |
366 Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException"); | |
367 Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" ); | |
368 Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero"); | |
369 Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler(); | |
370 Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL ); | |
371 Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler(); | |
372 } | |
373 | |
374 | |
375 | |
376 #define method_entry(kind) \ | |
377 { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \ | |
378 Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \ | |
379 } | |
380 | |
381 // all non-native method kinds | |
382 method_entry(zerolocals) | |
383 method_entry(zerolocals_synchronized) | |
384 method_entry(empty) | |
385 method_entry(accessor) | |
386 method_entry(abstract) | |
387 method_entry(java_lang_math_sin ) | |
388 method_entry(java_lang_math_cos ) | |
389 method_entry(java_lang_math_tan ) | |
390 method_entry(java_lang_math_abs ) | |
391 method_entry(java_lang_math_sqrt ) | |
392 method_entry(java_lang_math_log ) | |
393 method_entry(java_lang_math_log10) | |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3451
diff
changeset
|
394 method_entry(java_lang_math_exp ) |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3451
diff
changeset
|
395 method_entry(java_lang_math_pow ) |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2142
diff
changeset
|
396 method_entry(java_lang_ref_reference_get) |
0 | 397 |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
6926
diff
changeset
|
398 if (UseCRC32Intrinsics) { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
6926
diff
changeset
|
399 method_entry(java_util_zip_CRC32_update) |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
6926
diff
changeset
|
400 method_entry(java_util_zip_CRC32_updateBytes) |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
6926
diff
changeset
|
401 method_entry(java_util_zip_CRC32_updateByteBuffer) |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
6926
diff
changeset
|
402 } |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
6926
diff
changeset
|
403 |
6926 | 404 initialize_method_handle_entries(); |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6084
diff
changeset
|
405 |
0 | 406 // all native method kinds (must be one contiguous block) |
407 Interpreter::_native_entry_begin = Interpreter::code()->code_end(); | |
408 method_entry(native) | |
409 method_entry(native_synchronized) | |
410 Interpreter::_native_entry_end = Interpreter::code()->code_end(); | |
411 | |
412 #undef method_entry | |
413 | |
414 // Bytecodes | |
415 set_entry_points_for_all_bytes(); | |
416 set_safepoints_for_all_bytes(); | |
417 } | |
418 | |
419 //------------------------------------------------------------------------------------------------------------------------ | |
420 | |
421 address TemplateInterpreterGenerator::generate_error_exit(const char* msg) { | |
422 address entry = __ pc(); | |
423 __ stop(msg); | |
424 return entry; | |
425 } | |
426 | |
427 | |
428 //------------------------------------------------------------------------------------------------------------------------ | |
429 | |
430 void TemplateInterpreterGenerator::set_entry_points_for_all_bytes() { | |
431 for (int i = 0; i < DispatchTable::length; i++) { | |
432 Bytecodes::Code code = (Bytecodes::Code)i; | |
433 if (Bytecodes::is_defined(code)) { | |
434 set_entry_points(code); | |
435 } else { | |
436 set_unimplemented(i); | |
437 } | |
438 } | |
439 } | |
440 | |
441 | |
442 void TemplateInterpreterGenerator::set_safepoints_for_all_bytes() { | |
443 for (int i = 0; i < DispatchTable::length; i++) { | |
444 Bytecodes::Code code = (Bytecodes::Code)i; | |
445 if (Bytecodes::is_defined(code)) Interpreter::_safept_table.set_entry(code, Interpreter::_safept_entry); | |
446 } | |
447 } | |
448 | |
449 | |
450 void TemplateInterpreterGenerator::set_unimplemented(int i) { | |
451 address e = _unimplemented_bytecode; | |
23614 | 452 EntryPoint entry(e, e, e, e, e, e, e, e, e, e); |
0 | 453 Interpreter::_normal_table.set_entry(i, entry); |
454 Interpreter::_wentry_point[i] = _unimplemented_bytecode; | |
455 } | |
456 | |
457 | |
458 void TemplateInterpreterGenerator::set_entry_points(Bytecodes::Code code) { | |
459 CodeletMark cm(_masm, Bytecodes::name(code), code); | |
460 // initialize entry points | |
461 assert(_unimplemented_bytecode != NULL, "should have been generated before"); | |
462 assert(_illegal_bytecode_sequence != NULL, "should have been generated before"); | |
463 address bep = _illegal_bytecode_sequence; | |
23614 | 464 address zep = _illegal_bytecode_sequence; |
0 | 465 address cep = _illegal_bytecode_sequence; |
466 address sep = _illegal_bytecode_sequence; | |
467 address aep = _illegal_bytecode_sequence; | |
468 address iep = _illegal_bytecode_sequence; | |
469 address lep = _illegal_bytecode_sequence; | |
470 address fep = _illegal_bytecode_sequence; | |
471 address dep = _illegal_bytecode_sequence; | |
472 address vep = _unimplemented_bytecode; | |
473 address wep = _unimplemented_bytecode; | |
474 // code for short & wide version of bytecode | |
475 if (Bytecodes::is_defined(code)) { | |
476 Template* t = TemplateTable::template_for(code); | |
477 assert(t->is_valid(), "just checking"); | |
478 set_short_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); | |
479 } | |
480 if (Bytecodes::wide_is_defined(code)) { | |
481 Template* t = TemplateTable::template_for_wide(code); | |
482 assert(t->is_valid(), "just checking"); | |
483 set_wide_entry_point(t, wep); | |
484 } | |
485 // set entry points | |
23614 | 486 EntryPoint entry(bep, zep, cep, sep, aep, iep, lep, fep, dep, vep); |
0 | 487 Interpreter::_normal_table.set_entry(code, entry); |
488 Interpreter::_wentry_point[code] = wep; | |
489 } | |
490 | |
491 | |
492 void TemplateInterpreterGenerator::set_wide_entry_point(Template* t, address& wep) { | |
493 assert(t->is_valid(), "template must exist"); | |
1489
cff162798819
6888953: some calls to function-like macros are missing semicolons
jcoomes
parents:
1071
diff
changeset
|
494 assert(t->tos_in() == vtos, "only vtos tos_in supported for wide instructions"); |
0 | 495 wep = __ pc(); generate_and_dispatch(t); |
496 } | |
497 | |
498 | |
499 void TemplateInterpreterGenerator::set_short_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) { | |
500 assert(t->is_valid(), "template must exist"); | |
501 switch (t->tos_in()) { | |
1071
b18963243361
6902000: use ShouldNotReachHere() for btos/ctos/stos in TemplateInterpreterGenerator::set_short_entry_points
twisti
parents:
1059
diff
changeset
|
502 case btos: |
23614 | 503 case ztos: |
1071
b18963243361
6902000: use ShouldNotReachHere() for btos/ctos/stos in TemplateInterpreterGenerator::set_short_entry_points
twisti
parents:
1059
diff
changeset
|
504 case ctos: |
b18963243361
6902000: use ShouldNotReachHere() for btos/ctos/stos in TemplateInterpreterGenerator::set_short_entry_points
twisti
parents:
1059
diff
changeset
|
505 case stos: |
b18963243361
6902000: use ShouldNotReachHere() for btos/ctos/stos in TemplateInterpreterGenerator::set_short_entry_points
twisti
parents:
1059
diff
changeset
|
506 ShouldNotReachHere(); // btos/ctos/stos should use itos. |
b18963243361
6902000: use ShouldNotReachHere() for btos/ctos/stos in TemplateInterpreterGenerator::set_short_entry_points
twisti
parents:
1059
diff
changeset
|
507 break; |
0 | 508 case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break; |
509 case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break; | |
510 case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break; | |
511 case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break; | |
512 case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break; | |
513 case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); break; | |
514 default : ShouldNotReachHere(); break; | |
515 } | |
516 } | |
517 | |
518 | |
519 //------------------------------------------------------------------------------------------------------------------------ | |
520 | |
521 void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) { | |
522 if (PrintBytecodeHistogram) histogram_bytecode(t); | |
523 #ifndef PRODUCT | |
524 // debugging code | |
525 if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode(); | |
526 if (PrintBytecodePairHistogram) histogram_bytecode_pair(t); | |
527 if (TraceBytecodes) trace_bytecode(t); | |
528 if (StopInterpreterAt > 0) stop_interpreter_at(); | |
529 __ verify_FPU(1, t->tos_in()); | |
530 #endif // !PRODUCT | |
23822
626f594dffa6
8139040: Fix initializations before ShouldNotReachHere() etc. and enable -Wuninitialized on linux.
csahu
parents:
17937
diff
changeset
|
531 int step = 0; |
0 | 532 if (!t->does_dispatch()) { |
533 step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode()); | |
534 if (tos_out == ilgl) tos_out = t->tos_out(); | |
535 // compute bytecode size | |
536 assert(step > 0, "just checkin'"); | |
537 // setup stuff for dispatching next bytecode | |
538 if (ProfileInterpreter && VerifyDataPointer | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
539 && MethodData::bytecode_has_profile(t->bytecode())) { |
0 | 540 __ verify_method_data_pointer(); |
541 } | |
542 __ dispatch_prolog(tos_out, step); | |
543 } | |
544 // generate template | |
545 t->generate(_masm); | |
546 // advance | |
547 if (t->does_dispatch()) { | |
548 #ifdef ASSERT | |
549 // make sure execution doesn't go beyond this point if code is broken | |
550 __ should_not_reach_here(); | |
551 #endif // ASSERT | |
552 } else { | |
553 // dispatch to next bytecode | |
554 __ dispatch_epilog(tos_out, step); | |
555 } | |
556 } | |
557 | |
558 //------------------------------------------------------------------------------------------------------------------------ | |
559 // Entry points | |
560 | |
13010
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
561 /** |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
562 * Returns the return entry table for the given invoke bytecode. |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
563 */ |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
564 address* TemplateInterpreter::invoke_return_entry_table_for(Bytecodes::Code code) { |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
565 switch (code) { |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
566 case Bytecodes::_invokestatic: |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
567 case Bytecodes::_invokespecial: |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
568 case Bytecodes::_invokevirtual: |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
569 case Bytecodes::_invokehandle: |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
570 return Interpreter::invoke_return_entry_table(); |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
571 case Bytecodes::_invokeinterface: |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
572 return Interpreter::invokeinterface_return_entry_table(); |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
573 case Bytecodes::_invokedynamic: |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
574 return Interpreter::invokedynamic_return_entry_table(); |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
575 default: |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
576 fatal(err_msg("invalid bytecode: %s", Bytecodes::name(code))); |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
577 return NULL; |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
578 } |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
579 } |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
580 |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
581 /** |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
582 * Returns the return entry address for the given top-of-stack state and bytecode. |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
583 */ |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
584 address TemplateInterpreter::return_entry(TosState state, int length, Bytecodes::Code code) { |
0 | 585 guarantee(0 <= length && length < Interpreter::number_of_return_entries, "illegal length"); |
13010
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
586 const int index = TosState_as_index(state); |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
587 switch (code) { |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
588 case Bytecodes::_invokestatic: |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
589 case Bytecodes::_invokespecial: |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
590 case Bytecodes::_invokevirtual: |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
591 case Bytecodes::_invokehandle: |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
592 return _invoke_return_entry[index]; |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
593 case Bytecodes::_invokeinterface: |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
594 return _invokeinterface_return_entry[index]; |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
595 case Bytecodes::_invokedynamic: |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
596 return _invokedynamic_return_entry[index]; |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
597 default: |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
598 assert(!Bytecodes::is_invoke(code), err_msg("invoke instructions should be handled separately: %s", Bytecodes::name(code))); |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
599 return _return_entry[length].entry(state); |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
11080
diff
changeset
|
600 } |
0 | 601 } |
602 | |
603 | |
604 address TemplateInterpreter::deopt_entry(TosState state, int length) { | |
605 guarantee(0 <= length && length < Interpreter::number_of_deopt_entries, "illegal length"); | |
606 return _deopt_entry[length].entry(state); | |
607 } | |
608 | |
609 //------------------------------------------------------------------------------------------------------------------------ | |
610 // Suport for invokes | |
611 | |
612 int TemplateInterpreter::TosState_as_index(TosState state) { | |
613 assert( state < number_of_states , "Invalid state in TosState_as_index"); | |
614 assert(0 <= (int)state && (int)state < TemplateInterpreter::number_of_return_addrs, "index out of bounds"); | |
615 return (int)state; | |
616 } | |
617 | |
618 | |
619 //------------------------------------------------------------------------------------------------------------------------ | |
620 // Safepoint suppport | |
621 | |
622 static inline void copy_table(address* from, address* to, int size) { | |
623 // Copy non-overlapping tables. The copy has to occur word wise for MT safety. | |
624 while (size-- > 0) *to++ = *from++; | |
625 } | |
626 | |
627 void TemplateInterpreter::notice_safepoints() { | |
628 if (!_notice_safepoints) { | |
629 // switch to safepoint dispatch table | |
630 _notice_safepoints = true; | |
631 copy_table((address*)&_safept_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address)); | |
632 } | |
633 } | |
634 | |
635 // switch from the dispatch table which notices safepoints back to the | |
636 // normal dispatch table. So that we can notice single stepping points, | |
637 // keep the safepoint dispatch table if we are single stepping in JVMTI. | |
638 // Note that the should_post_single_step test is exactly as fast as the | |
639 // JvmtiExport::_enabled test and covers both cases. | |
640 void TemplateInterpreter::ignore_safepoints() { | |
641 if (_notice_safepoints) { | |
642 if (!JvmtiExport::should_post_single_step()) { | |
643 // switch to normal dispatch table | |
644 _notice_safepoints = false; | |
645 copy_table((address*)&_normal_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address)); | |
646 } | |
647 } | |
648 } | |
649 | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
650 //------------------------------------------------------------------------------------------------------------------------ |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
651 // Deoptimization support |
0 | 652 |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
653 // If deoptimization happens, this function returns the point of next bytecode to continue execution |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
654 address TemplateInterpreter::deopt_continue_after_entry(Method* method, address bcp, int callee_parameters, bool is_top_frame) { |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
655 return AbstractInterpreter::deopt_continue_after_entry(method, bcp, callee_parameters, is_top_frame); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
656 } |
0 | 657 |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
658 // If deoptimization happens, this function returns the point where the interpreter reexecutes |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
659 // the bytecode. |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
660 // Note: Bytecodes::_athrow (C1 only) and Bytecodes::_return are the special cases |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
661 // that do not return "Interpreter::deopt_entry(vtos, 0)" |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
662 address TemplateInterpreter::deopt_reexecute_entry(Method* method, address bcp) { |
0 | 663 assert(method->contains(bcp), "just checkin'"); |
2142 | 664 Bytecodes::Code code = Bytecodes::java_code_at(method, bcp); |
0 | 665 if (code == Bytecodes::_return) { |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
666 // This is used for deopt during registration of finalizers |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
667 // during Object.<init>. We simply need to resume execution at |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
668 // the standard return vtos bytecode to pop the frame normally. |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
669 // reexecuting the real bytecode would cause double registration |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
670 // of the finalizable object. |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
671 return _normal_table.entry(Bytecodes::_return).entry(vtos); |
0 | 672 } else { |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
673 return AbstractInterpreter::deopt_reexecute_entry(method, bcp); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
674 } |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
675 } |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
676 |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
677 // If deoptimization happens, the interpreter should reexecute this bytecode. |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
678 // This function mainly helps the compilers to set up the reexecute bit. |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
679 bool TemplateInterpreter::bytecode_should_reexecute(Bytecodes::Code code) { |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
680 if (code == Bytecodes::_return) { |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
681 //Yes, we consider Bytecodes::_return as a special case of reexecution |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
682 return true; |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
683 } else { |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
684 return AbstractInterpreter::bytecode_should_reexecute(code); |
0 | 685 } |
686 } | |
687 | |
688 #endif // !CC_INTERP |