Bug 1601072 part 1 - Rewrite BytecodeEmitter::emitYieldStar to emit a loop. r=arai
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 11 Dec 2019 14:06:53 +0000
changeset 507044 cad2de45dfa1ca61a3aed2089ed2dcb5c4c30908
parent 507043 6946b03252679929f2c275df87f74a65557d3ceb
child 507045 099b03af31e1e873e46063d4b11232dc20e0752b
push id36922
push userncsoregi@mozilla.com
push dateMon, 16 Dec 2019 17:21:47 +0000
treeherdermozilla-central@27d0d6cc2131 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1601072
milestone73.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 1601072 part 1 - Rewrite BytecodeEmitter::emitYieldStar to emit a loop. r=arai This way we get proper JIT tiering. It will also make it possible to assert all backward jumps are to a JSOP_LOOPHEAD. Differential Revision: https://phabricator.services.mozilla.com/D56715
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/SharedContext.h
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -6250,18 +6250,19 @@ bool BytecodeEmitter::emitYieldStar(Pars
 
   TryEmitter tryCatch(this, TryEmitter::Kind::TryCatchFinally,
                       TryEmitter::ControlKind::NonSyntactic);
   if (!tryCatch.emitJumpOverCatchAndFinally()) {
     //              [stack] NEXT ITER RESULT
     return false;
   }
 
-  JumpTarget tryStart;
-  if (!emitJumpTarget(&tryStart)) {
+  LoopControl loopInfo(this, StatementKind::YieldStar);
+
+  if (!loopInfo.emitLoopHead(this, Nothing())) {
     //              [stack] NEXT ITER RESULT
     return false;
   }
 
   if (iterKind == IteratorKind::Async) {
     // Step 7.a.vi.
     // Step 7.b.ii.7.
     // Step 7.c.ix.
@@ -6553,25 +6554,21 @@ bool BytecodeEmitter::emitYieldStar(Pars
   if (!emit2(JSOP_UNPICK, 3)) {
     //              [stack] NEXT ITER RESULT OLDRESULT FTYPE FVALUE
     return false;
   }
   if (!emitPopN(3)) {
     //              [stack] NEXT ITER RESULT
     return false;
   }
-  {
-    // goto tryStart;
-    JumpList beq;
-    JumpTarget breakTarget;
-    if (!emitBackwardJump(JSOP_GOTO, tryStart, &beq, &breakTarget)) {
-      //            [stack] NEXT ITER RESULT
-      return false;
-    }
-  }
+  if (!emitJump(JSOP_GOTO, &loopInfo.continues)) {
+    //              [stack] NEXT ITER RESULT
+    return false;
+  }
+
   bytecodeSection().setStackDepth(savedDepthTemp);
   if (!ifReturnDone.emitEnd()) {
     return false;
   }
 
   if (!ifReturnMethodIsDefined.emitElse()) {
     //              [stack] NEXT ITER RESULT FTYPE FVALUE ITER RET
     return false;
@@ -6649,33 +6646,38 @@ bool BytecodeEmitter::emitYieldStar(Pars
   if (!emitJumpTargetAndPatch(checkResult)) {
     //              [stack] NEXT ITER RESULT
     //              [stack] # checkResult:
     return false;
   }
 
   //                [stack] NEXT ITER RESULT
 
-  // if (!result.done) goto tryStart;
+  // if (result.done) break;
   if (!emit1(JSOP_DUP)) {
     //              [stack] NEXT ITER RESULT RESULT
     return false;
   }
   if (!emitAtomOp(cx->names().done, JSOP_GETPROP)) {
     //              [stack] NEXT ITER RESULT DONE
     return false;
   }
-  // if (!DONE) goto tryStart;
-  {
-    JumpList beq;
-    JumpTarget breakTarget;
-    if (!emitBackwardJump(JSOP_IFEQ, tryStart, &beq, &breakTarget)) {
-      //            [stack] NEXT ITER RESULT
-      return false;
-    }
+  if (!emitJump(JSOP_IFNE, &loopInfo.breaks)) {
+    //              [stack] NEXT ITER RESULT
+    return false;
+  }
+
+  if (!loopInfo.emitContinueTarget(this)) {
+    //              [stack] NEXT ITER RESULT
+    return false;
+  }
+
+  if (!loopInfo.emitLoopEnd(this, JSOP_GOTO, JSTRY_LOOP)) {
+    //              [stack] NEXT ITER RESULT
+    return false;
   }
 
   // result.value
   if (!emit2(JSOP_UNPICK, 2)) {
     //              [stack] RESULT NEXT ITER
     return false;
   }
   if (!emitPopN(2)) {
--- a/js/src/frontend/SharedContext.h
+++ b/js/src/frontend/SharedContext.h
@@ -38,23 +38,25 @@ enum class StatementKind : uint8_t {
   ForLoop,
   ForInLoop,
   ForOfLoop,
   DoLoop,
   WhileLoop,
   Class,
 
   // Used only by BytecodeEmitter.
-  Spread
+  Spread,
+  YieldStar,
 };
 
 static inline bool StatementKindIsLoop(StatementKind kind) {
   return kind == StatementKind::ForLoop || kind == StatementKind::ForInLoop ||
          kind == StatementKind::ForOfLoop || kind == StatementKind::DoLoop ||
-         kind == StatementKind::WhileLoop || kind == StatementKind::Spread;
+         kind == StatementKind::WhileLoop || kind == StatementKind::Spread ||
+         kind == StatementKind::YieldStar;
 }
 
 static inline bool StatementKindIsUnlabeledBreakTarget(StatementKind kind) {
   return StatementKindIsLoop(kind) || kind == StatementKind::Switch;
 }
 
 // List of directives that may be encountered in a Directive Prologue
 // (ES5 15.1).