< prev index next >

src/hotspot/share/code/nmethod.cpp

Print this page




 906     if (WizardMode) {
 907       CompileTask::print(st, this, msg, /*short_form:*/ true);
 908       st->print_cr(" (" INTPTR_FORMAT ")", p2i(this));
 909     } else {
 910       CompileTask::print(st, this, msg, /*short_form:*/ false);
 911     }
 912   }
 913 }
 914 
 915 void nmethod::maybe_print_nmethod(DirectiveSet* directive) {
 916   bool printnmethods = directive->PrintAssemblyOption || directive->PrintNMethodsOption;
 917   if (printnmethods || PrintDebugInfo || PrintRelocations || PrintDependencies || PrintExceptionHandlers) {
 918     print_nmethod(printnmethods);
 919   }
 920 }
 921 
 922 void nmethod::print_nmethod(bool printmethod) {
 923   ttyLocker ttyl;  // keep the following output all in one block
 924   if (xtty != NULL) {
 925     xtty->begin_head("print_nmethod");
 926     log_identity(xtty);
 927     xtty->stamp();
 928     xtty->end_head();
 929   }
 930   // Print the header part, then print the requested information.
 931   // This is both handled in decode2().
 932   if (printmethod) {
 933     HandleMark hm;
 934     ResourceMark m;
 935     if (is_compiled_by_c1()) {
 936       tty->cr();
 937       tty->print_cr("============================= C1-compiled nmethod ==============================");
 938     }
 939     if (is_compiled_by_jvmci()) {
 940       tty->cr();
 941       tty->print_cr("=========================== JVMCI-compiled nmethod =============================");
 942     }
 943     tty->print_cr("----------------------------------- Assembly -----------------------------------");
 944     decode2(tty);
 945 #if defined(SUPPORT_DATA_STRUCTS)
 946     if (AbstractDisassembler::show_structs()) {


2077   for (Dependencies::DepStream deps(this); deps.next(); ) {
2078     if (deps.type() != Dependencies::evol_method)
2079       continue;
2080     Method* method = deps.method_argument(0);
2081     if (method == dependee) return true;
2082   }
2083   return false;
2084 }
2085 
2086 
2087 bool nmethod::is_patchable_at(address instr_addr) {
2088   assert(insts_contains(instr_addr), "wrong nmethod used");
2089   if (is_zombie()) {
2090     // a zombie may never be patched
2091     return false;
2092   }
2093   return true;
2094 }
2095 
2096 




























2097 void nmethod_init() {
2098   // make sure you didn't forget to adjust the filler fields
2099   assert(sizeof(nmethod) % oopSize == 0, "nmethod size must be multiple of a word");
2100 }
2101 
2102 
2103 //-------------------------------------------------------------------------------------------
2104 
2105 
2106 // QQQ might we make this work from a frame??
2107 nmethodLocker::nmethodLocker(address pc) {
2108   CodeBlob* cb = CodeCache::find_blob(pc);
2109   guarantee(cb != NULL && cb->is_compiled(), "bad pc for a nmethod found");
2110   _nm = cb->as_compiled_method();
2111   lock_nmethod(_nm);
2112 }
2113 
2114 // Only JvmtiDeferredEvent::compiled_method_unload_event()
2115 // should pass zombie_ok == true.
2116 void nmethodLocker::lock_nmethod(CompiledMethod* cm, bool zombie_ok) {


2169   ResourceMark rm;
2170 
2171   if (!CodeCache::contains(this)) {
2172     fatal("nmethod at " INTPTR_FORMAT " not in zone", p2i(this));
2173   }
2174 
2175   if(is_native_method() )
2176     return;
2177 
2178   nmethod* nm = CodeCache::find_nmethod(verified_entry_point());
2179   if (nm != this) {
2180     fatal("findNMethod did not find this nmethod (" INTPTR_FORMAT ")", p2i(this));
2181   }
2182 
2183   for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) {
2184     if (! p->verify(this)) {
2185       tty->print_cr("\t\tin nmethod at " INTPTR_FORMAT " (pcs)", p2i(this));
2186     }
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
2212 
2213   VerifyOopsClosure voc(this);
2214   oops_do(&voc);
2215   assert(voc.ok(), "embedded oops must be OK");
2216   Universe::heap()->verify_nmethod(this);
2217 
2218   verify_scopes();
2219 }
2220 
2221 
2222 void nmethod::verify_interrupt_point(address call_site) {
2223   // Verify IC only when nmethod installation is finished.
2224   if (!is_not_installed()) {
2225     if (CompiledICLocker::is_safe(this)) {
2226       CompiledIC_at(this, call_site);
2227       CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
2228     } else {
2229       CompiledICLocker ml_verify(this);
2230       CompiledIC_at(this, call_site);
2231     }
2232   }


2992         stream->move_to(tab1);
2993         stream->print("[%s+0x%x]", spname, stack_slot_offset);
2994         stream->print("  (%s of caller)", spname);
2995         stream->cr();
2996       }
2997     }
2998   }
2999 }
3000 
3001 // Returns whether this nmethod has code comments.
3002 bool nmethod::has_code_comment(address begin, address end) {
3003   // scopes?
3004   ScopeDesc* sd  = scope_desc_in(begin, end);
3005   if (sd != NULL) return true;
3006 
3007   // relocations?
3008   const char* str = reloc_string_for(begin, end);
3009   if (str != NULL) return true;
3010 
3011   // implicit exceptions?
3012   int cont_offset = ImplicitExceptionTable(this).continuation_offset(begin - code_begin());
3013   if (cont_offset != 0) return true;
3014 
3015   return false;
3016 }
3017 
3018 void nmethod::print_code_comment_on(outputStream* st, int column, address begin, address end) {
3019   ImplicitExceptionTable implicit_table(this);
3020   int pc_offset = begin - code_begin();
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.
3038   address base = code_begin();
3039   ImmutableOopMapSet* oms = oop_maps();
3040   if (oms != NULL) {
3041     for (int i = 0, imax = oms->count(); i < imax; i++) {
3042       const ImmutableOopMapPair* pair = oms->pair_at(i);
3043       const ImmutableOopMap* om = pair->get_from(oms);
3044       address pc = base + pair->pc_offset();
3045       if (pc >= begin) {
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) {
3052           st->move_to(column, 6, 0);
3053           st->print("; ");
3054           om->print_on(st);
3055           oop_map_required = false;
3056         }
3057       }
3058       if (pc > end) {
3059         break;
3060       }
3061     }
3062   }
3063   assert(!oop_map_required, "missed oopmap");
3064 
3065   // Print any debug info present at this pc.
3066   ScopeDesc* sd  = scope_desc_in(begin, end);
3067   if (sd != NULL) {
3068     st->move_to(column, 6, 0);
3069     if (sd->bci() == SynchronizationEntryBCI) {
3070       st->print(";*synchronization entry");
3071     } else if (sd->bci() == AfterBci) {
3072       st->print(";* method exit (unlocked if synchronized)");
3073     } else if (sd->bci() == UnwindBci) {
3074       st->print(";* unwind (locked if synchronized)");
3075     } else if (sd->bci() == AfterExceptionBci) {
3076       st->print(";* unwind (unlocked if synchronized)");
3077     } else if (sd->bci() == UnknownBci) {
3078       st->print(";* unknown");
3079     } else if (sd->bci() == InvalidFrameStateBci) {
3080       st->print(";* invalid frame state");
3081     } else {
3082       if (sd->method() == NULL) {
3083         st->print("method is NULL");


3133       }
3134       int lineno = sd->method()->line_number_from_bci(sd->bci());
3135       if (lineno != -1) {
3136         st->print("@%d (line %d)", sd->bci(), lineno);
3137       } else {
3138         st->print("@%d", sd->bci());
3139       }
3140       st->cr();
3141     }
3142   }
3143 
3144   // Print relocation information
3145   // Prevent memory leak: allocating without ResourceMark.
3146   ResourceMark rm;
3147   const char* str = reloc_string_for(begin, end);
3148   if (str != NULL) {
3149     if (sd != NULL) st->cr();
3150     st->move_to(column, 6, 0);
3151     st->print(";   {%s}", str);
3152   }






