Mercurial > hg > graal-jvmci-8
comparison src/share/vm/prims/forte.cpp @ 7176:59c790074993
8003635: NPG: AsynchGetCallTrace broken by Method* virtual call
Summary: Make metaspace::contains be lock free and used to see if something is in metaspace, also compare Method* with vtbl pointer.
Reviewed-by: dholmes, sspitsyn, dcubed, jmasa
author | coleenp |
---|---|
date | Wed, 28 Nov 2012 17:50:21 -0500 |
parents | da91efe96a93 |
children | dcb062bea05b |
comparison
equal
deleted
inserted
replaced
7175:b51dc8df86e5 | 7176:59c790074993 |
---|---|
214 // a valid method. Then again we may have caught an interpreter | 214 // a valid method. Then again we may have caught an interpreter |
215 // frame in the middle of construction and the bci field is | 215 // frame in the middle of construction and the bci field is |
216 // not yet valid. | 216 // not yet valid. |
217 | 217 |
218 *method_p = method; | 218 *method_p = method; |
219 | 219 if (!method->is_valid_method()) return false; |
220 // See if gc may have invalidated method since we validated frame | |
221 | |
222 if (!Universe::heap()->is_valid_method(method)) return false; | |
223 | 220 |
224 intptr_t bcx = fr->interpreter_frame_bcx(); | 221 intptr_t bcx = fr->interpreter_frame_bcx(); |
225 | 222 |
226 int bci = method->validate_bci_from_bcx(bcx); | 223 int bci = method->validate_bci_from_bcx(bcx); |
227 | 224 |
392 assert(trace->frames != NULL, "trace->frames must be non-NULL"); | 389 assert(trace->frames != NULL, "trace->frames must be non-NULL"); |
393 | 390 |
394 bool fully_decipherable = find_initial_Java_frame(thd, &top_frame, &initial_Java_frame, &method, &bci); | 391 bool fully_decipherable = find_initial_Java_frame(thd, &top_frame, &initial_Java_frame, &method, &bci); |
395 | 392 |
396 // The frame might not be walkable but still recovered a method | 393 // The frame might not be walkable but still recovered a method |
397 // (e.g. an nmethod with no scope info for the pc | 394 // (e.g. an nmethod with no scope info for the pc) |
398 | 395 |
399 if (method == NULL) return; | 396 if (method == NULL) return; |
400 | 397 |
401 CollectedHeap* ch = Universe::heap(); | 398 if (!method->is_valid_method()) { |
402 | |
403 // The method is not stored GC safe so see if GC became active | |
404 // after we entered AsyncGetCallTrace() and before we try to | |
405 // use the Method*. | |
406 // Yes, there is still a window after this check and before | |
407 // we use Method* below, but we can't lock out GC so that | |
408 // has to be an acceptable risk. | |
409 if (!ch->is_valid_method(method)) { | |
410 trace->num_frames = ticks_GC_active; // -2 | 399 trace->num_frames = ticks_GC_active; // -2 |
411 return; | 400 return; |
412 } | 401 } |
413 | 402 |
414 // We got a Java frame however it isn't fully decipherable | 403 // We got a Java frame however it isn't fully decipherable |
438 | 427 |
439 for (; !st.at_end() && count < depth; st.forte_next(), count++) { | 428 for (; !st.at_end() && count < depth; st.forte_next(), count++) { |
440 bci = st.bci(); | 429 bci = st.bci(); |
441 method = st.method(); | 430 method = st.method(); |
442 | 431 |
443 // The method is not stored GC safe so see if GC became active | 432 if (!method->is_valid_method()) { |
444 // after we entered AsyncGetCallTrace() and before we try to | |
445 // use the Method*. | |
446 // Yes, there is still a window after this check and before | |
447 // we use Method* below, but we can't lock out GC so that | |
448 // has to be an acceptable risk. | |
449 if (!ch->is_valid_method(method)) { | |
450 // we throw away everything we've gathered in this sample since | 433 // we throw away everything we've gathered in this sample since |
451 // none of it is safe | 434 // none of it is safe |
452 trace->num_frames = ticks_GC_active; // -2 | 435 trace->num_frames = ticks_GC_active; // -2 |
453 return; | 436 return; |
454 } | 437 } |