Bug 1143679 - Make TryNoteIterIon behave more like Baseline/interpreter iterators. r=shu, a=sledru
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 03 Jun 2015 09:35:30 +0200
changeset 262525 58f9c004fc05510c1bae98a366d1616f503ffd1a
parent 262524 bb72b2539a592339b1c7eb97c3f9ca223b08d823
child 262526 e5be8fc2066033f8472fc329ee281a3b35f7a900
push id8089
push userryanvm@gmail.com
push dateMon, 08 Jun 2015 13:16:11 +0000
treeherdermozilla-aurora@77aebefaa4de [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshu, sledru
bugs1143679
milestone40.0a2
Bug 1143679 - Make TryNoteIterIon behave more like Baseline/interpreter iterators. r=shu, a=sledru
js/src/jit/JitFrames.cpp
--- a/js/src/jit/JitFrames.cpp
+++ b/js/src/jit/JitFrames.cpp
@@ -371,58 +371,70 @@ JitFrameIterator::machineState() const
             (*iter).alignedAliased(a, &ftmp);
             machine.setRegisterLocation(ftmp, (double*)floatSpill);
         }
     }
 
     return machine;
 }
 
+static uint32_t
+NumArgAndLocalSlots(const InlineFrameIterator& frame)
+{
+    JSScript* script = frame.script();
+    return CountArgSlots(script, frame.maybeCalleeTemplate()) + script->nfixed();
+}
+
 static void
-CloseLiveIteratorIon(JSContext* cx, const InlineFrameIterator& frame, uint32_t localSlot)
+CloseLiveIteratorIon(JSContext* cx, const InlineFrameIterator& frame, uint32_t stackSlot)
 {
     SnapshotIterator si = frame.snapshotIterator();
 
     // Skip stack slots until we reach the iterator object.
-    uint32_t base = CountArgSlots(frame.script(), frame.maybeCalleeTemplate()) + frame.script()->nfixed();
-    uint32_t skipSlots = base + localSlot - 1;
+    uint32_t skipSlots = NumArgAndLocalSlots(frame) + stackSlot - 1;
 
     for (unsigned i = 0; i < skipSlots; i++)
         si.skip();
 
     Value v = si.read();
     RootedObject obj(cx, &v.toObject());
 
     if (cx->isExceptionPending())
         UnwindIteratorForException(cx, obj);
     else
         UnwindIteratorForUncatchableException(cx, obj);
 }
 
-class IgnoreStackDepthOp
+class IonFrameStackDepthOp
+{
+    uint32_t depth_;
+
+  public:
+    explicit IonFrameStackDepthOp(const InlineFrameIterator& frame) {
+        uint32_t base = NumArgAndLocalSlots(frame);
+        SnapshotIterator si = frame.snapshotIterator();
+        MOZ_ASSERT(si.numAllocations() >= base);
+        depth_ = si.numAllocations() - base;
+    }
+
+    uint32_t operator()() { return depth_; }
+};
+
+class TryNoteIterIon : public TryNoteIter<IonFrameStackDepthOp>
 {
   public:
-    uint32_t operator()() { return UINT32_MAX; }
-};
-
-class TryNoteIterIon : public TryNoteIter<IgnoreStackDepthOp>
-{
-  public:
-    TryNoteIterIon(JSContext* cx, JSScript* script, jsbytecode* pc)
-      : TryNoteIter(cx, script, pc, IgnoreStackDepthOp())
+    TryNoteIterIon(JSContext* cx, const InlineFrameIterator& frame)
+      : TryNoteIter(cx, frame.script(), frame.pc(), IonFrameStackDepthOp(frame))
     { }
 };
 
 static void
 HandleExceptionIon(JSContext* cx, const InlineFrameIterator& frame, ResumeFromException* rfe,
                    bool* overrecursed)
 {
-    RootedScript script(cx, frame.script());
-    jsbytecode* pc = frame.pc();
-
     if (cx->compartment()->isDebuggee()) {
         // We need to bail when there is a catchable exception, and we are the
         // debuggee of a Debugger with a live onExceptionUnwind hook, or if a
         // Debugger has observed this frame (e.g., for onPop).
         bool shouldBail = Debugger::hasLiveHook(cx->global(), Debugger::OnExceptionUnwind);
         RematerializedFrame* rematFrame = nullptr;
         if (!shouldBail) {
             JitActivation* act = cx->runtime()->activation()->asJit();
@@ -455,20 +467,21 @@ HandleExceptionIon(JSContext* cx, const 
             // cannot honor any Debugger hooks.
             if (rematFrame)
                 Debugger::handleUnrecoverableIonBailoutError(cx, rematFrame);
         }
 
         MOZ_ASSERT_IF(rematFrame, !Debugger::inFrameMaps(rematFrame));
     }
 
+    RootedScript script(cx, frame.script());
     if (!script->hasTrynotes())
         return;
 
-    for (TryNoteIterIon tni(cx, script, pc); !tni.done(); ++tni) {
+    for (TryNoteIterIon tni(cx, frame); !tni.done(); ++tni) {
         JSTryNote* tn = *tni;
 
         switch (tn->kind) {
           case JSTRY_FOR_IN: {
             MOZ_ASSERT(JSOp(*(script->main() + tn->start + tn->length)) == JSOP_ENDITER);
             MOZ_ASSERT(tn->stackDepth > 0);
 
             uint32_t localSlot = tn->stackDepth;