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