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 "code/codeCacheExtensions.hpp"
27 #include "interpreter/interpreter.hpp"
28 #include "interpreter/interpreterRuntime.hpp"
29 #include "interpreter/interp_masm.hpp"
30 #include "interpreter/templateInterpreter.hpp"
31 #include "interpreter/templateInterpreterGenerator.hpp"
32 #include "interpreter/templateTable.hpp"
33
34 #ifndef CC_INTERP
35
36 # define __ _masm->
37
38 TemplateInterpreterGenerator::TemplateInterpreterGenerator(StubQueue* _code): AbstractInterpreterGenerator(_code) {
39 _unimplemented_bytecode = NULL;
40 _illegal_bytecode_sequence = NULL;
41 generate_all();
42 }
43
44 static const BasicType types[Interpreter::number_of_result_handlers] = {
45 T_BOOLEAN,
46 T_CHAR ,
47 T_BYTE ,
48 T_SHORT ,
49 T_INT ,
50 T_LONG ,
51 T_VOID ,
52 T_FLOAT ,
249 if (UseCRC32Intrinsics) {
250 method_entry(java_util_zip_CRC32_update)
251 method_entry(java_util_zip_CRC32_updateBytes)
252 method_entry(java_util_zip_CRC32_updateByteBuffer)
253 }
254
255 if (UseCRC32CIntrinsics) {
256 method_entry(java_util_zip_CRC32C_updateBytes)
257 method_entry(java_util_zip_CRC32C_updateDirectByteBuffer)
258 }
259
260 method_entry(java_lang_Float_intBitsToFloat);
261 method_entry(java_lang_Float_floatToRawIntBits);
262 method_entry(java_lang_Double_longBitsToDouble);
263 method_entry(java_lang_Double_doubleToRawLongBits);
264
265 #undef method_entry
266
267 // Bytecodes
268 set_entry_points_for_all_bytes();
269 }
270 } while (CodeCacheExtensions::needs_other_interpreter_variant());
271
272 // installation of code in other places in the runtime
273 // (ExcutableCodeManager calls not needed to copy the entries)
274 set_safepoints_for_all_bytes();
275 }
276
277 //------------------------------------------------------------------------------------------------------------------------
278
279 address TemplateInterpreterGenerator::generate_error_exit(const char* msg) {
280 address entry = __ pc();
281 __ stop(msg);
282 return entry;
283 }
284
285
286 //------------------------------------------------------------------------------------------------------------------------
287
288 void TemplateInterpreterGenerator::set_entry_points_for_all_bytes() {
360
361 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& qep, address& vep) {
362 assert(t->is_valid(), "template must exist");
363 switch (t->tos_in()) {
364 case btos:
365 case ctos:
366 case stos:
367 ShouldNotReachHere(); // btos/ctos/stos should use itos.
368 break;
369 case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break;
370 case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break;
371 case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break;
372 case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break;
373 case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break;
374 case qtos: vep = __ pc(); __ pop(qtos); qep = __ pc(); generate_and_dispatch(t); break;
375 case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, qep, vep); break;
376 default : ShouldNotReachHere(); break;
377 }
378 }
379
380
381 //------------------------------------------------------------------------------------------------------------------------
382
383 void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) {
384 if (PrintBytecodeHistogram) histogram_bytecode(t);
385 #ifndef PRODUCT
386 // debugging code
387 if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode();
388 if (PrintBytecodePairHistogram) histogram_bytecode_pair(t);
389 if (TraceBytecodes) trace_bytecode(t);
390 if (StopInterpreterAt > 0) stop_interpreter_at();
391 __ verify_FPU(1, t->tos_in());
392 #endif // !PRODUCT
393 int step = 0;
394 if (!t->does_dispatch()) {
395 step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode());
396 if (tos_out == ilgl) tos_out = t->tos_out();
397 // compute bytecode size
398 assert(step > 0, "just checkin'");
399 // setup stuff for dispatching next bytecode
480 }
481
482 if (entry_point) {
483 return entry_point;
484 }
485
486 // We expect the normal and native entry points to be generated first so we can reuse them.
487 if (native) {
488 entry_point = Interpreter::entry_for_kind(synchronized ? Interpreter::native_synchronized : Interpreter::native);
489 if (entry_point == NULL) {
490 entry_point = generate_native_entry(synchronized);
491 }
492 } else {
493 entry_point = Interpreter::entry_for_kind(synchronized ? Interpreter::zerolocals_synchronized : Interpreter::zerolocals);
494 if (entry_point == NULL) {
495 entry_point = generate_normal_entry(synchronized);
496 }
497 }
498
499 return entry_point;
500 }
501 #endif // !CC_INTERP
|
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 "code/codeCacheExtensions.hpp"
27 #include "interpreter/interpreter.hpp"
28 #include "interpreter/interpreterRuntime.hpp"
29 #include "interpreter/interp_masm.hpp"
30 #include "interpreter/templateInterpreter.hpp"
31 #include "interpreter/templateInterpreterGenerator.hpp"
32 #include "interpreter/templateTable.hpp"
33 #include "interpreter/extendedBytecodes.hpp"
34
35 #ifndef CC_INTERP
36
37 # define __ _masm->
38
39 TemplateInterpreterGenerator::TemplateInterpreterGenerator(StubQueue* _code): AbstractInterpreterGenerator(_code) {
40 _unimplemented_bytecode = NULL;
41 _illegal_bytecode_sequence = NULL;
42 generate_all();
43 }
44
45 static const BasicType types[Interpreter::number_of_result_handlers] = {
46 T_BOOLEAN,
47 T_CHAR ,
48 T_BYTE ,
49 T_SHORT ,
50 T_INT ,
51 T_LONG ,
52 T_VOID ,
53 T_FLOAT ,
250 if (UseCRC32Intrinsics) {
251 method_entry(java_util_zip_CRC32_update)
252 method_entry(java_util_zip_CRC32_updateBytes)
253 method_entry(java_util_zip_CRC32_updateByteBuffer)
254 }
255
256 if (UseCRC32CIntrinsics) {
257 method_entry(java_util_zip_CRC32C_updateBytes)
258 method_entry(java_util_zip_CRC32C_updateDirectByteBuffer)
259 }
260
261 method_entry(java_lang_Float_intBitsToFloat);
262 method_entry(java_lang_Float_floatToRawIntBits);
263 method_entry(java_lang_Double_longBitsToDouble);
264 method_entry(java_lang_Double_doubleToRawLongBits);
265
266 #undef method_entry
267
268 // Bytecodes
269 set_entry_points_for_all_bytes();
270
271 set_entry_points_for_all_BCSets();
272 }
273 } while (CodeCacheExtensions::needs_other_interpreter_variant());
274
275 // installation of code in other places in the runtime
276 // (ExcutableCodeManager calls not needed to copy the entries)
277 set_safepoints_for_all_bytes();
278 }
279
280 //------------------------------------------------------------------------------------------------------------------------
281
282 address TemplateInterpreterGenerator::generate_error_exit(const char* msg) {
283 address entry = __ pc();
284 __ stop(msg);
285 return entry;
286 }
287
288
289 //------------------------------------------------------------------------------------------------------------------------
290
291 void TemplateInterpreterGenerator::set_entry_points_for_all_bytes() {
363
364 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& qep, address& vep) {
365 assert(t->is_valid(), "template must exist");
366 switch (t->tos_in()) {
367 case btos:
368 case ctos:
369 case stos:
370 ShouldNotReachHere(); // btos/ctos/stos should use itos.
371 break;
372 case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break;
373 case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break;
374 case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break;
375 case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break;
376 case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break;
377 case qtos: vep = __ pc(); __ pop(qtos); qep = __ pc(); generate_and_dispatch(t); break;
378 case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, qep, vep); break;
379 default : ShouldNotReachHere(); break;
380 }
381 }
382
383 void TemplateInterpreterGenerator::set_noTosCa_entry_point(Template* t, address* ep) {
384 assert(t->is_valid(), "template must exist");
385 *ep = __ pc();
386 switch (t->tos_in()) {
387 case btos:
388 case ctos:
389 case stos:
390 ShouldNotReachHere(); // btos/ctos/stos should use itos.
391 break;
392 case atos: __ pop(atos); break;
393 case itos: __ pop(itos); break;
394 case ltos: __ pop(ltos); break;
395 case ftos: __ pop(ftos); break;
396 case dtos: __ pop(dtos); break;
397 case qtos: __ pop(qtos); break;
398 case vtos: break;
399 default : ShouldNotReachHere();
400 }
401 generate_and_dispatch(t);
402 switch (t->tos_out()) {
403 case btos:
404 case ctos:
405 case stos:
406 ShouldNotReachHere(); // btos/ctos/stos should use itos.
407 break;
408 case atos: __ push(atos); break;
409 case itos: __ push(itos); break;
410 case ltos: __ push(ltos); break;
411 case ftos: __ push(ftos); break;
412 case dtos: __ push(dtos); break;
413 case qtos: __ push(qtos); break;
414 case vtos: break;
415 default : ShouldNotReachHere();
416 }
417 }
418
419 //------------------------------------------------------------------------------------------------------------------------
420
421 void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) {
422 if (PrintBytecodeHistogram) histogram_bytecode(t);
423 #ifndef PRODUCT
424 // debugging code
425 if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode();
426 if (PrintBytecodePairHistogram) histogram_bytecode_pair(t);
427 if (TraceBytecodes) trace_bytecode(t);
428 if (StopInterpreterAt > 0) stop_interpreter_at();
429 __ verify_FPU(1, t->tos_in());
430 #endif // !PRODUCT
431 int step = 0;
432 if (!t->does_dispatch()) {
433 step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode());
434 if (tos_out == ilgl) tos_out = t->tos_out();
435 // compute bytecode size
436 assert(step > 0, "just checkin'");
437 // setup stuff for dispatching next bytecode
518 }
519
520 if (entry_point) {
521 return entry_point;
522 }
523
524 // We expect the normal and native entry points to be generated first so we can reuse them.
525 if (native) {
526 entry_point = Interpreter::entry_for_kind(synchronized ? Interpreter::native_synchronized : Interpreter::native);
527 if (entry_point == NULL) {
528 entry_point = generate_native_entry(synchronized);
529 }
530 } else {
531 entry_point = Interpreter::entry_for_kind(synchronized ? Interpreter::zerolocals_synchronized : Interpreter::zerolocals);
532 if (entry_point == NULL) {
533 entry_point = generate_normal_entry(synchronized);
534 }
535 }
536
537 return entry_point;
538 }
539
540 void TemplateInterpreterGenerator::set_entry_points_for_all_BCSets() {
541 // Marking all entry points as unimplemented, so extended bytecodes generators can work lazily
542
543 for (int btype = 0; btype < Bytecodes::number_of_bcset; btype++) {
544 for (int bytecode = 0 ; bytecode < DispatchTable::length; bytecode ++) {
545 TemplateInterpreter::_typed_entry_point[btype][bytecode] = _unimplemented_bytecode;
546 TemplateInterpreter::_typed_wentry_point[btype][bytecode] = _unimplemented_bytecode;
547 }
548 }
549
550 // Iterations start at bcset == 1 because value zero is reserved for legacy bytecodes
551 for (int bcset = 1; bcset < Bytecodes::number_of_bcset; bcset++) {
552 BCSetTemplate* bcset_template = BCSetTemplate::BCSetTemplate_for((Bytecodes::BCSet(bcset)));
553 if (bcset_template != NULL) {
554 set_entry_points_for_BCSet(bcset_template);
555 }
556 }
557 }
558
559 void TemplateInterpreterGenerator::set_entry_points_for_BCSet(BCSetTemplate* bcset_template) {
560 GrowableArray<Alias>* aliases = bcset_template->aliases ();
561 if (aliases != NULL) {
562 for (int i = 0; i < aliases->length(); ++i) {
563 Alias a = aliases->at(i);
564 Bytecodes::BCSet btype = Bytecodes::bcset(a._extended_bytecode);
565 Bytecodes::Code code = Bytecodes::bytecode(a._extended_bytecode);
566 // All typed bytecodes have a vtos TosState in
567 address ep = TemplateInterpreter::_normal_table.entry(Bytecodes::bytecode(a._alias)).entry(vtos);
568 TemplateInterpreter::_typed_entry_point[btype][code] = ep;
569 if (Bytecodes::wide_is_defined(Bytecodes::bytecode(a._extended_bytecode))) {
570 TemplateInterpreter::_typed_wentry_point[btype][code] = TemplateInterpreter::_wentry_point[Bytecodes::bytecode(a._alias)];
571 }
572 }
573 }
574 GrowableArray<Template>* templates = bcset_template->templates();
575 if (templates != NULL) {
576 for (int i = 0; i < templates->length(); ++i) {
577 Template t = templates->at(i);
578 Bytecodes::Code ext_code = t.bytecode();
579 Bytecodes::Code code = Bytecodes::bytecode(ext_code);
580 Bytecodes::BCSet btype = Bytecodes::bcset(ext_code);
581 CodeletMark cm(_masm, Bytecodes::name(ext_code), ext_code);
582 address* ep = NULL;
583 if (t.is_wide()) {
584 ep = &TemplateInterpreter::_typed_wentry_point[btype][code];
585 } else {
586 ep = &TemplateInterpreter::_typed_entry_point[btype][code];
587 }
588 set_noTosCa_entry_point(&t, ep);
589 }
590 }
591 }
592 #endif // !CC_INTERP
|