Bug 1003694 - Settle on first frame by skipping all allocations. r=h4writer
authorNicolas B. Pierron <nicolas.b.pierron@mozilla.com>
Wed, 30 Apr 2014 01:34:07 -0700
changeset 181357 e0679448fd3ba60750ae9e427468a6cff631c5bb
parent 181356 133eecf5f0f0471c090ae41a3ba6ae44d1ee6d7b
child 181358 c9c1e001452bbdc054460038021bc928ee95e91b
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersh4writer
bugs1003694
milestone32.0a1
Bug 1003694 - Settle on first frame by skipping all allocations. r=h4writer
js/src/jit-test/tests/ion/bug1003694.js
js/src/jit/IonFrames.cpp
js/src/jit/JitFrameIterator.h
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug1003694.js
@@ -0,0 +1,9 @@
+function f(i) {
+    if (i >= 10)
+        return;
+    var d = 3 + Math.abs();
+    f(i ? i + 1 : 1);
+    bailout();
+}
+
+f(0);
--- a/js/src/jit/IonFrames.cpp
+++ b/js/src/jit/IonFrames.cpp
@@ -1624,21 +1624,29 @@ SnapshotIterator::storeInstructionResult
 Value
 SnapshotIterator::fromInstructionResult(uint32_t index) const
 {
     MOZ_ASSERT(!(*instructionResults_)[index].isMagic(JS_ION_BAILOUT));
     return (*instructionResults_)[index];
 }
 
 void
+SnapshotIterator::settleOnFrame()
+{
+    // Check that the current instruction can still be use.
+    MOZ_ASSERT(snapshot_.numAllocationsRead() == 0);
+    while (!instruction()->isResumePoint())
+        skipInstruction();
+}
+
+void
 SnapshotIterator::nextFrame()
 {
     nextInstruction();
-    while (!instruction()->isResumePoint())
-        skipInstruction();
+    settleOnFrame();
 }
 
 IonScript *
 JitFrameIterator::ionScript() const
 {
     JS_ASSERT(type() == JitFrame_IonJS);
 
     IonScript *ionScript = nullptr;
@@ -1694,18 +1702,17 @@ InlineFrameIteratorMaybeGC<allowGC>::fin
 
     // Read the initial frame out of the C stack.
     callee_ = frame_->maybeCallee();
     script_ = frame_->script();
     MOZ_ASSERT(script_->hasBaselineScript());
 
     // Settle on the outermost frame without evaluating any instructions before
     // looking for a pc.
-    if (!si_.instruction()->isResumePoint())
-        si_.nextFrame();
+    si_.settleOnFrame();
 
     pc_ = script_->offsetToPC(si_.pcOffset());
 #ifdef DEBUG
     numActualArgs_ = 0xbadbad;
 #endif
 
     // This unfortunately is O(n*m), because we must skip over outer frames
     // before reading inner ones.
--- a/js/src/jit/JitFrameIterator.h
+++ b/js/src/jit/JitFrameIterator.h
@@ -350,16 +350,17 @@ class SnapshotIterator
     // enough space for all instructions results, and return false iff it fails.
     bool initIntructionResults(AutoValueVector &results);
 
     void storeInstructionResult(Value v);
 
   public:
     // Handle iterating over frames of the snapshots.
     void nextFrame();
+    void settleOnFrame();
 
     inline bool moreFrames() const {
         // The last instruction is recovering the innermost frame, so as long as
         // there is more instruction there is necesseray more frames.
         return moreInstructions();
     }
 
   public: