src/share/vm/prims/forte.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/prims/forte.cpp Fri May 29 13:57:38 2015
--- new/src/share/vm/prims/forte.cpp Fri May 29 13:57:38 2015
*** 170,181 ****
--- 170,200 ----
PcDesc* pc_desc = nm->pc_desc_near(fr->pc() + 1);
// Now do we have a useful PcDesc?
if (pc_desc == NULL ||
pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) {
! // No debug information available for this pc
// vframeStream would explode if we try and walk the frames.
! // No debug information is available for this PC.
+ //
+ // vframeStreamCommon::fill_from_frame() will decode the frame depending
+ // on the state of the thread.
+ //
+ // Case #1: If the thread is in Java (state == _thread_in_Java), then
+ // the vframeStreamCommon object will be filled as if the frame were a native
+ // compiled frame. Therefore, no debug information is needed.
+ //
+ // Case #2: If the thread is in any other state, then two steps will be performed:
+ // - if asserts are enabled, found_bad_method_frame() will be called and
+ // the assert in found_bad_method_frame() will be triggered;
+ // - if asserts are disabled, the vframeStreamCommon object will be filled
+ // as if it were a native compiled frame.
+ //
+ // Case (2) is similar to the way interpreter frames are processed in
+ // vframeStreamCommon::fill_from_interpreter_frame in case no valid BCI
+ // was found for an interpreted frame. If asserts are enabled, the assert
+ // in found_bad_method_frame() will be triggered. If asserts are disabled,
+ // the vframeStreamCommon object will be filled afterwards as if the
+ // interpreter were at the point of entering into the method.
return false;
}
// This PcDesc is useful however we must adjust the frame's pc
// so that the vframeStream lookups will use this same pc
*** 228,240 ****
--- 247,260 ----
// NOTE: there is something to be said for the approach that
// if we don't find a valid bci then the method is not likely
// a valid method. Then again we may have caught an interpreter
// frame in the middle of construction and the bci field is
// not yet valid.
*method_p = method;
if (!method->is_valid_method()) return false;
+ *method_p = method; // If the Method* found is invalid, it is
+ // ignored by forte_fill_call_trace_given_top().
+ // So set method_p only if the Method is valid.
intptr_t bcx = fr->interpreter_frame_bcx();
int bci = method->validate_bci_from_bcx(bcx);
*** 245,266 ****
--- 265,301 ----
return false;
}
! // Determine if 'fr' can be used to find an initial Java frame.
// Return false if it can not find a fully decipherable Java frame
// (in other words a frame that isn't safe to use in a vframe stream).
! // Obviously if it can't even find a Java frame false will also be returned.
! // Determine if a Java frame can be found starting with the frame 'fr'.
+ //
+ // Check the return value of find_initial_Java_frame and the value of
! // 'method_p' to decide on how use the results returned by this method.
+ //
+ // If 'method_p' is not NULL, an initial Java frame has been found and
+ // the stack can be walked starting from that initial frame. In this case,
+ // 'method_p' points to the Method that the initial frame belongs to and
+ // the initial Java frame is returned in initial_frame_p.
+ //
+ // find_initial_Java_frame() returns true if a Method has been found (i.e.,
+ // 'method_p' is not NULL) and the initial frame that belongs to that Method
+ // is decipherable.
//
// If we find a Java frame decipherable or not then by definition we have
// identified a method and that will be returned to the caller via method_p.
// If we can determine a bci that is returned also. (Hmm is it possible
// to return a method and bci and still return false? )
+ // A frame is considered to be decipherable:
//
// The initial Java frame we find (if any) is return via initial_frame_p.
+ // - if the frame is a compiled frame and a PCDesc is available;
//
+ // - if the frame is an interpreter frame that is valid or the thread is
+ // state (_thread_in_native || state == _thread_in_vm || state == _thread_blocked).
+ //
+ // Note that find_initial_Java_frame() can return false even if an initial
+ // Java method was found (e.g., there is no PCDesc available for the method).
+ //
+ // If 'method_p' is NULL, it was not possible to find a Java frame when
+ // walking the stack starting from 'fr'. In this case find_initial_Java_frame
+ // returns false.
static bool find_initial_Java_frame(JavaThread* thread,
frame* fr,
frame* initial_frame_p,
Method** method_p,
*** 276,287 ****
--- 311,320 ----
// On the initial call to this method the frame we get may not be
// recognizable to us. This should only happen if we are in a JRT_LEAF
// or something called by a JRT_LEAF method.
frame candidate = *fr;
// If the starting frame we were given has no codeBlob associated with
// it see if we can find such a frame because only frames with codeBlobs
// are possible Java frames.
*** 332,366 ****
--- 365,401 ----
if (candidate.cb()->is_nmethod()) {
nmethod* nm = (nmethod*) candidate.cb();
*method_p = nm->method();
! // If the frame isn't fully decipherable then the default
! // value for the bci is a signal that we don't have a bci.
// If we have a decipherable frame this bci value will
! // If the frame is not decipherable, then the value of -1
! // for the BCI is used to signal that no BCI is available.
+ // Furthermore, the method returns false in this case.
+ //
+ // If a decipherable frame is available, the BCI value will
// not be used.
*bci_p = -1;
*initial_frame_p = candidate;
// Native wrapper code is trivial to decode by vframeStream
if (nm->is_native_method()) return true;
! // If it isn't decipherable then we have found a pc that doesn't
// have a PCDesc that can get us a bci however we did find
// a method
! // If the frame is not decipherable, then a PC was found
+ // that does not have a PCDesc from which a BCI can be obtained.
+ // Nevertheless, a Method was found.
if (!is_decipherable_compiled_frame(thread, &candidate, nm)) {
return false;
}
// is_decipherable_compiled_frame may modify candidate's pc
*initial_frame_p = candidate;
! assert(nm->pc_desc_at(candidate.pc()) != NULL, "if it's decipherable then pc must be valid");
! assert(nm->pc_desc_at(candidate.pc()) != NULL, "debug information must be available if the frame is decipherable");
return true;
}
// Must be some stub frame that we don't care about
*** 386,436 ****
--- 421,448 ----
frame top_frame) {
NoHandleMark nhm;
frame initial_Java_frame;
Method* method;
! int bci = -1; // assume BCI is not available for method
+ // update with correct information if available
int count;
count = 0;
assert(trace->frames != NULL, "trace->frames must be non-NULL");
bool fully_decipherable = find_initial_Java_frame(thd, &top_frame, &initial_Java_frame, &method, &bci);
// The frame might not be walkable but still recovered a method
// (e.g. an nmethod with no scope info for the pc)
+ // Walk the stack starting from 'top_frame' and search for an initial Java frame.
+ find_initial_Java_frame(thd, &top_frame, &initial_Java_frame, &method, &bci);
+ // Check if a Java Method has been found.
if (method == NULL) return;
if (!method->is_valid_method()) {
trace->num_frames = ticks_GC_active; // -2
return;
}
// We got a Java frame however it isn't fully decipherable
// so it won't necessarily be safe to use it for the
// initial frame in the vframe stream.
if (!fully_decipherable) {
// Take whatever method the top-frame decoder managed to scrape up.
// We look further at the top frame only if non-safepoint
// debugging information is available.
count++;
trace->num_frames = count;
trace->frames[0].method_id = method->find_jmethod_id_or_null();
if (!method->is_native()) {
trace->frames[0].lineno = bci;
} else {
trace->frames[0].lineno = -3;
}
if (!initial_Java_frame.safe_for_sender(thd)) return;
RegisterMap map(thd, false);
initial_Java_frame = initial_Java_frame.sender(&map);
}
vframeStreamForte st(thd, initial_Java_frame, false);
for (; !st.at_end() && count < depth; st.forte_next(), count++) {
bci = st.bci();
method = st.method();
src/share/vm/prims/forte.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File