169 Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler();
170 Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException");
171 Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException", "/ by zero");
172 Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler();
173 Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException", nullptr);
174 Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler();
175 }
176
177 { CodeletMark cm(_masm, "preemption resume adapter");
178 Interpreter::_cont_resume_interpreter_adapter = generate_cont_resume_interpreter_adapter();
179 }
180
181 #define method_entry(kind) \
182 { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \
183 Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind, false); \
184 }
185
186 // all non-native method kinds
187 method_entry(zerolocals)
188 method_entry(zerolocals_synchronized)
189 method_entry(empty)
190 method_entry(getter)
191 method_entry(setter)
192 method_entry(abstract)
193 method_entry(java_lang_math_sin )
194 method_entry(java_lang_math_cos )
195 method_entry(java_lang_math_tan )
196 method_entry(java_lang_math_sinh )
197 method_entry(java_lang_math_tanh )
198 method_entry(java_lang_math_cbrt )
199 method_entry(java_lang_math_abs )
200 method_entry(java_lang_math_sqrt )
201 method_entry(java_lang_math_sqrt_strict)
202 method_entry(java_lang_math_log )
203 method_entry(java_lang_math_log10)
204 method_entry(java_lang_math_exp )
205 method_entry(java_lang_math_pow )
206 method_entry(java_lang_math_fmaF )
207 method_entry(java_lang_math_fmaD )
208 method_entry(java_lang_ref_reference_get0)
209 AbstractInterpreter::initialize_method_handle_entries();
210
211 method_entry(java_util_zip_CRC32C_updateBytes)
212 method_entry(java_util_zip_CRC32C_updateDirectByteBuffer)
213
214 method_entry(java_lang_Float_float16ToFloat);
215 method_entry(java_lang_Float_floatToFloat16);
216
217 #undef method_entry
218
219 // all native method kinds
220 #define native_method_entry(kind) \
221 { CodeletMark cm(_masm, "native method entry point (kind = " #kind ")"); \
222 Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind, true); \
223 }
224
225 native_method_entry(native)
226 native_method_entry(native_synchronized)
227
228 // Entries to intrinsics for native methods should follow
229 // entries for `native` methods to use the same address in case
230 // intrinsic is disabled.
231 native_method_entry(java_lang_Thread_currentThread)
232 native_method_entry(java_lang_ref_reference_get0)
233
234 native_method_entry(java_util_zip_CRC32_update)
235 native_method_entry(java_util_zip_CRC32_updateBytes)
236 native_method_entry(java_util_zip_CRC32_updateByteBuffer)
237
238 #undef native_method_entry
239
240 // Bytecodes
241 set_entry_points_for_all_bytes();
242
243 // installation of code in other places in the runtime
244 set_safepoints_for_all_bytes();
245
246 { CodeletMark cm(_masm, "deoptimization entry points");
350 case btos:
351 case ztos:
352 case ctos:
353 case stos:
354 ShouldNotReachHere(); // btos/ctos/stos should use itos.
355 break;
356 case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break;
357 case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break;
358 case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break;
359 case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break;
360 case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break;
361 case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); break;
362 default : ShouldNotReachHere(); break;
363 }
364 }
365
366
367 //------------------------------------------------------------------------------------------------------------------------
368
369 void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) {
370 #ifndef PRODUCT
371 // debugging code
372 if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode();
373 if (PrintBytecodeHistogram) histogram_bytecode(t);
374 if (PrintBytecodePairHistogram) histogram_bytecode_pair(t);
375 if (TraceBytecodes) trace_bytecode(t);
376 if (StopInterpreterAt > 0) stop_interpreter_at();
377 #endif // !PRODUCT
378 int step = 0;
379 if (!t->does_dispatch()) {
380 step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode());
381 if (tos_out == ilgl) tos_out = t->tos_out();
382 // compute bytecode size
383 assert(step > 0, "just checkin'");
384 // setup stuff for dispatching next bytecode
385 if (ProfileInterpreter && VerifyDataPointer
386 && MethodData::bytecode_has_profile(t->bytecode())) {
387 __ verify_method_data_pointer();
388 }
389 __ dispatch_prolog(tos_out, step);
390 }
391 // generate template
392 t->generate(_masm);
393 // advance
394 if (t->does_dispatch()) {
395 #ifdef ASSERT
396 // make sure execution doesn't go beyond this point if code is broken
397 __ should_not_reach_here();
398 #endif // ASSERT
399 } else {
400 // dispatch to next bytecode
401 __ dispatch_epilog(tos_out, step);
402 }
403 }
404
405 // Generate method entries
406 address TemplateInterpreterGenerator::generate_method_entry(
407 AbstractInterpreter::MethodKind kind, bool native) {
408 // determine code generation flags
409 bool synchronized = false;
410 address entry_point = nullptr;
411
412 switch (kind) {
413 case Interpreter::zerolocals : break;
414 case Interpreter::zerolocals_synchronized: synchronized = true; break;
415 case Interpreter::native : break;
416 case Interpreter::native_synchronized : synchronized = true; break;
417 case Interpreter::empty : break;
418 case Interpreter::getter : break;
419 case Interpreter::setter : break;
420 case Interpreter::abstract : entry_point = generate_abstract_entry(); break;
421 default:
422 entry_point = generate_intrinsic_entry(kind); // process the rest
423 break;
424 }
425
426 if (entry_point) {
427 return entry_point;
428 }
429
430 // We expect the normal and native entry points to be generated first so we can reuse them.
431 if (native) {
432 entry_point = Interpreter::entry_for_kind(synchronized ? Interpreter::native_synchronized : Interpreter::native);
433 if (entry_point == nullptr) {
434 entry_point = generate_native_entry(synchronized);
435 }
436 } else {
437 entry_point = Interpreter::entry_for_kind(synchronized ? Interpreter::zerolocals_synchronized : Interpreter::zerolocals);
438 if (entry_point == nullptr) {
439 entry_point = generate_normal_entry(synchronized);
440 }
441 }
442
443 return entry_point;
444 }
445
446 // Generate intrinsic method entries
447 address TemplateInterpreterGenerator::generate_intrinsic_entry(AbstractInterpreter::MethodKind kind) {
448 if (!InlineIntrinsics || !vmIntrinsics::is_intrinsic_available(AbstractInterpreter::method_intrinsic(kind))) {
449 return nullptr;
450 }
451
452 address entry_point = nullptr;
453
454 switch (kind) {
455 case Interpreter::java_lang_math_sin : // fall thru
456 case Interpreter::java_lang_math_cos : // fall thru
457 case Interpreter::java_lang_math_tan : // fall thru
458 case Interpreter::java_lang_math_sinh : // fall thru
459 case Interpreter::java_lang_math_tanh : // fall thru
460 case Interpreter::java_lang_math_cbrt : // fall thru
|
169 Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler();
170 Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException");
171 Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException", "/ by zero");
172 Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler();
173 Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException", nullptr);
174 Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler();
175 }
176
177 { CodeletMark cm(_masm, "preemption resume adapter");
178 Interpreter::_cont_resume_interpreter_adapter = generate_cont_resume_interpreter_adapter();
179 }
180
181 #define method_entry(kind) \
182 { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \
183 Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind, false); \
184 }
185
186 // all non-native method kinds
187 method_entry(zerolocals)
188 method_entry(zerolocals_synchronized)
189 method_entry(zerolocals_upcalls)
190 method_entry(zerolocals_synchronized_upcalls)
191 method_entry(empty)
192 method_entry(empty_upcalls)
193 method_entry(getter)
194 method_entry(setter)
195 method_entry(abstract)
196 method_entry(java_lang_math_sin )
197 method_entry(java_lang_math_cos )
198 method_entry(java_lang_math_tan )
199 method_entry(java_lang_math_sinh )
200 method_entry(java_lang_math_tanh )
201 method_entry(java_lang_math_cbrt )
202 method_entry(java_lang_math_abs )
203 method_entry(java_lang_math_sqrt )
204 method_entry(java_lang_math_sqrt_strict)
205 method_entry(java_lang_math_log )
206 method_entry(java_lang_math_log10)
207 method_entry(java_lang_math_exp )
208 method_entry(java_lang_math_pow )
209 method_entry(java_lang_math_fmaF )
210 method_entry(java_lang_math_fmaD )
211 method_entry(java_lang_ref_reference_get0)
212 AbstractInterpreter::initialize_method_handle_entries();
213
214 method_entry(java_util_zip_CRC32C_updateBytes)
215 method_entry(java_util_zip_CRC32C_updateDirectByteBuffer)
216
217 method_entry(java_lang_Float_float16ToFloat);
218 method_entry(java_lang_Float_floatToFloat16);
219
220 #undef method_entry
221
222 // all native method kinds
223 #define native_method_entry(kind) \
224 { CodeletMark cm(_masm, "native method entry point (kind = " #kind ")"); \
225 Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind, true); \
226 }
227
228 native_method_entry(native)
229 native_method_entry(native_synchronized)
230 native_method_entry(native_upcalls)
231 native_method_entry(native_synchronized_upcalls)
232
233 // Entries to intrinsics for native methods should follow
234 // entries for `native` methods to use the same address in case
235 // intrinsic is disabled.
236 native_method_entry(java_lang_Thread_currentThread)
237 native_method_entry(java_lang_ref_reference_get0)
238
239 native_method_entry(java_util_zip_CRC32_update)
240 native_method_entry(java_util_zip_CRC32_updateBytes)
241 native_method_entry(java_util_zip_CRC32_updateByteBuffer)
242
243 #undef native_method_entry
244
245 // Bytecodes
246 set_entry_points_for_all_bytes();
247
248 // installation of code in other places in the runtime
249 set_safepoints_for_all_bytes();
250
251 { CodeletMark cm(_masm, "deoptimization entry points");
355 case btos:
356 case ztos:
357 case ctos:
358 case stos:
359 ShouldNotReachHere(); // btos/ctos/stos should use itos.
360 break;
361 case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break;
362 case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break;
363 case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break;
364 case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break;
365 case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break;
366 case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); break;
367 default : ShouldNotReachHere(); break;
368 }
369 }
370
371
372 //------------------------------------------------------------------------------------------------------------------------
373
374 void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) {
375 if (CountBytecodes || CountBytecodesPerThread || TraceBytecodes || StopInterpreterAt > 0) {
376 count_bytecode();
377 }
378 if (PrintBytecodeHistogram) histogram_bytecode(t);
379 #ifndef PRODUCT
380 // debugging code
381 if (PrintBytecodePairHistogram) histogram_bytecode_pair(t);
382 if (TraceBytecodes) trace_bytecode(t);
383 if (StopInterpreterAt > 0) stop_interpreter_at();
384 #endif // !PRODUCT
385 int step = 0;
386 if (!t->does_dispatch()) {
387 step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode());
388 if (tos_out == ilgl) tos_out = t->tos_out();
389 // compute bytecode size
390 assert(step > 0, "just checkin'");
391 // setup stuff for dispatching next bytecode
392 if (ProfileInterpreter && VerifyDataPointer
393 && MethodData::bytecode_has_profile(t->bytecode())) {
394 __ verify_method_data_pointer();
395 }
396 __ dispatch_prolog(tos_out, step);
397 }
398 // generate template
399 t->generate(_masm);
400 // advance
401 if (t->does_dispatch()) {
402 #ifdef ASSERT
403 // make sure execution doesn't go beyond this point if code is broken
404 __ should_not_reach_here();
405 #endif // ASSERT
406 } else {
407 // dispatch to next bytecode
408 __ dispatch_epilog(tos_out, step);
409 }
410 }
411
412 bool TemplateInterpreterGenerator::is_synchronized_method(AbstractInterpreter::MethodKind kind) {
413 switch (kind) {
414 case Interpreter::zerolocals_synchronized : // fall thru
415 case Interpreter::zerolocals_synchronized_upcalls: // fall thru
416 case Interpreter::native_synchronized : // fall thru
417 case Interpreter::native_synchronized_upcalls :
418 return true;
419 default:
420 return false;
421 }
422 }
423
424 bool TemplateInterpreterGenerator::is_runtime_upcalls_method(AbstractInterpreter::MethodKind kind) {
425 switch (kind) {
426 case Interpreter::zerolocals_upcalls : // fall thru
427 case Interpreter::zerolocals_synchronized_upcalls: // fall thru
428 case Interpreter::native_upcalls : // fall thru
429 case Interpreter::native_synchronized_upcalls : // fall thru
430 case Interpreter::empty_upcalls :
431 return true;
432 default:
433 return false;
434 }
435 }
436
437 bool TemplateInterpreterGenerator::is_intrinsic_method(AbstractInterpreter::MethodKind kind) {
438 switch (kind) {
439 case Interpreter::zerolocals : // fall thru
440 case Interpreter::zerolocals_synchronized : // fall thru
441 case Interpreter::zerolocals_upcalls : // fall thru
442 case Interpreter::zerolocals_synchronized_upcalls: // fall thru
443 case Interpreter::native : // fall thru
444 case Interpreter::native_synchronized : // fall thru
445 case Interpreter::native_upcalls : // fall thru
446 case Interpreter::native_synchronized_upcalls : // fall thru
447 case Interpreter::empty : // fall thru
448 case Interpreter::empty_upcalls : // fall thru
449 case Interpreter::getter : // fall thru
450 case Interpreter::setter : // fall thru
451 case Interpreter::abstract :
452 return false;
453 default:
454 return true;
455 }
456 }
457
458 bool TemplateInterpreterGenerator::is_abstract_method(AbstractInterpreter::MethodKind kind) {
459 switch (kind) {
460 case Interpreter::abstract:
461 return true;
462 default:
463 return false;
464 }
465 }
466
467 // Generate method entries
468 address TemplateInterpreterGenerator::generate_method_entry(
469 AbstractInterpreter::MethodKind kind, bool native) {
470 address entry_point = nullptr;
471
472 if (is_abstract_method(kind)) {
473 entry_point = generate_abstract_entry();
474 } else if (is_intrinsic_method(kind)) {
475 entry_point = generate_intrinsic_entry(kind);
476 }
477
478 if (entry_point) {
479 return entry_point;
480 }
481
482 bool synchronized = is_synchronized_method(kind);
483 bool upcalls = is_runtime_upcalls_method(kind);
484
485 // We expect the normal and native entry points to be generated first so we can reuse them.
486 if (!synchronized && !upcalls) {
487 entry_point = Interpreter::entry_for_kind(native ? Interpreter::native
488 : Interpreter::zerolocals);
489 } else if (synchronized && !upcalls) {
490 entry_point = Interpreter::entry_for_kind(native ? Interpreter::native_synchronized
491 : Interpreter::zerolocals_synchronized);
492 } else if (!synchronized && upcalls) {
493 entry_point = Interpreter::entry_for_kind(native ? Interpreter::native_upcalls
494 : Interpreter::zerolocals_upcalls);
495 } else if (synchronized && upcalls) {
496 entry_point = Interpreter::entry_for_kind(native ? Interpreter::native_synchronized_upcalls
497 : Interpreter::zerolocals_synchronized_upcalls);
498 }
499
500 if (entry_point == nullptr) {
501 entry_point = native ? generate_native_entry(synchronized, upcalls)
502 : generate_normal_entry(synchronized, upcalls);
503 }
504
505 return entry_point;
506 }
507
508 // Generate intrinsic method entries
509 address TemplateInterpreterGenerator::generate_intrinsic_entry(AbstractInterpreter::MethodKind kind) {
510 if (!InlineIntrinsics || !vmIntrinsics::is_intrinsic_available(AbstractInterpreter::method_intrinsic(kind))) {
511 return nullptr;
512 }
513
514 address entry_point = nullptr;
515
516 switch (kind) {
517 case Interpreter::java_lang_math_sin : // fall thru
518 case Interpreter::java_lang_math_cos : // fall thru
519 case Interpreter::java_lang_math_tan : // fall thru
520 case Interpreter::java_lang_math_sinh : // fall thru
521 case Interpreter::java_lang_math_tanh : // fall thru
522 case Interpreter::java_lang_math_cbrt : // fall thru
|