OLD | NEW |
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/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
9 #include "src/compiler/ast-loop-assignment-analyzer.h" | 9 #include "src/compiler/ast-loop-assignment-analyzer.h" |
10 #include "src/compiler/control-builders.h" | 10 #include "src/compiler/control-builders.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 | 33 |
34 // Determines how to combine the frame state with the value | 34 // Determines how to combine the frame state with the value |
35 // that is about to be plugged into this AstContext. | 35 // that is about to be plugged into this AstContext. |
36 OutputFrameStateCombine GetStateCombine() { | 36 OutputFrameStateCombine GetStateCombine() { |
37 return IsEffect() ? OutputFrameStateCombine::Ignore() | 37 return IsEffect() ? OutputFrameStateCombine::Ignore() |
38 : OutputFrameStateCombine::Push(); | 38 : OutputFrameStateCombine::Push(); |
39 } | 39 } |
40 | 40 |
41 // Plug a node into this expression context. Call this function in tail | 41 // Plug a node into this expression context. Call this function in tail |
42 // position in the Visit functions for expressions. | 42 // position in the Visit functions for expressions. |
43 virtual void ProduceValue(Expression* expr, Node* value) = 0; | 43 virtual void ProduceValue(Node* value) = 0; |
44 | 44 |
45 // Unplugs a node from this expression context. Call this to retrieve the | 45 // Unplugs a node from this expression context. Call this to retrieve the |
46 // result of another Visit function that already plugged the context. | 46 // result of another Visit function that already plugged the context. |
47 virtual Node* ConsumeValue() = 0; | 47 virtual Node* ConsumeValue() = 0; |
48 | 48 |
49 // Shortcut for "context->ProduceValue(context->ConsumeValue())". | 49 // Shortcut for "context->ProduceValue(context->ConsumeValue())". |
50 void ReplaceValue(Expression* expr) { ProduceValue(expr, ConsumeValue()); } | 50 void ReplaceValue() { ProduceValue(ConsumeValue()); } |
51 | 51 |
52 protected: | 52 protected: |
53 AstContext(AstGraphBuilder* owner, Expression::Context kind); | 53 AstContext(AstGraphBuilder* owner, Expression::Context kind); |
54 virtual ~AstContext(); | 54 virtual ~AstContext(); |
55 | 55 |
56 AstGraphBuilder* owner() const { return owner_; } | 56 AstGraphBuilder* owner() const { return owner_; } |
57 Environment* environment() const { return owner_->environment(); } | 57 Environment* environment() const { return owner_->environment(); } |
58 | 58 |
59 // We want to be able to assert, in a context-specific way, that the stack | 59 // We want to be able to assert, in a context-specific way, that the stack |
60 // height makes sense when the context is filled. | 60 // height makes sense when the context is filled. |
61 #ifdef DEBUG | 61 #ifdef DEBUG |
62 int original_height_; | 62 int original_height_; |
63 #endif | 63 #endif |
64 | 64 |
65 private: | 65 private: |
66 Expression::Context kind_; | 66 Expression::Context kind_; |
67 AstGraphBuilder* owner_; | 67 AstGraphBuilder* owner_; |
68 AstContext* outer_; | 68 AstContext* outer_; |
69 }; | 69 }; |
70 | 70 |
71 | 71 |
72 // Context to evaluate expression for its side effects only. | 72 // Context to evaluate expression for its side effects only. |
73 class AstGraphBuilder::AstEffectContext final : public AstContext { | 73 class AstGraphBuilder::AstEffectContext final : public AstContext { |
74 public: | 74 public: |
75 explicit AstEffectContext(AstGraphBuilder* owner) | 75 explicit AstEffectContext(AstGraphBuilder* owner) |
76 : AstContext(owner, Expression::kEffect) {} | 76 : AstContext(owner, Expression::kEffect) {} |
77 ~AstEffectContext() final; | 77 ~AstEffectContext() final; |
78 void ProduceValue(Expression* expr, Node* value) final; | 78 void ProduceValue(Node* value) final; |
79 Node* ConsumeValue() final; | 79 Node* ConsumeValue() final; |
80 }; | 80 }; |
81 | 81 |
82 | 82 |
83 // Context to evaluate expression for its value (and side effects). | 83 // Context to evaluate expression for its value (and side effects). |
84 class AstGraphBuilder::AstValueContext final : public AstContext { | 84 class AstGraphBuilder::AstValueContext final : public AstContext { |
85 public: | 85 public: |
86 explicit AstValueContext(AstGraphBuilder* owner) | 86 explicit AstValueContext(AstGraphBuilder* owner) |
87 : AstContext(owner, Expression::kValue) {} | 87 : AstContext(owner, Expression::kValue) {} |
88 ~AstValueContext() final; | 88 ~AstValueContext() final; |
89 void ProduceValue(Expression* expr, Node* value) final; | 89 void ProduceValue(Node* value) final; |
90 Node* ConsumeValue() final; | 90 Node* ConsumeValue() final; |
91 }; | 91 }; |
92 | 92 |
93 | 93 |
94 // Context to evaluate expression for a condition value (and side effects). | 94 // Context to evaluate expression for a condition value (and side effects). |
95 class AstGraphBuilder::AstTestContext final : public AstContext { | 95 class AstGraphBuilder::AstTestContext final : public AstContext { |
96 public: | 96 public: |
97 AstTestContext(AstGraphBuilder* owner, TypeFeedbackId feedback_id) | 97 AstTestContext(AstGraphBuilder* owner, TypeFeedbackId feedback_id) |
98 : AstContext(owner, Expression::kTest), feedback_id_(feedback_id) {} | 98 : AstContext(owner, Expression::kTest), feedback_id_(feedback_id) {} |
99 ~AstTestContext() final; | 99 ~AstTestContext() final; |
100 void ProduceValue(Expression* expr, Node* value) final; | 100 void ProduceValue(Node* value) final; |
101 Node* ConsumeValue() final; | 101 Node* ConsumeValue() final; |
102 | 102 |
103 private: | 103 private: |
104 TypeFeedbackId const feedback_id_; | 104 TypeFeedbackId const feedback_id_; |
105 }; | 105 }; |
106 | 106 |
107 | 107 |
108 // Scoped class tracking context objects created by the visitor. Represents | 108 // Scoped class tracking context objects created by the visitor. Represents |
109 // mutations of the context chain within the function body and allows to | 109 // mutations of the context chain within the function body and allows to |
110 // change the current {scope} and {context} during visitation. | 110 // change the current {scope} and {context} during visitation. |
(...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
961 | 961 |
962 AstGraphBuilder::AstValueContext::~AstValueContext() { | 962 AstGraphBuilder::AstValueContext::~AstValueContext() { |
963 DCHECK(environment()->stack_height() == original_height_ + 1); | 963 DCHECK(environment()->stack_height() == original_height_ + 1); |
964 } | 964 } |
965 | 965 |
966 | 966 |
967 AstGraphBuilder::AstTestContext::~AstTestContext() { | 967 AstGraphBuilder::AstTestContext::~AstTestContext() { |
968 DCHECK(environment()->stack_height() == original_height_ + 1); | 968 DCHECK(environment()->stack_height() == original_height_ + 1); |
969 } | 969 } |
970 | 970 |
971 void AstGraphBuilder::AstEffectContext::ProduceValue(Expression* expr, | 971 |
972 Node* value) { | 972 void AstGraphBuilder::AstEffectContext::ProduceValue(Node* value) { |
973 // The value is ignored. | 973 // The value is ignored. |
974 owner()->PrepareEagerCheckpoint(expr->id()); | |
975 } | |
976 | |
977 void AstGraphBuilder::AstValueContext::ProduceValue(Expression* expr, | |
978 Node* value) { | |
979 environment()->Push(value); | |
980 owner()->PrepareEagerCheckpoint(expr->id()); | |
981 } | |
982 | |
983 void AstGraphBuilder::AstTestContext::ProduceValue(Expression* expr, | |
984 Node* value) { | |
985 environment()->Push(owner()->BuildToBoolean(value, feedback_id_)); | |
986 owner()->PrepareEagerCheckpoint(expr->id()); | |
987 } | 974 } |
988 | 975 |
989 | 976 |
| 977 void AstGraphBuilder::AstValueContext::ProduceValue(Node* value) { |
| 978 environment()->Push(value); |
| 979 } |
| 980 |
| 981 |
| 982 void AstGraphBuilder::AstTestContext::ProduceValue(Node* value) { |
| 983 environment()->Push(owner()->BuildToBoolean(value, feedback_id_)); |
| 984 } |
| 985 |
| 986 |
990 Node* AstGraphBuilder::AstEffectContext::ConsumeValue() { return nullptr; } | 987 Node* AstGraphBuilder::AstEffectContext::ConsumeValue() { return nullptr; } |
991 | 988 |
992 | 989 |
993 Node* AstGraphBuilder::AstValueContext::ConsumeValue() { | 990 Node* AstGraphBuilder::AstValueContext::ConsumeValue() { |
994 return environment()->Pop(); | 991 return environment()->Pop(); |
995 } | 992 } |
996 | 993 |
997 | 994 |
998 Node* AstGraphBuilder::AstTestContext::ConsumeValue() { | 995 Node* AstGraphBuilder::AstTestContext::ConsumeValue() { |
999 return environment()->Pop(); | 996 return environment()->Pop(); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1067 VisitForValue(exprs->at(i)); | 1064 VisitForValue(exprs->at(i)); |
1068 } | 1065 } |
1069 } | 1066 } |
1070 | 1067 |
1071 | 1068 |
1072 void AstGraphBuilder::VisitForValue(Expression* expr) { | 1069 void AstGraphBuilder::VisitForValue(Expression* expr) { |
1073 AstValueContext for_value(this); | 1070 AstValueContext for_value(this); |
1074 if (!CheckStackOverflow()) { | 1071 if (!CheckStackOverflow()) { |
1075 expr->Accept(this); | 1072 expr->Accept(this); |
1076 } else { | 1073 } else { |
1077 ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant()); | 1074 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); |
1078 } | 1075 } |
1079 } | 1076 } |
1080 | 1077 |
1081 | 1078 |
1082 void AstGraphBuilder::VisitForEffect(Expression* expr) { | 1079 void AstGraphBuilder::VisitForEffect(Expression* expr) { |
1083 AstEffectContext for_effect(this); | 1080 AstEffectContext for_effect(this); |
1084 if (!CheckStackOverflow()) { | 1081 if (!CheckStackOverflow()) { |
1085 expr->Accept(this); | 1082 expr->Accept(this); |
1086 } else { | 1083 } else { |
1087 ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant()); | 1084 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); |
1088 } | 1085 } |
1089 } | 1086 } |
1090 | 1087 |
1091 | 1088 |
1092 void AstGraphBuilder::VisitForTest(Expression* expr) { | 1089 void AstGraphBuilder::VisitForTest(Expression* expr) { |
1093 AstTestContext for_condition(this, expr->test_id()); | 1090 AstTestContext for_condition(this, expr->test_id()); |
1094 if (!CheckStackOverflow()) { | 1091 if (!CheckStackOverflow()) { |
1095 expr->Accept(this); | 1092 expr->Accept(this); |
1096 } else { | 1093 } else { |
1097 ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant()); | 1094 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); |
1098 } | 1095 } |
1099 } | 1096 } |
1100 | 1097 |
1101 | 1098 |
1102 void AstGraphBuilder::Visit(Expression* expr) { | 1099 void AstGraphBuilder::Visit(Expression* expr) { |
1103 // Reuses enclosing AstContext. | 1100 // Reuses enclosing AstContext. |
1104 if (!CheckStackOverflow()) { | 1101 if (!CheckStackOverflow()) { |
1105 expr->Accept(this); | 1102 expr->Accept(this); |
1106 } else { | 1103 } else { |
1107 ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant()); | 1104 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); |
1108 } | 1105 } |
1109 } | 1106 } |
1110 | 1107 |
1111 | 1108 |
1112 void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) { | 1109 void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) { |
1113 Variable* variable = decl->proxy()->var(); | 1110 Variable* variable = decl->proxy()->var(); |
1114 VariableMode mode = decl->mode(); | 1111 VariableMode mode = decl->mode(); |
1115 bool hole_init = mode == CONST || mode == LET; | 1112 bool hole_init = mode == CONST || mode == LET; |
1116 switch (variable->location()) { | 1113 switch (variable->location()) { |
1117 case VariableLocation::GLOBAL: | 1114 case VariableLocation::GLOBAL: |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1434 PrepareFrameState(value, stmt->FilterId(), | 1431 PrepareFrameState(value, stmt->FilterId(), |
1435 OutputFrameStateCombine::Push()); | 1432 OutputFrameStateCombine::Push()); |
1436 IfBuilder test_value(this); | 1433 IfBuilder test_value(this); |
1437 Node* test_value_cond = | 1434 Node* test_value_cond = |
1438 NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), | 1435 NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), |
1439 value, jsgraph()->UndefinedConstant()); | 1436 value, jsgraph()->UndefinedConstant()); |
1440 test_value.If(test_value_cond, BranchHint::kFalse); | 1437 test_value.If(test_value_cond, BranchHint::kFalse); |
1441 test_value.Then(); | 1438 test_value.Then(); |
1442 test_value.Else(); | 1439 test_value.Else(); |
1443 { | 1440 { |
1444 environment()->Push(value); | |
1445 PrepareEagerCheckpoint(stmt->FilterId()); | |
1446 value = environment()->Pop(); | |
1447 // Bind value and do loop body. | 1441 // Bind value and do loop body. |
1448 VectorSlotPair feedback = | 1442 VectorSlotPair feedback = |
1449 CreateVectorSlotPair(stmt->EachFeedbackSlot()); | 1443 CreateVectorSlotPair(stmt->EachFeedbackSlot()); |
1450 VisitForInAssignment(stmt->each(), value, feedback, | 1444 VisitForInAssignment(stmt->each(), value, feedback, stmt->FilterId(), |
1451 stmt->AssignmentId()); | 1445 stmt->AssignmentId()); |
1452 VisitIterationBody(stmt, &for_loop); | 1446 VisitIterationBody(stmt, &for_loop); |
1453 } | 1447 } |
1454 test_value.End(); | 1448 test_value.End(); |
1455 for_loop.EndBody(); | 1449 for_loop.EndBody(); |
1456 | 1450 |
1457 // Increment counter and continue. | 1451 // Increment counter and continue. |
1458 index = environment()->Peek(0); | 1452 index = environment()->Peek(0); |
1459 index = NewNode(javascript()->ForInStep(), index); | 1453 index = NewNode(javascript()->ForInStep(), index); |
1460 environment()->Poke(0, index); | 1454 environment()->Poke(0, index); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1588 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { | 1582 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { |
1589 // Find or build a shared function info. | 1583 // Find or build a shared function info. |
1590 Handle<SharedFunctionInfo> shared_info = | 1584 Handle<SharedFunctionInfo> shared_info = |
1591 Compiler::GetSharedFunctionInfo(expr, info()->script(), info()); | 1585 Compiler::GetSharedFunctionInfo(expr, info()->script(), info()); |
1592 CHECK(!shared_info.is_null()); // TODO(mstarzinger): Set stack overflow? | 1586 CHECK(!shared_info.is_null()); // TODO(mstarzinger): Set stack overflow? |
1593 | 1587 |
1594 // Create node to instantiate a new closure. | 1588 // Create node to instantiate a new closure. |
1595 PretenureFlag pretenure = expr->pretenure() ? TENURED : NOT_TENURED; | 1589 PretenureFlag pretenure = expr->pretenure() ? TENURED : NOT_TENURED; |
1596 const Operator* op = javascript()->CreateClosure(shared_info, pretenure); | 1590 const Operator* op = javascript()->CreateClosure(shared_info, pretenure); |
1597 Node* value = NewNode(op); | 1591 Node* value = NewNode(op); |
1598 ast_context()->ProduceValue(expr, value); | 1592 ast_context()->ProduceValue(value); |
1599 } | 1593 } |
1600 | 1594 |
1601 | 1595 |
1602 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { | 1596 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { |
1603 // Visit declarations and class literal in a block scope. | 1597 // Visit declarations and class literal in a block scope. |
1604 if (expr->scope()->ContextLocalCount() > 0) { | 1598 if (expr->scope()->ContextLocalCount() > 0) { |
1605 Node* context = BuildLocalBlockContext(expr->scope()); | 1599 Node* context = BuildLocalBlockContext(expr->scope()); |
1606 ContextScope scope(this, expr->scope(), context); | 1600 ContextScope scope(this, expr->scope(), context); |
1607 VisitDeclarations(expr->scope()->declarations()); | 1601 VisitDeclarations(expr->scope()->declarations()); |
1608 VisitClassLiteralContents(expr); | 1602 VisitClassLiteralContents(expr); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1703 | 1697 |
1704 // Assign to class variable. | 1698 // Assign to class variable. |
1705 if (expr->class_variable_proxy() != nullptr) { | 1699 if (expr->class_variable_proxy() != nullptr) { |
1706 Variable* var = expr->class_variable_proxy()->var(); | 1700 Variable* var = expr->class_variable_proxy()->var(); |
1707 VectorSlotPair feedback = CreateVectorSlotPair( | 1701 VectorSlotPair feedback = CreateVectorSlotPair( |
1708 expr->NeedsProxySlot() ? expr->ProxySlot() | 1702 expr->NeedsProxySlot() ? expr->ProxySlot() |
1709 : FeedbackVectorSlot::Invalid()); | 1703 : FeedbackVectorSlot::Invalid()); |
1710 BuildVariableAssignment(var, literal, Token::INIT, feedback, | 1704 BuildVariableAssignment(var, literal, Token::INIT, feedback, |
1711 BailoutId::None()); | 1705 BailoutId::None()); |
1712 } | 1706 } |
1713 ast_context()->ProduceValue(expr, literal); | 1707 ast_context()->ProduceValue(literal); |
1714 } | 1708 } |
1715 | 1709 |
1716 | 1710 |
1717 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { | 1711 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { |
1718 UNREACHABLE(); | 1712 UNREACHABLE(); |
1719 } | 1713 } |
1720 | 1714 |
1721 | 1715 |
1722 void AstGraphBuilder::VisitDoExpression(DoExpression* expr) { | 1716 void AstGraphBuilder::VisitDoExpression(DoExpression* expr) { |
1723 VisitBlock(expr->block()); | 1717 VisitBlock(expr->block()); |
1724 VisitVariableProxy(expr->result()); | 1718 VisitVariableProxy(expr->result()); |
1725 ast_context()->ReplaceValue(expr); | 1719 ast_context()->ReplaceValue(); |
1726 } | 1720 } |
1727 | 1721 |
1728 | 1722 |
1729 void AstGraphBuilder::VisitConditional(Conditional* expr) { | 1723 void AstGraphBuilder::VisitConditional(Conditional* expr) { |
1730 IfBuilder compare_if(this); | 1724 IfBuilder compare_if(this); |
1731 VisitForTest(expr->condition()); | 1725 VisitForTest(expr->condition()); |
1732 Node* condition = environment()->Pop(); | 1726 Node* condition = environment()->Pop(); |
1733 compare_if.If(condition); | 1727 compare_if.If(condition); |
1734 compare_if.Then(); | 1728 compare_if.Then(); |
1735 Visit(expr->then_expression()); | 1729 Visit(expr->then_expression()); |
1736 compare_if.Else(); | 1730 compare_if.Else(); |
1737 Visit(expr->else_expression()); | 1731 Visit(expr->else_expression()); |
1738 compare_if.End(); | 1732 compare_if.End(); |
1739 // Skip plugging AST evaluation contexts of the test kind. This is to stay in | 1733 ast_context()->ReplaceValue(); |
1740 // sync with full codegen which doesn't prepare the proper bailout point (see | |
1741 // the implementation of FullCodeGenerator::VisitForControl). | |
1742 if (ast_context()->IsTest()) return; | |
1743 ast_context()->ReplaceValue(expr); | |
1744 } | 1734 } |
1745 | 1735 |
1746 | 1736 |
1747 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 1737 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
1748 VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot()); | 1738 VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot()); |
1749 PrepareEagerCheckpoint(BeforeId(expr)); | 1739 PrepareEagerCheckpoint(BeforeId(expr)); |
1750 Node* value = BuildVariableLoad(expr->var(), expr->id(), pair, | 1740 Node* value = BuildVariableLoad(expr->var(), expr->id(), pair, |
1751 ast_context()->GetStateCombine()); | 1741 ast_context()->GetStateCombine()); |
1752 ast_context()->ProduceValue(expr, value); | 1742 ast_context()->ProduceValue(value); |
1753 } | 1743 } |
1754 | 1744 |
1755 | 1745 |
1756 void AstGraphBuilder::VisitLiteral(Literal* expr) { | 1746 void AstGraphBuilder::VisitLiteral(Literal* expr) { |
1757 Node* value = jsgraph()->Constant(expr->value()); | 1747 Node* value = jsgraph()->Constant(expr->value()); |
1758 ast_context()->ProduceValue(expr, value); | 1748 ast_context()->ProduceValue(value); |
1759 } | 1749 } |
1760 | 1750 |
1761 | 1751 |
1762 void AstGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { | 1752 void AstGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { |
1763 Node* closure = GetFunctionClosure(); | 1753 Node* closure = GetFunctionClosure(); |
1764 | 1754 |
1765 // Create node to materialize a regular expression literal. | 1755 // Create node to materialize a regular expression literal. |
1766 const Operator* op = javascript()->CreateLiteralRegExp( | 1756 const Operator* op = javascript()->CreateLiteralRegExp( |
1767 expr->pattern(), expr->flags(), expr->literal_index()); | 1757 expr->pattern(), expr->flags(), expr->literal_index()); |
1768 Node* literal = NewNode(op, closure); | 1758 Node* literal = NewNode(op, closure); |
1769 PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine()); | 1759 PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine()); |
1770 ast_context()->ProduceValue(expr, literal); | 1760 ast_context()->ProduceValue(literal); |
1771 } | 1761 } |
1772 | 1762 |
1773 | 1763 |
1774 void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | 1764 void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
1775 Node* closure = GetFunctionClosure(); | 1765 Node* closure = GetFunctionClosure(); |
1776 | 1766 |
1777 // Create node to deep-copy the literal boilerplate. | 1767 // Create node to deep-copy the literal boilerplate. |
1778 const Operator* op = javascript()->CreateLiteralObject( | 1768 const Operator* op = javascript()->CreateLiteralObject( |
1779 expr->constant_properties(), expr->ComputeFlags(true), | 1769 expr->constant_properties(), expr->ComputeFlags(true), |
1780 expr->literal_index(), expr->properties_count()); | 1770 expr->literal_index(), expr->properties_count()); |
(...skipping 19 matching lines...) Expand all Loading... |
1800 UNREACHABLE(); | 1790 UNREACHABLE(); |
1801 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1791 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1802 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1792 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1803 // Fall through. | 1793 // Fall through. |
1804 case ObjectLiteral::Property::COMPUTED: { | 1794 case ObjectLiteral::Property::COMPUTED: { |
1805 // It is safe to use [[Put]] here because the boilerplate already | 1795 // It is safe to use [[Put]] here because the boilerplate already |
1806 // contains computed properties with an uninitialized value. | 1796 // contains computed properties with an uninitialized value. |
1807 if (key->value()->IsInternalizedString()) { | 1797 if (key->value()->IsInternalizedString()) { |
1808 if (property->emit_store()) { | 1798 if (property->emit_store()) { |
1809 VisitForValue(property->value()); | 1799 VisitForValue(property->value()); |
| 1800 PrepareEagerCheckpoint(property->value()->id()); |
1810 Node* value = environment()->Pop(); | 1801 Node* value = environment()->Pop(); |
1811 Node* literal = environment()->Top(); | 1802 Node* literal = environment()->Top(); |
1812 Handle<Name> name = key->AsPropertyName(); | 1803 Handle<Name> name = key->AsPropertyName(); |
1813 VectorSlotPair feedback = | 1804 VectorSlotPair feedback = |
1814 CreateVectorSlotPair(property->GetSlot(0)); | 1805 CreateVectorSlotPair(property->GetSlot(0)); |
1815 Node* store = BuildNamedStore(literal, name, value, feedback); | 1806 Node* store = BuildNamedStore(literal, name, value, feedback); |
1816 PrepareFrameState(store, key->id(), | 1807 PrepareFrameState(store, key->id(), |
1817 OutputFrameStateCombine::Ignore()); | 1808 OutputFrameStateCombine::Ignore()); |
1818 BuildSetHomeObject(value, literal, property, 1); | 1809 BuildSetHomeObject(value, literal, property, 1); |
1819 } else { | 1810 } else { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1945 Node* attr = jsgraph()->Constant(NONE); | 1936 Node* attr = jsgraph()->Constant(NONE); |
1946 const Operator* op = javascript()->CallRuntime( | 1937 const Operator* op = javascript()->CallRuntime( |
1947 Runtime::kDefineSetterPropertyUnchecked, 4); | 1938 Runtime::kDefineSetterPropertyUnchecked, 4); |
1948 Node* call = NewNode(op, receiver, key, value, attr); | 1939 Node* call = NewNode(op, receiver, key, value, attr); |
1949 PrepareFrameState(call, BailoutId::None()); | 1940 PrepareFrameState(call, BailoutId::None()); |
1950 break; | 1941 break; |
1951 } | 1942 } |
1952 } | 1943 } |
1953 } | 1944 } |
1954 | 1945 |
1955 ast_context()->ProduceValue(expr, environment()->Pop()); | 1946 ast_context()->ProduceValue(environment()->Pop()); |
1956 } | 1947 } |
1957 | 1948 |
1958 | 1949 |
1959 void AstGraphBuilder::VisitObjectLiteralAccessor( | 1950 void AstGraphBuilder::VisitObjectLiteralAccessor( |
1960 Node* home_object, ObjectLiteralProperty* property) { | 1951 Node* home_object, ObjectLiteralProperty* property) { |
1961 if (property == nullptr) { | 1952 if (property == nullptr) { |
1962 VisitForValueOrNull(nullptr); | 1953 VisitForValueOrNull(nullptr); |
1963 } else { | 1954 } else { |
1964 VisitForValue(property->value()); | 1955 VisitForValue(property->value()); |
1965 BuildSetHomeObject(environment()->Top(), home_object, property); | 1956 BuildSetHomeObject(environment()->Top(), home_object, property); |
(...skipping 18 matching lines...) Expand all Loading... |
1984 | 1975 |
1985 // Create nodes to evaluate all the non-constant subexpressions and to store | 1976 // Create nodes to evaluate all the non-constant subexpressions and to store |
1986 // them into the newly cloned array. | 1977 // them into the newly cloned array. |
1987 int array_index = 0; | 1978 int array_index = 0; |
1988 for (; array_index < expr->values()->length(); array_index++) { | 1979 for (; array_index < expr->values()->length(); array_index++) { |
1989 Expression* subexpr = expr->values()->at(array_index); | 1980 Expression* subexpr = expr->values()->at(array_index); |
1990 DCHECK(!subexpr->IsSpread()); | 1981 DCHECK(!subexpr->IsSpread()); |
1991 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 1982 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
1992 | 1983 |
1993 VisitForValue(subexpr); | 1984 VisitForValue(subexpr); |
1994 VectorSlotPair pair = CreateVectorSlotPair(expr->LiteralFeedbackSlot()); | 1985 { |
1995 Node* value = environment()->Pop(); | 1986 PrepareEagerCheckpoint(subexpr->id()); |
1996 Node* index = jsgraph()->Constant(array_index); | 1987 VectorSlotPair pair = CreateVectorSlotPair(expr->LiteralFeedbackSlot()); |
1997 Node* literal = environment()->Top(); | 1988 Node* value = environment()->Pop(); |
1998 Node* store = BuildKeyedStore(literal, index, value, pair); | 1989 Node* index = jsgraph()->Constant(array_index); |
1999 PrepareFrameState(store, expr->GetIdForElement(array_index), | 1990 Node* literal = environment()->Top(); |
2000 OutputFrameStateCombine::Ignore()); | 1991 Node* store = BuildKeyedStore(literal, index, value, pair); |
| 1992 PrepareFrameState(store, expr->GetIdForElement(array_index), |
| 1993 OutputFrameStateCombine::Ignore()); |
| 1994 } |
2001 } | 1995 } |
2002 | 1996 |
2003 // In case the array literal contains spread expressions it has two parts. The | 1997 // In case the array literal contains spread expressions it has two parts. The |
2004 // first part is the "static" array which has a literal index is handled | 1998 // first part is the "static" array which has a literal index is handled |
2005 // above. The second part is the part after the first spread expression | 1999 // above. The second part is the part after the first spread expression |
2006 // (inclusive) and these elements gets appended to the array. Note that the | 2000 // (inclusive) and these elements gets appended to the array. Note that the |
2007 // number elements an iterable produces is unknown ahead of time. | 2001 // number elements an iterable produces is unknown ahead of time. |
2008 for (; array_index < expr->values()->length(); array_index++) { | 2002 for (; array_index < expr->values()->length(); array_index++) { |
2009 Expression* subexpr = expr->values()->at(array_index); | 2003 Expression* subexpr = expr->values()->at(array_index); |
2010 DCHECK(!subexpr->IsSpread()); | 2004 DCHECK(!subexpr->IsSpread()); |
2011 | 2005 |
2012 VisitForValue(subexpr); | 2006 VisitForValue(subexpr); |
2013 { | 2007 { |
2014 Node* value = environment()->Pop(); | 2008 Node* value = environment()->Pop(); |
2015 Node* array = environment()->Pop(); | 2009 Node* array = environment()->Pop(); |
2016 const Operator* op = javascript()->CallRuntime(Runtime::kAppendElement); | 2010 const Operator* op = javascript()->CallRuntime(Runtime::kAppendElement); |
2017 Node* result = NewNode(op, array, value); | 2011 Node* result = NewNode(op, array, value); |
2018 PrepareFrameState(result, expr->GetIdForElement(array_index)); | 2012 PrepareFrameState(result, expr->GetIdForElement(array_index)); |
2019 environment()->Push(result); | 2013 environment()->Push(result); |
2020 } | 2014 } |
2021 } | 2015 } |
2022 | 2016 |
2023 ast_context()->ProduceValue(expr, environment()->Pop()); | 2017 ast_context()->ProduceValue(environment()->Pop()); |
2024 } | 2018 } |
2025 | 2019 |
| 2020 |
2026 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, | 2021 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, |
2027 const VectorSlotPair& feedback, | 2022 const VectorSlotPair& feedback, |
2028 BailoutId bailout_id) { | 2023 BailoutId bailout_id_before, |
| 2024 BailoutId bailout_id_after) { |
2029 DCHECK(expr->IsValidReferenceExpressionOrThis()); | 2025 DCHECK(expr->IsValidReferenceExpressionOrThis()); |
2030 | 2026 |
2031 // Left-hand side can only be a property, a global or a variable slot. | 2027 // Left-hand side can only be a property, a global or a variable slot. |
2032 Property* property = expr->AsProperty(); | 2028 Property* property = expr->AsProperty(); |
2033 LhsKind assign_type = Property::GetAssignType(property); | 2029 LhsKind assign_type = Property::GetAssignType(property); |
2034 | 2030 |
2035 // Evaluate LHS expression and store the value. | 2031 // Evaluate LHS expression and store the value. |
2036 switch (assign_type) { | 2032 switch (assign_type) { |
2037 case VARIABLE: { | 2033 case VARIABLE: { |
2038 Variable* var = expr->AsVariableProxy()->var(); | 2034 Variable* var = expr->AsVariableProxy()->var(); |
2039 BuildVariableAssignment(var, value, Token::ASSIGN, feedback, bailout_id); | 2035 environment()->Push(value); |
| 2036 PrepareEagerCheckpoint(bailout_id_before); |
| 2037 value = environment()->Pop(); |
| 2038 BuildVariableAssignment(var, value, Token::ASSIGN, feedback, |
| 2039 bailout_id_after); |
2040 break; | 2040 break; |
2041 } | 2041 } |
2042 case NAMED_PROPERTY: { | 2042 case NAMED_PROPERTY: { |
2043 environment()->Push(value); | 2043 environment()->Push(value); |
2044 VisitForValue(property->obj()); | 2044 VisitForValue(property->obj()); |
| 2045 PrepareEagerCheckpoint(property->obj()->id()); |
2045 Node* object = environment()->Pop(); | 2046 Node* object = environment()->Pop(); |
2046 value = environment()->Pop(); | 2047 value = environment()->Pop(); |
2047 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2048 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2048 Node* store = BuildNamedStore(object, name, value, feedback); | 2049 Node* store = BuildNamedStore(object, name, value, feedback); |
2049 PrepareFrameState(store, bailout_id, OutputFrameStateCombine::Ignore()); | 2050 PrepareFrameState(store, bailout_id_after, |
| 2051 OutputFrameStateCombine::Ignore()); |
2050 break; | 2052 break; |
2051 } | 2053 } |
2052 case KEYED_PROPERTY: { | 2054 case KEYED_PROPERTY: { |
2053 environment()->Push(value); | 2055 environment()->Push(value); |
2054 VisitForValue(property->obj()); | 2056 VisitForValue(property->obj()); |
2055 VisitForValue(property->key()); | 2057 VisitForValue(property->key()); |
| 2058 PrepareEagerCheckpoint(property->key()->id()); |
2056 Node* key = environment()->Pop(); | 2059 Node* key = environment()->Pop(); |
2057 Node* object = environment()->Pop(); | 2060 Node* object = environment()->Pop(); |
2058 value = environment()->Pop(); | 2061 value = environment()->Pop(); |
2059 Node* store = BuildKeyedStore(object, key, value, feedback); | 2062 Node* store = BuildKeyedStore(object, key, value, feedback); |
2060 PrepareFrameState(store, bailout_id, OutputFrameStateCombine::Ignore()); | 2063 PrepareFrameState(store, bailout_id_after, |
| 2064 OutputFrameStateCombine::Ignore()); |
2061 break; | 2065 break; |
2062 } | 2066 } |
2063 case NAMED_SUPER_PROPERTY: { | 2067 case NAMED_SUPER_PROPERTY: { |
2064 environment()->Push(value); | 2068 environment()->Push(value); |
2065 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2069 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
2066 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | 2070 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); |
| 2071 PrepareEagerCheckpoint(property->obj()->id()); |
2067 Node* home_object = environment()->Pop(); | 2072 Node* home_object = environment()->Pop(); |
2068 Node* receiver = environment()->Pop(); | 2073 Node* receiver = environment()->Pop(); |
2069 value = environment()->Pop(); | 2074 value = environment()->Pop(); |
2070 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2075 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2071 Node* store = BuildNamedSuperStore(receiver, home_object, name, value); | 2076 Node* store = BuildNamedSuperStore(receiver, home_object, name, value); |
2072 PrepareFrameState(store, bailout_id, OutputFrameStateCombine::Ignore()); | 2077 PrepareFrameState(store, bailout_id_after, |
| 2078 OutputFrameStateCombine::Ignore()); |
2073 break; | 2079 break; |
2074 } | 2080 } |
2075 case KEYED_SUPER_PROPERTY: { | 2081 case KEYED_SUPER_PROPERTY: { |
2076 environment()->Push(value); | 2082 environment()->Push(value); |
2077 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2083 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
2078 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | 2084 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); |
2079 VisitForValue(property->key()); | 2085 VisitForValue(property->key()); |
| 2086 PrepareEagerCheckpoint(property->key()->id()); |
2080 Node* key = environment()->Pop(); | 2087 Node* key = environment()->Pop(); |
2081 Node* home_object = environment()->Pop(); | 2088 Node* home_object = environment()->Pop(); |
2082 Node* receiver = environment()->Pop(); | 2089 Node* receiver = environment()->Pop(); |
2083 value = environment()->Pop(); | 2090 value = environment()->Pop(); |
2084 Node* store = BuildKeyedSuperStore(receiver, home_object, key, value); | 2091 Node* store = BuildKeyedSuperStore(receiver, home_object, key, value); |
2085 PrepareFrameState(store, bailout_id, OutputFrameStateCombine::Ignore()); | 2092 PrepareFrameState(store, bailout_id_after, |
| 2093 OutputFrameStateCombine::Ignore()); |
2086 break; | 2094 break; |
2087 } | 2095 } |
2088 } | 2096 } |
2089 } | 2097 } |
2090 | 2098 |
2091 | 2099 |
2092 void AstGraphBuilder::VisitAssignment(Assignment* expr) { | 2100 void AstGraphBuilder::VisitAssignment(Assignment* expr) { |
2093 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); | 2101 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); |
2094 | 2102 |
2095 // Left-hand side can only be a property, a global or a variable slot. | 2103 // Left-hand side can only be a property, a global or a variable slot. |
(...skipping 23 matching lines...) Expand all Loading... |
2119 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2127 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
2120 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | 2128 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); |
2121 break; | 2129 break; |
2122 case KEYED_SUPER_PROPERTY: | 2130 case KEYED_SUPER_PROPERTY: |
2123 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2131 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
2124 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | 2132 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); |
2125 VisitForValue(property->key()); | 2133 VisitForValue(property->key()); |
2126 break; | 2134 break; |
2127 } | 2135 } |
2128 | 2136 |
| 2137 BailoutId before_store_id = BailoutId::None(); |
2129 // Evaluate the value and potentially handle compound assignments by loading | 2138 // Evaluate the value and potentially handle compound assignments by loading |
2130 // the left-hand side value and performing a binary operation. | 2139 // the left-hand side value and performing a binary operation. |
2131 if (expr->is_compound()) { | 2140 if (expr->is_compound()) { |
2132 Node* old_value = nullptr; | 2141 Node* old_value = nullptr; |
2133 switch (assign_type) { | 2142 switch (assign_type) { |
2134 case VARIABLE: { | 2143 case VARIABLE: { |
2135 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 2144 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
2136 VectorSlotPair pair = | 2145 VectorSlotPair pair = |
2137 CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 2146 CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
2138 PrepareEagerCheckpoint(BeforeId(proxy)); | 2147 PrepareEagerCheckpoint(BeforeId(proxy)); |
2139 old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair, | 2148 old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair, |
2140 OutputFrameStateCombine::Push()); | 2149 OutputFrameStateCombine::Push()); |
2141 break; | 2150 break; |
2142 } | 2151 } |
2143 case NAMED_PROPERTY: { | 2152 case NAMED_PROPERTY: { |
2144 Node* object = environment()->Top(); | 2153 Node* object = environment()->Top(); |
2145 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2154 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2146 VectorSlotPair pair = | 2155 VectorSlotPair pair = |
2147 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2156 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
| 2157 PrepareEagerCheckpoint(property->obj()->id()); |
2148 old_value = BuildNamedLoad(object, name, pair); | 2158 old_value = BuildNamedLoad(object, name, pair); |
2149 PrepareFrameState(old_value, property->LoadId(), | 2159 PrepareFrameState(old_value, property->LoadId(), |
2150 OutputFrameStateCombine::Push()); | 2160 OutputFrameStateCombine::Push()); |
2151 break; | 2161 break; |
2152 } | 2162 } |
2153 case KEYED_PROPERTY: { | 2163 case KEYED_PROPERTY: { |
2154 Node* key = environment()->Top(); | 2164 Node* key = environment()->Top(); |
2155 Node* object = environment()->Peek(1); | 2165 Node* object = environment()->Peek(1); |
2156 VectorSlotPair pair = | 2166 VectorSlotPair pair = |
2157 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2167 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
| 2168 PrepareEagerCheckpoint(property->key()->id()); |
2158 old_value = BuildKeyedLoad(object, key, pair); | 2169 old_value = BuildKeyedLoad(object, key, pair); |
2159 PrepareFrameState(old_value, property->LoadId(), | 2170 PrepareFrameState(old_value, property->LoadId(), |
2160 OutputFrameStateCombine::Push()); | 2171 OutputFrameStateCombine::Push()); |
2161 break; | 2172 break; |
2162 } | 2173 } |
2163 case NAMED_SUPER_PROPERTY: { | 2174 case NAMED_SUPER_PROPERTY: { |
2164 Node* home_object = environment()->Top(); | 2175 Node* home_object = environment()->Top(); |
2165 Node* receiver = environment()->Peek(1); | 2176 Node* receiver = environment()->Peek(1); |
2166 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2177 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2167 VectorSlotPair pair = | 2178 VectorSlotPair pair = |
2168 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2179 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
| 2180 PrepareEagerCheckpoint(property->obj()->id()); |
2169 old_value = BuildNamedSuperLoad(receiver, home_object, name, pair); | 2181 old_value = BuildNamedSuperLoad(receiver, home_object, name, pair); |
2170 PrepareFrameState(old_value, property->LoadId(), | 2182 PrepareFrameState(old_value, property->LoadId(), |
2171 OutputFrameStateCombine::Push()); | 2183 OutputFrameStateCombine::Push()); |
2172 break; | 2184 break; |
2173 } | 2185 } |
2174 case KEYED_SUPER_PROPERTY: { | 2186 case KEYED_SUPER_PROPERTY: { |
2175 Node* key = environment()->Top(); | 2187 Node* key = environment()->Top(); |
2176 Node* home_object = environment()->Peek(1); | 2188 Node* home_object = environment()->Peek(1); |
2177 Node* receiver = environment()->Peek(2); | 2189 Node* receiver = environment()->Peek(2); |
2178 VectorSlotPair pair = | 2190 VectorSlotPair pair = |
2179 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2191 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
| 2192 PrepareEagerCheckpoint(property->key()->id()); |
2180 old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair); | 2193 old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair); |
2181 PrepareFrameState(old_value, property->LoadId(), | 2194 PrepareFrameState(old_value, property->LoadId(), |
2182 OutputFrameStateCombine::Push()); | 2195 OutputFrameStateCombine::Push()); |
2183 break; | 2196 break; |
2184 } | 2197 } |
2185 } | 2198 } |
2186 environment()->Push(old_value); | 2199 environment()->Push(old_value); |
2187 VisitForValue(expr->value()); | 2200 VisitForValue(expr->value()); |
2188 Node* value; | 2201 Node* value; |
2189 { | 2202 { |
2190 FrameStateBeforeAndAfter states(this, expr->value()->id()); | 2203 FrameStateBeforeAndAfter states(this, expr->value()->id()); |
2191 Node* right = environment()->Pop(); | 2204 Node* right = environment()->Pop(); |
2192 Node* left = environment()->Pop(); | 2205 Node* left = environment()->Pop(); |
2193 value = | 2206 value = |
2194 BuildBinaryOp(left, right, expr->binary_op(), | 2207 BuildBinaryOp(left, right, expr->binary_op(), |
2195 expr->binary_operation()->BinaryOperationFeedbackId()); | 2208 expr->binary_operation()->BinaryOperationFeedbackId()); |
2196 states.AddToNode(value, expr->binary_operation()->id(), | 2209 states.AddToNode(value, expr->binary_operation()->id(), |
2197 OutputFrameStateCombine::Push()); | 2210 OutputFrameStateCombine::Push()); |
2198 } | 2211 } |
2199 environment()->Push(value); | 2212 environment()->Push(value); |
2200 if (needs_frame_state_before) { | 2213 if (needs_frame_state_before) { |
2201 PrepareEagerCheckpoint(expr->binary_operation()->id()); | 2214 before_store_id = expr->binary_operation()->id(); |
2202 } | 2215 } |
2203 } else { | 2216 } else { |
2204 VisitForValue(expr->value()); | 2217 VisitForValue(expr->value()); |
| 2218 if (needs_frame_state_before) { |
| 2219 before_store_id = expr->value()->id(); |
| 2220 } |
2205 } | 2221 } |
2206 | 2222 |
2207 // Store the value. | 2223 // Store the value. |
| 2224 PrepareEagerCheckpoint(before_store_id); |
2208 Node* value = environment()->Pop(); | 2225 Node* value = environment()->Pop(); |
2209 VectorSlotPair feedback = CreateVectorSlotPair(expr->AssignmentSlot()); | 2226 VectorSlotPair feedback = CreateVectorSlotPair(expr->AssignmentSlot()); |
2210 switch (assign_type) { | 2227 switch (assign_type) { |
2211 case VARIABLE: { | 2228 case VARIABLE: { |
2212 Variable* variable = expr->target()->AsVariableProxy()->var(); | 2229 Variable* variable = expr->target()->AsVariableProxy()->var(); |
2213 BuildVariableAssignment(variable, value, expr->op(), feedback, expr->id(), | 2230 BuildVariableAssignment(variable, value, expr->op(), feedback, expr->id(), |
2214 ast_context()->GetStateCombine()); | 2231 ast_context()->GetStateCombine()); |
2215 break; | 2232 break; |
2216 } | 2233 } |
2217 case NAMED_PROPERTY: { | 2234 case NAMED_PROPERTY: { |
(...skipping 21 matching lines...) Expand all Loading... |
2239 case KEYED_SUPER_PROPERTY: { | 2256 case KEYED_SUPER_PROPERTY: { |
2240 Node* key = environment()->Pop(); | 2257 Node* key = environment()->Pop(); |
2241 Node* home_object = environment()->Pop(); | 2258 Node* home_object = environment()->Pop(); |
2242 Node* receiver = environment()->Pop(); | 2259 Node* receiver = environment()->Pop(); |
2243 Node* store = BuildKeyedSuperStore(receiver, home_object, key, value); | 2260 Node* store = BuildKeyedSuperStore(receiver, home_object, key, value); |
2244 PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine()); | 2261 PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine()); |
2245 break; | 2262 break; |
2246 } | 2263 } |
2247 } | 2264 } |
2248 | 2265 |
2249 ast_context()->ProduceValue(expr, value); | 2266 ast_context()->ProduceValue(value); |
2250 } | 2267 } |
2251 | 2268 |
2252 | 2269 |
2253 void AstGraphBuilder::VisitYield(Yield* expr) { | 2270 void AstGraphBuilder::VisitYield(Yield* expr) { |
2254 // Generator functions are supported only by going through Ignition first. | 2271 // Generator functions are supported only by going through Ignition first. |
2255 SetStackOverflow(); | 2272 SetStackOverflow(); |
2256 ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant()); | 2273 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); |
2257 } | 2274 } |
2258 | 2275 |
2259 | 2276 |
2260 void AstGraphBuilder::VisitThrow(Throw* expr) { | 2277 void AstGraphBuilder::VisitThrow(Throw* expr) { |
2261 VisitForValue(expr->exception()); | 2278 VisitForValue(expr->exception()); |
2262 Node* exception = environment()->Pop(); | 2279 Node* exception = environment()->Pop(); |
2263 Node* value = BuildThrowError(exception, expr->id()); | 2280 Node* value = BuildThrowError(exception, expr->id()); |
2264 ast_context()->ProduceValue(expr, value); | 2281 ast_context()->ProduceValue(value); |
2265 } | 2282 } |
2266 | 2283 |
2267 | 2284 |
2268 void AstGraphBuilder::VisitProperty(Property* expr) { | 2285 void AstGraphBuilder::VisitProperty(Property* expr) { |
2269 Node* value = nullptr; | 2286 Node* value = nullptr; |
2270 LhsKind property_kind = Property::GetAssignType(expr); | 2287 LhsKind property_kind = Property::GetAssignType(expr); |
2271 VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot()); | 2288 VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot()); |
2272 switch (property_kind) { | 2289 switch (property_kind) { |
2273 case VARIABLE: | 2290 case VARIABLE: |
2274 UNREACHABLE(); | 2291 UNREACHABLE(); |
2275 break; | 2292 break; |
2276 case NAMED_PROPERTY: { | 2293 case NAMED_PROPERTY: { |
2277 VisitForValue(expr->obj()); | 2294 VisitForValue(expr->obj()); |
| 2295 PrepareEagerCheckpoint(expr->obj()->id()); |
2278 Node* object = environment()->Pop(); | 2296 Node* object = environment()->Pop(); |
2279 Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); | 2297 Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); |
2280 value = BuildNamedLoad(object, name, pair); | 2298 value = BuildNamedLoad(object, name, pair); |
2281 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2299 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
2282 break; | 2300 break; |
2283 } | 2301 } |
2284 case KEYED_PROPERTY: { | 2302 case KEYED_PROPERTY: { |
2285 VisitForValue(expr->obj()); | 2303 VisitForValue(expr->obj()); |
2286 VisitForValue(expr->key()); | 2304 VisitForValue(expr->key()); |
| 2305 PrepareEagerCheckpoint(expr->key()->id()); |
2287 Node* key = environment()->Pop(); | 2306 Node* key = environment()->Pop(); |
2288 Node* object = environment()->Pop(); | 2307 Node* object = environment()->Pop(); |
2289 value = BuildKeyedLoad(object, key, pair); | 2308 value = BuildKeyedLoad(object, key, pair); |
2290 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2309 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
2291 break; | 2310 break; |
2292 } | 2311 } |
2293 case NAMED_SUPER_PROPERTY: { | 2312 case NAMED_SUPER_PROPERTY: { |
2294 VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2313 VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
2295 VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object()); | 2314 VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object()); |
| 2315 PrepareEagerCheckpoint(expr->obj()->id()); |
2296 Node* home_object = environment()->Pop(); | 2316 Node* home_object = environment()->Pop(); |
2297 Node* receiver = environment()->Pop(); | 2317 Node* receiver = environment()->Pop(); |
2298 Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); | 2318 Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); |
2299 value = BuildNamedSuperLoad(receiver, home_object, name, pair); | 2319 value = BuildNamedSuperLoad(receiver, home_object, name, pair); |
2300 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2320 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
2301 break; | 2321 break; |
2302 } | 2322 } |
2303 case KEYED_SUPER_PROPERTY: { | 2323 case KEYED_SUPER_PROPERTY: { |
2304 VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2324 VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
2305 VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object()); | 2325 VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object()); |
2306 VisitForValue(expr->key()); | 2326 VisitForValue(expr->key()); |
| 2327 PrepareEagerCheckpoint(expr->key()->id()); |
2307 Node* key = environment()->Pop(); | 2328 Node* key = environment()->Pop(); |
2308 Node* home_object = environment()->Pop(); | 2329 Node* home_object = environment()->Pop(); |
2309 Node* receiver = environment()->Pop(); | 2330 Node* receiver = environment()->Pop(); |
2310 value = BuildKeyedSuperLoad(receiver, home_object, key, pair); | 2331 value = BuildKeyedSuperLoad(receiver, home_object, key, pair); |
2311 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2332 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
2312 break; | 2333 break; |
2313 } | 2334 } |
2314 } | 2335 } |
2315 ast_context()->ProduceValue(expr, value); | 2336 ast_context()->ProduceValue(value); |
2316 } | 2337 } |
2317 | 2338 |
2318 | 2339 |
2319 void AstGraphBuilder::VisitCall(Call* expr) { | 2340 void AstGraphBuilder::VisitCall(Call* expr) { |
2320 Expression* callee = expr->expression(); | 2341 Expression* callee = expr->expression(); |
2321 Call::CallType call_type = expr->GetCallType(isolate()); | 2342 Call::CallType call_type = expr->GetCallType(isolate()); |
2322 | 2343 |
2323 // Prepare the callee and the receiver to the function call. This depends on | 2344 // Prepare the callee and the receiver to the function call. This depends on |
2324 // the semantics of the underlying call type. | 2345 // the semantics of the underlying call type. |
2325 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; | 2346 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; |
(...skipping 22 matching lines...) Expand all Loading... |
2348 receiver_value = NewNode(common()->Projection(1), pair); | 2369 receiver_value = NewNode(common()->Projection(1), pair); |
2349 PrepareFrameState(pair, expr->LookupId(), | 2370 PrepareFrameState(pair, expr->LookupId(), |
2350 OutputFrameStateCombine::Push(2)); | 2371 OutputFrameStateCombine::Push(2)); |
2351 break; | 2372 break; |
2352 } | 2373 } |
2353 case Call::NAMED_PROPERTY_CALL: { | 2374 case Call::NAMED_PROPERTY_CALL: { |
2354 Property* property = callee->AsProperty(); | 2375 Property* property = callee->AsProperty(); |
2355 VectorSlotPair feedback = | 2376 VectorSlotPair feedback = |
2356 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2377 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2357 VisitForValue(property->obj()); | 2378 VisitForValue(property->obj()); |
| 2379 PrepareEagerCheckpoint(property->obj()->id()); |
2358 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2380 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2359 Node* object = environment()->Top(); | 2381 Node* object = environment()->Top(); |
2360 callee_value = BuildNamedLoad(object, name, feedback); | 2382 callee_value = BuildNamedLoad(object, name, feedback); |
2361 PrepareFrameState(callee_value, property->LoadId(), | 2383 PrepareFrameState(callee_value, property->LoadId(), |
2362 OutputFrameStateCombine::Push()); | 2384 OutputFrameStateCombine::Push()); |
2363 // Note that a property call requires the receiver to be wrapped into | 2385 // Note that a property call requires the receiver to be wrapped into |
2364 // an object for sloppy callees. However the receiver is guaranteed | 2386 // an object for sloppy callees. However the receiver is guaranteed |
2365 // not to be null or undefined at this point. | 2387 // not to be null or undefined at this point. |
2366 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined; | 2388 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined; |
2367 receiver_value = environment()->Pop(); | 2389 receiver_value = environment()->Pop(); |
2368 break; | 2390 break; |
2369 } | 2391 } |
2370 case Call::KEYED_PROPERTY_CALL: { | 2392 case Call::KEYED_PROPERTY_CALL: { |
2371 Property* property = callee->AsProperty(); | 2393 Property* property = callee->AsProperty(); |
2372 VectorSlotPair feedback = | 2394 VectorSlotPair feedback = |
2373 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2395 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2374 VisitForValue(property->obj()); | 2396 VisitForValue(property->obj()); |
2375 VisitForValue(property->key()); | 2397 VisitForValue(property->key()); |
| 2398 PrepareEagerCheckpoint(property->key()->id()); |
2376 Node* key = environment()->Pop(); | 2399 Node* key = environment()->Pop(); |
2377 Node* object = environment()->Top(); | 2400 Node* object = environment()->Top(); |
2378 callee_value = BuildKeyedLoad(object, key, feedback); | 2401 callee_value = BuildKeyedLoad(object, key, feedback); |
2379 PrepareFrameState(callee_value, property->LoadId(), | 2402 PrepareFrameState(callee_value, property->LoadId(), |
2380 OutputFrameStateCombine::Push()); | 2403 OutputFrameStateCombine::Push()); |
2381 // Note that a property call requires the receiver to be wrapped into | 2404 // Note that a property call requires the receiver to be wrapped into |
2382 // an object for sloppy callees. However the receiver is guaranteed | 2405 // an object for sloppy callees. However the receiver is guaranteed |
2383 // not to be null or undefined at this point. | 2406 // not to be null or undefined at this point. |
2384 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined; | 2407 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined; |
2385 receiver_value = environment()->Pop(); | 2408 receiver_value = environment()->Pop(); |
2386 break; | 2409 break; |
2387 } | 2410 } |
2388 case Call::NAMED_SUPER_PROPERTY_CALL: { | 2411 case Call::NAMED_SUPER_PROPERTY_CALL: { |
2389 Property* property = callee->AsProperty(); | 2412 Property* property = callee->AsProperty(); |
2390 SuperPropertyReference* super_ref = | 2413 SuperPropertyReference* super_ref = |
2391 property->obj()->AsSuperPropertyReference(); | 2414 property->obj()->AsSuperPropertyReference(); |
2392 VisitForValue(super_ref->home_object()); | 2415 VisitForValue(super_ref->home_object()); |
2393 VisitForValue(super_ref->this_var()); | 2416 VisitForValue(super_ref->this_var()); |
2394 Node* home = environment()->Peek(1); | 2417 Node* home = environment()->Peek(1); |
2395 Node* object = environment()->Top(); | 2418 Node* object = environment()->Top(); |
2396 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2419 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
| 2420 PrepareEagerCheckpoint(property->obj()->id()); |
2397 callee_value = BuildNamedSuperLoad(object, home, name, VectorSlotPair()); | 2421 callee_value = BuildNamedSuperLoad(object, home, name, VectorSlotPair()); |
2398 PrepareFrameState(callee_value, property->LoadId(), | 2422 PrepareFrameState(callee_value, property->LoadId(), |
2399 OutputFrameStateCombine::Push()); | 2423 OutputFrameStateCombine::Push()); |
2400 // Note that a property call requires the receiver to be wrapped into | 2424 // Note that a property call requires the receiver to be wrapped into |
2401 // an object for sloppy callees. Since the receiver is not the target of | 2425 // an object for sloppy callees. Since the receiver is not the target of |
2402 // the load, it could very well be null or undefined at this point. | 2426 // the load, it could very well be null or undefined at this point. |
2403 receiver_value = environment()->Pop(); | 2427 receiver_value = environment()->Pop(); |
2404 environment()->Drop(1); | 2428 environment()->Drop(1); |
2405 break; | 2429 break; |
2406 } | 2430 } |
2407 case Call::KEYED_SUPER_PROPERTY_CALL: { | 2431 case Call::KEYED_SUPER_PROPERTY_CALL: { |
2408 Property* property = callee->AsProperty(); | 2432 Property* property = callee->AsProperty(); |
2409 SuperPropertyReference* super_ref = | 2433 SuperPropertyReference* super_ref = |
2410 property->obj()->AsSuperPropertyReference(); | 2434 property->obj()->AsSuperPropertyReference(); |
2411 VisitForValue(super_ref->home_object()); | 2435 VisitForValue(super_ref->home_object()); |
2412 VisitForValue(super_ref->this_var()); | 2436 VisitForValue(super_ref->this_var()); |
2413 environment()->Push(environment()->Top()); // Duplicate this_var. | 2437 environment()->Push(environment()->Top()); // Duplicate this_var. |
2414 environment()->Push(environment()->Peek(2)); // Duplicate home_obj. | 2438 environment()->Push(environment()->Peek(2)); // Duplicate home_obj. |
2415 VisitForValue(property->key()); | 2439 VisitForValue(property->key()); |
2416 Node* key = environment()->Pop(); | 2440 Node* key = environment()->Pop(); |
2417 Node* home = environment()->Pop(); | 2441 Node* home = environment()->Pop(); |
2418 Node* object = environment()->Pop(); | 2442 Node* object = environment()->Pop(); |
| 2443 PrepareEagerCheckpoint(property->key()->id()); |
2419 callee_value = BuildKeyedSuperLoad(object, home, key, VectorSlotPair()); | 2444 callee_value = BuildKeyedSuperLoad(object, home, key, VectorSlotPair()); |
2420 PrepareFrameState(callee_value, property->LoadId(), | 2445 PrepareFrameState(callee_value, property->LoadId(), |
2421 OutputFrameStateCombine::Push()); | 2446 OutputFrameStateCombine::Push()); |
2422 // Note that a property call requires the receiver to be wrapped into | 2447 // Note that a property call requires the receiver to be wrapped into |
2423 // an object for sloppy callees. Since the receiver is not the target of | 2448 // an object for sloppy callees. Since the receiver is not the target of |
2424 // the load, it could very well be null or undefined at this point. | 2449 // the load, it could very well be null or undefined at this point. |
2425 receiver_value = environment()->Pop(); | 2450 receiver_value = environment()->Pop(); |
2426 environment()->Drop(1); | 2451 environment()->Drop(1); |
2427 break; | 2452 break; |
2428 } | 2453 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2484 OutputFrameStateCombine::PokeAt(arg_count + 1)); | 2509 OutputFrameStateCombine::PokeAt(arg_count + 1)); |
2485 | 2510 |
2486 // Patch callee on the environment. | 2511 // Patch callee on the environment. |
2487 environment()->Poke(arg_count + 1, new_callee); | 2512 environment()->Poke(arg_count + 1, new_callee); |
2488 } | 2513 } |
2489 | 2514 |
2490 // Create node to perform the function call. | 2515 // Create node to perform the function call. |
2491 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot()); | 2516 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot()); |
2492 const Operator* call = javascript()->CallFunction( | 2517 const Operator* call = javascript()->CallFunction( |
2493 args->length() + 2, feedback, receiver_hint, expr->tail_call_mode()); | 2518 args->length() + 2, feedback, receiver_hint, expr->tail_call_mode()); |
2494 PrepareEagerCheckpoint(possibly_eval ? expr->EvalId() : expr->CallId()); | 2519 PrepareEagerCheckpoint(expr->CallId()); |
2495 Node* value = ProcessArguments(call, args->length() + 2); | 2520 Node* value = ProcessArguments(call, args->length() + 2); |
2496 environment()->Push(value->InputAt(0)); // The callee passed to the call. | 2521 environment()->Push(value->InputAt(0)); // The callee passed to the call. |
2497 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); | 2522 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); |
2498 environment()->Drop(1); | 2523 environment()->Drop(1); |
2499 ast_context()->ProduceValue(expr, value); | 2524 ast_context()->ProduceValue(value); |
2500 } | 2525 } |
2501 | 2526 |
2502 | 2527 |
2503 void AstGraphBuilder::VisitCallSuper(Call* expr) { | 2528 void AstGraphBuilder::VisitCallSuper(Call* expr) { |
2504 SuperCallReference* super = expr->expression()->AsSuperCallReference(); | 2529 SuperCallReference* super = expr->expression()->AsSuperCallReference(); |
2505 DCHECK_NOT_NULL(super); | 2530 DCHECK_NOT_NULL(super); |
2506 | 2531 |
2507 // Prepare the callee to the super call. | 2532 // Prepare the callee to the super call. |
2508 VisitForValue(super->this_function_var()); | 2533 VisitForValue(super->this_function_var()); |
2509 Node* this_function = environment()->Pop(); | 2534 Node* this_function = environment()->Pop(); |
2510 const Operator* op = | 2535 const Operator* op = |
2511 javascript()->CallRuntime(Runtime::kInlineGetSuperConstructor, 1); | 2536 javascript()->CallRuntime(Runtime::kInlineGetSuperConstructor, 1); |
2512 Node* super_function = NewNode(op, this_function); | 2537 Node* super_function = NewNode(op, this_function); |
2513 environment()->Push(super_function); | 2538 environment()->Push(super_function); |
2514 | 2539 |
2515 // Evaluate all arguments to the super call. | 2540 // Evaluate all arguments to the super call. |
2516 ZoneList<Expression*>* args = expr->arguments(); | 2541 ZoneList<Expression*>* args = expr->arguments(); |
2517 VisitForValues(args); | 2542 VisitForValues(args); |
2518 | 2543 |
2519 // The new target is loaded from the {new.target} variable. | 2544 // The new target is loaded from the {new.target} variable. |
2520 VisitForValue(super->new_target_var()); | 2545 VisitForValue(super->new_target_var()); |
2521 | 2546 |
2522 // Create node to perform the super call. | 2547 // Create node to perform the super call. |
2523 const Operator* call = | 2548 const Operator* call = |
2524 javascript()->CallConstruct(args->length() + 2, VectorSlotPair()); | 2549 javascript()->CallConstruct(args->length() + 2, VectorSlotPair()); |
| 2550 PrepareEagerCheckpoint(super->new_target_var()->id()); |
2525 Node* value = ProcessArguments(call, args->length() + 2); | 2551 Node* value = ProcessArguments(call, args->length() + 2); |
2526 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); | 2552 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); |
2527 ast_context()->ProduceValue(expr, value); | 2553 ast_context()->ProduceValue(value); |
2528 } | 2554 } |
2529 | 2555 |
2530 | 2556 |
2531 void AstGraphBuilder::VisitCallNew(CallNew* expr) { | 2557 void AstGraphBuilder::VisitCallNew(CallNew* expr) { |
2532 VisitForValue(expr->expression()); | 2558 VisitForValue(expr->expression()); |
2533 | 2559 |
2534 // Evaluate all arguments to the construct call. | 2560 // Evaluate all arguments to the construct call. |
2535 ZoneList<Expression*>* args = expr->arguments(); | 2561 ZoneList<Expression*>* args = expr->arguments(); |
2536 VisitForValues(args); | 2562 VisitForValues(args); |
2537 | 2563 |
| 2564 // The baseline compiler doesn't push the new.target, so we need to record |
| 2565 // the frame state before the push. |
| 2566 PrepareEagerCheckpoint(args->is_empty() ? expr->expression()->id() |
| 2567 : args->last()->id()); |
| 2568 |
2538 // The new target is the same as the callee. | 2569 // The new target is the same as the callee. |
2539 environment()->Push(environment()->Peek(args->length())); | 2570 environment()->Push(environment()->Peek(args->length())); |
2540 | 2571 |
2541 // Create node to perform the construct call. | 2572 // Create node to perform the construct call. |
2542 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallNewFeedbackSlot()); | 2573 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallNewFeedbackSlot()); |
2543 const Operator* call = | 2574 const Operator* call = |
2544 javascript()->CallConstruct(args->length() + 2, feedback); | 2575 javascript()->CallConstruct(args->length() + 2, feedback); |
2545 Node* value = ProcessArguments(call, args->length() + 2); | 2576 Node* value = ProcessArguments(call, args->length() + 2); |
2546 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); | 2577 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); |
2547 ast_context()->ProduceValue(expr, value); | 2578 ast_context()->ProduceValue(value); |
2548 } | 2579 } |
2549 | 2580 |
2550 | 2581 |
2551 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { | 2582 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { |
2552 // The callee and the receiver both have to be pushed onto the operand stack | 2583 // The callee and the receiver both have to be pushed onto the operand stack |
2553 // before arguments are being evaluated. | 2584 // before arguments are being evaluated. |
2554 Node* callee_value = BuildLoadNativeContextField(expr->context_index()); | 2585 Node* callee_value = BuildLoadNativeContextField(expr->context_index()); |
2555 Node* receiver_value = jsgraph()->UndefinedConstant(); | 2586 Node* receiver_value = jsgraph()->UndefinedConstant(); |
2556 | 2587 |
2557 environment()->Push(callee_value); | 2588 environment()->Push(callee_value); |
2558 environment()->Push(receiver_value); | 2589 environment()->Push(receiver_value); |
2559 | 2590 |
2560 // Evaluate all arguments to the JS runtime call. | 2591 // Evaluate all arguments to the JS runtime call. |
2561 ZoneList<Expression*>* args = expr->arguments(); | 2592 ZoneList<Expression*>* args = expr->arguments(); |
2562 VisitForValues(args); | 2593 VisitForValues(args); |
2563 | 2594 |
2564 // Create node to perform the JS runtime call. | 2595 // Create node to perform the JS runtime call. |
2565 const Operator* call = javascript()->CallFunction(args->length() + 2); | 2596 const Operator* call = javascript()->CallFunction(args->length() + 2); |
2566 PrepareEagerCheckpoint(expr->CallId()); | 2597 PrepareEagerCheckpoint(expr->CallId()); |
2567 Node* value = ProcessArguments(call, args->length() + 2); | 2598 Node* value = ProcessArguments(call, args->length() + 2); |
2568 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2599 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
2569 ast_context()->ProduceValue(expr, value); | 2600 ast_context()->ProduceValue(value); |
2570 } | 2601 } |
2571 | 2602 |
2572 | 2603 |
2573 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 2604 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
2574 // Handle calls to runtime functions implemented in JavaScript separately as | 2605 // Handle calls to runtime functions implemented in JavaScript separately as |
2575 // the call follows JavaScript ABI and the callee is statically unknown. | 2606 // the call follows JavaScript ABI and the callee is statically unknown. |
2576 if (expr->is_jsruntime()) { | 2607 if (expr->is_jsruntime()) { |
2577 return VisitCallJSRuntime(expr); | 2608 return VisitCallJSRuntime(expr); |
2578 } | 2609 } |
2579 | 2610 |
2580 // Evaluate all arguments to the runtime call. | 2611 // Evaluate all arguments to the runtime call. |
2581 ZoneList<Expression*>* args = expr->arguments(); | 2612 ZoneList<Expression*>* args = expr->arguments(); |
2582 VisitForValues(args); | 2613 VisitForValues(args); |
2583 | 2614 |
2584 // Create node to perform the runtime call. | 2615 // Create node to perform the runtime call. |
2585 Runtime::FunctionId functionId = expr->function()->function_id; | 2616 Runtime::FunctionId functionId = expr->function()->function_id; |
2586 const Operator* call = javascript()->CallRuntime(functionId, args->length()); | 2617 const Operator* call = javascript()->CallRuntime(functionId, args->length()); |
2587 if (expr->function()->intrinsic_type == Runtime::IntrinsicType::RUNTIME || | 2618 PrepareEagerCheckpoint(expr->CallId()); |
2588 expr->function()->function_id == Runtime::kInlineCall) { | |
2589 PrepareEagerCheckpoint(expr->CallId()); | |
2590 } | |
2591 Node* value = ProcessArguments(call, args->length()); | 2619 Node* value = ProcessArguments(call, args->length()); |
2592 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2620 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
2593 ast_context()->ProduceValue(expr, value); | 2621 ast_context()->ProduceValue(value); |
2594 } | 2622 } |
2595 | 2623 |
2596 | 2624 |
2597 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { | 2625 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { |
2598 switch (expr->op()) { | 2626 switch (expr->op()) { |
2599 case Token::DELETE: | 2627 case Token::DELETE: |
2600 return VisitDelete(expr); | 2628 return VisitDelete(expr); |
2601 case Token::VOID: | 2629 case Token::VOID: |
2602 return VisitVoid(expr); | 2630 return VisitVoid(expr); |
2603 case Token::TYPEOF: | 2631 case Token::TYPEOF: |
(...skipping 27 matching lines...) Expand all Loading... |
2631 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 2659 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
2632 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 2660 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
2633 PrepareEagerCheckpoint(BeforeId(proxy)); | 2661 PrepareEagerCheckpoint(BeforeId(proxy)); |
2634 old_value = BuildVariableLoad(proxy->var(), expr->expression()->id(), | 2662 old_value = BuildVariableLoad(proxy->var(), expr->expression()->id(), |
2635 pair, OutputFrameStateCombine::Push()); | 2663 pair, OutputFrameStateCombine::Push()); |
2636 stack_depth = 0; | 2664 stack_depth = 0; |
2637 break; | 2665 break; |
2638 } | 2666 } |
2639 case NAMED_PROPERTY: { | 2667 case NAMED_PROPERTY: { |
2640 VisitForValue(property->obj()); | 2668 VisitForValue(property->obj()); |
| 2669 PrepareEagerCheckpoint(property->obj()->id()); |
2641 Node* object = environment()->Top(); | 2670 Node* object = environment()->Top(); |
2642 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2671 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2643 VectorSlotPair pair = | 2672 VectorSlotPair pair = |
2644 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2673 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2645 old_value = BuildNamedLoad(object, name, pair); | 2674 old_value = BuildNamedLoad(object, name, pair); |
2646 PrepareFrameState(old_value, property->LoadId(), | 2675 PrepareFrameState(old_value, property->LoadId(), |
2647 OutputFrameStateCombine::Push()); | 2676 OutputFrameStateCombine::Push()); |
2648 stack_depth = 1; | 2677 stack_depth = 1; |
2649 break; | 2678 break; |
2650 } | 2679 } |
2651 case KEYED_PROPERTY: { | 2680 case KEYED_PROPERTY: { |
2652 VisitForValue(property->obj()); | 2681 VisitForValue(property->obj()); |
2653 VisitForValue(property->key()); | 2682 VisitForValue(property->key()); |
| 2683 PrepareEagerCheckpoint(property->key()->id()); |
2654 Node* key = environment()->Top(); | 2684 Node* key = environment()->Top(); |
2655 Node* object = environment()->Peek(1); | 2685 Node* object = environment()->Peek(1); |
2656 VectorSlotPair pair = | 2686 VectorSlotPair pair = |
2657 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2687 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2658 old_value = BuildKeyedLoad(object, key, pair); | 2688 old_value = BuildKeyedLoad(object, key, pair); |
2659 PrepareFrameState(old_value, property->LoadId(), | 2689 PrepareFrameState(old_value, property->LoadId(), |
2660 OutputFrameStateCombine::Push()); | 2690 OutputFrameStateCombine::Push()); |
2661 stack_depth = 2; | 2691 stack_depth = 2; |
2662 break; | 2692 break; |
2663 } | 2693 } |
2664 case NAMED_SUPER_PROPERTY: { | 2694 case NAMED_SUPER_PROPERTY: { |
2665 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2695 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
2666 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | 2696 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); |
| 2697 PrepareEagerCheckpoint(property->obj()->id()); |
2667 Node* home_object = environment()->Top(); | 2698 Node* home_object = environment()->Top(); |
2668 Node* receiver = environment()->Peek(1); | 2699 Node* receiver = environment()->Peek(1); |
2669 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2700 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2670 VectorSlotPair pair = | 2701 VectorSlotPair pair = |
2671 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2702 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2672 old_value = BuildNamedSuperLoad(receiver, home_object, name, pair); | 2703 old_value = BuildNamedSuperLoad(receiver, home_object, name, pair); |
2673 PrepareFrameState(old_value, property->LoadId(), | 2704 PrepareFrameState(old_value, property->LoadId(), |
2674 OutputFrameStateCombine::Push()); | 2705 OutputFrameStateCombine::Push()); |
2675 stack_depth = 2; | 2706 stack_depth = 2; |
2676 break; | 2707 break; |
2677 } | 2708 } |
2678 case KEYED_SUPER_PROPERTY: { | 2709 case KEYED_SUPER_PROPERTY: { |
2679 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2710 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
2680 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | 2711 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); |
2681 VisitForValue(property->key()); | 2712 VisitForValue(property->key()); |
| 2713 PrepareEagerCheckpoint(property->obj()->id()); |
2682 Node* key = environment()->Top(); | 2714 Node* key = environment()->Top(); |
2683 Node* home_object = environment()->Peek(1); | 2715 Node* home_object = environment()->Peek(1); |
2684 Node* receiver = environment()->Peek(2); | 2716 Node* receiver = environment()->Peek(2); |
2685 VectorSlotPair pair = | 2717 VectorSlotPair pair = |
2686 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2718 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2687 old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair); | 2719 old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair); |
2688 PrepareFrameState(old_value, property->LoadId(), | 2720 PrepareFrameState(old_value, property->LoadId(), |
2689 OutputFrameStateCombine::Push()); | 2721 OutputFrameStateCombine::Push()); |
2690 stack_depth = 3; | 2722 stack_depth = 3; |
2691 break; | 2723 break; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2770 PrepareFrameState(store, expr->AssignmentId(), | 2802 PrepareFrameState(store, expr->AssignmentId(), |
2771 OutputFrameStateCombine::Ignore()); | 2803 OutputFrameStateCombine::Ignore()); |
2772 environment()->Pop(); | 2804 environment()->Pop(); |
2773 break; | 2805 break; |
2774 } | 2806 } |
2775 } | 2807 } |
2776 | 2808 |
2777 // Restore old value for postfix expressions. | 2809 // Restore old value for postfix expressions. |
2778 if (is_postfix) value = environment()->Pop(); | 2810 if (is_postfix) value = environment()->Pop(); |
2779 | 2811 |
2780 ast_context()->ProduceValue(expr, value); | 2812 ast_context()->ProduceValue(value); |
2781 } | 2813 } |
2782 | 2814 |
2783 | 2815 |
2784 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { | 2816 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { |
2785 switch (expr->op()) { | 2817 switch (expr->op()) { |
2786 case Token::COMMA: | 2818 case Token::COMMA: |
2787 return VisitComma(expr); | 2819 return VisitComma(expr); |
2788 case Token::OR: | 2820 case Token::OR: |
2789 case Token::AND: | 2821 case Token::AND: |
2790 return VisitLogicalExpression(expr); | 2822 return VisitLogicalExpression(expr); |
2791 default: { | 2823 default: { |
2792 VisitForValue(expr->left()); | 2824 VisitForValue(expr->left()); |
2793 VisitForValue(expr->right()); | 2825 VisitForValue(expr->right()); |
2794 FrameStateBeforeAndAfter states(this, expr->right()->id()); | 2826 FrameStateBeforeAndAfter states(this, expr->right()->id()); |
2795 Node* right = environment()->Pop(); | 2827 Node* right = environment()->Pop(); |
2796 Node* left = environment()->Pop(); | 2828 Node* left = environment()->Pop(); |
2797 Node* value = BuildBinaryOp(left, right, expr->op(), | 2829 Node* value = BuildBinaryOp(left, right, expr->op(), |
2798 expr->BinaryOperationFeedbackId()); | 2830 expr->BinaryOperationFeedbackId()); |
2799 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); | 2831 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); |
2800 ast_context()->ProduceValue(expr, value); | 2832 ast_context()->ProduceValue(value); |
2801 } | 2833 } |
2802 } | 2834 } |
2803 } | 2835 } |
2804 | 2836 |
2805 void AstGraphBuilder::VisitLiteralCompareNil(CompareOperation* expr, | 2837 void AstGraphBuilder::VisitLiteralCompareNil(CompareOperation* expr, |
2806 Expression* sub_expr, | 2838 Expression* sub_expr, |
2807 Node* nil_value) { | 2839 Node* nil_value) { |
2808 const Operator* op = nullptr; | 2840 const Operator* op = nullptr; |
2809 switch (expr->op()) { | 2841 switch (expr->op()) { |
2810 case Token::EQ: | 2842 case Token::EQ: |
2811 op = javascript()->Equal(CompareOperationHints::Any()); | 2843 op = javascript()->Equal(CompareOperationHints::Any()); |
2812 break; | 2844 break; |
2813 case Token::EQ_STRICT: | 2845 case Token::EQ_STRICT: |
2814 op = javascript()->StrictEqual(CompareOperationHints::Any()); | 2846 op = javascript()->StrictEqual(CompareOperationHints::Any()); |
2815 break; | 2847 break; |
2816 default: | 2848 default: |
2817 UNREACHABLE(); | 2849 UNREACHABLE(); |
2818 } | 2850 } |
2819 VisitForValue(sub_expr); | 2851 VisitForValue(sub_expr); |
| 2852 PrepareEagerCheckpoint(sub_expr->id()); |
2820 Node* value_to_compare = environment()->Pop(); | 2853 Node* value_to_compare = environment()->Pop(); |
2821 Node* value = NewNode(op, value_to_compare, nil_value); | 2854 Node* value = NewNode(op, value_to_compare, nil_value); |
2822 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2855 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
2823 return ast_context()->ProduceValue(expr, value); | 2856 return ast_context()->ProduceValue(value); |
2824 } | 2857 } |
2825 | 2858 |
2826 void AstGraphBuilder::VisitLiteralCompareTypeof(CompareOperation* expr, | 2859 void AstGraphBuilder::VisitLiteralCompareTypeof(CompareOperation* expr, |
2827 Expression* sub_expr, | 2860 Expression* sub_expr, |
2828 Handle<String> check) { | 2861 Handle<String> check) { |
2829 VisitTypeofExpression(sub_expr); | 2862 VisitTypeofExpression(sub_expr); |
| 2863 PrepareEagerCheckpoint(sub_expr->id()); |
2830 Node* typeof_arg = NewNode(javascript()->TypeOf(), environment()->Pop()); | 2864 Node* typeof_arg = NewNode(javascript()->TypeOf(), environment()->Pop()); |
2831 Node* value = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), | 2865 Node* value = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), |
2832 typeof_arg, jsgraph()->Constant(check)); | 2866 typeof_arg, jsgraph()->Constant(check)); |
2833 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2867 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
2834 return ast_context()->ProduceValue(expr, value); | 2868 return ast_context()->ProduceValue(value); |
2835 } | 2869 } |
2836 | 2870 |
2837 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { | 2871 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
2838 // Check for a few fast cases. The AST visiting behavior must be in sync | 2872 // Check for a few fast cases. The AST visiting behavior must be in sync |
2839 // with the full codegen: We don't push both left and right values onto | 2873 // with the full codegen: We don't push both left and right values onto |
2840 // the expression stack when one side is a special-case literal. | 2874 // the expression stack when one side is a special-case literal. |
2841 Expression* sub_expr = nullptr; | 2875 Expression* sub_expr = nullptr; |
2842 Handle<String> check; | 2876 Handle<String> check; |
2843 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { | 2877 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { |
2844 return VisitLiteralCompareTypeof(expr, sub_expr, check); | 2878 return VisitLiteralCompareTypeof(expr, sub_expr, check); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2894 op = nullptr; | 2928 op = nullptr; |
2895 UNREACHABLE(); | 2929 UNREACHABLE(); |
2896 } | 2930 } |
2897 VisitForValue(expr->left()); | 2931 VisitForValue(expr->left()); |
2898 VisitForValue(expr->right()); | 2932 VisitForValue(expr->right()); |
2899 FrameStateBeforeAndAfter states(this, expr->right()->id()); | 2933 FrameStateBeforeAndAfter states(this, expr->right()->id()); |
2900 Node* right = environment()->Pop(); | 2934 Node* right = environment()->Pop(); |
2901 Node* left = environment()->Pop(); | 2935 Node* left = environment()->Pop(); |
2902 Node* value = NewNode(op, left, right); | 2936 Node* value = NewNode(op, left, right); |
2903 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); | 2937 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); |
2904 ast_context()->ProduceValue(expr, value); | 2938 ast_context()->ProduceValue(value); |
2905 } | 2939 } |
2906 | 2940 |
2907 | 2941 |
2908 void AstGraphBuilder::VisitSpread(Spread* expr) { | 2942 void AstGraphBuilder::VisitSpread(Spread* expr) { |
2909 // Handled entirely by the parser itself. | 2943 // Handled entirely by the parser itself. |
2910 UNREACHABLE(); | 2944 UNREACHABLE(); |
2911 } | 2945 } |
2912 | 2946 |
2913 | 2947 |
2914 void AstGraphBuilder::VisitEmptyParentheses(EmptyParentheses* expr) { | 2948 void AstGraphBuilder::VisitEmptyParentheses(EmptyParentheses* expr) { |
2915 // Handled entirely by the parser itself. | 2949 // Handled entirely by the parser itself. |
2916 UNREACHABLE(); | 2950 UNREACHABLE(); |
2917 } | 2951 } |
2918 | 2952 |
2919 | 2953 |
2920 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 2954 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
2921 Node* value = GetFunctionClosure(); | 2955 Node* value = GetFunctionClosure(); |
2922 ast_context()->ProduceValue(expr, value); | 2956 ast_context()->ProduceValue(value); |
2923 } | 2957 } |
2924 | 2958 |
2925 | 2959 |
2926 void AstGraphBuilder::VisitSuperPropertyReference( | 2960 void AstGraphBuilder::VisitSuperPropertyReference( |
2927 SuperPropertyReference* expr) { | 2961 SuperPropertyReference* expr) { |
2928 Node* value = BuildThrowUnsupportedSuperError(expr->id()); | 2962 Node* value = BuildThrowUnsupportedSuperError(expr->id()); |
2929 ast_context()->ProduceValue(expr, value); | 2963 ast_context()->ProduceValue(value); |
2930 } | 2964 } |
2931 | 2965 |
2932 | 2966 |
2933 void AstGraphBuilder::VisitSuperCallReference(SuperCallReference* expr) { | 2967 void AstGraphBuilder::VisitSuperCallReference(SuperCallReference* expr) { |
2934 // Handled by VisitCall | 2968 // Handled by VisitCall |
2935 UNREACHABLE(); | 2969 UNREACHABLE(); |
2936 } | 2970 } |
2937 | 2971 |
2938 | 2972 |
2939 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { | 2973 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3000 VisitForValue(property->obj()); | 3034 VisitForValue(property->obj()); |
3001 VisitForValue(property->key()); | 3035 VisitForValue(property->key()); |
3002 Node* key = environment()->Pop(); | 3036 Node* key = environment()->Pop(); |
3003 Node* object = environment()->Pop(); | 3037 Node* object = environment()->Pop(); |
3004 value = NewNode(javascript()->DeleteProperty(language_mode()), object, key); | 3038 value = NewNode(javascript()->DeleteProperty(language_mode()), object, key); |
3005 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 3039 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
3006 } else { | 3040 } else { |
3007 VisitForEffect(expr->expression()); | 3041 VisitForEffect(expr->expression()); |
3008 value = jsgraph()->TrueConstant(); | 3042 value = jsgraph()->TrueConstant(); |
3009 } | 3043 } |
3010 ast_context()->ProduceValue(expr, value); | 3044 ast_context()->ProduceValue(value); |
3011 } | 3045 } |
3012 | 3046 |
3013 | 3047 |
3014 void AstGraphBuilder::VisitVoid(UnaryOperation* expr) { | 3048 void AstGraphBuilder::VisitVoid(UnaryOperation* expr) { |
3015 VisitForEffect(expr->expression()); | 3049 VisitForEffect(expr->expression()); |
3016 Node* value = jsgraph()->UndefinedConstant(); | 3050 Node* value = jsgraph()->UndefinedConstant(); |
3017 ast_context()->ProduceValue(expr, value); | 3051 ast_context()->ProduceValue(value); |
3018 } | 3052 } |
3019 | 3053 |
3020 void AstGraphBuilder::VisitTypeofExpression(Expression* expr) { | 3054 void AstGraphBuilder::VisitTypeofExpression(Expression* expr) { |
3021 if (expr->IsVariableProxy()) { | 3055 if (expr->IsVariableProxy()) { |
3022 // Typeof does not throw a reference error on global variables, hence we | 3056 // Typeof does not throw a reference error on global variables, hence we |
3023 // perform a non-contextual load in case the operand is a variable proxy. | 3057 // perform a non-contextual load in case the operand is a variable proxy. |
3024 VariableProxy* proxy = expr->AsVariableProxy(); | 3058 VariableProxy* proxy = expr->AsVariableProxy(); |
3025 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 3059 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
3026 PrepareEagerCheckpoint(BeforeId(proxy)); | 3060 PrepareEagerCheckpoint(BeforeId(proxy)); |
3027 Node* load = | 3061 Node* load = |
3028 BuildVariableLoad(proxy->var(), expr->id(), pair, | 3062 BuildVariableLoad(proxy->var(), expr->id(), pair, |
3029 OutputFrameStateCombine::Push(), INSIDE_TYPEOF); | 3063 OutputFrameStateCombine::Push(), INSIDE_TYPEOF); |
3030 environment()->Push(load); | 3064 environment()->Push(load); |
3031 } else { | 3065 } else { |
3032 VisitForValue(expr); | 3066 VisitForValue(expr); |
3033 } | 3067 } |
3034 } | 3068 } |
3035 | 3069 |
3036 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) { | 3070 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) { |
3037 VisitTypeofExpression(expr->expression()); | 3071 VisitTypeofExpression(expr->expression()); |
3038 Node* value = NewNode(javascript()->TypeOf(), environment()->Pop()); | 3072 Node* value = NewNode(javascript()->TypeOf(), environment()->Pop()); |
3039 ast_context()->ProduceValue(expr, value); | 3073 ast_context()->ProduceValue(value); |
3040 } | 3074 } |
3041 | 3075 |
3042 | 3076 |
3043 void AstGraphBuilder::VisitNot(UnaryOperation* expr) { | 3077 void AstGraphBuilder::VisitNot(UnaryOperation* expr) { |
3044 VisitForTest(expr->expression()); | 3078 VisitForValue(expr->expression()); |
3045 Node* input = environment()->Pop(); | 3079 Node* operand = environment()->Pop(); |
| 3080 Node* input = BuildToBoolean(operand, expr->expression()->test_id()); |
3046 Node* value = NewNode(common()->Select(MachineRepresentation::kTagged), input, | 3081 Node* value = NewNode(common()->Select(MachineRepresentation::kTagged), input, |
3047 jsgraph()->FalseConstant(), jsgraph()->TrueConstant()); | 3082 jsgraph()->FalseConstant(), jsgraph()->TrueConstant()); |
3048 // Skip plugging AST evaluation contexts of the test kind. This is to stay in | 3083 ast_context()->ProduceValue(value); |
3049 // sync with full codegen which doesn't prepare the proper bailout point (see | |
3050 // the implementation of FullCodeGenerator::VisitForControl). | |
3051 if (ast_context()->IsTest()) return environment()->Push(value); | |
3052 ast_context()->ProduceValue(expr, value); | |
3053 } | 3084 } |
3054 | 3085 |
3055 | 3086 |
3056 void AstGraphBuilder::VisitComma(BinaryOperation* expr) { | 3087 void AstGraphBuilder::VisitComma(BinaryOperation* expr) { |
3057 VisitForEffect(expr->left()); | 3088 VisitForEffect(expr->left()); |
3058 Visit(expr->right()); | 3089 Visit(expr->right()); |
3059 ast_context()->ReplaceValue(expr); | 3090 ast_context()->ReplaceValue(); |
3060 } | 3091 } |
3061 | 3092 |
3062 | 3093 |
3063 void AstGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) { | 3094 void AstGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) { |
3064 bool is_logical_and = expr->op() == Token::AND; | 3095 bool is_logical_and = expr->op() == Token::AND; |
3065 IfBuilder compare_if(this); | 3096 IfBuilder compare_if(this); |
3066 // Only use an AST evaluation context of the value kind when this expression | 3097 VisitForValue(expr->left()); |
3067 // is evaluated as value as well. Otherwise stick to a test context which is | 3098 Node* condition = environment()->Top(); |
3068 // in sync with full codegen (see FullCodeGenerator::VisitLogicalExpression). | 3099 compare_if.If(BuildToBoolean(condition, expr->left()->test_id())); |
3069 Node* condition = nullptr; | |
3070 if (ast_context()->IsValue()) { | |
3071 VisitForValue(expr->left()); | |
3072 Node* left = environment()->Top(); | |
3073 condition = BuildToBoolean(left, expr->left()->test_id()); | |
3074 } else { | |
3075 VisitForTest(expr->left()); | |
3076 condition = environment()->Top(); | |
3077 } | |
3078 compare_if.If(condition); | |
3079 compare_if.Then(); | 3100 compare_if.Then(); |
3080 if (is_logical_and) { | 3101 if (is_logical_and) { |
3081 environment()->Pop(); | 3102 environment()->Pop(); |
3082 Visit(expr->right()); | 3103 Visit(expr->right()); |
3083 } else if (ast_context()->IsEffect()) { | 3104 } else if (ast_context()->IsEffect()) { |
3084 environment()->Pop(); | 3105 environment()->Pop(); |
3085 } else if (ast_context()->IsTest()) { | 3106 } else if (ast_context()->IsTest()) { |
3086 environment()->Poke(0, jsgraph()->TrueConstant()); | 3107 environment()->Poke(0, jsgraph()->TrueConstant()); |
3087 } | 3108 } |
3088 compare_if.Else(); | 3109 compare_if.Else(); |
3089 if (!is_logical_and) { | 3110 if (!is_logical_and) { |
3090 environment()->Pop(); | 3111 environment()->Pop(); |
3091 Visit(expr->right()); | 3112 Visit(expr->right()); |
3092 } else if (ast_context()->IsEffect()) { | 3113 } else if (ast_context()->IsEffect()) { |
3093 environment()->Pop(); | 3114 environment()->Pop(); |
3094 } else if (ast_context()->IsTest()) { | 3115 } else if (ast_context()->IsTest()) { |
3095 environment()->Poke(0, jsgraph()->FalseConstant()); | 3116 environment()->Poke(0, jsgraph()->FalseConstant()); |
3096 } | 3117 } |
3097 compare_if.End(); | 3118 compare_if.End(); |
3098 // Skip plugging AST evaluation contexts of the test kind. This is to stay in | 3119 ast_context()->ReplaceValue(); |
3099 // sync with full codegen which doesn't prepare the proper bailout point (see | |
3100 // the implementation of FullCodeGenerator::VisitForControl). | |
3101 if (ast_context()->IsTest()) return; | |
3102 ast_context()->ReplaceValue(expr); | |
3103 } | 3120 } |
3104 | 3121 |
3105 | 3122 |
3106 LanguageMode AstGraphBuilder::language_mode() const { | 3123 LanguageMode AstGraphBuilder::language_mode() const { |
3107 return current_scope()->language_mode(); | 3124 return current_scope()->language_mode(); |
3108 } | 3125 } |
3109 | 3126 |
3110 | 3127 |
3111 VectorSlotPair AstGraphBuilder::CreateVectorSlotPair( | 3128 VectorSlotPair AstGraphBuilder::CreateVectorSlotPair( |
3112 FeedbackVectorSlot slot) const { | 3129 FeedbackVectorSlot slot) const { |
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4053 } | 4070 } |
4054 } | 4071 } |
4055 | 4072 |
4056 void AstGraphBuilder::PrepareEagerCheckpoint(BailoutId ast_id) { | 4073 void AstGraphBuilder::PrepareEagerCheckpoint(BailoutId ast_id) { |
4057 if (environment()->GetEffectDependency()->opcode() == IrOpcode::kCheckpoint) { | 4074 if (environment()->GetEffectDependency()->opcode() == IrOpcode::kCheckpoint) { |
4058 // We skip preparing a checkpoint if there already is one the current effect | 4075 // We skip preparing a checkpoint if there already is one the current effect |
4059 // dependency. This is just an optimization and not need for correctness. | 4076 // dependency. This is just an optimization and not need for correctness. |
4060 return; | 4077 return; |
4061 } | 4078 } |
4062 if (ast_id != BailoutId::None()) { | 4079 if (ast_id != BailoutId::None()) { |
4063 DCHECK(info()->shared_info()->VerifyBailoutId(ast_id)); | |
4064 Node* node = NewNode(common()->Checkpoint()); | 4080 Node* node = NewNode(common()->Checkpoint()); |
4065 DCHECK_EQ(IrOpcode::kDead, | 4081 DCHECK_EQ(IrOpcode::kDead, |
4066 NodeProperties::GetFrameStateInput(node, 0)->opcode()); | 4082 NodeProperties::GetFrameStateInput(node, 0)->opcode()); |
4067 NodeProperties::ReplaceFrameStateInput(node, 0, | 4083 NodeProperties::ReplaceFrameStateInput(node, 0, |
4068 environment()->Checkpoint(ast_id)); | 4084 environment()->Checkpoint(ast_id)); |
4069 } | 4085 } |
4070 } | 4086 } |
4071 | 4087 |
4072 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( | 4088 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( |
4073 IterationStatement* stmt) { | 4089 IterationStatement* stmt) { |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4372 // Phi does not exist yet, introduce one. | 4388 // Phi does not exist yet, introduce one. |
4373 value = NewPhi(inputs, value, control); | 4389 value = NewPhi(inputs, value, control); |
4374 value->ReplaceInput(inputs - 1, other); | 4390 value->ReplaceInput(inputs - 1, other); |
4375 } | 4391 } |
4376 return value; | 4392 return value; |
4377 } | 4393 } |
4378 | 4394 |
4379 } // namespace compiler | 4395 } // namespace compiler |
4380 } // namespace internal | 4396 } // namespace internal |
4381 } // namespace v8 | 4397 } // namespace v8 |
OLD | NEW |