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

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 1398723002: [turbofan] Optimize stores to global properties. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address Jaro's comment. Created 5 years, 2 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 unified diff | Download patch
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/js-global-specialization.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/ast-graph-builder.h" 5 #include "src/compiler/ast-graph-builder.h"
6 6
7 #include "src/compiler.h" 7 #include "src/compiler.h"
8 #include "src/compiler/ast-loop-assignment-analyzer.h" 8 #include "src/compiler/ast-loop-assignment-analyzer.h"
9 #include "src/compiler/control-builders.h" 9 #include "src/compiler/control-builders.h"
10 #include "src/compiler/js-type-feedback.h" 10 #include "src/compiler/js-type-feedback.h"
(...skipping 1341 matching lines...) Expand 10 before | Expand all | Expand 10 after
1352 IfBuilder test_value(this); 1352 IfBuilder test_value(this);
1353 Node* test_value_cond = NewNode(javascript()->StrictEqual(), value, 1353 Node* test_value_cond = NewNode(javascript()->StrictEqual(), value,
1354 jsgraph()->UndefinedConstant()); 1354 jsgraph()->UndefinedConstant());
1355 test_value.If(test_value_cond, BranchHint::kFalse); 1355 test_value.If(test_value_cond, BranchHint::kFalse);
1356 test_value.Then(); 1356 test_value.Then();
1357 test_value.Else(); 1357 test_value.Else();
1358 { 1358 {
1359 // Bind value and do loop body. 1359 // Bind value and do loop body.
1360 VectorSlotPair feedback = 1360 VectorSlotPair feedback =
1361 CreateVectorSlotPair(stmt->EachFeedbackSlot()); 1361 CreateVectorSlotPair(stmt->EachFeedbackSlot());
1362 VisitForInAssignment(stmt->each(), value, feedback, 1362 VisitForInAssignment(stmt->each(), value, feedback, stmt->FilterId(),
1363 stmt->AssignmentId()); 1363 stmt->AssignmentId());
1364 VisitIterationBody(stmt, &for_loop); 1364 VisitIterationBody(stmt, &for_loop);
1365 } 1365 }
1366 test_value.End(); 1366 test_value.End();
1367 index = environment()->Peek(0); 1367 index = environment()->Peek(0);
1368 for_loop.EndBody(); 1368 for_loop.EndBody();
1369 1369
1370 // Increment counter and continue. 1370 // Increment counter and continue.
1371 index = NewNode(javascript()->ForInStep(), index); 1371 index = NewNode(javascript()->ForInStep(), index);
1372 environment()->Poke(0, index); 1372 environment()->Poke(0, index);
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after
1980 PrepareFrameState(result, expr->GetIdForElement(array_index)); 1980 PrepareFrameState(result, expr->GetIdForElement(array_index));
1981 environment()->Push(result); 1981 environment()->Push(result);
1982 } 1982 }
1983 1983
1984 ast_context()->ProduceValue(environment()->Pop()); 1984 ast_context()->ProduceValue(environment()->Pop());
1985 } 1985 }
1986 1986
1987 1987
1988 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, 1988 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value,
1989 const VectorSlotPair& feedback, 1989 const VectorSlotPair& feedback,
1990 BailoutId bailout_id) { 1990 BailoutId bailout_id_before,
1991 BailoutId bailout_id_after) {
1991 DCHECK(expr->IsValidReferenceExpressionOrThis()); 1992 DCHECK(expr->IsValidReferenceExpressionOrThis());
1992 1993
1993 // Left-hand side can only be a property, a global or a variable slot. 1994 // Left-hand side can only be a property, a global or a variable slot.
1994 Property* property = expr->AsProperty(); 1995 Property* property = expr->AsProperty();
1995 LhsKind assign_type = Property::GetAssignType(property); 1996 LhsKind assign_type = Property::GetAssignType(property);
1996 1997
1997 // Evaluate LHS expression and store the value. 1998 // Evaluate LHS expression and store the value.
1998 switch (assign_type) { 1999 switch (assign_type) {
1999 case VARIABLE: { 2000 case VARIABLE: {
2000 Variable* var = expr->AsVariableProxy()->var(); 2001 Variable* var = expr->AsVariableProxy()->var();
2001 FrameStateBeforeAndAfter states(this, BailoutId::None()); 2002 environment()->Push(value);
2002 BuildVariableAssignment(var, value, Token::ASSIGN, feedback, bailout_id, 2003 FrameStateBeforeAndAfter states(this, bailout_id_before);
2003 states); 2004 value = environment()->Pop();
2005 BuildVariableAssignment(var, value, Token::ASSIGN, feedback,
2006 bailout_id_after, states);
2004 break; 2007 break;
2005 } 2008 }
2006 case NAMED_PROPERTY: { 2009 case NAMED_PROPERTY: {
2007 environment()->Push(value); 2010 environment()->Push(value);
2008 VisitForValue(property->obj()); 2011 VisitForValue(property->obj());
2009 FrameStateBeforeAndAfter states(this, property->obj()->id()); 2012 FrameStateBeforeAndAfter states(this, property->obj()->id());
2010 Node* object = environment()->Pop(); 2013 Node* object = environment()->Pop();
2011 value = environment()->Pop(); 2014 value = environment()->Pop();
2012 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); 2015 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
2013 Node* store = BuildNamedStore(object, name, value, feedback, 2016 Node* store = BuildNamedStore(object, name, value, feedback,
2014 TypeFeedbackId::None()); 2017 TypeFeedbackId::None());
2015 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); 2018 states.AddToNode(store, bailout_id_after,
2019 OutputFrameStateCombine::Ignore());
2016 break; 2020 break;
2017 } 2021 }
2018 case KEYED_PROPERTY: { 2022 case KEYED_PROPERTY: {
2019 environment()->Push(value); 2023 environment()->Push(value);
2020 VisitForValue(property->obj()); 2024 VisitForValue(property->obj());
2021 VisitForValue(property->key()); 2025 VisitForValue(property->key());
2022 FrameStateBeforeAndAfter states(this, property->key()->id()); 2026 FrameStateBeforeAndAfter states(this, property->key()->id());
2023 Node* key = environment()->Pop(); 2027 Node* key = environment()->Pop();
2024 Node* object = environment()->Pop(); 2028 Node* object = environment()->Pop();
2025 value = environment()->Pop(); 2029 value = environment()->Pop();
2026 Node* store = 2030 Node* store =
2027 BuildKeyedStore(object, key, value, feedback, TypeFeedbackId::None()); 2031 BuildKeyedStore(object, key, value, feedback, TypeFeedbackId::None());
2028 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); 2032 states.AddToNode(store, bailout_id_after,
2033 OutputFrameStateCombine::Ignore());
2029 break; 2034 break;
2030 } 2035 }
2031 case NAMED_SUPER_PROPERTY: { 2036 case NAMED_SUPER_PROPERTY: {
2032 environment()->Push(value); 2037 environment()->Push(value);
2033 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); 2038 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
2034 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); 2039 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
2035 FrameStateBeforeAndAfter states(this, property->obj()->id()); 2040 FrameStateBeforeAndAfter states(this, property->obj()->id());
2036 Node* home_object = environment()->Pop(); 2041 Node* home_object = environment()->Pop();
2037 Node* receiver = environment()->Pop(); 2042 Node* receiver = environment()->Pop();
2038 value = environment()->Pop(); 2043 value = environment()->Pop();
2039 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); 2044 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
2040 Node* store = BuildNamedSuperStore(receiver, home_object, name, value, 2045 Node* store = BuildNamedSuperStore(receiver, home_object, name, value,
2041 TypeFeedbackId::None()); 2046 TypeFeedbackId::None());
2042 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); 2047 states.AddToNode(store, bailout_id_after,
2048 OutputFrameStateCombine::Ignore());
2043 break; 2049 break;
2044 } 2050 }
2045 case KEYED_SUPER_PROPERTY: { 2051 case KEYED_SUPER_PROPERTY: {
2046 environment()->Push(value); 2052 environment()->Push(value);
2047 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); 2053 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
2048 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); 2054 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
2049 VisitForValue(property->key()); 2055 VisitForValue(property->key());
2050 FrameStateBeforeAndAfter states(this, property->key()->id()); 2056 FrameStateBeforeAndAfter states(this, property->key()->id());
2051 Node* key = environment()->Pop(); 2057 Node* key = environment()->Pop();
2052 Node* home_object = environment()->Pop(); 2058 Node* home_object = environment()->Pop();
2053 Node* receiver = environment()->Pop(); 2059 Node* receiver = environment()->Pop();
2054 value = environment()->Pop(); 2060 value = environment()->Pop();
2055 Node* store = BuildKeyedSuperStore(receiver, home_object, key, value, 2061 Node* store = BuildKeyedSuperStore(receiver, home_object, key, value,
2056 TypeFeedbackId::None()); 2062 TypeFeedbackId::None());
2057 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); 2063 states.AddToNode(store, bailout_id_after,
2064 OutputFrameStateCombine::Ignore());
2058 break; 2065 break;
2059 } 2066 }
2060 } 2067 }
2061 } 2068 }
2062 2069
2063 2070
2064 void AstGraphBuilder::VisitAssignment(Assignment* expr) { 2071 void AstGraphBuilder::VisitAssignment(Assignment* expr) {
2065 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); 2072 DCHECK(expr->target()->IsValidReferenceExpressionOrThis());
2066 2073
2067 // Left-hand side can only be a property, a global or a variable slot. 2074 // Left-hand side can only be a property, a global or a variable slot.
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after
2668 } 2675 }
2669 } 2676 }
2670 2677
2671 // Convert old value into a number. 2678 // Convert old value into a number.
2672 if (!is_strong(language_mode())) { 2679 if (!is_strong(language_mode())) {
2673 old_value = NewNode(javascript()->ToNumber(), old_value); 2680 old_value = NewNode(javascript()->ToNumber(), old_value);
2674 PrepareFrameState(old_value, expr->ToNumberId(), 2681 PrepareFrameState(old_value, expr->ToNumberId(),
2675 OutputFrameStateCombine::Push()); 2682 OutputFrameStateCombine::Push());
2676 } 2683 }
2677 2684
2678 // TODO(titzer): combine this framestate with the above?
2679 FrameStateBeforeAndAfter store_states(this, assign_type == KEYED_PROPERTY
2680 ? expr->ToNumberId()
2681 : BailoutId::None());
2682
2683 // Save result for postfix expressions at correct stack depth. 2685 // Save result for postfix expressions at correct stack depth.
2684 if (is_postfix) environment()->Poke(stack_depth, old_value); 2686 if (is_postfix) {
2687 environment()->Poke(stack_depth, old_value);
2688 } else {
2689 environment()->Push(old_value);
2690 }
2691 // TODO(bmeurer): This might not match the fullcodegen in case of non VARIABLE
2692 // eager deoptimization; we will figure out when we get there.
2693 FrameStateBeforeAndAfter store_states(this, expr->ToNumberId());
2694 if (!is_postfix) old_value = environment()->Pop();
2685 2695
2686 // Create node to perform +1/-1 operation. 2696 // Create node to perform +1/-1 operation.
2687 Node* value; 2697 Node* value;
2688 { 2698 {
2689 FrameStateBeforeAndAfter states(this, BailoutId::None()); 2699 FrameStateBeforeAndAfter states(this, BailoutId::None());
2690 value = 2700 value =
2691 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); 2701 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op());
2692 // This should never deoptimize outside strong mode because otherwise we 2702 // This should never deoptimize outside strong mode because otherwise we
2693 // have converted to number before. 2703 // have converted to number before.
2694 states.AddToNode(value, is_strong(language_mode()) ? expr->ToNumberId() 2704 states.AddToNode(value, is_strong(language_mode()) ? expr->ToNumberId()
(...skipping 1583 matching lines...) Expand 10 before | Expand all | Expand 10 after
4278 // Phi does not exist yet, introduce one. 4288 // Phi does not exist yet, introduce one.
4279 value = NewPhi(inputs, value, control); 4289 value = NewPhi(inputs, value, control);
4280 value->ReplaceInput(inputs - 1, other); 4290 value->ReplaceInput(inputs - 1, other);
4281 } 4291 }
4282 return value; 4292 return value;
4283 } 4293 }
4284 4294
4285 } // namespace compiler 4295 } // namespace compiler
4286 } // namespace internal 4296 } // namespace internal
4287 } // namespace v8 4297 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/js-global-specialization.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698