Thu, 01 Apr 2010 16:06:57 -0700
6936709: AsyncGetCallTrace doesn't handle inexact stack walking properly
Reviewed-by: kvn
src/share/vm/prims/forte.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/prims/forte.cpp Wed Mar 31 16:29:10 2010 -0700 1.2 +++ b/src/share/vm/prims/forte.cpp Thu Apr 01 16:06:57 2010 -0700 1.3 @@ -55,12 +55,11 @@ 1.4 }; 1.5 1.6 1.7 -static void is_decipherable_compiled_frame(frame* fr, RegisterMap* map, 1.8 - bool* is_compiled_p, bool* is_walkable_p); 1.9 +static bool is_decipherable_compiled_frame(JavaThread* thread, frame* fr, nmethod* nm); 1.10 static bool is_decipherable_interpreted_frame(JavaThread* thread, 1.11 - frame* fr, 1.12 - methodOop* method_p, 1.13 - int* bci_p); 1.14 + frame* fr, 1.15 + methodOop* method_p, 1.16 + int* bci_p); 1.17 1.18 1.19 1.20 @@ -122,41 +121,43 @@ 1.21 // Determine if 'fr' is a decipherable compiled frame. We are already 1.22 // assured that fr is for a java nmethod. 1.23 1.24 -static bool is_decipherable_compiled_frame(frame* fr) { 1.25 - 1.26 - assert(fr->cb() != NULL && fr->cb()->is_nmethod(), "invariant"); 1.27 - nmethod* nm = (nmethod*) fr->cb(); 1.28 +static bool is_decipherable_compiled_frame(JavaThread* thread, frame* fr, nmethod* nm) { 1.29 assert(nm->is_java_method(), "invariant"); 1.30 1.31 - // First try and find an exact PcDesc 1.32 + if (thread->has_last_Java_frame() && thread->last_Java_pc() == fr->pc()) { 1.33 + // We're stopped at a call into the JVM so look for a PcDesc with 1.34 + // the actual pc reported by the frame. 1.35 + PcDesc* pc_desc = nm->pc_desc_at(fr->pc()); 1.36 1.37 - PcDesc* pc_desc = nm->pc_desc_at(fr->pc()); 1.38 - 1.39 - // Did we find a useful PcDesc? 1.40 - if (pc_desc != NULL && 1.41 - pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) { 1.42 - 1.43 - address probe_pc = fr->pc() + 1; 1.44 - pc_desc = nm->pc_desc_near(probe_pc); 1.45 - 1.46 - // Now do we have a useful PcDesc? 1.47 - 1.48 + // Did we find a useful PcDesc? 1.49 if (pc_desc != NULL && 1.50 - pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) { 1.51 - // No debug information available for this pc 1.52 - // vframeStream would explode if we try and walk the frames. 1.53 - return false; 1.54 + pc_desc->scope_decode_offset() != DebugInformationRecorder::serialized_null) { 1.55 + return true; 1.56 } 1.57 - 1.58 - // This PcDesc is useful however we must adjust the frame's pc 1.59 - // so that the vframeStream lookups will use this same pc 1.60 - 1.61 - fr->set_pc(pc_desc->real_pc(nm)); 1.62 } 1.63 1.64 + // We're at some random pc in the nmethod so search for the PcDesc 1.65 + // whose pc is greater than the current PC. It's done this way 1.66 + // because the extra PcDescs that are recorded for improved debug 1.67 + // info record the end of the region covered by the ScopeDesc 1.68 + // instead of the beginning. 1.69 + PcDesc* pc_desc = nm->pc_desc_near(fr->pc() + 1); 1.70 + 1.71 + // Now do we have a useful PcDesc? 1.72 + if (pc_desc == NULL || 1.73 + pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) { 1.74 + // No debug information available for this pc 1.75 + // vframeStream would explode if we try and walk the frames. 1.76 + return false; 1.77 + } 1.78 + 1.79 + // This PcDesc is useful however we must adjust the frame's pc 1.80 + // so that the vframeStream lookups will use this same pc 1.81 + fr->set_pc(pc_desc->real_pc(nm)); 1.82 return true; 1.83 } 1.84 1.85 + 1.86 // Determine if 'fr' is a walkable interpreted frame. Returns false 1.87 // if it is not. *method_p, and *bci_p are not set when false is 1.88 // returned. *method_p is non-NULL if frame was executing a Java 1.89 @@ -166,9 +167,9 @@ 1.90 // even if a valid BCI cannot be found. 1.91 1.92 static bool is_decipherable_interpreted_frame(JavaThread* thread, 1.93 - frame* fr, 1.94 - methodOop* method_p, 1.95 - int* bci_p) { 1.96 + frame* fr, 1.97 + methodOop* method_p, 1.98 + int* bci_p) { 1.99 assert(fr->is_interpreted_frame(), "just checking"); 1.100 1.101 // top frame is an interpreted frame 1.102 @@ -323,13 +324,15 @@ 1.103 // have a PCDesc that can get us a bci however we did find 1.104 // a method 1.105 1.106 - if (!is_decipherable_compiled_frame(&candidate)) { 1.107 + if (!is_decipherable_compiled_frame(thread, &candidate, nm)) { 1.108 return false; 1.109 } 1.110 1.111 // is_decipherable_compiled_frame may modify candidate's pc 1.112 *initial_frame_p = candidate; 1.113 1.114 + assert(nm->pc_desc_at(candidate.pc()) != NULL, "if it's decipherable then pc must be valid"); 1.115 + 1.116 return true; 1.117 } 1.118