|
1 /* |
|
2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. |
|
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 * |
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
20 * or visit www.oracle.com if you need additional information or have any |
|
21 * questions. |
|
22 * |
|
23 */ |
|
24 |
|
25 #include "precompiled.hpp" |
|
26 #include "interpreter/interpreter.hpp" |
|
27 #include "interpreter/interpreterGenerator.hpp" |
|
28 #include "interpreter/interpreterRuntime.hpp" |
|
29 #include "interpreter/templateTable.hpp" |
|
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() { |
|
64 assert(number_of_states == 9, "check the code below"); |
|
65 _entry[btos] = NULL; |
|
66 _entry[ctos] = NULL; |
|
67 _entry[stos] = NULL; |
|
68 _entry[atos] = NULL; |
|
69 _entry[itos] = NULL; |
|
70 _entry[ltos] = NULL; |
|
71 _entry[ftos] = NULL; |
|
72 _entry[dtos] = NULL; |
|
73 _entry[vtos] = NULL; |
|
74 } |
|
75 |
|
76 |
|
77 EntryPoint::EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) { |
|
78 assert(number_of_states == 9, "check the code below"); |
|
79 _entry[btos] = bentry; |
|
80 _entry[ctos] = centry; |
|
81 _entry[stos] = sentry; |
|
82 _entry[atos] = aentry; |
|
83 _entry[itos] = ientry; |
|
84 _entry[ltos] = lentry; |
|
85 _entry[ftos] = fentry; |
|
86 _entry[dtos] = dentry; |
|
87 _entry[vtos] = ventry; |
|
88 } |
|
89 |
|
90 |
|
91 void EntryPoint::set_entry(TosState state, address entry) { |
|
92 assert(0 <= state && state < number_of_states, "state out of bounds"); |
|
93 _entry[state] = entry; |
|
94 } |
|
95 |
|
96 |
|
97 address EntryPoint::entry(TosState state) const { |
|
98 assert(0 <= state && state < number_of_states, "state out of bounds"); |
|
99 return _entry[state]; |
|
100 } |
|
101 |
|
102 |
|
103 void EntryPoint::print() { |
|
104 tty->print("["); |
|
105 for (int i = 0; i < number_of_states; i++) { |
|
106 if (i > 0) tty->print(", "); |
|
107 tty->print(INTPTR_FORMAT, p2i(_entry[i])); |
|
108 } |
|
109 tty->print("]"); |
|
110 } |
|
111 |
|
112 |
|
113 bool EntryPoint::operator == (const EntryPoint& y) { |
|
114 int i = number_of_states; |
|
115 while (i-- > 0) { |
|
116 if (_entry[i] != y._entry[i]) return false; |
|
117 } |
|
118 return true; |
|
119 } |
|
120 |
|
121 |
|
122 //------------------------------------------------------------------------------------------------------------------------ |
|
123 // Implementation of DispatchTable |
|
124 |
|
125 EntryPoint DispatchTable::entry(int i) const { |
|
126 assert(0 <= i && i < length, "index out of bounds"); |
|
127 return |
|
128 EntryPoint( |
|
129 _table[btos][i], |
|
130 _table[ctos][i], |
|
131 _table[stos][i], |
|
132 _table[atos][i], |
|
133 _table[itos][i], |
|
134 _table[ltos][i], |
|
135 _table[ftos][i], |
|
136 _table[dtos][i], |
|
137 _table[vtos][i] |
|
138 ); |
|
139 } |
|
140 |
|
141 |
|
142 void DispatchTable::set_entry(int i, EntryPoint& entry) { |
|
143 assert(0 <= i && i < length, "index out of bounds"); |
|
144 assert(number_of_states == 9, "check the code below"); |
|
145 _table[btos][i] = entry.entry(btos); |
|
146 _table[ctos][i] = entry.entry(ctos); |
|
147 _table[stos][i] = entry.entry(stos); |
|
148 _table[atos][i] = entry.entry(atos); |
|
149 _table[itos][i] = entry.entry(itos); |
|
150 _table[ltos][i] = entry.entry(ltos); |
|
151 _table[ftos][i] = entry.entry(ftos); |
|
152 _table[dtos][i] = entry.entry(dtos); |
|
153 _table[vtos][i] = entry.entry(vtos); |
|
154 } |
|
155 |
|
156 |
|
157 bool DispatchTable::operator == (DispatchTable& y) { |
|
158 int i = length; |
|
159 while (i-- > 0) { |
|
160 EntryPoint t = y.entry(i); // for compiler compatibility (BugId 4150096) |
|
161 if (!(entry(i) == t)) return false; |
|
162 } |
|
163 return true; |
|
164 } |
|
165 |
|
166 address TemplateInterpreter::_remove_activation_entry = NULL; |
|
167 address TemplateInterpreter::_remove_activation_preserving_args_entry = NULL; |
|
168 |
|
169 |
|
170 address TemplateInterpreter::_throw_ArrayIndexOutOfBoundsException_entry = NULL; |
|
171 address TemplateInterpreter::_throw_ArrayStoreException_entry = NULL; |
|
172 address TemplateInterpreter::_throw_ArithmeticException_entry = NULL; |
|
173 address TemplateInterpreter::_throw_ClassCastException_entry = NULL; |
|
174 address TemplateInterpreter::_throw_NullPointerException_entry = NULL; |
|
175 address TemplateInterpreter::_throw_StackOverflowError_entry = NULL; |
|
176 address TemplateInterpreter::_throw_exception_entry = NULL; |
|
177 |
|
178 #ifndef PRODUCT |
|
179 EntryPoint TemplateInterpreter::_trace_code; |
|
180 #endif // !PRODUCT |
|
181 EntryPoint TemplateInterpreter::_return_entry[TemplateInterpreter::number_of_return_entries]; |
|
182 EntryPoint TemplateInterpreter::_earlyret_entry; |
|
183 EntryPoint TemplateInterpreter::_deopt_entry [TemplateInterpreter::number_of_deopt_entries ]; |
|
184 EntryPoint TemplateInterpreter::_continuation_entry; |
|
185 EntryPoint TemplateInterpreter::_safept_entry; |
|
186 |
|
187 address TemplateInterpreter::_invoke_return_entry[TemplateInterpreter::number_of_return_addrs]; |
|
188 address TemplateInterpreter::_invokeinterface_return_entry[TemplateInterpreter::number_of_return_addrs]; |
|
189 address TemplateInterpreter::_invokedynamic_return_entry[TemplateInterpreter::number_of_return_addrs]; |
|
190 |
|
191 DispatchTable TemplateInterpreter::_active_table; |
|
192 DispatchTable TemplateInterpreter::_normal_table; |
|
193 DispatchTable TemplateInterpreter::_safept_table; |
|
194 address TemplateInterpreter::_wentry_point[DispatchTable::length]; |
|
195 |
|
196 TemplateInterpreterGenerator::TemplateInterpreterGenerator(StubQueue* _code): AbstractInterpreterGenerator(_code) { |
|
197 _unimplemented_bytecode = NULL; |
|
198 _illegal_bytecode_sequence = NULL; |
|
199 } |
|
200 |
|
201 static const BasicType types[Interpreter::number_of_result_handlers] = { |
|
202 T_BOOLEAN, |
|
203 T_CHAR , |
|
204 T_BYTE , |
|
205 T_SHORT , |
|
206 T_INT , |
|
207 T_LONG , |
|
208 T_VOID , |
|
209 T_FLOAT , |
|
210 T_DOUBLE , |
|
211 T_OBJECT |
|
212 }; |
|
213 |
|
214 void TemplateInterpreterGenerator::generate_all() { |
|
215 AbstractInterpreterGenerator::generate_all(); |
|
216 |
|
217 { CodeletMark cm(_masm, "error exits"); |
|
218 _unimplemented_bytecode = generate_error_exit("unimplemented bytecode"); |
|
219 _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified"); |
|
220 } |
|
221 |
|
222 #ifndef PRODUCT |
|
223 if (TraceBytecodes) { |
|
224 CodeletMark cm(_masm, "bytecode tracing support"); |
|
225 Interpreter::_trace_code = |
|
226 EntryPoint( |
|
227 generate_trace_code(btos), |
|
228 generate_trace_code(ctos), |
|
229 generate_trace_code(stos), |
|
230 generate_trace_code(atos), |
|
231 generate_trace_code(itos), |
|
232 generate_trace_code(ltos), |
|
233 generate_trace_code(ftos), |
|
234 generate_trace_code(dtos), |
|
235 generate_trace_code(vtos) |
|
236 ); |
|
237 } |
|
238 #endif // !PRODUCT |
|
239 |
|
240 { CodeletMark cm(_masm, "return entry points"); |
|
241 const int index_size = sizeof(u2); |
|
242 for (int i = 0; i < Interpreter::number_of_return_entries; i++) { |
|
243 Interpreter::_return_entry[i] = |
|
244 EntryPoint( |
|
245 generate_return_entry_for(itos, i, index_size), |
|
246 generate_return_entry_for(itos, i, index_size), |
|
247 generate_return_entry_for(itos, i, index_size), |
|
248 generate_return_entry_for(atos, i, index_size), |
|
249 generate_return_entry_for(itos, i, index_size), |
|
250 generate_return_entry_for(ltos, i, index_size), |
|
251 generate_return_entry_for(ftos, i, index_size), |
|
252 generate_return_entry_for(dtos, i, index_size), |
|
253 generate_return_entry_for(vtos, i, index_size) |
|
254 ); |
|
255 } |
|
256 } |
|
257 |
|
258 { CodeletMark cm(_masm, "invoke return entry points"); |
|
259 const TosState states[] = {itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos}; |
|
260 const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic); |
|
261 const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface); |
|
262 const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic); |
|
263 |
|
264 for (int i = 0; i < Interpreter::number_of_return_addrs; i++) { |
|
265 TosState state = states[i]; |
|
266 Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2)); |
|
267 Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2)); |
|
268 Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4)); |
|
269 } |
|
270 } |
|
271 |
|
272 { CodeletMark cm(_masm, "earlyret entry points"); |
|
273 Interpreter::_earlyret_entry = |
|
274 EntryPoint( |
|
275 generate_earlyret_entry_for(btos), |
|
276 generate_earlyret_entry_for(ctos), |
|
277 generate_earlyret_entry_for(stos), |
|
278 generate_earlyret_entry_for(atos), |
|
279 generate_earlyret_entry_for(itos), |
|
280 generate_earlyret_entry_for(ltos), |
|
281 generate_earlyret_entry_for(ftos), |
|
282 generate_earlyret_entry_for(dtos), |
|
283 generate_earlyret_entry_for(vtos) |
|
284 ); |
|
285 } |
|
286 |
|
287 { CodeletMark cm(_masm, "deoptimization entry points"); |
|
288 for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) { |
|
289 Interpreter::_deopt_entry[i] = |
|
290 EntryPoint( |
|
291 generate_deopt_entry_for(itos, i), |
|
292 generate_deopt_entry_for(itos, i), |
|
293 generate_deopt_entry_for(itos, i), |
|
294 generate_deopt_entry_for(atos, i), |
|
295 generate_deopt_entry_for(itos, i), |
|
296 generate_deopt_entry_for(ltos, i), |
|
297 generate_deopt_entry_for(ftos, i), |
|
298 generate_deopt_entry_for(dtos, i), |
|
299 generate_deopt_entry_for(vtos, i) |
|
300 ); |
|
301 } |
|
302 } |
|
303 |
|
304 { CodeletMark cm(_masm, "result handlers for native calls"); |
|
305 // The various result converter stublets. |
|
306 int is_generated[Interpreter::number_of_result_handlers]; |
|
307 memset(is_generated, 0, sizeof(is_generated)); |
|
308 |
|
309 for (int i = 0; i < Interpreter::number_of_result_handlers; i++) { |
|
310 BasicType type = types[i]; |
|
311 if (!is_generated[Interpreter::BasicType_as_index(type)]++) { |
|
312 Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type); |
|
313 } |
|
314 } |
|
315 } |
|
316 |
|
317 { CodeletMark cm(_masm, "continuation entry points"); |
|
318 Interpreter::_continuation_entry = |
|
319 EntryPoint( |
|
320 generate_continuation_for(btos), |
|
321 generate_continuation_for(ctos), |
|
322 generate_continuation_for(stos), |
|
323 generate_continuation_for(atos), |
|
324 generate_continuation_for(itos), |
|
325 generate_continuation_for(ltos), |
|
326 generate_continuation_for(ftos), |
|
327 generate_continuation_for(dtos), |
|
328 generate_continuation_for(vtos) |
|
329 ); |
|
330 } |
|
331 |
|
332 { CodeletMark cm(_masm, "safepoint entry points"); |
|
333 Interpreter::_safept_entry = |
|
334 EntryPoint( |
|
335 generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
336 generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
337 generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
338 generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
339 generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
340 generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
341 generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
342 generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
343 generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)) |
|
344 ); |
|
345 } |
|
346 |
|
347 { CodeletMark cm(_masm, "exception handling"); |
|
348 // (Note: this is not safepoint safe because thread may return to compiled code) |
|
349 generate_throw_exception(); |
|
350 } |
|
351 |
|
352 { CodeletMark cm(_masm, "throw exception entrypoints"); |
|
353 Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException"); |
|
354 Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" ); |
|
355 Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero"); |
|
356 Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler(); |
|
357 Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL ); |
|
358 Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler(); |
|
359 } |
|
360 |
|
361 |
|
362 |
|
363 #define method_entry(kind) \ |
|
364 { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \ |
|
365 Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \ |
|
366 } |
|
367 |
|
368 // all non-native method kinds |
|
369 method_entry(zerolocals) |
|
370 method_entry(zerolocals_synchronized) |
|
371 method_entry(empty) |
|
372 method_entry(accessor) |
|
373 method_entry(abstract) |
|
374 method_entry(java_lang_math_sin ) |
|
375 method_entry(java_lang_math_cos ) |
|
376 method_entry(java_lang_math_tan ) |
|
377 method_entry(java_lang_math_abs ) |
|
378 method_entry(java_lang_math_sqrt ) |
|
379 method_entry(java_lang_math_log ) |
|
380 method_entry(java_lang_math_log10) |
|
381 method_entry(java_lang_math_exp ) |
|
382 method_entry(java_lang_math_pow ) |
|
383 method_entry(java_lang_ref_reference_get) |
|
384 |
|
385 if (UseCRC32Intrinsics) { |
|
386 method_entry(java_util_zip_CRC32_update) |
|
387 method_entry(java_util_zip_CRC32_updateBytes) |
|
388 method_entry(java_util_zip_CRC32_updateByteBuffer) |
|
389 } |
|
390 |
|
391 initialize_method_handle_entries(); |
|
392 |
|
393 // all native method kinds (must be one contiguous block) |
|
394 Interpreter::_native_entry_begin = Interpreter::code()->code_end(); |
|
395 method_entry(native) |
|
396 method_entry(native_synchronized) |
|
397 Interpreter::_native_entry_end = Interpreter::code()->code_end(); |
|
398 |
|
399 #undef method_entry |
|
400 |
|
401 // Bytecodes |
|
402 set_entry_points_for_all_bytes(); |
|
403 set_safepoints_for_all_bytes(); |
|
404 } |
|
405 |
|
406 //------------------------------------------------------------------------------------------------------------------------ |
|
407 |
|
408 address TemplateInterpreterGenerator::generate_error_exit(const char* msg) { |
|
409 address entry = __ pc(); |
|
410 __ stop(msg); |
|
411 return entry; |
|
412 } |
|
413 |
|
414 |
|
415 //------------------------------------------------------------------------------------------------------------------------ |
|
416 |
|
417 void TemplateInterpreterGenerator::set_entry_points_for_all_bytes() { |
|
418 for (int i = 0; i < DispatchTable::length; i++) { |
|
419 Bytecodes::Code code = (Bytecodes::Code)i; |
|
420 if (Bytecodes::is_defined(code)) { |
|
421 set_entry_points(code); |
|
422 } else { |
|
423 set_unimplemented(i); |
|
424 } |
|
425 } |
|
426 } |
|
427 |
|
428 |
|
429 void TemplateInterpreterGenerator::set_safepoints_for_all_bytes() { |
|
430 for (int i = 0; i < DispatchTable::length; i++) { |
|
431 Bytecodes::Code code = (Bytecodes::Code)i; |
|
432 if (Bytecodes::is_defined(code)) Interpreter::_safept_table.set_entry(code, Interpreter::_safept_entry); |
|
433 } |
|
434 } |
|
435 |
|
436 |
|
437 void TemplateInterpreterGenerator::set_unimplemented(int i) { |
|
438 address e = _unimplemented_bytecode; |
|
439 EntryPoint entry(e, e, e, e, e, e, e, e, e); |
|
440 Interpreter::_normal_table.set_entry(i, entry); |
|
441 Interpreter::_wentry_point[i] = _unimplemented_bytecode; |
|
442 } |
|
443 |
|
444 |
|
445 void TemplateInterpreterGenerator::set_entry_points(Bytecodes::Code code) { |
|
446 CodeletMark cm(_masm, Bytecodes::name(code), code); |
|
447 // initialize entry points |
|
448 assert(_unimplemented_bytecode != NULL, "should have been generated before"); |
|
449 assert(_illegal_bytecode_sequence != NULL, "should have been generated before"); |
|
450 address bep = _illegal_bytecode_sequence; |
|
451 address cep = _illegal_bytecode_sequence; |
|
452 address sep = _illegal_bytecode_sequence; |
|
453 address aep = _illegal_bytecode_sequence; |
|
454 address iep = _illegal_bytecode_sequence; |
|
455 address lep = _illegal_bytecode_sequence; |
|
456 address fep = _illegal_bytecode_sequence; |
|
457 address dep = _illegal_bytecode_sequence; |
|
458 address vep = _unimplemented_bytecode; |
|
459 address wep = _unimplemented_bytecode; |
|
460 // code for short & wide version of bytecode |
|
461 if (Bytecodes::is_defined(code)) { |
|
462 Template* t = TemplateTable::template_for(code); |
|
463 assert(t->is_valid(), "just checking"); |
|
464 set_short_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); |
|
465 } |
|
466 if (Bytecodes::wide_is_defined(code)) { |
|
467 Template* t = TemplateTable::template_for_wide(code); |
|
468 assert(t->is_valid(), "just checking"); |
|
469 set_wide_entry_point(t, wep); |
|
470 } |
|
471 // set entry points |
|
472 EntryPoint entry(bep, cep, sep, aep, iep, lep, fep, dep, vep); |
|
473 Interpreter::_normal_table.set_entry(code, entry); |
|
474 Interpreter::_wentry_point[code] = wep; |
|
475 } |
|
476 |
|
477 |
|
478 void TemplateInterpreterGenerator::set_wide_entry_point(Template* t, address& wep) { |
|
479 assert(t->is_valid(), "template must exist"); |
|
480 assert(t->tos_in() == vtos, "only vtos tos_in supported for wide instructions"); |
|
481 wep = __ pc(); generate_and_dispatch(t); |
|
482 } |
|
483 |
|
484 |
|
485 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) { |
|
486 assert(t->is_valid(), "template must exist"); |
|
487 switch (t->tos_in()) { |
|
488 case btos: |
|
489 case ctos: |
|
490 case stos: |
|
491 ShouldNotReachHere(); // btos/ctos/stos should use itos. |
|
492 break; |
|
493 case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break; |
|
494 case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break; |
|
495 case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break; |
|
496 case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break; |
|
497 case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break; |
|
498 case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); break; |
|
499 default : ShouldNotReachHere(); break; |
|
500 } |
|
501 } |
|
502 |
|
503 |
|
504 //------------------------------------------------------------------------------------------------------------------------ |
|
505 |
|
506 void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) { |
|
507 if (PrintBytecodeHistogram) histogram_bytecode(t); |
|
508 #ifndef PRODUCT |
|
509 // debugging code |
|
510 if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode(); |
|
511 if (PrintBytecodePairHistogram) histogram_bytecode_pair(t); |
|
512 if (TraceBytecodes) trace_bytecode(t); |
|
513 if (StopInterpreterAt > 0) stop_interpreter_at(); |
|
514 __ verify_FPU(1, t->tos_in()); |
|
515 #endif // !PRODUCT |
|
516 int step; |
|
517 if (!t->does_dispatch()) { |
|
518 step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode()); |
|
519 if (tos_out == ilgl) tos_out = t->tos_out(); |
|
520 // compute bytecode size |
|
521 assert(step > 0, "just checkin'"); |
|
522 // setup stuff for dispatching next bytecode |
|
523 if (ProfileInterpreter && VerifyDataPointer |
|
524 && MethodData::bytecode_has_profile(t->bytecode())) { |
|
525 __ verify_method_data_pointer(); |
|
526 } |
|
527 __ dispatch_prolog(tos_out, step); |
|
528 } |
|
529 // generate template |
|
530 t->generate(_masm); |
|
531 // advance |
|
532 if (t->does_dispatch()) { |
|
533 #ifdef ASSERT |
|
534 // make sure execution doesn't go beyond this point if code is broken |
|
535 __ should_not_reach_here(); |
|
536 #endif // ASSERT |
|
537 } else { |
|
538 // dispatch to next bytecode |
|
539 __ dispatch_epilog(tos_out, step); |
|
540 } |
|
541 } |
|
542 |
|
543 //------------------------------------------------------------------------------------------------------------------------ |
|
544 // Entry points |
|
545 |
|
546 /** |
|
547 * Returns the return entry table for the given invoke bytecode. |
|
548 */ |
|
549 address* TemplateInterpreter::invoke_return_entry_table_for(Bytecodes::Code code) { |
|
550 switch (code) { |
|
551 case Bytecodes::_invokestatic: |
|
552 case Bytecodes::_invokespecial: |
|
553 case Bytecodes::_invokevirtual: |
|
554 case Bytecodes::_invokehandle: |
|
555 return Interpreter::invoke_return_entry_table(); |
|
556 case Bytecodes::_invokeinterface: |
|
557 return Interpreter::invokeinterface_return_entry_table(); |
|
558 case Bytecodes::_invokedynamic: |
|
559 return Interpreter::invokedynamic_return_entry_table(); |
|
560 default: |
|
561 fatal(err_msg("invalid bytecode: %s", Bytecodes::name(code))); |
|
562 return NULL; |
|
563 } |
|
564 } |
|
565 |
|
566 /** |
|
567 * Returns the return entry address for the given top-of-stack state and bytecode. |
|
568 */ |
|
569 address TemplateInterpreter::return_entry(TosState state, int length, Bytecodes::Code code) { |
|
570 guarantee(0 <= length && length < Interpreter::number_of_return_entries, "illegal length"); |
|
571 const int index = TosState_as_index(state); |
|
572 switch (code) { |
|
573 case Bytecodes::_invokestatic: |
|
574 case Bytecodes::_invokespecial: |
|
575 case Bytecodes::_invokevirtual: |
|
576 case Bytecodes::_invokehandle: |
|
577 return _invoke_return_entry[index]; |
|
578 case Bytecodes::_invokeinterface: |
|
579 return _invokeinterface_return_entry[index]; |
|
580 case Bytecodes::_invokedynamic: |
|
581 return _invokedynamic_return_entry[index]; |
|
582 default: |
|
583 assert(!Bytecodes::is_invoke(code), err_msg("invoke instructions should be handled separately: %s", Bytecodes::name(code))); |
|
584 return _return_entry[length].entry(state); |
|
585 } |
|
586 } |
|
587 |
|
588 |
|
589 address TemplateInterpreter::deopt_entry(TosState state, int length) { |
|
590 guarantee(0 <= length && length < Interpreter::number_of_deopt_entries, "illegal length"); |
|
591 return _deopt_entry[length].entry(state); |
|
592 } |
|
593 |
|
594 //------------------------------------------------------------------------------------------------------------------------ |
|
595 // Suport for invokes |
|
596 |
|
597 int TemplateInterpreter::TosState_as_index(TosState state) { |
|
598 assert( state < number_of_states , "Invalid state in TosState_as_index"); |
|
599 assert(0 <= (int)state && (int)state < TemplateInterpreter::number_of_return_addrs, "index out of bounds"); |
|
600 return (int)state; |
|
601 } |
|
602 |
|
603 |
|
604 //------------------------------------------------------------------------------------------------------------------------ |
|
605 // Safepoint suppport |
|
606 |
|
607 static inline void copy_table(address* from, address* to, int size) { |
|
608 // Copy non-overlapping tables. The copy has to occur word wise for MT safety. |
|
609 while (size-- > 0) *to++ = *from++; |
|
610 } |
|
611 |
|
612 void TemplateInterpreter::notice_safepoints() { |
|
613 if (!_notice_safepoints) { |
|
614 // switch to safepoint dispatch table |
|
615 _notice_safepoints = true; |
|
616 copy_table((address*)&_safept_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address)); |
|
617 } |
|
618 } |
|
619 |
|
620 // switch from the dispatch table which notices safepoints back to the |
|
621 // normal dispatch table. So that we can notice single stepping points, |
|
622 // keep the safepoint dispatch table if we are single stepping in JVMTI. |
|
623 // Note that the should_post_single_step test is exactly as fast as the |
|
624 // JvmtiExport::_enabled test and covers both cases. |
|
625 void TemplateInterpreter::ignore_safepoints() { |
|
626 if (_notice_safepoints) { |
|
627 if (!JvmtiExport::should_post_single_step()) { |
|
628 // switch to normal dispatch table |
|
629 _notice_safepoints = false; |
|
630 copy_table((address*)&_normal_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address)); |
|
631 } |
|
632 } |
|
633 } |
|
634 |
|
635 //------------------------------------------------------------------------------------------------------------------------ |
|
636 // Deoptimization support |
|
637 |
|
638 // If deoptimization happens, this function returns the point of next bytecode to continue execution |
|
639 address TemplateInterpreter::deopt_continue_after_entry(Method* method, address bcp, int callee_parameters, bool is_top_frame) { |
|
640 return AbstractInterpreter::deopt_continue_after_entry(method, bcp, callee_parameters, is_top_frame); |
|
641 } |
|
642 |
|
643 // If deoptimization happens, this function returns the point where the interpreter reexecutes |
|
644 // the bytecode. |
|
645 // Note: Bytecodes::_athrow (C1 only) and Bytecodes::_return are the special cases |
|
646 // that do not return "Interpreter::deopt_entry(vtos, 0)" |
|
647 address TemplateInterpreter::deopt_reexecute_entry(Method* method, address bcp) { |
|
648 assert(method->contains(bcp), "just checkin'"); |
|
649 Bytecodes::Code code = Bytecodes::java_code_at(method, bcp); |
|
650 if (code == Bytecodes::_return) { |
|
651 // This is used for deopt during registration of finalizers |
|
652 // during Object.<init>. We simply need to resume execution at |
|
653 // the standard return vtos bytecode to pop the frame normally. |
|
654 // reexecuting the real bytecode would cause double registration |
|
655 // of the finalizable object. |
|
656 return _normal_table.entry(Bytecodes::_return).entry(vtos); |
|
657 } else { |
|
658 return AbstractInterpreter::deopt_reexecute_entry(method, bcp); |
|
659 } |
|
660 } |
|
661 |
|
662 // If deoptimization happens, the interpreter should reexecute this bytecode. |
|
663 // This function mainly helps the compilers to set up the reexecute bit. |
|
664 bool TemplateInterpreter::bytecode_should_reexecute(Bytecodes::Code code) { |
|
665 if (code == Bytecodes::_return) { |
|
666 //Yes, we consider Bytecodes::_return as a special case of reexecution |
|
667 return true; |
|
668 } else { |
|
669 return AbstractInterpreter::bytecode_should_reexecute(code); |
|
670 } |
|
671 } |
|
672 |
|
673 #endif // !CC_INTERP |