< prev index next >

src/hotspot/share/interpreter/templateInterpreterGenerator.cpp

Print this page

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_tanh )
197   method_entry(java_lang_math_cbrt )
198   method_entry(java_lang_math_abs  )
199   method_entry(java_lang_math_sqrt )
200   method_entry(java_lang_math_sqrt_strict)
201   method_entry(java_lang_math_log  )
202   method_entry(java_lang_math_log10)
203   method_entry(java_lang_math_exp  )
204   method_entry(java_lang_math_pow  )
205   method_entry(java_lang_math_fmaF )
206   method_entry(java_lang_math_fmaD )
207   method_entry(java_lang_ref_reference_get)
208   AbstractInterpreter::initialize_method_handle_entries();
209 
210   method_entry(java_util_zip_CRC32C_updateBytes)
211   method_entry(java_util_zip_CRC32C_updateDirectByteBuffer)
212 
213   method_entry(java_lang_Float_float16ToFloat);
214   method_entry(java_lang_Float_floatToFloat16);
215 
216 #undef method_entry
217 
218   // all native method kinds
219 #define native_method_entry(kind)                                                                  \
220   { CodeletMark cm(_masm, "native method entry point (kind = " #kind ")");                         \
221     Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind, true); \
222   }
223 
224   native_method_entry(native)
225   native_method_entry(native_synchronized)


226 
227   // Entries to intrinsics for native methods should follow
228   // entries for `native` methods to use the same address in case
229   // intrinsic is disabled.
230   native_method_entry(java_lang_Thread_currentThread)
231 
232   native_method_entry(java_util_zip_CRC32_update)
233   native_method_entry(java_util_zip_CRC32_updateBytes)
234   native_method_entry(java_util_zip_CRC32_updateByteBuffer)
235 
236 #undef native_method_entry
237 
238   // Bytecodes
239   set_entry_points_for_all_bytes();
240 
241   // installation of code in other places in the runtime
242   set_safepoints_for_all_bytes();
243 
244   { CodeletMark cm(_masm, "deoptimization entry points");
245     Interpreter::_deopt_entry[0] = EntryPoint();

348     case btos:
349     case ztos:
350     case ctos:
351     case stos:
352       ShouldNotReachHere();  // btos/ctos/stos should use itos.
353       break;
354     case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break;
355     case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break;
356     case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break;
357     case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break;
358     case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break;
359     case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep);     break;
360     default  : ShouldNotReachHere();                                                 break;
361   }
362 }
363 
364 
365 //------------------------------------------------------------------------------------------------------------------------
366 
367 void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) {




368 #ifndef PRODUCT
369   // debugging code
370   if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode();
371   if (PrintBytecodeHistogram)                                    histogram_bytecode(t);
372   if (PrintBytecodePairHistogram)                                histogram_bytecode_pair(t);
373   if (TraceBytecodes)                                            trace_bytecode(t);
374   if (StopInterpreterAt > 0)                                     stop_interpreter_at();
375 #endif // !PRODUCT
376   int step = 0;
377   if (!t->does_dispatch()) {
378     step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode());
379     if (tos_out == ilgl) tos_out = t->tos_out();
380     // compute bytecode size
381     assert(step > 0, "just checkin'");
382     // setup stuff for dispatching next bytecode
383     if (ProfileInterpreter && VerifyDataPointer
384         && MethodData::bytecode_has_profile(t->bytecode())) {
385       __ verify_method_data_pointer();
386     }
387     __ dispatch_prolog(tos_out, step);
388   }
389   // generate template
390   t->generate(_masm);
391   // advance
392   if (t->does_dispatch()) {
393 #ifdef ASSERT
394     // make sure execution doesn't go beyond this point if code is broken
395     __ should_not_reach_here();
396 #endif // ASSERT
397   } else {
398     // dispatch to next bytecode
399     __ dispatch_epilog(tos_out, step);
400   }
401 }
402 























































