Bug 1026485 - Fix sps bug relating to ArgumentCheck bailouts that cause OOMs. r=nbp
authorKannan Vijayan <kvijayan@mozilla.com>
Fri, 11 Jul 2014 14:47:47 -0400
changeset 193547 394a87a6450f8aa03e0f124e1e3deb5f99c27661
parent 193546 6b3cbfdec943cceaf1b4354ced77349a69771b9e
child 193548 62f11352d1988c6274dc0ea4361c8063605ff8be
push id46144
push userkvijayan@mozilla.com
push dateFri, 11 Jul 2014 18:48:26 +0000
treeherdermozilla-inbound@394a87a6450f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1026485
milestone33.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 1026485 - Fix sps bug relating to ArgumentCheck bailouts that cause OOMs. r=nbp
js/src/jit-test/tests/profiler/test-bug1026485.js
js/src/jit/Bailouts.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/test-bug1026485.js
@@ -0,0 +1,14 @@
+
+function TestCase(n, d, e, a)
+  TestCase.prototype.dump = function () {}
+enableSPSProfiling();
+new TestCase(typeof Number(new Number()));
+new TestCase(typeof Number(new Number(Number.NaN)));
+test();
+function test() {
+    try {
+        test();
+    } catch (e) {
+        new TestCase();
+    }
+}
--- a/js/src/jit/Bailouts.cpp
+++ b/js/src/jit/Bailouts.cpp
@@ -105,19 +105,24 @@ jit::Bailout(BailoutStack *sp, BaselineB
     if (retval != BAILOUT_RETURN_OK) {
         // If the bailout failed, then bailout trampoline will pop the
         // current frame and jump straight to exception handling code when
         // this function returns.  Any SPS entry pushed for this frame will
         // be silently forgotten.
         //
         // We call ExitScript here to ensure that if the ionScript had SPS
         // instrumentation, then the SPS entry for it is popped.
+        //
+        // However, if the bailout was during argument check, then a
+        // pseudostack frame would not have been pushed in the first
+        // place, so don't pop anything in that case.
+        bool popSPSFrame = iter.ionScript()->hasSPSInstrumentation() &&
+                           (SnapshotIterator(iter).bailoutKind() != Bailout_ArgumentCheck);
         JSScript *script = iter.script();
-        probes::ExitScript(cx, script, script->functionNonDelazifying(),
-                           iter.ionScript()->hasSPSInstrumentation());
+        probes::ExitScript(cx, script, script->functionNonDelazifying(), popSPSFrame);
 
         EnsureExitFrame(iter.jsFrame());
     }
 
     return retval;
 }
 
 uint32_t
@@ -156,19 +161,24 @@ jit::InvalidationBailout(InvalidationBai
     if (retval != BAILOUT_RETURN_OK) {
         // If the bailout failed, then bailout trampoline will pop the
         // current frame and jump straight to exception handling code when
         // this function returns.  Any SPS entry pushed for this frame will
         // be silently forgotten.
         //
         // We call ExitScript here to ensure that if the ionScript had SPS
         // instrumentation, then the SPS entry for it is popped.
+        //
+        // However, if the bailout was during argument check, then a
+        // pseudostack frame would not have been pushed in the first
+        // place, so don't pop anything in that case.
+        bool popSPSFrame = iter.ionScript()->hasSPSInstrumentation() &&
+                           (SnapshotIterator(iter).bailoutKind() != Bailout_ArgumentCheck);
         JSScript *script = iter.script();
-        probes::ExitScript(cx, script, script->functionNonDelazifying(),
-                           iter.ionScript()->hasSPSInstrumentation());
+        probes::ExitScript(cx, script, script->functionNonDelazifying(), popSPSFrame);
 
         IonJSFrameLayout *frame = iter.jsFrame();
         IonSpew(IonSpew_Invalidate, "Bailout failed (%s): converting to exit frame",
                 (retval == BAILOUT_RETURN_FATAL_ERROR) ? "Fatal Error" : "Over Recursion");
         IonSpew(IonSpew_Invalidate, "   orig calleeToken %p", (void *) frame->calleeToken());
         IonSpew(IonSpew_Invalidate, "   orig frameSize %u", unsigned(frame->prevFrameLocalSize()));
         IonSpew(IonSpew_Invalidate, "   orig ra %p", (void *) frame->returnAddress());