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