Bug 1161351 - Fix unwound exit frame sizes in JitProfilingFrameIterator. (r=nbp)
☠☠ backed out by ea1a2a86fa0a ☠ ☠
authorShu-yu Guo <shu@rfrn.org>
Wed, 06 May 2015 15:55:26 -0700
changeset 274055 7c7e849bb5fd8f7e4e6a7afd49b6f3377984990e
parent 274054 93af6e2a390d94f86c85f6d342c94f06857543fc
child 274056 cb1b4b057dad90200759e2c00a8e0f37b95ae8f4
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1161351
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1161351 - Fix unwound exit frame sizes in JitProfilingFrameIterator. (r=nbp)
js/src/jit-test/tests/profiler/bug1161351.js
js/src/jit/JitFrames-inl.h
js/src/jit/JitFrames.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1161351.js
@@ -0,0 +1,15 @@
+function x() { n; }
+function f() {
+  try  { x(); } catch(ex) {}
+}
+var g = newGlobal();
+g.parent = this;
+g.eval("new Debugger(parent).onExceptionUnwind = function () {};");
+enableSPSProfiling();
+try {
+  enableSingleStepProfiling();
+} catch (e) {
+}
+f();
+f();
+f();
--- a/js/src/jit/JitFrames-inl.h
+++ b/js/src/jit/JitFrames-inl.h
@@ -44,26 +44,32 @@ JitFrameIterator::prevFrameLocalSize() c
 inline FrameType
 JitFrameIterator::prevType() const
 {
     CommonFrameLayout* current = (CommonFrameLayout*) current_;
     return current->prevType();
 }
 
 inline bool
+IsUnwoundFrame(FrameType type)
+{
+    return type == JitFrame_Unwound_Rectifier ||
+           type == JitFrame_Unwound_IonJS ||
+           type == JitFrame_Unwound_BaselineJS ||
+           type == JitFrame_Unwound_BaselineStub ||
+           type == JitFrame_Unwound_IonAccessorIC;
+}
+
+inline bool
 JitFrameIterator::isFakeExitFrame() const
 {
     if (type() == JitFrame_LazyLink)
         return false;
-    bool res = (prevType() == JitFrame_Unwound_Rectifier ||
-                prevType() == JitFrame_Unwound_IonJS ||
-                prevType() == JitFrame_Unwound_BaselineJS ||
-                prevType() == JitFrame_Unwound_BaselineStub ||
-                prevType() == JitFrame_Unwound_IonAccessorIC ||
-                (prevType() == JitFrame_Entry && type() == JitFrame_Exit));
+    bool res = IsUnwoundFrame(prevType()) ||
+               (prevType() == JitFrame_Entry && type() == JitFrame_Exit);
     MOZ_ASSERT_IF(res, type() == JitFrame_Exit || type() == JitFrame_BaselineJS);
     return res;
 }
 
 inline ExitFrameLayout*
 JitFrameIterator::exitFrame() const
 {
     MOZ_ASSERT(isExitFrame());
--- a/js/src/jit/JitFrames.cpp
+++ b/js/src/jit/JitFrames.cpp
@@ -2930,32 +2930,46 @@ JitProfilingFrameIterator::JitProfilingF
     returnAddressToFp_ = frameScript()->baselineScript()->method()->raw();
 }
 
 template <typename FrameType, typename ReturnType=CommonFrameLayout*>
 inline ReturnType
 GetPreviousRawFrame(FrameType* frame)
 {
     size_t prevSize = frame->prevFrameLocalSize() + FrameType::Size();
-    return (ReturnType) (((uint8_t*) frame) + prevSize);
+    return ReturnType(((uint8_t*) frame) + prevSize);
+}
+
+template <typename ReturnType=CommonFrameLayout*>
+inline ReturnType
+GetPreviousRawFrame(ExitFrameLayout* frame)
+{
+    // Unwound exit frames are fake exit frames, and have the size of a
+    // JitFrameLayout instead of ExitFrameLayout. See
+    // JitFrameIterator::prevFp.
+    size_t frameSize = IsUnwoundFrame(frame->prevType())
+                       ? JitFrameLayout::Size()
+                       : ExitFrameLayout::Size();
+    size_t prevSize = frame->prevFrameLocalSize() + frameSize;
+    return ReturnType(((uint8_t*) frame) + prevSize);
 }
 
 JitProfilingFrameIterator::JitProfilingFrameIterator(void* exitFrame)
 {
     ExitFrameLayout* frame = (ExitFrameLayout*) exitFrame;
     FrameType prevType = frame->prevType();
 
     if (prevType == JitFrame_IonJS || prevType == JitFrame_Unwound_IonJS) {
         returnAddressToFp_ = frame->returnAddress();
         fp_ = GetPreviousRawFrame<ExitFrameLayout, uint8_t*>(frame);
         type_ = JitFrame_IonJS;
         return;
     }
 
-    if (prevType == JitFrame_BaselineJS) {
+    if (prevType == JitFrame_BaselineJS || prevType == JitFrame_Unwound_BaselineJS) {
         returnAddressToFp_ = frame->returnAddress();
         fp_ = GetPreviousRawFrame<ExitFrameLayout, uint8_t*>(frame);
         type_ = JitFrame_BaselineJS;
         fixBaselineDebugModeOSRReturnAddress();
         return;
     }
 
     if (prevType == JitFrame_BaselineStub || prevType == JitFrame_Unwound_BaselineStub) {