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

Unified Diff: src/compiler/ast-graph-builder.cc

Issue 890543002: [turbofan] Fix OSR compilations of for-in. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 11 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
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/graph-builder.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/ast-graph-builder.cc
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
index 7b62443ca1ecd0a59a450abef8371450bbd07683..ce9accc0432af3c69ed472c7502cc4b2fbe193a7 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -702,90 +702,9 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
environment()->Push(cache_array);
environment()->Push(cache_length);
environment()->Push(jsgraph()->ZeroConstant());
- // PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
- LoopBuilder for_loop(this);
- for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt),
- IsOsrLoopEntry(stmt));
- // Check loop termination condition.
- Node* index = environment()->Peek(0);
- Node* exit_cond =
- NewNode(javascript()->LessThan(), index, cache_length);
- // TODO(jarin): provide real bailout id.
- PrepareFrameState(exit_cond, BailoutId::None());
- for_loop.BreakUnless(exit_cond);
- // TODO(dcarney): this runtime call should be a handful of
- // simplified instructions that
- // basically produce
- // value = array[index]
- environment()->Push(obj);
- environment()->Push(cache_array);
- environment()->Push(cache_type);
- environment()->Push(index);
- Node* pair = ProcessArguments(
- javascript()->CallRuntime(Runtime::kForInNext, 4), 4);
- Node* value = NewNode(common()->Projection(0), pair);
- Node* should_filter = NewNode(common()->Projection(1), pair);
- environment()->Push(value);
- {
- // Test if FILTER_KEY needs to be called.
- IfBuilder test_should_filter(this);
- Node* should_filter_cond =
- NewNode(javascript()->StrictEqual(), should_filter,
- jsgraph()->TrueConstant());
- test_should_filter.If(should_filter_cond);
- test_should_filter.Then();
- value = environment()->Pop();
- Node* builtins = BuildLoadBuiltinsObject();
- Node* function = BuildLoadObjectField(
- builtins,
- JSBuiltinsObject::OffsetOfFunctionWithId(Builtins::FILTER_KEY));
- // Callee.
- environment()->Push(function);
- // Receiver.
- environment()->Push(obj);
- // Args.
- environment()->Push(value);
- // result is either the string key or Smi(0) indicating the property
- // is gone.
- Node* res = ProcessArguments(
- javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS), 3);
- // TODO(jarin): provide real bailout id.
- PrepareFrameState(res, BailoutId::None());
- Node* property_missing = NewNode(javascript()->StrictEqual(), res,
- jsgraph()->ZeroConstant());
- {
- IfBuilder is_property_missing(this);
- is_property_missing.If(property_missing);
- is_property_missing.Then();
- // Inc counter and continue.
- Node* index_inc =
- NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
- // TODO(jarin): provide real bailout id.
- PrepareFrameState(index_inc, BailoutId::None());
- environment()->Poke(0, index_inc);
- for_loop.Continue();
- is_property_missing.Else();
- is_property_missing.End();
- }
- // Replace 'value' in environment.
- environment()->Push(res);
- test_should_filter.Else();
- test_should_filter.End();
- }
- value = environment()->Pop();
- // Bind value and do loop body.
- VisitForInAssignment(stmt->each(), value, stmt->AssignmentId());
- VisitIterationBody(stmt, &for_loop, 5);
- for_loop.EndBody();
- // Inc counter and continue.
- Node* index_inc =
- NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
- // TODO(jarin): provide real bailout id.
- PrepareFrameState(index_inc, BailoutId::None());
- environment()->Poke(0, index_inc);
- for_loop.EndLoop();
- environment()->Drop(5);
- // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
+
+ // Build the actual loop body.
+ VisitForInBody(stmt);
}
have_no_properties.End();
}
@@ -795,6 +714,91 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
}
+// TODO(dcarney): this is a big function. Try to clean up some.
+void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) {
+ LoopBuilder for_loop(this);
+ for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt));
+
+ // These stack values are renamed in the case of OSR, so reload them
+ // from the environment.
+ Node* index = environment()->Peek(0);
+ Node* cache_length = environment()->Peek(1);
+ Node* cache_array = environment()->Peek(2);
+ Node* cache_type = environment()->Peek(3);
+ Node* obj = environment()->Peek(4);
+
+ // Check loop termination condition.
+ Node* exit_cond = NewNode(javascript()->LessThan(), index, cache_length);
+ // TODO(jarin): provide real bailout id.
+ PrepareFrameState(exit_cond, BailoutId::None());
+ for_loop.BreakUnless(exit_cond);
+ Node* pair = NewNode(javascript()->CallRuntime(Runtime::kForInNext, 4), obj,
+ cache_array, cache_type, index);
+ Node* value = NewNode(common()->Projection(0), pair);
+ Node* should_filter = NewNode(common()->Projection(1), pair);
+ environment()->Push(value);
+ {
+ // Test if FILTER_KEY needs to be called.
+ IfBuilder test_should_filter(this);
+ Node* should_filter_cond = NewNode(
+ javascript()->StrictEqual(), should_filter, jsgraph()->TrueConstant());
+ test_should_filter.If(should_filter_cond);
+ test_should_filter.Then();
+ value = environment()->Pop();
+ Node* builtins = BuildLoadBuiltinsObject();
+ Node* function = BuildLoadObjectField(
+ builtins,
+ JSBuiltinsObject::OffsetOfFunctionWithId(Builtins::FILTER_KEY));
+ // Callee.
+ environment()->Push(function);
+ // Receiver.
+ environment()->Push(obj);
+ // Args.
+ environment()->Push(value);
+ // result is either the string key or Smi(0) indicating the property
+ // is gone.
+ Node* res = ProcessArguments(
+ javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS), 3);
+ // TODO(jarin): provide real bailout id.
+ PrepareFrameState(res, BailoutId::None());
+ Node* property_missing =
+ NewNode(javascript()->StrictEqual(), res, jsgraph()->ZeroConstant());
+ {
+ IfBuilder is_property_missing(this);
+ is_property_missing.If(property_missing);
+ is_property_missing.Then();
+ // Inc counter and continue.
+ Node* index_inc =
+ NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
+ // TODO(jarin): provide real bailout id.
+ PrepareFrameState(index_inc, BailoutId::None());
+ environment()->Poke(0, index_inc);
+ for_loop.Continue();
+ is_property_missing.Else();
+ is_property_missing.End();
+ }
+ // Replace 'value' in environment.
+ environment()->Push(res);
+ test_should_filter.Else();
+ test_should_filter.End();
+ }
+ value = environment()->Pop();
+ // Bind value and do loop body.
+ VisitForInAssignment(stmt->each(), value, stmt->AssignmentId());
+ VisitIterationBody(stmt, &for_loop, 5);
+ for_loop.EndBody();
+ // Inc counter and continue.
+ Node* index_inc =
+ NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
+ // TODO(jarin): provide real bailout id.
+ PrepareFrameState(index_inc, BailoutId::None());
+ environment()->Poke(0, index_inc);
+ for_loop.EndLoop();
+ environment()->Drop(5);
+ // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
+}
+
+
void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
LoopBuilder for_loop(this);
VisitForEffect(stmt->assign_iterator());
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/graph-builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698