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

Unified Diff: src/interpreter/bytecode-generator.cc

Issue 1502243002: [Interpreter] Local flow control in the bytecode graph builder. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Incorporate comments by mstarzinger on patchet 10. Created 5 years 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
« no previous file with comments | « src/interpreter/bytecode-array-iterator.cc ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/interpreter/bytecode-generator.cc
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
index 96b513c8b065e14b13ab504e113d8fd6ab9387b0..22972537abcbccb0e72a702ba07e9e4eb12a011a 100644
--- a/src/interpreter/bytecode-generator.cc
+++ b/src/interpreter/bytecode-generator.cc
@@ -628,14 +628,17 @@ void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
BytecodeLabel else_label, end_label;
if (stmt->condition()->ToBooleanIsTrue()) {
- // Generate only then block.
+ // Generate then block unconditionally as always true.
Visit(stmt->then_statement());
} else if (stmt->condition()->ToBooleanIsFalse()) {
- // Generate only else block if it exists.
+ // Generate else block unconditionally if it exists.
if (stmt->HasElseStatement()) {
Visit(stmt->else_statement());
}
} else {
+ // TODO(oth): If then statement is BreakStatement or
+ // ContinueStatement we can reduce number of generated
+ // jump/jump_ifs here. See BasicLoops test.
VisitForAccumulatorValue(stmt->condition());
builder()->JumpIfFalse(&else_label);
Visit(stmt->then_statement());
@@ -736,95 +739,70 @@ void BytecodeGenerator::VisitCaseClause(CaseClause* clause) {
void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
LoopBuilder loop_builder(builder());
ControlScopeForIteration execution_control(this, stmt, &loop_builder);
- BytecodeLabel body_label, condition_label, done_label;
+ loop_builder.LoopHeader();
if (stmt->cond()->ToBooleanIsFalse()) {
Visit(stmt->body());
- // Bind condition_label and done_label for processing continue and break.
- builder()->Bind(&condition_label);
- builder()->Bind(&done_label);
+ loop_builder.Condition();
+ } else if (stmt->cond()->ToBooleanIsTrue()) {
+ loop_builder.Condition();
+ Visit(stmt->body());
+ loop_builder.JumpToHeader();
} else {
- builder()->Bind(&body_label);
Visit(stmt->body());
-
- builder()->Bind(&condition_label);
- if (stmt->cond()->ToBooleanIsTrue()) {
- builder()->Jump(&body_label);
- } else {
- VisitForAccumulatorValue(stmt->cond());
- builder()->JumpIfTrue(&body_label);
- }
- builder()->Bind(&done_label);
+ loop_builder.Condition();
+ VisitForAccumulatorValue(stmt->cond());
+ loop_builder.JumpToHeaderIfTrue();
}
- loop_builder.SetBreakTarget(done_label);
- loop_builder.SetContinueTarget(condition_label);
+ loop_builder.LoopEnd();
}
void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
- LoopBuilder loop_builder(builder());
- ControlScopeForIteration execution_control(this, stmt, &loop_builder);
-
- BytecodeLabel body_label, condition_label, done_label;
if (stmt->cond()->ToBooleanIsFalse()) {
// If the condition is false there is no need to generate the loop.
return;
}
+ LoopBuilder loop_builder(builder());
+ ControlScopeForIteration execution_control(this, stmt, &loop_builder);
+ loop_builder.LoopHeader();
+ loop_builder.Condition();
if (!stmt->cond()->ToBooleanIsTrue()) {
- builder()->Jump(&condition_label);
- }
- builder()->Bind(&body_label);
- Visit(stmt->body());
-
- builder()->Bind(&condition_label);
- if (stmt->cond()->ToBooleanIsTrue()) {
- builder()->Jump(&body_label);
- } else {
VisitForAccumulatorValue(stmt->cond());
- builder()->JumpIfTrue(&body_label);
+ loop_builder.BreakIfFalse();
}
- builder()->Bind(&done_label);
-
- loop_builder.SetBreakTarget(done_label);
- loop_builder.SetContinueTarget(condition_label);
+ Visit(stmt->body());
+ loop_builder.JumpToHeader();
+ loop_builder.LoopEnd();
}
void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
- LoopBuilder loop_builder(builder());
- ControlScopeForIteration execution_control(this, stmt, &loop_builder);
-
if (stmt->init() != nullptr) {
Visit(stmt->init());
}
-
if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
// If the condition is known to be false there is no need to generate
// body, next or condition blocks. Init block should be generated.
return;
}
- BytecodeLabel body_label, condition_label, next_label, done_label;
+ LoopBuilder loop_builder(builder());
+ ControlScopeForIteration execution_control(this, stmt, &loop_builder);
+
+ loop_builder.LoopHeader();
+ loop_builder.Condition();
if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
- builder()->Jump(&condition_label);
+ VisitForAccumulatorValue(stmt->cond());
+ loop_builder.BreakIfFalse();
}
- builder()->Bind(&body_label);
Visit(stmt->body());
- builder()->Bind(&next_label);
if (stmt->next() != nullptr) {
+ loop_builder.Next();
Visit(stmt->next());
}
- if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
- builder()->Bind(&condition_label);
- VisitForAccumulatorValue(stmt->cond());
- builder()->JumpIfTrue(&body_label);
- } else {
- builder()->Jump(&body_label);
- }
- builder()->Bind(&done_label);
-
- loop_builder.SetBreakTarget(done_label);
- loop_builder.SetContinueTarget(next_label);
+ loop_builder.JumpToHeader();
+ loop_builder.LoopEnd();
}
@@ -898,42 +876,25 @@ void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Register for_in_state = execution_result()->NewRegister();
builder()->StoreAccumulatorInRegister(for_in_state);
- // The loop.
- BytecodeLabel condition_label, break_label, continue_label;
+ // Check loop termination (accumulator holds index).
Register index = receiver; // Re-using register as receiver no longer used.
builder()->LoadLiteral(Smi::FromInt(0));
-
- // Check loop termination (accumulator holds index).
- builder()
- ->Bind(&condition_label)
- .StoreAccumulatorInRegister(index)
- .ForInDone(for_in_state);
+ loop_builder.LoopHeader();
+ loop_builder.Condition();
+ builder()->StoreAccumulatorInRegister(index).ForInDone(for_in_state);
loop_builder.BreakIfTrue();
-
- // Get the next item.
builder()->ForInNext(for_in_state, index);
-
- // Start again if the item, currently in the accumulator, is undefined.
loop_builder.ContinueIfUndefined();
- // Store the value in the each variable.
VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot());
- // NB the user's loop variable will be assigned the value of each so
- // even an empty body will have this assignment.
Visit(stmt->body());
- // Increment the index and start loop again.
- builder()
- ->Bind(&continue_label)
- .LoadAccumulatorWithRegister(index)
- .CountOperation(Token::Value::ADD, language_mode_strength())
- .Jump(&condition_label);
-
- // End of the loop.
- builder()->Bind(&break_label);
-
- loop_builder.SetBreakTarget(break_label);
- loop_builder.SetContinueTarget(continue_label);
+ // TODO(oth): replace CountOperation here with ForInStep.
+ loop_builder.Next();
+ builder()->LoadAccumulatorWithRegister(index).CountOperation(
+ Token::Value::ADD, language_mode_strength());
+ loop_builder.JumpToHeader();
+ loop_builder.LoopEnd();
}
« no previous file with comments | « src/interpreter/bytecode-array-iterator.cc ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698