3737#include " oops/methodData.hpp"
3838#include " prims/jvmtiRedefineClassesTrace.hpp"
3939#include " prims/jvmtiImpl.hpp"
40+ #include " runtime/deoptimization.hpp"
4041#include " runtime/orderAccess.inline.hpp"
4142#include " runtime/sharedRuntime.hpp"
4243#include " runtime/sweeper.hpp"
@@ -1136,6 +1137,7 @@ void nmethod::print_nmethod(bool printmethod) {
11361137 ttyLocker ttyl; // keep the following output all in one block
11371138 if (xtty != NULL ) {
11381139 xtty->begin_head (" print_nmethod" );
1140+ log_identity (xtty);
11391141 xtty->stamp ();
11401142 xtty->end_head ();
11411143 }
@@ -2789,11 +2791,11 @@ bool nmethod::is_patchable_at(address instr_addr) {
27892791}
27902792
27912793
2792- address nmethod::continuation_for_implicit_exception (address pc) {
2794+ address nmethod::continuation_for_implicit_exception (address pc, bool for_div0_check ) {
27932795 // Exception happened outside inline-cache check code => we are inside
27942796 // an active nmethod => use cpc to determine a return address
27952797 int exception_offset = pc - code_begin ();
2796- int cont_offset = ImplicitExceptionTable (this ).at ( exception_offset );
2798+ int cont_offset = ImplicitExceptionTable (this ).continuation_offset ( exception_offset );
27972799#ifdef ASSERT
27982800 if (cont_offset == 0 ) {
27992801 Thread* thread = ThreadLocalStorage::get_thread_slow ();
@@ -2813,6 +2815,18 @@ address nmethod::continuation_for_implicit_exception(address pc) {
28132815 // Let the normal error handling report the exception
28142816 return NULL ;
28152817 }
2818+ if (cont_offset == exception_offset) {
2819+ #if INCLUDE_JVMCI
2820+ Deoptimization::DeoptReason deopt_reason = for_div0_check ? Deoptimization::Reason_div0_check : Deoptimization::Reason_null_check;
2821+ JavaThread *thread = JavaThread::current ();
2822+ thread->set_jvmci_implicit_exception_pc (pc);
2823+ thread->set_pending_deoptimization (Deoptimization::make_trap_request (deopt_reason,
2824+ Deoptimization::Action_reinterpret));
2825+ return (SharedRuntime::deopt_blob ()->implicit_exception_uncommon_trap ());
2826+ #else
2827+ ShouldNotReachHere ();
2828+ #endif
2829+ }
28162830 return code_begin () + cont_offset;
28172831}
28182832
@@ -2934,6 +2948,28 @@ void nmethod::verify() {
29342948 }
29352949 }
29362950
2951+ #ifdef INCLUDE_JVMCI
2952+ {
2953+ // Verify that implicit exceptions that deoptimize have a PcDesc and OopMap
2954+ OopMapSet* oms = oop_maps ();
2955+ ImplicitExceptionTable implicit_table (this );
2956+ for (uint i = 0 ; i < implicit_table.len (); i++) {
2957+ int exec_offset = (int ) implicit_table.get_exec_offset (i);
2958+ if (implicit_table.get_exec_offset (i) == implicit_table.get_cont_offset (i)) {
2959+ assert (find_pc_desc (code_begin () + exec_offset, false ) != NULL , " missing PcDesc" );
2960+ bool found = false ;
2961+ for (int i = 0 , imax = oms->size (); i < imax; i++) {
2962+ if (oms->at (i)->offset () == exec_offset) {
2963+ found = true ;
2964+ break ;
2965+ }
2966+ }
2967+ assert (found, " missing oopmap" );
2968+ }
2969+ }
2970+ }
2971+ #endif
2972+
29372973 VerifyOopsClosure voc (this );
29382974 oops_do (&voc);
29392975 assert (voc.ok (), " embedded oops must be OK" );
@@ -3366,21 +3402,40 @@ void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) co
33663402}
33673403
33683404void nmethod::print_code_comment_on (outputStream* st, int column, u_char* begin, u_char* end) {
3369- // First, find an oopmap in (begin, end].
3370- // We use the odd half-closed interval so that oop maps and scope descs
3371- // which are tied to the byte after a call are printed with the call itself.
3405+ ImplicitExceptionTable implicit_table (this );
3406+ int pc_offset = begin - code_begin ();
3407+ int cont_offset = implicit_table.continuation_offset (pc_offset);
3408+ if (cont_offset != 0 ) {
3409+ st->move_to (column);
3410+ if (pc_offset == cont_offset) {
3411+ st->print (" ; implicit exception: deoptimizes" );
3412+ } else {
3413+ st->print (" ; implicit exception: dispatches to " INTPTR_FORMAT, code_begin () + cont_offset);
3414+ }
3415+ }
3416+
3417+ // Find an oopmap in (begin, end]. We use the odd half-closed
3418+ // interval so that oop maps and scope descs which are tied to the
3419+ // byte after a call are printed with the call itself. OopMaps
3420+ // associated with implicit exceptions are printed with the implicit
3421+ // instruction.
33723422 address base = code_begin ();
33733423 OopMapSet* oms = oop_maps ();
33743424 if (oms != NULL ) {
33753425 for (int i = 0 , imax = oms->size (); i < imax; i++) {
33763426 OopMap* om = oms->at (i);
33773427 address pc = base + om->offset ();
3378- if (pc > begin) {
3379- if (pc <= end) {
3380- st->move_to (column);
3381- st->print (" ; " );
3382- om->print_on (st);
3383- }
3428+ #ifdef INCLUDE_JVMCI
3429+ bool is_implicit_deopt = implicit_table.continuation_offset (om->offset ()) == (uint) om->offset ();
3430+ #else
3431+ bool is_implicit_deopt = false ;
3432+ #endif
3433+ if (is_implicit_deopt ? pc == begin : pc > begin && pc <= end) {
3434+ st->move_to (column);
3435+ st->print (" ; " );
3436+ om->print_on (st);
3437+ }
3438+ if (pc > end) {
33843439 break ;
33853440 }
33863441 }
@@ -3457,12 +3512,6 @@ void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin,
34573512 st->move_to (column);
34583513 st->print (" ; {%s}" , str);
34593514 }
3460- int cont_offset = ImplicitExceptionTable (this ).at (begin - code_begin ());
3461- if (cont_offset != 0 ) {
3462- st->move_to (column);
3463- st->print (" ; implicit exception: dispatches to " INTPTR_FORMAT, code_begin () + cont_offset);
3464- }
3465-
34663515}
34673516
34683517#ifndef PRODUCT
0 commit comments