Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1564)

Unified Diff: src/interpreter/control-flow-builders.cc

Issue 1901713003: [generators] Perform state dispatch in loop header. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/interpreter/control-flow-builders.cc
diff --git a/src/interpreter/control-flow-builders.cc b/src/interpreter/control-flow-builders.cc
index 6510aa443aaa2a605989865596cc8227406d3a48..2cd2ba790fb343b5bd4e831d2d150246d349b4ee 100644
--- a/src/interpreter/control-flow-builders.cc
+++ b/src/interpreter/control-flow-builders.cc
@@ -97,6 +97,48 @@ void LoopBuilder::LoopHeader() {
// and misplaced between the headers.
DCHECK(break_sites_.empty() && continue_sites_.empty());
builder()->Bind(&loop_header_);
+
+ if (yield_count > 0) {
+ // Special treatment for loops containing yields (in generator functions).
+
+ // Bind all labels for resume points within the loop to the loop header.
+ // Also create fresh labels for these resume points, to be used inside the
+ // loop.
+ auto& resume_points = builder()->generator_resume_points;
+ int yields_seen = builder()->generator_yields_seen();
+ for (int id = yields_seen; id < yields_seen + yield_count; id++) {
+ DCHECK(0 <= id && id < resume_points.size());
+ builder()->Bind(loop_header_, &(resume_points[id]));
+ resume_points[id] = BytecodeLabel();
+ }
+
+ Register state = Register::new_target(); // HACK
+
+ // If we are not resuming, fall through to loop body.
+ // If we are resuming, perform state dispatch.
+ BytecodeLabel not_resuming;
+ builder()
+ ->LoadLiteral(Smi::FromInt(yields_seen))
+ .CompareOperation(Token::Value::LT, state)
+ .JumpIfTrue(&not_resuming)
+ .IndexedJump(state, yields_seen, yield_count, resume_points)
+ .Bind(&not_resuming);
rmcilroy 2016/04/19 09:30:03 I really think this logic should live in the bytec
neis 2016/04/19 11:02:15 See my comments below.
+ }
+}
+
+
+void LoopBuilder::JumpToHeader() {
+ if (yield_count > 0) {
+ // Special treatment for loops containing yields (in generator functions).
+ // Before jumping back to the loop header, set state to something that
+ // will cause the next iteration to "not resume", i.e. to start from the
+ // beginning.
+ Register state = Register::new_target(); // HACK
+ builder()
+ ->LoadLiteral(Smi::FromInt(-1))
+ .StoreAccumulatorInRegister(state);
rmcilroy 2016/04/19 09:30:03 Could we instead set the resume value to -1 at the
neis 2016/04/19 11:02:15 There is no "final" yield. Eg.: while (...) { .
rmcilroy 2016/04/19 11:14:26 Both of these are different yield points though, r
Jarin 2016/04/25 09:50:37 Indeed, I thought we set the state to -1 after the
+ }
+ builder()->Jump(&loop_header_);
}
« src/interpreter/bytecode-generator.cc ('K') | « src/interpreter/control-flow-builders.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698