403 // Generate method entries
404 address TemplateInterpreterGenerator::generate_method_entry(
405                                         AbstractInterpreter::MethodKind kind, bool native) {
406   // determine code generation flags
407   bool synchronized = false;
408   address entry_point = nullptr;
409 
410   switch (kind) {
411   case Interpreter::zerolocals             :                           break;
412   case Interpreter::zerolocals_synchronized: synchronized = true;      break;
413   case Interpreter::native                 :                           break;
414   case Interpreter::native_synchronized    : synchronized = true;      break;
415   case Interpreter::empty                  : break;
416   case Interpreter::getter                 : break;
417   case Interpreter::setter                 : break;
418   case Interpreter::abstract               : entry_point = generate_abstract_entry(); break;
419   default:
420     entry_point = generate_intrinsic_entry(kind); // process the rest
421     break;
422   }
423 
424   if (entry_point) {
425     return entry_point;
426   }
427 



428   // We expect the normal and native entry points to be generated first so we can reuse them.
429   if (native) {
430     entry_point = Interpreter::entry_for_kind(synchronized ? Interpreter::native_synchronized : Interpreter::native);
431     if (entry_point == nullptr) {
432       entry_point = generate_native_entry(synchronized);
433     }
434   } else {
435     entry_point = Interpreter::entry_for_kind(synchronized ? Interpreter::zerolocals_synchronized : Interpreter::zerolocals);
436     if (entry_point == nullptr) {
437       entry_point = generate_normal_entry(synchronized);
438     }







439   }
440 
441   return entry_point;
442 }
443 
444 // Generate intrinsic method entries
445 address TemplateInterpreterGenerator::generate_intrinsic_entry(AbstractInterpreter::MethodKind kind) {
446   if (!InlineIntrinsics || !vmIntrinsics::is_intrinsic_available(AbstractInterpreter::method_intrinsic(kind))) {
447     return nullptr;
448   }
449 
450   address entry_point = nullptr;
451 
452   switch (kind) {
453   case Interpreter::java_lang_math_sin     : // fall thru
454   case Interpreter::java_lang_math_cos     : // fall thru
455   case Interpreter::java_lang_math_tan     : // fall thru
456   case Interpreter::java_lang_math_tanh    : // fall thru
457   case Interpreter::java_lang_math_cbrt    : // fall thru
458   case Interpreter::java_lang_math_abs     : // 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_tanh )
200   method_entry(java_lang_math_cbrt )
201   method_entry(java_lang_math_abs  )
202   method_entry(java_lang_math_sqrt )
203   method_entry(java_lang_math_sqrt_strict)
204   method_entry(java_lang_math_log  )
205   method_entry(java_lang_math_log10)
206   method_entry(java_lang_math_exp  )
207   method_entry(java_lang_math_pow  )
208   method_entry(java_lang_math_fmaF )
209   method_entry(java_lang_math_fmaD )
210   method_entry(java_lang_ref_reference_get)
211   AbstractInterpreter::initialize_method_handle_entries();
212 
213   method_entry(java_util_zip_CRC32C_updateBytes)
214   method_entry(java_util_zip_CRC32C_updateDirectByteBuffer)
215 
216   method_entry(java_lang_Float_float16ToFloat);
217   method_entry(java_lang_Float_floatToFloat16);
218 
219 #undef method_entry
220 
221   // all native method kinds
222 #define native_method_entry(kind)                                                                  \
223   { CodeletMark cm(_masm, "native method entry point (kind = " #kind ")");                         \
224     Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind, true); \
225   }
226 
227   native_method_entry(native)
228   native_method_entry(native_synchronized)
229   native_method_entry(native_upcalls)
230   native_method_entry(native_synchronized_upcalls)
231 
232   // Entries to intrinsics for native methods should follow
233   // entries for `native` methods to use the same address in case
234   // intrinsic is disabled.
235   native_method_entry(java_lang_Thread_currentThread)
236 
237   native_method_entry(java_util_zip_CRC32_update)
238   native_method_entry(java_util_zip_CRC32_updateBytes)
239   native_method_entry(java_util_zip_CRC32_updateByteBuffer)
240 
241 #undef native_method_entry
242 
243   // Bytecodes
244   set_entry_points_for_all_bytes();
245 
246   // installation of code in other places in the runtime
247   set_safepoints_for_all_bytes();
248 
249   { CodeletMark cm(_masm, "deoptimization entry points");
250     Interpreter::_deopt_entry[0] = EntryPoint();

353     case btos:
354     case ztos:
355     case ctos:
356     case stos:
357       ShouldNotReachHere();  // btos/ctos/stos should use itos.
358       break;
359     case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break;
360     case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break;
361     case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break;
362     case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break;
363     case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break;
364     case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep);     break;
365     default  : ShouldNotReachHere();                                                 break;
366   }
367 }
368 
369 
370 //------------------------------------------------------------------------------------------------------------------------
371 
372 void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) {
373   if (CountBytecodes || CountBytecodesPerThread || TraceBytecodes || StopInterpreterAt > 0) {
374     count_bytecode();
375   }
376   if (PrintBytecodeHistogram)                                    histogram_bytecode(t);
377 #ifndef PRODUCT
378   // debugging code


379   if (PrintBytecodePairHistogram)                                histogram_bytecode_pair(t);
380   if (TraceBytecodes)                                            trace_bytecode(t);
381   if (StopInterpreterAt > 0)                                     stop_interpreter_at();
382 #endif // !PRODUCT
383   int step = 0;
384   if (!t->does_dispatch()) {
385     step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode());
386     if (tos_out == ilgl) tos_out = t->tos_out();
387     // compute bytecode size
388     assert(step > 0, "just checkin'");
389     // setup stuff for dispatching next bytecode
390     if (ProfileInterpreter && VerifyDataPointer
391         && MethodData::bytecode_has_profile(t->bytecode())) {
392       __ verify_method_data_pointer();
393     }
394     __ dispatch_prolog(tos_out, step);
395   }
396   // generate template
397   t->generate(_masm);
398   // advance
399   if (t->does_dispatch()) {
400 #ifdef ASSERT
401     // make sure execution doesn't go beyond this point if code is broken
402     __ should_not_reach_here();
403 #endif // ASSERT
404   } else {
405     // dispatch to next bytecode
406     __ dispatch_epilog(tos_out, step);
407   }
408 }
409 
410 bool TemplateInterpreterGenerator::is_synchronized_method(AbstractInterpreter::MethodKind kind) {
411   switch (kind) {
412     case Interpreter::zerolocals_synchronized        : // fall thru
413     case Interpreter::zerolocals_synchronized_upcalls: // fall thru
414     case Interpreter::native_synchronized            : // fall thru
415     case Interpreter::native_synchronized_upcalls    :
416       return true;
417     default:
418       return false;
419   }
420 }
421 
422 bool TemplateInterpreterGenerator::is_runtime_upcalls_method(AbstractInterpreter::MethodKind kind) {
423   switch (kind) {
424     case Interpreter::zerolocals_upcalls             : // fall thru
425     case Interpreter::zerolocals_synchronized_upcalls: // fall thru
426     case Interpreter::native_upcalls                 : // fall thru
427     case Interpreter::native_synchronized_upcalls    : // fall thru
428     case Interpreter::empty_upcalls                  :
429       return true;
430     default:
431       return false;
432   }
433 }
434 
435 bool TemplateInterpreterGenerator::is_intrinsic_method(AbstractInterpreter::MethodKind kind) {
436   switch (kind) {
437     case Interpreter::zerolocals                     : // fall thru
438     case Interpreter::zerolocals_synchronized        : // fall thru
439     case Interpreter::zerolocals_upcalls             : // fall thru
440     case Interpreter::zerolocals_synchronized_upcalls: // fall thru
441     case Interpreter::native                         : // fall thru
442     case Interpreter::native_synchronized            : // fall thru
443     case Interpreter::native_upcalls                 : // fall thru
444     case Interpreter::native_synchronized_upcalls    : // fall thru
445     case Interpreter::empty                          : // fall thru
446     case Interpreter::empty_upcalls                  : // fall thru
447     case Interpreter::getter                         : // fall thru
448     case Interpreter::setter                         : // fall thru
449     case Interpreter::abstract                       :
450       return false;
451     default:
452       return true;
453   }
454 }
455 
456 bool TemplateInterpreterGenerator::is_abstract_method(AbstractInterpreter::MethodKind kind) {
457   switch (kind) {
458     case Interpreter::abstract:
459       return true;
460     default:
461       return false;
462   }
463 }
464 
465 // Generate method entries
466 address TemplateInterpreterGenerator::generate_method_entry(
467                                         AbstractInterpreter::MethodKind kind, bool native) {


468   address entry_point = nullptr;
469 
470   if (is_abstract_method(kind)) {
471     entry_point = generate_abstract_entry();
472   } else if (is_intrinsic_method(kind)) {
473     entry_point = generate_intrinsic_entry(kind);








474   }
475 
476   if (entry_point) {
477     return entry_point;
478   }
479 
480   bool synchronized = is_synchronized_method(kind);
481   bool upcalls = is_runtime_upcalls_method(kind);
482 
483   // We expect the normal and native entry points to be generated first so we can reuse them.
484   if (!synchronized && !upcalls) {
485     entry_point = Interpreter::entry_for_kind(native ? Interpreter::native
486                                                      : Interpreter::zerolocals);
487   } else if (synchronized && !upcalls) {
488     entry_point = Interpreter::entry_for_kind(native ? Interpreter::native_synchronized
489                                                      : Interpreter::zerolocals_synchronized);
490   } else if (!synchronized && upcalls) {
491     entry_point = Interpreter::entry_for_kind(native ? Interpreter::native_upcalls
492                                                      : Interpreter::zerolocals_upcalls);
493   } else if (synchronized && upcalls) {
494     entry_point = Interpreter::entry_for_kind(native ? Interpreter::native_synchronized_upcalls
495                                                      : Interpreter::zerolocals_synchronized_upcalls);
496   }
497 
498   if (entry_point == nullptr) {
499       entry_point = native ? generate_native_entry(synchronized, upcalls)
500                            : generate_normal_entry(synchronized, upcalls);
501   }
502 
503   return entry_point;
504 }
505 
506 // Generate intrinsic method entries
507 address TemplateInterpreterGenerator::generate_intrinsic_entry(AbstractInterpreter::MethodKind kind) {
508   if (!InlineIntrinsics || !vmIntrinsics::is_intrinsic_available(AbstractInterpreter::method_intrinsic(kind))) {
509     return nullptr;
510   }
511 
512   address entry_point = nullptr;
513 
514   switch (kind) {
515   case Interpreter::java_lang_math_sin     : // fall thru
516   case Interpreter::java_lang_math_cos     : // fall thru
517   case Interpreter::java_lang_math_tan     : // fall thru
518   case Interpreter::java_lang_math_tanh    : // fall thru
519   case Interpreter::java_lang_math_cbrt    : // fall thru
520   case Interpreter::java_lang_math_abs     : // fall thru
< prev index next >