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 { |