3153 }
3154 
3155 #endif
3156 
3157 class DirectNativeCallWrapper: public NativeCallWrapper {
3158 private:
3159   NativeCall* _call;
3160 
3161 public:
3162   DirectNativeCallWrapper(NativeCall* call) : _call(call) {}
3163 
3164   virtual address destination() const { return _call->destination(); }
3165   virtual address instruction_address() const { return _call->instruction_address(); }
3166   virtual address next_instruction_address() const { return _call->next_instruction_address(); }
3167   virtual address return_address() const { return _call->return_address(); }
3168 
3169   virtual address get_resolve_call_stub(bool is_optimized) const {
3170     if (is_optimized) {
3171       return SharedRuntime::get_resolve_opt_virtual_call_stub();
3172     }




 906     if (WizardMode) {
 907       CompileTask::print(st, this, msg, /*short_form:*/ true);
 908       st->print_cr(" (" INTPTR_FORMAT ")", p2i(this));
 909     } else {
 910       CompileTask::print(st, this, msg, /*short_form:*/ false);
 911     }
 912   }
 913 }
 914 
 915 void nmethod::maybe_print_nmethod(DirectiveSet* directive) {
 916   bool printnmethods = directive->PrintAssemblyOption || directive->PrintNMethodsOption;
 917   if (printnmethods || PrintDebugInfo || PrintRelocations || PrintDependencies || PrintExceptionHandlers) {
 918     print_nmethod(printnmethods);
 919   }
 920 }
 921 
 922 void nmethod::print_nmethod(bool printmethod) {
 923   ttyLocker ttyl;  // keep the following output all in one block
 924   if (xtty != NULL) {
 925     xtty->begin_head("print_nmethod");

 926     xtty->stamp();
 927     xtty->end_head();
 928   }
 929   // Print the header part, then print the requested information.
 930   // This is both handled in decode2().
 931   if (printmethod) {
 932     HandleMark hm;
 933     ResourceMark m;
 934     if (is_compiled_by_c1()) {
 935       tty->cr();
 936       tty->print_cr("============================= C1-compiled nmethod ==============================");
 937     }
 938     if (is_compiled_by_jvmci()) {
 939       tty->cr();
 940       tty->print_cr("=========================== JVMCI-compiled nmethod =============================");
 941     }
 942     tty->print_cr("----------------------------------- Assembly -----------------------------------");
 943     decode2(tty);
 944 #if defined(SUPPORT_DATA_STRUCTS)
 945     if (AbstractDisassembler::show_structs()) {


2076   for (Dependencies::DepStream deps(this); deps.next(); ) {
2077     if (deps.type() != Dependencies::evol_method)
2078       continue;
2079     Method* method = deps.method_argument(0);
2080     if (method == dependee) return true;
2081   }
2082   return false;
2083 }
2084 
2085 
2086 bool nmethod::is_patchable_at(address instr_addr) {
2087   assert(insts_contains(instr_addr), "wrong nmethod used");
2088   if (is_zombie()) {
2089     // a zombie may never be patched
2090     return false;
2091   }
2092   return true;
2093 }
2094 
2095 
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() {
2125   // 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");
2127 }
2128 
2129 
2130 //-------------------------------------------------------------------------------------------
2131 
2132 
2133 // QQQ might we make this work from a frame??
2134 nmethodLocker::nmethodLocker(address pc) {
2135   CodeBlob* cb = CodeCache::find_blob(pc);
2136   guarantee(cb != NULL && cb->is_compiled(), "bad pc for a nmethod found");
2137   _nm = cb->as_compiled_method();
2138   lock_nmethod(_nm);
2139 }
2140 
2141 // Only JvmtiDeferredEvent::compiled_method_unload_event()
2142 // should pass zombie_ok == true.
2143 void nmethodLocker::lock_nmethod(CompiledMethod* cm, bool zombie_ok) {


2196   ResourceMark rm;
2197 
2198   if (!CodeCache::contains(this)) {
2199     fatal("nmethod at " INTPTR_FORMAT " not in zone", p2i(this));
2200   }
2201 
2202   if(is_native_method() )
2203     return;
2204 
2205   nmethod* nm = CodeCache::find_nmethod(verified_entry_point());
2206   if (nm != this) {
2207     fatal("findNMethod did not find this nmethod (" INTPTR_FORMAT ")", p2i(this));
2208   }
2209 
2210   for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) {
2211     if (! p->verify(this)) {
2212       tty->print_cr("\t\tin nmethod at " INTPTR_FORMAT " (pcs)", p2i(this));
2213     }
2214   }
2215 
























2216   VerifyOopsClosure voc(this);
2217   oops_do(&voc);
2218   assert(voc.ok(), "embedded oops must be OK");
2219   Universe::heap()->verify_nmethod(this);
2220 
2221   verify_scopes();
2222 }
2223 
2224 
2225 void nmethod::verify_interrupt_point(address call_site) {
2226   // Verify IC only when nmethod installation is finished.
2227   if (!is_not_installed()) {
2228     if (CompiledICLocker::is_safe(this)) {
2229       CompiledIC_at(this, call_site);
2230       CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
2231     } else {
2232       CompiledICLocker ml_verify(this);
2233       CompiledIC_at(this, call_site);
2234     }
2235   }


2995         stream->move_to(tab1);
2996         stream->print("[%s+0x%x]", spname, stack_slot_offset);
2997         stream->print("  (%s of caller)", spname);
2998         stream->cr();
2999       }
3000     }
3001   }
3002 }
3003 
3004 // Returns whether this nmethod has code comments.
3005 bool nmethod::has_code_comment(address begin, address end) {
3006   // scopes?
3007   ScopeDesc* sd  = scope_desc_in(begin, end);
3008   if (sd != NULL) return true;
3009 
3010   // relocations?
3011   const char* str = reloc_string_for(begin, end);
3012   if (str != NULL) return true;
3013 
3014   // implicit exceptions?
3015   int cont_offset = ImplicitExceptionTable(this).at(begin - code_begin());
3016   if (cont_offset != 0) return true;
3017 
3018   return false;
3019 }
3020 
3021 void nmethod::print_code_comment_on(outputStream* st, int column, address begin, address end) {
3022   // First, find an oopmap in (begin, end].
3023   // We use the odd half-closed interval so that oop maps and scope descs
3024   // which are tied to the byte after a call are printed with the call itself.
















3025   address base = code_begin();
3026   ImmutableOopMapSet* oms = oop_maps();
3027   if (oms != NULL) {
3028     for (int i = 0, imax = oms->count(); i < imax; i++) {
3029       const ImmutableOopMapPair* pair = oms->pair_at(i);
3030       const ImmutableOopMap* om = pair->get_from(oms);
3031       address pc = base + pair->pc_offset();
3032       if (pc > begin) {
3033         if (pc <= end) {





3034           st->move_to(column, 6, 0);
3035           st->print("; ");
3036           om->print_on(st);

3037         }


3038         break;
3039       }
3040     }
3041   }

3042 
3043   // Print any debug info present at this pc.
3044   ScopeDesc* sd  = scope_desc_in(begin, end);
3045   if (sd != NULL) {
3046     st->move_to(column, 6, 0);
3047     if (sd->bci() == SynchronizationEntryBCI) {
3048       st->print(";*synchronization entry");
3049     } else if (sd->bci() == AfterBci) {
3050       st->print(";* method exit (unlocked if synchronized)");
3051     } else if (sd->bci() == UnwindBci) {
3052       st->print(";* unwind (locked if synchronized)");
3053     } else if (sd->bci() == AfterExceptionBci) {
3054       st->print(";* unwind (unlocked if synchronized)");
3055     } else if (sd->bci() == UnknownBci) {
3056       st->print(";* unknown");
3057     } else if (sd->bci() == InvalidFrameStateBci) {
3058       st->print(";* invalid frame state");
3059     } else {
3060       if (sd->method() == NULL) {
3061         st->print("method is NULL");


3111       }
3112       int lineno = sd->method()->line_number_from_bci(sd->bci());
3113       if (lineno != -1) {
3114         st->print("@%d (line %d)", sd->bci(), lineno);
3115       } else {
3116         st->print("@%d", sd->bci());
3117       }
3118       st->cr();
3119     }
3120   }
3121 
3122   // Print relocation information
3123   // Prevent memory leak: allocating without ResourceMark.
3124   ResourceMark rm;
3125   const char* str = reloc_string_for(begin, end);
3126   if (str != NULL) {
3127     if (sd != NULL) st->cr();
3128     st->move_to(column, 6, 0);
3129     st->print(";   {%s}", str);
3130   }
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 }
3138 
3139 #endif
3140 
3141 class DirectNativeCallWrapper: public NativeCallWrapper {
3142 private:
3143   NativeCall* _call;
3144 
3145 public:
3146   DirectNativeCallWrapper(NativeCall* call) : _call(call) {}
3147 
3148   virtual address destination() const { return _call->destination(); }
3149   virtual address instruction_address() const { return _call->instruction_address(); }
3150   virtual address next_instruction_address() const { return _call->next_instruction_address(); }
3151   virtual address return_address() const { return _call->return_address(); }
3152 
3153   virtual address get_resolve_call_stub(bool is_optimized) const {
3154     if (is_optimized) {
3155       return SharedRuntime::get_resolve_opt_virtual_call_stub();
3156     }


< prev index next >