src/share/vm/prims/forte.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
8068945-8u-patched Cdiff src/share/vm/prims/forte.cpp
src/share/vm/prims/forte.cpp
Print this page
rev 7386 : 8068945: Use RBP register as proper frame pointer in JIT compiled code on x86
Summary: Introduce the PreserveFramePointer flag to control if RBP is used as the frame pointer or as a general purpose register.
Reviewed-by: kvn, roland, dlong, enevill, shade
*** 170,181 ****
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.
return false;
}
// This PcDesc is useful however we must adjust the frame's pc
// so that the vframeStream lookups will use this same pc
--- 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 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 ****
// 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;
intptr_t bcx = fr->interpreter_frame_bcx();
int bci = method->validate_bci_from_bcx(bcx);
--- 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.
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 ****
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.
//
! // 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? )
//
! // The initial Java frame we find (if any) is return via initial_frame_p.
//
static bool find_initial_Java_frame(JavaThread* thread,
frame* fr,
frame* initial_frame_p,
Method** method_p,
--- 265,301 ----
return false;
}
! // 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.
//
! // A frame is considered to be decipherable:
//
! // - 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 ****
// 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.
--- 311,320 ----
*** 332,366 ****
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
// 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 (!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");
return true;
}
// Must be some stub frame that we don't care about
--- 365,401 ----
if (candidate.cb()->is_nmethod()) {
nmethod* nm = (nmethod*) candidate.cb();
*method_p = nm->method();
! // 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 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, "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 ****
frame top_frame) {
NoHandleMark nhm;
frame initial_Java_frame;
Method* method;
! int bci;
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)
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();
--- 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");
! // 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;
}
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