Mercurial > hg > truffle
comparison src/share/vm/runtime/sharedRuntime.cpp @ 14212:22ae97935e05
8028107: Kitchensink crashed with EAV
Summary: check the state of caller and callee nmethods and skip call site patching if any of them is not alive
Reviewed-by: jrose, twisti
author | kvn |
---|---|
date | Fri, 06 Dec 2013 12:11:51 -0800 |
parents | b8b5791fa045 |
children | b9b6934ad75c |
comparison
equal
deleted
inserted
replaced
14211:a2a3f08b96fa | 14212:22ae97935e05 |
---|---|
1176 frame caller_frame = thread->last_frame().sender(&cbl_map); | 1176 frame caller_frame = thread->last_frame().sender(&cbl_map); |
1177 | 1177 |
1178 CodeBlob* caller_cb = caller_frame.cb(); | 1178 CodeBlob* caller_cb = caller_frame.cb(); |
1179 guarantee(caller_cb != NULL && caller_cb->is_nmethod(), "must be called from nmethod"); | 1179 guarantee(caller_cb != NULL && caller_cb->is_nmethod(), "must be called from nmethod"); |
1180 nmethod* caller_nm = caller_cb->as_nmethod_or_null(); | 1180 nmethod* caller_nm = caller_cb->as_nmethod_or_null(); |
1181 | |
1181 // make sure caller is not getting deoptimized | 1182 // make sure caller is not getting deoptimized |
1182 // and removed before we are done with it. | 1183 // and removed before we are done with it. |
1183 // CLEANUP - with lazy deopt shouldn't need this lock | 1184 // CLEANUP - with lazy deopt shouldn't need this lock |
1184 nmethodLocker caller_lock(caller_nm); | 1185 nmethodLocker caller_lock(caller_nm); |
1185 | |
1186 | 1186 |
1187 // determine call info & receiver | 1187 // determine call info & receiver |
1188 // note: a) receiver is NULL for static calls | 1188 // note: a) receiver is NULL for static calls |
1189 // b) an exception is thrown if receiver is NULL for non-static calls | 1189 // b) an exception is thrown if receiver is NULL for non-static calls |
1190 CallInfo call_info; | 1190 CallInfo call_info; |
1196 assert((!is_virtual && invoke_code == Bytecodes::_invokestatic ) || | 1196 assert((!is_virtual && invoke_code == Bytecodes::_invokestatic ) || |
1197 (!is_virtual && invoke_code == Bytecodes::_invokehandle ) || | 1197 (!is_virtual && invoke_code == Bytecodes::_invokehandle ) || |
1198 (!is_virtual && invoke_code == Bytecodes::_invokedynamic) || | 1198 (!is_virtual && invoke_code == Bytecodes::_invokedynamic) || |
1199 ( is_virtual && invoke_code != Bytecodes::_invokestatic ), "inconsistent bytecode"); | 1199 ( is_virtual && invoke_code != Bytecodes::_invokestatic ), "inconsistent bytecode"); |
1200 | 1200 |
1201 // We do not patch the call site if the caller nmethod has been made non-entrant. | |
1202 if (!caller_nm->is_in_use()) { | |
1203 return callee_method; | |
1204 } | |
1205 | |
1201 #ifndef PRODUCT | 1206 #ifndef PRODUCT |
1202 // tracing/debugging/statistics | 1207 // tracing/debugging/statistics |
1203 int *addr = (is_optimized) ? (&_resolve_opt_virtual_ctr) : | 1208 int *addr = (is_optimized) ? (&_resolve_opt_virtual_ctr) : |
1204 (is_virtual) ? (&_resolve_virtual_ctr) : | 1209 (is_virtual) ? (&_resolve_virtual_ctr) : |
1205 (&_resolve_static_ctr); | 1210 (&_resolve_static_ctr); |
1235 CompiledICInfo virtual_call_info; | 1240 CompiledICInfo virtual_call_info; |
1236 | 1241 |
1237 // Make sure the callee nmethod does not get deoptimized and removed before | 1242 // Make sure the callee nmethod does not get deoptimized and removed before |
1238 // we are done patching the code. | 1243 // we are done patching the code. |
1239 nmethod* callee_nm = callee_method->code(); | 1244 nmethod* callee_nm = callee_method->code(); |
1245 if (callee_nm != NULL && !callee_nm->is_in_use()) { | |
1246 // Patch call site to C2I adapter if callee nmethod is deoptimized or unloaded. | |
1247 callee_nm = NULL; | |
1248 } | |
1240 nmethodLocker nl_callee(callee_nm); | 1249 nmethodLocker nl_callee(callee_nm); |
1241 #ifdef ASSERT | 1250 #ifdef ASSERT |
1242 address dest_entry_point = callee_nm == NULL ? 0 : callee_nm->entry_point(); // used below | 1251 address dest_entry_point = callee_nm == NULL ? 0 : callee_nm->entry_point(); // used below |
1243 #endif | 1252 #endif |
1244 | 1253 |
1256 | 1265 |
1257 // grab lock, check for deoptimization and potentially patch caller | 1266 // grab lock, check for deoptimization and potentially patch caller |
1258 { | 1267 { |
1259 MutexLocker ml_patch(CompiledIC_lock); | 1268 MutexLocker ml_patch(CompiledIC_lock); |
1260 | 1269 |
1270 // Lock blocks for safepoint during which both nmethods can change state. | |
1271 | |
1261 // Now that we are ready to patch if the Method* was redefined then | 1272 // Now that we are ready to patch if the Method* was redefined then |
1262 // don't update call site and let the caller retry. | 1273 // don't update call site and let the caller retry. |
1263 | 1274 // Don't update call site if caller nmethod has been made non-entrant |
1264 if (!callee_method->is_old()) { | 1275 // as it is a waste of time. |
1276 // Don't update call site if callee nmethod was unloaded or deoptimized. | |
1277 // Don't update call site if callee nmethod was replaced by an other nmethod | |
1278 // which may happen when multiply alive nmethod (tiered compilation) | |
1279 // will be supported. | |
1280 if (!callee_method->is_old() && caller_nm->is_in_use() && | |
1281 (callee_nm == NULL || callee_nm->is_in_use() && (callee_method->code() == callee_nm))) { | |
1265 #ifdef ASSERT | 1282 #ifdef ASSERT |
1266 // We must not try to patch to jump to an already unloaded method. | 1283 // We must not try to patch to jump to an already unloaded method. |
1267 if (dest_entry_point != 0) { | 1284 if (dest_entry_point != 0) { |
1268 assert(CodeCache::find_blob(dest_entry_point) != NULL, | 1285 CodeBlob* cb = CodeCache::find_blob(dest_entry_point); |
1269 "should not unload nmethod while locked"); | 1286 assert((cb != NULL) && cb->is_nmethod() && (((nmethod*)cb) == callee_nm), |
1287 "should not call unloaded nmethod"); | |
1270 } | 1288 } |
1271 #endif | 1289 #endif |
1272 if (is_virtual) { | 1290 if (is_virtual) { |
1273 nmethod* nm = callee_nm; | 1291 nmethod* nm = callee_nm; |
1274 if (nm == NULL) CodeCache::find_blob(caller_frame.pc()); | 1292 if (nm == NULL) CodeCache::find_blob(caller_frame.pc()); |