src/hotspot/share/code/nmethod.cpp
changeset 55293 d19dc5b10fbb
parent 55068 f6260463dbe4
child 55454 8892555795cd
equal deleted inserted replaced
55292:f4b2d5b83ebf 55293:d19dc5b10fbb
   921 
   921 
   922 void nmethod::print_nmethod(bool printmethod) {
   922 void nmethod::print_nmethod(bool printmethod) {
   923   ttyLocker ttyl;  // keep the following output all in one block
   923   ttyLocker ttyl;  // keep the following output all in one block
   924   if (xtty != NULL) {
   924   if (xtty != NULL) {
   925     xtty->begin_head("print_nmethod");
   925     xtty->begin_head("print_nmethod");
       
   926     log_identity(xtty);
   926     xtty->stamp();
   927     xtty->stamp();
   927     xtty->end_head();
   928     xtty->end_head();
   928   }
   929   }
   929   // Print the header part, then print the requested information.
   930   // Print the header part, then print the requested information.
   930   // This is both handled in decode2().
   931   // This is both handled in decode2().
  2091   }
  2092   }
  2092   return true;
  2093   return true;
  2093 }
  2094 }
  2094 
  2095 
  2095 
  2096 
  2096 address nmethod::continuation_for_implicit_exception(address pc) {
       
  2097   // Exception happened outside inline-cache check code => we are inside
       
  2098   // an active nmethod => use cpc to determine a return address
       
  2099   int exception_offset = pc - code_begin();
       
  2100   int cont_offset = ImplicitExceptionTable(this).at( exception_offset );
       
  2101 #ifdef ASSERT
       
  2102   if (cont_offset == 0) {
       
  2103     Thread* thread = Thread::current();
       
  2104     ResetNoHandleMark rnm; // Might be called from LEAF/QUICK ENTRY
       
  2105     HandleMark hm(thread);
       
  2106     ResourceMark rm(thread);
       
  2107     CodeBlob* cb = CodeCache::find_blob(pc);
       
  2108     assert(cb != NULL && cb == this, "");
       
  2109     ttyLocker ttyl;
       
  2110     tty->print_cr("implicit exception happened at " INTPTR_FORMAT, p2i(pc));
       
  2111     // Print all available nmethod info.
       
  2112     print_nmethod(true);
       
  2113     method()->print_codes();
       
  2114   }
       
  2115 #endif
       
  2116   if (cont_offset == 0) {
       
  2117     // Let the normal error handling report the exception
       
  2118     return NULL;
       
  2119   }
       
  2120   return code_begin() + cont_offset;
       
  2121 }
       
  2122 
       
  2123 
       
  2124 void nmethod_init() {
  2097 void nmethod_init() {
  2125   // make sure you didn't forget to adjust the filler fields
  2098   // make sure you didn't forget to adjust the filler fields
  2126   assert(sizeof(nmethod) % oopSize == 0, "nmethod size must be multiple of a word");
  2099   assert(sizeof(nmethod) % oopSize == 0, "nmethod size must be multiple of a word");
  2127 }
  2100 }
  2128 
  2101 
  2210   for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) {
  2183   for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) {
  2211     if (! p->verify(this)) {
  2184     if (! p->verify(this)) {
  2212       tty->print_cr("\t\tin nmethod at " INTPTR_FORMAT " (pcs)", p2i(this));
  2185       tty->print_cr("\t\tin nmethod at " INTPTR_FORMAT " (pcs)", p2i(this));
  2213     }
  2186     }
  2214   }
  2187   }
       
  2188 
       
  2189 #ifdef ASSERT
       
  2190 #if INCLUDE_JVMCI
       
  2191   {
       
  2192     // Verify that implicit exceptions that deoptimize have a PcDesc and OopMap
       
  2193     ImmutableOopMapSet* oms = oop_maps();
       
  2194     ImplicitExceptionTable implicit_table(this);
       
  2195     for (uint i = 0; i < implicit_table.len(); i++) {
       
  2196       int exec_offset = (int) implicit_table.get_exec_offset(i);
       
  2197       if (implicit_table.get_exec_offset(i) == implicit_table.get_cont_offset(i)) {
       
  2198         assert(pc_desc_at(code_begin() + exec_offset) != NULL, "missing PcDesc");
       
  2199         bool found = false;
       
  2200         for (int i = 0, imax = oms->count(); i < imax; i++) {
       
  2201           if (oms->pair_at(i)->pc_offset() == exec_offset) {
       
  2202             found = true;
       
  2203             break;
       
  2204           }
       
  2205         }
       
  2206         assert(found, "missing oopmap");
       
  2207       }
       
  2208     }
       
  2209   }
       
  2210 #endif
       
  2211 #endif
  2215 
  2212 
  2216   VerifyOopsClosure voc(this);
  2213   VerifyOopsClosure voc(this);
  2217   oops_do(&voc);
  2214   oops_do(&voc);
  2218   assert(voc.ok(), "embedded oops must be OK");
  2215   assert(voc.ok(), "embedded oops must be OK");
  2219   Universe::heap()->verify_nmethod(this);
  2216   Universe::heap()->verify_nmethod(this);
  3010   // relocations?
  3007   // relocations?
  3011   const char* str = reloc_string_for(begin, end);
  3008   const char* str = reloc_string_for(begin, end);
  3012   if (str != NULL) return true;
  3009   if (str != NULL) return true;
  3013 
  3010 
  3014   // implicit exceptions?
  3011   // implicit exceptions?
  3015   int cont_offset = ImplicitExceptionTable(this).at(begin - code_begin());
  3012   int cont_offset = ImplicitExceptionTable(this).continuation_offset(begin - code_begin());
  3016   if (cont_offset != 0) return true;
  3013   if (cont_offset != 0) return true;
  3017 
  3014 
  3018   return false;
  3015   return false;
  3019 }
  3016 }
  3020 
  3017 
  3021 void nmethod::print_code_comment_on(outputStream* st, int column, address begin, address end) {
  3018 void nmethod::print_code_comment_on(outputStream* st, int column, address begin, address end) {
  3022   // First, find an oopmap in (begin, end].
  3019   ImplicitExceptionTable implicit_table(this);
  3023   // We use the odd half-closed interval so that oop maps and scope descs
  3020   int pc_offset = begin - code_begin();
  3024   // which are tied to the byte after a call are printed with the call itself.
  3021   int cont_offset = implicit_table.continuation_offset(pc_offset);
       
  3022   bool oop_map_required = false;
       
  3023   if (cont_offset != 0) {
       
  3024     st->move_to(column, 6, 0);
       
  3025     if (pc_offset == cont_offset) {
       
  3026       st->print("; implicit exception: deoptimizes");
       
  3027       oop_map_required = true;
       
  3028     } else {
       
  3029       st->print("; implicit exception: dispatches to " INTPTR_FORMAT, p2i(code_begin() + cont_offset));
       
  3030     }
       
  3031   }
       
  3032 
       
  3033   // Find an oopmap in (begin, end].  We use the odd half-closed
       
  3034   // interval so that oop maps and scope descs which are tied to the
       
  3035   // byte after a call are printed with the call itself.  OopMaps
       
  3036   // associated with implicit exceptions are printed with the implicit
       
  3037   // instruction.
  3025   address base = code_begin();
  3038   address base = code_begin();
  3026   ImmutableOopMapSet* oms = oop_maps();
  3039   ImmutableOopMapSet* oms = oop_maps();
  3027   if (oms != NULL) {
  3040   if (oms != NULL) {
  3028     for (int i = 0, imax = oms->count(); i < imax; i++) {
  3041     for (int i = 0, imax = oms->count(); i < imax; i++) {
  3029       const ImmutableOopMapPair* pair = oms->pair_at(i);
  3042       const ImmutableOopMapPair* pair = oms->pair_at(i);
  3030       const ImmutableOopMap* om = pair->get_from(oms);
  3043       const ImmutableOopMap* om = pair->get_from(oms);
  3031       address pc = base + pair->pc_offset();
  3044       address pc = base + pair->pc_offset();
  3032       if (pc > begin) {
  3045       if (pc >= begin) {
  3033         if (pc <= end) {
  3046 #if INCLUDE_JVMCI
       
  3047         bool is_implicit_deopt = implicit_table.continuation_offset(pair->pc_offset()) == (uint) pair->pc_offset();
       
  3048 #else
       
  3049         bool is_implicit_deopt = false;
       
  3050 #endif
       
  3051         if (is_implicit_deopt ? pc == begin : pc > begin && pc <= end) {
  3034           st->move_to(column, 6, 0);
  3052           st->move_to(column, 6, 0);
  3035           st->print("; ");
  3053           st->print("; ");
  3036           om->print_on(st);
  3054           om->print_on(st);
       
  3055           oop_map_required = false;
  3037         }
  3056         }
       
  3057       }
       
  3058       if (pc > end) {
  3038         break;
  3059         break;
  3039       }
  3060       }
  3040     }
  3061     }
  3041   }
  3062   }
       
  3063   assert(!oop_map_required, "missed oopmap");
  3042 
  3064 
  3043   // Print any debug info present at this pc.
  3065   // Print any debug info present at this pc.
  3044   ScopeDesc* sd  = scope_desc_in(begin, end);
  3066   ScopeDesc* sd  = scope_desc_in(begin, end);
  3045   if (sd != NULL) {
  3067   if (sd != NULL) {
  3046     st->move_to(column, 6, 0);
  3068     st->move_to(column, 6, 0);
  3126   if (str != NULL) {
  3148   if (str != NULL) {
  3127     if (sd != NULL) st->cr();
  3149     if (sd != NULL) st->cr();
  3128     st->move_to(column, 6, 0);
  3150     st->move_to(column, 6, 0);
  3129     st->print(";   {%s}", str);
  3151     st->print(";   {%s}", str);
  3130   }
  3152   }
  3131   int cont_offset = ImplicitExceptionTable(this).at(begin - code_begin());
       
  3132   if (cont_offset != 0) {
       
  3133     st->move_to(column, 6, 0);
       
  3134     st->print("; implicit exception: dispatches to " INTPTR_FORMAT, p2i(code_begin() + cont_offset));
       
  3135   }
       
  3136 
       
  3137 }
  3153 }
  3138 
  3154 
  3139 #endif
  3155 #endif
  3140 
  3156 
  3141 class DirectNativeCallWrapper: public NativeCallWrapper {
  3157 class DirectNativeCallWrapper: public NativeCallWrapper {