Bug 1480390: Replace TryNoteIter template op with a more general filter op r=tcampbell
authorIain Ireland <iireland@mozilla.com>
Fri, 11 Jan 2019 18:43:24 +0000
changeset 513510 e5caca48603e0eb7683c052a1f0ce97ed96c2d70
parent 513509 b3d4bff86800675552438e3d7498796e7f26ec2b
child 513511 e920686642fa8461a7c4b72e1c6ed3335b553614
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell
bugs1480390
milestone66.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 1480390: Replace TryNoteIter template op with a more general filter op r=tcampbell Depends on D14784 Differential Revision: https://phabricator.services.mozilla.com/D16250
js/src/jit/JitFrames.cpp
js/src/vm/Interpreter.cpp
js/src/vm/Interpreter.h
--- a/js/src/jit/JitFrames.cpp
+++ b/js/src/jit/JitFrames.cpp
@@ -128,35 +128,35 @@ static void CloseLiveIteratorIon(JSConte
     } else {
       IteratorCloseForException(cx, iterObject);
     }
   } else {
     UnwindIteratorForUncatchableException(iterObject);
   }
 }
 
-class IonFrameStackDepthOp {
+class IonTryNoteFilter {
   uint32_t depth_;
 
  public:
-  explicit IonFrameStackDepthOp(const InlineFrameIterator& frame) {
+  explicit IonTryNoteFilter(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_; }
+  bool operator()(const JSTryNote* note) { return note->stackDepth <= depth_; }
 };
 
-class TryNoteIterIon : public TryNoteIter<IonFrameStackDepthOp> {
+class TryNoteIterIon : public TryNoteIter<IonTryNoteFilter> {
  public:
   TryNoteIterIon(JSContext* cx, const InlineFrameIterator& frame)
       : TryNoteIter(cx, frame.script(), frame.pc(),
-                    IonFrameStackDepthOp(frame)) {}
+                    IonTryNoteFilter(frame)) {}
 };
 
 static void HandleExceptionIon(JSContext* cx, const InlineFrameIterator& frame,
                                ResumeFromException* rfe,
                                bool* hitBailoutException) {
   if (cx->realm()->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
@@ -303,31 +303,32 @@ struct AutoBaselineHandlingException {
     frame->setOverridePc(pc);
   }
   ~AutoBaselineHandlingException() {
     frame->unsetIsHandlingException();
     frame->clearOverridePc();
   }
 };
 
-class BaselineFrameStackDepthOp {
+class BaselineTryNoteFilter {
   BaselineFrame* frame_;
 
  public:
-  explicit BaselineFrameStackDepthOp(BaselineFrame* frame) : frame_(frame) {}
-  uint32_t operator()() {
+  explicit BaselineTryNoteFilter(BaselineFrame* frame) : frame_(frame) {}
+  bool operator()(const JSTryNote* note) {
     MOZ_ASSERT(frame_->numValueSlots() >= frame_->script()->nfixed());
-    return frame_->numValueSlots() - frame_->script()->nfixed();
+    uint32_t currDepth = frame_->numValueSlots() - frame_->script()->nfixed();
+    return note->stackDepth <= currDepth;
   }
 };
 
-class TryNoteIterBaseline : public TryNoteIter<BaselineFrameStackDepthOp> {
+class TryNoteIterBaseline : public TryNoteIter<BaselineTryNoteFilter> {
  public:
   TryNoteIterBaseline(JSContext* cx, BaselineFrame* frame, jsbytecode* pc)
-      : TryNoteIter(cx, frame->script(), pc, BaselineFrameStackDepthOp(frame)) {
+      : TryNoteIter(cx, frame->script(), pc, BaselineTryNoteFilter(frame)) {
   }
 };
 
 // Close all live iterators on a BaselineFrame due to exception unwinding. The
 // pc parameter is updated to where the envs have been unwound to.
 static void CloseLiveIteratorsBaselineForUncatchableException(
     JSContext* cx, const JSJitFrameIter& frame, jsbytecode* pc) {
   for (TryNoteIterBaseline tni(cx, frame.baselineFrame(), pc); !tni.done();
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -1094,31 +1094,33 @@ static void SettleOnTryNote(JSContext* c
   UnwindEnvironment(cx, ei, UnwindEnvironmentToTryPc(regs.fp()->script(), tn));
 
   // Set pc to the first bytecode after the the try note to point
   // to the beginning of catch or finally.
   regs.pc = regs.fp()->script()->offsetToPC(tn->start + tn->length);
   regs.sp = regs.spForStackDepth(tn->stackDepth);
 }
 
-class InterpreterFrameStackDepthOp {
+class InterpreterTryNoteFilter {
   const InterpreterRegs& regs_;
 
  public:
-  explicit InterpreterFrameStackDepthOp(const InterpreterRegs& regs)
+  explicit InterpreterTryNoteFilter(const InterpreterRegs& regs)
       : regs_(regs) {}
-  uint32_t operator()() { return regs_.stackDepth(); }
+  bool operator()(const JSTryNote* note) {
+    return note->stackDepth <= regs_.stackDepth();
+  }
 };
 
 class TryNoteIterInterpreter
-    : public TryNoteIter<InterpreterFrameStackDepthOp> {
+    : public TryNoteIter<InterpreterTryNoteFilter> {
  public:
   TryNoteIterInterpreter(JSContext* cx, const InterpreterRegs& regs)
       : TryNoteIter(cx, regs.fp()->script(), regs.pc,
-                    InterpreterFrameStackDepthOp(regs)) {}
+                    InterpreterTryNoteFilter(regs)) {}
 };
 
 static void UnwindIteratorsForUncatchableException(
     JSContext* cx, const InterpreterRegs& regs) {
   // c.f. the regular (catchable) TryNoteIterInterpreter loop in
   // ProcessTryNotes.
   for (TryNoteIterInterpreter tni(cx, regs); !tni.done(); ++tni) {
     const JSTryNote* tn = *tni;
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -304,21 +304,21 @@ extern void UnwindEnvironment(JSContext*
 // Unwind all environments.
 extern void UnwindAllEnvironmentsInFrame(JSContext* cx, EnvironmentIter& ei);
 
 // Compute the pc needed to unwind the scope to the beginning of the block
 // pointed to by the try note.
 extern jsbytecode* UnwindEnvironmentToTryPc(JSScript* script,
                                             const JSTryNote* tn);
 
-template <class StackDepthOp>
+template <class TryNoteFilter>
 class MOZ_STACK_CLASS TryNoteIter {
   RootedScript script_;
   uint32_t pcOffset_;
-  StackDepthOp getStackDepth_;
+  TryNoteFilter isTryNoteValid_;
 
   const JSTryNote* tn_;
   const JSTryNote* tnEnd_;
 
   void settle() {
     for (; tn_ != tnEnd_; ++tn_) {
       if (!pcInRange()) {
         continue;
@@ -374,28 +374,28 @@ class MOZ_STACK_CLASS TryNoteIter {
        * invoked the finally blocks.
        *
        * To address this, we make [enditer] always decrease the stack even
        * when its implementation throws an exception. Thus already executed
        * [enditer] and [gosub] opcodes will have try notes with the stack
        * depth exceeding the current one and this condition is what we use to
        * filter them out.
        */
-      if (tn_ == tnEnd_ || tn_->stackDepth <= getStackDepth_()) {
+      if (tn_ == tnEnd_ || isTryNoteValid_(tn_)) {
         return;
       }
     }
   }
 
  public:
   TryNoteIter(JSContext* cx, JSScript* script, jsbytecode* pc,
-              StackDepthOp getStackDepth)
+              TryNoteFilter isTryNoteValid)
       : script_(cx, script),
         pcOffset_(script->pcToOffset(pc)),
-        getStackDepth_(getStackDepth) {
+        isTryNoteValid_(isTryNoteValid) {
     if (script->hasTrynotes()) {
       // NOTE: The Span is a temporary so we can't use begin()/end()
       // here or the iterator will outlive the span.
       auto trynotes = script->trynotes();
       tn_ = trynotes.data();
       tnEnd_ = tn_ + trynotes.size();
     } else {
       tn_ = tnEnd_ = nullptr;