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/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
10 #include "src/compiler/js-type-feedback.h" | 10 #include "src/compiler/js-type-feedback.h" |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 Property* property = expr->AsProperty(); | 625 Property* property = expr->AsProperty(); |
626 DCHECK(expr->IsValidReferenceExpression()); | 626 DCHECK(expr->IsValidReferenceExpression()); |
627 LhsKind lhs_kind = | 627 LhsKind lhs_kind = |
628 (property == NULL) ? VARIABLE : (property->key()->IsPropertyName()) | 628 (property == NULL) ? VARIABLE : (property->key()->IsPropertyName()) |
629 ? NAMED_PROPERTY | 629 ? NAMED_PROPERTY |
630 : KEYED_PROPERTY; | 630 : KEYED_PROPERTY; |
631 return lhs_kind; | 631 return lhs_kind; |
632 } | 632 } |
633 | 633 |
634 | 634 |
| 635 // Gets the bailout id just before reading a variable proxy, but only for |
| 636 // unallocated variables. |
| 637 static BailoutId BeforeId(VariableProxy* proxy) { |
| 638 return proxy->var()->location() == Variable::UNALLOCATED ? proxy->BeforeId() |
| 639 : BailoutId::None(); |
| 640 } |
| 641 |
| 642 |
635 static const char* GetDebugParameterName(Zone* zone, Scope* scope, int index) { | 643 static const char* GetDebugParameterName(Zone* zone, Scope* scope, int index) { |
636 #if DEBUG | 644 #if DEBUG |
637 const AstRawString* name = scope->parameter(index)->raw_name(); | 645 const AstRawString* name = scope->parameter(index)->raw_name(); |
638 if (name && name->length() > 0) { | 646 if (name && name->length() > 0) { |
639 char* data = zone->NewArray<char>(name->length() + 1); | 647 char* data = zone->NewArray<char>(name->length() + 1); |
640 data[name->length()] = 0; | 648 data[name->length()] = 0; |
641 memcpy(data, name->raw_data(), name->length()); | 649 memcpy(data, name->raw_data(), name->length()); |
642 return data; | 650 return data; |
643 } | 651 } |
644 #endif | 652 #endif |
(...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1636 | 1644 |
1637 // Transform both the class literal and the prototype to fast properties. | 1645 // Transform both the class literal and the prototype to fast properties. |
1638 const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties, 1); | 1646 const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties, 1); |
1639 NewNode(op, environment()->Pop()); // prototype | 1647 NewNode(op, environment()->Pop()); // prototype |
1640 NewNode(op, environment()->Pop()); // literal | 1648 NewNode(op, environment()->Pop()); // literal |
1641 | 1649 |
1642 // Assign to class variable. | 1650 // Assign to class variable. |
1643 if (expr->scope() != NULL) { | 1651 if (expr->scope() != NULL) { |
1644 DCHECK_NOT_NULL(expr->class_variable_proxy()); | 1652 DCHECK_NOT_NULL(expr->class_variable_proxy()); |
1645 Variable* var = expr->class_variable_proxy()->var(); | 1653 Variable* var = expr->class_variable_proxy()->var(); |
1646 BuildVariableAssignment(var, literal, Token::INIT_CONST, BailoutId::None()); | 1654 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
| 1655 BuildVariableAssignment(states, var, literal, Token::INIT_CONST, |
| 1656 BailoutId::None()); |
1647 } | 1657 } |
1648 | 1658 |
1649 ast_context()->ProduceValue(literal); | 1659 ast_context()->ProduceValue(literal); |
1650 } | 1660 } |
1651 | 1661 |
1652 | 1662 |
1653 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { | 1663 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { |
1654 UNREACHABLE(); | 1664 UNREACHABLE(); |
1655 } | 1665 } |
1656 | 1666 |
1657 | 1667 |
1658 void AstGraphBuilder::VisitConditional(Conditional* expr) { | 1668 void AstGraphBuilder::VisitConditional(Conditional* expr) { |
1659 IfBuilder compare_if(this); | 1669 IfBuilder compare_if(this); |
1660 VisitForTest(expr->condition()); | 1670 VisitForTest(expr->condition()); |
1661 Node* condition = environment()->Pop(); | 1671 Node* condition = environment()->Pop(); |
1662 compare_if.If(condition); | 1672 compare_if.If(condition); |
1663 compare_if.Then(); | 1673 compare_if.Then(); |
1664 Visit(expr->then_expression()); | 1674 Visit(expr->then_expression()); |
1665 compare_if.Else(); | 1675 compare_if.Else(); |
1666 Visit(expr->else_expression()); | 1676 Visit(expr->else_expression()); |
1667 compare_if.End(); | 1677 compare_if.End(); |
1668 ast_context()->ReplaceValue(); | 1678 ast_context()->ReplaceValue(); |
1669 } | 1679 } |
1670 | 1680 |
1671 | 1681 |
1672 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 1682 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
1673 VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot()); | 1683 VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot()); |
1674 Node* value = BuildVariableLoad(expr->var(), expr->id(), pair); | 1684 FrameStateBeforeAndAfter states(this, BeforeId(expr)); |
| 1685 Node* value = BuildVariableLoad(states, expr->var(), expr->id(), pair, |
| 1686 ast_context()->GetStateCombine()); |
1675 ast_context()->ProduceValue(value); | 1687 ast_context()->ProduceValue(value); |
1676 } | 1688 } |
1677 | 1689 |
1678 | 1690 |
1679 void AstGraphBuilder::VisitLiteral(Literal* expr) { | 1691 void AstGraphBuilder::VisitLiteral(Literal* expr) { |
1680 Node* value = jsgraph()->Constant(expr->value()); | 1692 Node* value = jsgraph()->Constant(expr->value()); |
1681 ast_context()->ProduceValue(value); | 1693 ast_context()->ProduceValue(value); |
1682 } | 1694 } |
1683 | 1695 |
1684 | 1696 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1737 UNREACHABLE(); | 1749 UNREACHABLE(); |
1738 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1750 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1739 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1751 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1740 // Fall through. | 1752 // Fall through. |
1741 case ObjectLiteral::Property::COMPUTED: { | 1753 case ObjectLiteral::Property::COMPUTED: { |
1742 // It is safe to use [[Put]] here because the boilerplate already | 1754 // It is safe to use [[Put]] here because the boilerplate already |
1743 // contains computed properties with an uninitialized value. | 1755 // contains computed properties with an uninitialized value. |
1744 if (key->value()->IsInternalizedString()) { | 1756 if (key->value()->IsInternalizedString()) { |
1745 if (property->emit_store()) { | 1757 if (property->emit_store()) { |
1746 VisitForValue(property->value()); | 1758 VisitForValue(property->value()); |
| 1759 FrameStateBeforeAndAfter states(this, property->value()->id()); |
1747 Node* value = environment()->Pop(); | 1760 Node* value = environment()->Pop(); |
1748 Handle<Name> name = key->AsPropertyName(); | 1761 Handle<Name> name = key->AsPropertyName(); |
1749 Node* store = | 1762 Node* store = |
1750 BuildNamedStore(literal, name, value, TypeFeedbackId::None()); | 1763 BuildNamedStore(literal, name, value, TypeFeedbackId::None()); |
1751 PrepareFrameState(store, key->id()); | 1764 states.AddToNode(store, key->id(), |
| 1765 OutputFrameStateCombine::Ignore()); |
1752 BuildSetHomeObject(value, literal, property->value()); | 1766 BuildSetHomeObject(value, literal, property->value()); |
1753 } else { | 1767 } else { |
1754 VisitForEffect(property->value()); | 1768 VisitForEffect(property->value()); |
1755 } | 1769 } |
1756 break; | 1770 break; |
1757 } | 1771 } |
1758 environment()->Push(literal); // Duplicate receiver. | 1772 environment()->Push(literal); // Duplicate receiver. |
1759 VisitForValue(property->key()); | 1773 VisitForValue(property->key()); |
1760 VisitForValue(property->value()); | 1774 VisitForValue(property->value()); |
1761 Node* value = environment()->Pop(); | 1775 Node* value = environment()->Pop(); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1938 DCHECK(expr->IsValidReferenceExpression()); | 1952 DCHECK(expr->IsValidReferenceExpression()); |
1939 | 1953 |
1940 // Left-hand side can only be a property, a global or a variable slot. | 1954 // Left-hand side can only be a property, a global or a variable slot. |
1941 Property* property = expr->AsProperty(); | 1955 Property* property = expr->AsProperty(); |
1942 LhsKind assign_type = DetermineLhsKind(expr); | 1956 LhsKind assign_type = DetermineLhsKind(expr); |
1943 | 1957 |
1944 // Evaluate LHS expression and store the value. | 1958 // Evaluate LHS expression and store the value. |
1945 switch (assign_type) { | 1959 switch (assign_type) { |
1946 case VARIABLE: { | 1960 case VARIABLE: { |
1947 Variable* var = expr->AsVariableProxy()->var(); | 1961 Variable* var = expr->AsVariableProxy()->var(); |
1948 BuildVariableAssignment(var, value, Token::ASSIGN, bailout_id); | 1962 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
| 1963 BuildVariableAssignment(states, var, value, Token::ASSIGN, bailout_id); |
1949 break; | 1964 break; |
1950 } | 1965 } |
1951 case NAMED_PROPERTY: { | 1966 case NAMED_PROPERTY: { |
1952 environment()->Push(value); | 1967 environment()->Push(value); |
1953 VisitForValue(property->obj()); | 1968 VisitForValue(property->obj()); |
| 1969 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
1954 Node* object = environment()->Pop(); | 1970 Node* object = environment()->Pop(); |
1955 value = environment()->Pop(); | 1971 value = environment()->Pop(); |
1956 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 1972 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
1957 Node* store = | 1973 Node* store = |
1958 BuildNamedStore(object, name, value, TypeFeedbackId::None()); | 1974 BuildNamedStore(object, name, value, TypeFeedbackId::None()); |
1959 PrepareFrameState(store, bailout_id); | 1975 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); |
1960 break; | 1976 break; |
1961 } | 1977 } |
1962 case KEYED_PROPERTY: { | 1978 case KEYED_PROPERTY: { |
1963 environment()->Push(value); | 1979 environment()->Push(value); |
1964 VisitForValue(property->obj()); | 1980 VisitForValue(property->obj()); |
1965 VisitForValue(property->key()); | 1981 VisitForValue(property->key()); |
1966 { | 1982 FrameStateBeforeAndAfter states(this, property->key()->id()); |
1967 // TODO(jarin) Provide a real frame state before. | 1983 Node* key = environment()->Pop(); |
1968 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 1984 Node* object = environment()->Pop(); |
1969 Node* key = environment()->Pop(); | 1985 value = environment()->Pop(); |
1970 Node* object = environment()->Pop(); | 1986 Node* store = BuildKeyedStore(object, key, value, TypeFeedbackId::None()); |
1971 value = environment()->Pop(); | 1987 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); |
1972 Node* store = | |
1973 BuildKeyedStore(object, key, value, TypeFeedbackId::None()); | |
1974 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); | |
1975 } | |
1976 break; | 1988 break; |
1977 } | 1989 } |
1978 } | 1990 } |
1979 } | 1991 } |
1980 | 1992 |
1981 | 1993 |
1982 void AstGraphBuilder::VisitAssignment(Assignment* expr) { | 1994 void AstGraphBuilder::VisitAssignment(Assignment* expr) { |
1983 DCHECK(expr->target()->IsValidReferenceExpression()); | 1995 DCHECK(expr->target()->IsValidReferenceExpression()); |
1984 | 1996 |
1985 // Left-hand side can only be a property, a global or a variable slot. | 1997 // Left-hand side can only be a property, a global or a variable slot. |
(...skipping 25 matching lines...) Expand all Loading... |
2011 BailoutId before_store_id = BailoutId::None(); | 2023 BailoutId before_store_id = BailoutId::None(); |
2012 // Evaluate the value and potentially handle compound assignments by loading | 2024 // Evaluate the value and potentially handle compound assignments by loading |
2013 // the left-hand side value and performing a binary operation. | 2025 // the left-hand side value and performing a binary operation. |
2014 if (expr->is_compound()) { | 2026 if (expr->is_compound()) { |
2015 Node* old_value = NULL; | 2027 Node* old_value = NULL; |
2016 switch (assign_type) { | 2028 switch (assign_type) { |
2017 case VARIABLE: { | 2029 case VARIABLE: { |
2018 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 2030 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
2019 VectorSlotPair pair = | 2031 VectorSlotPair pair = |
2020 CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 2032 CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
2021 old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair); | 2033 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); |
| 2034 old_value = |
| 2035 BuildVariableLoad(states, proxy->var(), expr->target()->id(), pair, |
| 2036 OutputFrameStateCombine::Push()); |
2022 break; | 2037 break; |
2023 } | 2038 } |
2024 case NAMED_PROPERTY: { | 2039 case NAMED_PROPERTY: { |
2025 Node* object = environment()->Top(); | 2040 Node* object = environment()->Top(); |
2026 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2041 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2027 VectorSlotPair pair = | 2042 VectorSlotPair pair = |
2028 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2043 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
| 2044 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
2029 old_value = | 2045 old_value = |
2030 BuildNamedLoad(object, name, pair, property->PropertyFeedbackId()); | 2046 BuildNamedLoad(object, name, pair, property->PropertyFeedbackId()); |
2031 PrepareFrameState(old_value, property->LoadId(), | 2047 states.AddToNode(old_value, property->LoadId(), |
2032 OutputFrameStateCombine::Push()); | 2048 OutputFrameStateCombine::Push()); |
2033 break; | 2049 break; |
2034 } | 2050 } |
2035 case KEYED_PROPERTY: { | 2051 case KEYED_PROPERTY: { |
2036 Node* key = environment()->Top(); | 2052 Node* key = environment()->Top(); |
2037 Node* object = environment()->Peek(1); | 2053 Node* object = environment()->Peek(1); |
2038 VectorSlotPair pair = | 2054 VectorSlotPair pair = |
2039 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2055 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
| 2056 FrameStateBeforeAndAfter states(this, property->key()->id()); |
2040 old_value = | 2057 old_value = |
2041 BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId()); | 2058 BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId()); |
2042 PrepareFrameState(old_value, property->LoadId(), | 2059 states.AddToNode(old_value, property->LoadId(), |
2043 OutputFrameStateCombine::Push()); | 2060 OutputFrameStateCombine::Push()); |
2044 break; | 2061 break; |
2045 } | 2062 } |
2046 } | 2063 } |
2047 environment()->Push(old_value); | 2064 environment()->Push(old_value); |
2048 VisitForValue(expr->value()); | 2065 VisitForValue(expr->value()); |
2049 Node* value; | 2066 Node* value; |
2050 { | 2067 { |
2051 FrameStateBeforeAndAfter states(this, expr->value()->id()); | 2068 FrameStateBeforeAndAfter states(this, expr->value()->id()); |
2052 Node* right = environment()->Pop(); | 2069 Node* right = environment()->Pop(); |
2053 Node* left = environment()->Pop(); | 2070 Node* left = environment()->Pop(); |
(...skipping 11 matching lines...) Expand all Loading... |
2065 before_store_id = expr->value()->id(); | 2082 before_store_id = expr->value()->id(); |
2066 } | 2083 } |
2067 } | 2084 } |
2068 | 2085 |
2069 FrameStateBeforeAndAfter store_states(this, before_store_id); | 2086 FrameStateBeforeAndAfter store_states(this, before_store_id); |
2070 // Store the value. | 2087 // Store the value. |
2071 Node* value = environment()->Pop(); | 2088 Node* value = environment()->Pop(); |
2072 switch (assign_type) { | 2089 switch (assign_type) { |
2073 case VARIABLE: { | 2090 case VARIABLE: { |
2074 Variable* variable = expr->target()->AsVariableProxy()->var(); | 2091 Variable* variable = expr->target()->AsVariableProxy()->var(); |
2075 BuildVariableAssignment(variable, value, expr->op(), expr->id(), | 2092 BuildVariableAssignment(store_states, variable, value, expr->op(), |
2076 ast_context()->GetStateCombine()); | 2093 expr->id(), ast_context()->GetStateCombine()); |
2077 break; | 2094 break; |
2078 } | 2095 } |
2079 case NAMED_PROPERTY: { | 2096 case NAMED_PROPERTY: { |
2080 Node* object = environment()->Pop(); | 2097 Node* object = environment()->Pop(); |
2081 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2098 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2082 Node* store = | 2099 Node* store = |
2083 BuildNamedStore(object, name, value, expr->AssignmentFeedbackId()); | 2100 BuildNamedStore(object, name, value, expr->AssignmentFeedbackId()); |
2084 store_states.AddToNode(store, expr->id(), | 2101 store_states.AddToNode(store, expr->id(), |
2085 ast_context()->GetStateCombine()); | 2102 ast_context()->GetStateCombine()); |
2086 break; | 2103 break; |
(...skipping 26 matching lines...) Expand all Loading... |
2113 Node* value = BuildThrowError(exception, expr->id()); | 2130 Node* value = BuildThrowError(exception, expr->id()); |
2114 ast_context()->ProduceValue(value); | 2131 ast_context()->ProduceValue(value); |
2115 } | 2132 } |
2116 | 2133 |
2117 | 2134 |
2118 void AstGraphBuilder::VisitProperty(Property* expr) { | 2135 void AstGraphBuilder::VisitProperty(Property* expr) { |
2119 Node* value; | 2136 Node* value; |
2120 VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot()); | 2137 VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot()); |
2121 if (expr->key()->IsPropertyName()) { | 2138 if (expr->key()->IsPropertyName()) { |
2122 VisitForValue(expr->obj()); | 2139 VisitForValue(expr->obj()); |
| 2140 FrameStateBeforeAndAfter states(this, expr->obj()->id()); |
2123 Node* object = environment()->Pop(); | 2141 Node* object = environment()->Pop(); |
2124 Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); | 2142 Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); |
2125 value = BuildNamedLoad(object, name, pair, expr->PropertyFeedbackId()); | 2143 value = BuildNamedLoad(object, name, pair, expr->PropertyFeedbackId()); |
| 2144 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); |
2126 } else { | 2145 } else { |
2127 VisitForValue(expr->obj()); | 2146 VisitForValue(expr->obj()); |
2128 VisitForValue(expr->key()); | 2147 VisitForValue(expr->key()); |
| 2148 FrameStateBeforeAndAfter states(this, expr->key()->id()); |
2129 Node* key = environment()->Pop(); | 2149 Node* key = environment()->Pop(); |
2130 Node* object = environment()->Pop(); | 2150 Node* object = environment()->Pop(); |
2131 value = BuildKeyedLoad(object, key, pair, expr->PropertyFeedbackId()); | 2151 value = BuildKeyedLoad(object, key, pair, expr->PropertyFeedbackId()); |
| 2152 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); |
2132 } | 2153 } |
2133 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | |
2134 ast_context()->ProduceValue(value); | 2154 ast_context()->ProduceValue(value); |
2135 } | 2155 } |
2136 | 2156 |
2137 | 2157 |
2138 void AstGraphBuilder::VisitCall(Call* expr) { | 2158 void AstGraphBuilder::VisitCall(Call* expr) { |
2139 Expression* callee = expr->expression(); | 2159 Expression* callee = expr->expression(); |
2140 Call::CallType call_type = expr->GetCallType(isolate()); | 2160 Call::CallType call_type = expr->GetCallType(isolate()); |
2141 | 2161 |
2142 // Prepare the callee and the receiver to the function call. This depends on | 2162 // Prepare the callee and the receiver to the function call. This depends on |
2143 // the semantics of the underlying call type. | 2163 // the semantics of the underlying call type. |
2144 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; | 2164 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; |
2145 Node* receiver_value = NULL; | 2165 Node* receiver_value = NULL; |
2146 Node* callee_value = NULL; | 2166 Node* callee_value = NULL; |
2147 bool possibly_eval = false; | 2167 bool possibly_eval = false; |
2148 switch (call_type) { | 2168 switch (call_type) { |
2149 case Call::GLOBAL_CALL: { | 2169 case Call::GLOBAL_CALL: { |
2150 VariableProxy* proxy = callee->AsVariableProxy(); | 2170 VariableProxy* proxy = callee->AsVariableProxy(); |
2151 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 2171 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
| 2172 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); |
2152 callee_value = | 2173 callee_value = |
2153 BuildVariableLoad(proxy->var(), expr->expression()->id(), pair); | 2174 BuildVariableLoad(states, proxy->var(), expr->expression()->id(), |
| 2175 pair, OutputFrameStateCombine::Push()); |
2154 receiver_value = jsgraph()->UndefinedConstant(); | 2176 receiver_value = jsgraph()->UndefinedConstant(); |
2155 break; | 2177 break; |
2156 } | 2178 } |
2157 case Call::LOOKUP_SLOT_CALL: { | 2179 case Call::LOOKUP_SLOT_CALL: { |
2158 Variable* variable = callee->AsVariableProxy()->var(); | 2180 Variable* variable = callee->AsVariableProxy()->var(); |
2159 DCHECK(variable->location() == Variable::LOOKUP); | 2181 DCHECK(variable->location() == Variable::LOOKUP); |
2160 Node* name = jsgraph()->Constant(variable->name()); | 2182 Node* name = jsgraph()->Constant(variable->name()); |
2161 const Operator* op = | 2183 const Operator* op = |
2162 javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2); | 2184 javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2); |
2163 Node* pair = NewNode(op, current_context(), name); | 2185 Node* pair = NewNode(op, current_context(), name); |
2164 callee_value = NewNode(common()->Projection(0), pair); | 2186 callee_value = NewNode(common()->Projection(0), pair); |
2165 receiver_value = NewNode(common()->Projection(1), pair); | 2187 receiver_value = NewNode(common()->Projection(1), pair); |
2166 | 2188 |
2167 PrepareFrameState(pair, expr->EvalOrLookupId(), | 2189 PrepareFrameState(pair, expr->EvalOrLookupId(), |
2168 OutputFrameStateCombine::Push(2)); | 2190 OutputFrameStateCombine::Push(2)); |
2169 break; | 2191 break; |
2170 } | 2192 } |
2171 case Call::PROPERTY_CALL: { | 2193 case Call::PROPERTY_CALL: { |
2172 Property* property = callee->AsProperty(); | 2194 Property* property = callee->AsProperty(); |
2173 VisitForValue(property->obj()); | 2195 VisitForValue(property->obj()); |
2174 Node* object = environment()->Top(); | 2196 Node* object = environment()->Top(); |
2175 VectorSlotPair pair = | 2197 VectorSlotPair pair = |
2176 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2198 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2177 if (property->key()->IsPropertyName()) { | 2199 if (property->key()->IsPropertyName()) { |
| 2200 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
2178 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2201 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2179 callee_value = | 2202 callee_value = |
2180 BuildNamedLoad(object, name, pair, property->PropertyFeedbackId()); | 2203 BuildNamedLoad(object, name, pair, property->PropertyFeedbackId()); |
| 2204 states.AddToNode(callee_value, property->LoadId(), |
| 2205 OutputFrameStateCombine::Push()); |
2181 } else { | 2206 } else { |
2182 VisitForValue(property->key()); | 2207 VisitForValue(property->key()); |
| 2208 FrameStateBeforeAndAfter states(this, property->key()->id()); |
2183 Node* key = environment()->Pop(); | 2209 Node* key = environment()->Pop(); |
2184 callee_value = | 2210 callee_value = |
2185 BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId()); | 2211 BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId()); |
| 2212 states.AddToNode(callee_value, property->LoadId(), |
| 2213 OutputFrameStateCombine::Push()); |
2186 } | 2214 } |
2187 PrepareFrameState(callee_value, property->LoadId(), | |
2188 OutputFrameStateCombine::Push()); | |
2189 receiver_value = environment()->Pop(); | 2215 receiver_value = environment()->Pop(); |
2190 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an | 2216 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an |
2191 // object for sloppy callees. This could also be modeled explicitly here, | 2217 // object for sloppy callees. This could also be modeled explicitly here, |
2192 // thereby obsoleting the need for a flag to the call operator. | 2218 // thereby obsoleting the need for a flag to the call operator. |
2193 flags = CALL_AS_METHOD; | 2219 flags = CALL_AS_METHOD; |
2194 break; | 2220 break; |
2195 } | 2221 } |
2196 case Call::SUPER_CALL: | 2222 case Call::SUPER_CALL: |
2197 // TODO(dslomov): Implement super calls. | 2223 // TODO(dslomov): Implement super calls. |
2198 callee_value = jsgraph()->UndefinedConstant(); | 2224 callee_value = jsgraph()->UndefinedConstant(); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2288 | 2314 |
2289 | 2315 |
2290 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { | 2316 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { |
2291 Handle<String> name = expr->name(); | 2317 Handle<String> name = expr->name(); |
2292 | 2318 |
2293 // The callee and the receiver both have to be pushed onto the operand stack | 2319 // The callee and the receiver both have to be pushed onto the operand stack |
2294 // before arguments are being evaluated. | 2320 // before arguments are being evaluated. |
2295 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; | 2321 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; |
2296 Node* receiver_value = BuildLoadBuiltinsObject(); | 2322 Node* receiver_value = BuildLoadBuiltinsObject(); |
2297 VectorSlotPair pair = CreateVectorSlotPair(expr->CallRuntimeFeedbackSlot()); | 2323 VectorSlotPair pair = CreateVectorSlotPair(expr->CallRuntimeFeedbackSlot()); |
| 2324 // TODO(jarin): bailout ids for runtime calls. |
| 2325 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
2298 Node* callee_value = | 2326 Node* callee_value = |
2299 BuildNamedLoad(receiver_value, name, pair, expr->CallRuntimeFeedbackId()); | 2327 BuildNamedLoad(receiver_value, name, pair, expr->CallRuntimeFeedbackId()); |
2300 // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft | 2328 states.AddToNode(callee_value, BailoutId::None(), |
2301 // refuses to optimize functions with jsruntime calls). | 2329 OutputFrameStateCombine::Push()); |
2302 PrepareFrameState(callee_value, BailoutId::None(), | |
2303 OutputFrameStateCombine::Push()); | |
2304 environment()->Push(callee_value); | 2330 environment()->Push(callee_value); |
2305 environment()->Push(receiver_value); | 2331 environment()->Push(receiver_value); |
2306 | 2332 |
2307 // Evaluate all arguments to the JS runtime call. | 2333 // Evaluate all arguments to the JS runtime call. |
2308 ZoneList<Expression*>* args = expr->arguments(); | 2334 ZoneList<Expression*>* args = expr->arguments(); |
2309 VisitForValues(args); | 2335 VisitForValues(args); |
2310 | 2336 |
2311 // Create node to perform the JS runtime call. | 2337 // Create node to perform the JS runtime call. |
2312 const Operator* call = | 2338 const Operator* call = |
2313 javascript()->CallFunction(args->length() + 2, flags, language_mode()); | 2339 javascript()->CallFunction(args->length() + 2, flags, language_mode()); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2367 bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect(); | 2393 bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect(); |
2368 if (is_postfix) environment()->Push(jsgraph()->UndefinedConstant()); | 2394 if (is_postfix) environment()->Push(jsgraph()->UndefinedConstant()); |
2369 | 2395 |
2370 // Evaluate LHS expression and get old value. | 2396 // Evaluate LHS expression and get old value. |
2371 Node* old_value = NULL; | 2397 Node* old_value = NULL; |
2372 int stack_depth = -1; | 2398 int stack_depth = -1; |
2373 switch (assign_type) { | 2399 switch (assign_type) { |
2374 case VARIABLE: { | 2400 case VARIABLE: { |
2375 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 2401 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
2376 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 2402 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
| 2403 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); |
2377 old_value = | 2404 old_value = |
2378 BuildVariableLoad(proxy->var(), expr->expression()->id(), pair); | 2405 BuildVariableLoad(states, proxy->var(), expr->expression()->id(), |
| 2406 pair, OutputFrameStateCombine::Push()); |
2379 stack_depth = 0; | 2407 stack_depth = 0; |
2380 break; | 2408 break; |
2381 } | 2409 } |
2382 case NAMED_PROPERTY: { | 2410 case NAMED_PROPERTY: { |
2383 VisitForValue(property->obj()); | 2411 VisitForValue(property->obj()); |
| 2412 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
2384 Node* object = environment()->Top(); | 2413 Node* object = environment()->Top(); |
2385 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2414 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2386 VectorSlotPair pair = | 2415 VectorSlotPair pair = |
2387 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2416 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2388 old_value = | 2417 old_value = |
2389 BuildNamedLoad(object, name, pair, property->PropertyFeedbackId()); | 2418 BuildNamedLoad(object, name, pair, property->PropertyFeedbackId()); |
2390 PrepareFrameState(old_value, property->LoadId(), | 2419 states.AddToNode(old_value, property->LoadId(), |
2391 OutputFrameStateCombine::Push()); | 2420 OutputFrameStateCombine::Push()); |
2392 stack_depth = 1; | 2421 stack_depth = 1; |
2393 break; | 2422 break; |
2394 } | 2423 } |
2395 case KEYED_PROPERTY: { | 2424 case KEYED_PROPERTY: { |
2396 VisitForValue(property->obj()); | 2425 VisitForValue(property->obj()); |
2397 VisitForValue(property->key()); | 2426 VisitForValue(property->key()); |
| 2427 FrameStateBeforeAndAfter states(this, property->key()->id()); |
2398 Node* key = environment()->Top(); | 2428 Node* key = environment()->Top(); |
2399 Node* object = environment()->Peek(1); | 2429 Node* object = environment()->Peek(1); |
2400 VectorSlotPair pair = | 2430 VectorSlotPair pair = |
2401 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2431 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2402 old_value = | 2432 old_value = |
2403 BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId()); | 2433 BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId()); |
2404 PrepareFrameState(old_value, property->LoadId(), | 2434 states.AddToNode(old_value, property->LoadId(), |
2405 OutputFrameStateCombine::Push()); | 2435 OutputFrameStateCombine::Push()); |
2406 stack_depth = 2; | 2436 stack_depth = 2; |
2407 break; | 2437 break; |
2408 } | 2438 } |
2409 } | 2439 } |
2410 | 2440 |
2411 // Convert old value into a number. | 2441 // Convert old value into a number. |
2412 old_value = NewNode(javascript()->ToNumber(), old_value); | 2442 old_value = NewNode(javascript()->ToNumber(), old_value); |
2413 PrepareFrameState(old_value, expr->ToNumberId(), | 2443 PrepareFrameState(old_value, expr->ToNumberId(), |
2414 OutputFrameStateCombine::Push()); | 2444 OutputFrameStateCombine::Push()); |
2415 | 2445 |
(...skipping 15 matching lines...) Expand all Loading... |
2431 // before. | 2461 // before. |
2432 states.AddToNode(value, BailoutId::None(), | 2462 states.AddToNode(value, BailoutId::None(), |
2433 OutputFrameStateCombine::Ignore()); | 2463 OutputFrameStateCombine::Ignore()); |
2434 } | 2464 } |
2435 | 2465 |
2436 // Store the value. | 2466 // Store the value. |
2437 switch (assign_type) { | 2467 switch (assign_type) { |
2438 case VARIABLE: { | 2468 case VARIABLE: { |
2439 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 2469 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
2440 environment()->Push(value); | 2470 environment()->Push(value); |
2441 BuildVariableAssignment(variable, value, expr->op(), | 2471 BuildVariableAssignment(store_states, variable, value, expr->op(), |
2442 expr->AssignmentId()); | 2472 expr->AssignmentId()); |
2443 environment()->Pop(); | 2473 environment()->Pop(); |
2444 break; | 2474 break; |
2445 } | 2475 } |
2446 case NAMED_PROPERTY: { | 2476 case NAMED_PROPERTY: { |
2447 Node* object = environment()->Pop(); | 2477 Node* object = environment()->Pop(); |
2448 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2478 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2449 Node* store = | 2479 Node* store = |
2450 BuildNamedStore(object, name, value, expr->CountStoreFeedbackId()); | 2480 BuildNamedStore(object, name, value, expr->CountStoreFeedbackId()); |
2451 environment()->Push(value); | 2481 environment()->Push(value); |
2452 PrepareFrameState(store, expr->AssignmentId()); | 2482 store_states.AddToNode(store, expr->AssignmentId(), |
| 2483 OutputFrameStateCombine::Ignore()); |
2453 environment()->Pop(); | 2484 environment()->Pop(); |
2454 break; | 2485 break; |
2455 } | 2486 } |
2456 case KEYED_PROPERTY: { | 2487 case KEYED_PROPERTY: { |
2457 Node* key = environment()->Pop(); | 2488 Node* key = environment()->Pop(); |
2458 Node* object = environment()->Pop(); | 2489 Node* object = environment()->Pop(); |
2459 Node* store = | 2490 Node* store = |
2460 BuildKeyedStore(object, key, value, expr->CountStoreFeedbackId()); | 2491 BuildKeyedStore(object, key, value, expr->CountStoreFeedbackId()); |
2461 environment()->Push(value); | 2492 environment()->Push(value); |
2462 store_states.AddToNode(store, expr->AssignmentId(), | 2493 store_states.AddToNode(store, expr->AssignmentId(), |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2632 } | 2663 } |
2633 | 2664 |
2634 | 2665 |
2635 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) { | 2666 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) { |
2636 Node* operand; | 2667 Node* operand; |
2637 if (expr->expression()->IsVariableProxy()) { | 2668 if (expr->expression()->IsVariableProxy()) { |
2638 // Typeof does not throw a reference error on global variables, hence we | 2669 // Typeof does not throw a reference error on global variables, hence we |
2639 // perform a non-contextual load in case the operand is a variable proxy. | 2670 // perform a non-contextual load in case the operand is a variable proxy. |
2640 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 2671 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
2641 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 2672 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
2642 operand = BuildVariableLoad(proxy->var(), expr->expression()->id(), pair, | 2673 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); |
2643 NOT_CONTEXTUAL); | 2674 operand = |
| 2675 BuildVariableLoad(states, proxy->var(), expr->expression()->id(), pair, |
| 2676 OutputFrameStateCombine::Push(), NOT_CONTEXTUAL); |
2644 } else { | 2677 } else { |
2645 VisitForValue(expr->expression()); | 2678 VisitForValue(expr->expression()); |
2646 operand = environment()->Pop(); | 2679 operand = environment()->Pop(); |
2647 } | 2680 } |
2648 Node* value = NewNode(javascript()->TypeOf(), operand); | 2681 Node* value = NewNode(javascript()->TypeOf(), operand); |
2649 ast_context()->ProduceValue(value); | 2682 ast_context()->ProduceValue(value); |
2650 } | 2683 } |
2651 | 2684 |
2652 | 2685 |
2653 void AstGraphBuilder::VisitNot(UnaryOperation* expr) { | 2686 void AstGraphBuilder::VisitNot(UnaryOperation* expr) { |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2803 if (arguments == NULL) return NULL; | 2836 if (arguments == NULL) return NULL; |
2804 | 2837 |
2805 // Allocate and initialize a new arguments object. | 2838 // Allocate and initialize a new arguments object. |
2806 Node* callee = GetFunctionClosure(); | 2839 Node* callee = GetFunctionClosure(); |
2807 const Operator* op = javascript()->CallRuntime(Runtime::kNewArguments, 1); | 2840 const Operator* op = javascript()->CallRuntime(Runtime::kNewArguments, 1); |
2808 Node* object = NewNode(op, callee); | 2841 Node* object = NewNode(op, callee); |
2809 | 2842 |
2810 // Assign the object to the arguments variable. | 2843 // Assign the object to the arguments variable. |
2811 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); | 2844 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); |
2812 // This should never lazy deopt, so it is fine to send invalid bailout id. | 2845 // This should never lazy deopt, so it is fine to send invalid bailout id. |
2813 BuildVariableAssignment(arguments, object, Token::ASSIGN, BailoutId::None()); | 2846 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
| 2847 BuildVariableAssignment(states, arguments, object, Token::ASSIGN, |
| 2848 BailoutId::None()); |
2814 | 2849 |
2815 return object; | 2850 return object; |
2816 } | 2851 } |
2817 | 2852 |
2818 | 2853 |
2819 Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest, int index) { | 2854 Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest, int index) { |
2820 if (rest == NULL) return NULL; | 2855 if (rest == NULL) return NULL; |
2821 | 2856 |
2822 DCHECK(index >= 0); | 2857 DCHECK(index >= 0); |
2823 const Operator* op = javascript()->CallRuntime(Runtime::kNewRestParamSlow, 1); | 2858 const Operator* op = javascript()->CallRuntime(Runtime::kNewRestParamSlow, 1); |
2824 Node* object = NewNode(op, jsgraph()->SmiConstant(index)); | 2859 Node* object = NewNode(op, jsgraph()->SmiConstant(index)); |
2825 | 2860 |
2826 // Assign the object to the rest array | 2861 // Assign the object to the rest array |
2827 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); | 2862 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); |
2828 // This should never lazy deopt, so it is fine to send invalid bailout id. | 2863 // This should never lazy deopt, so it is fine to send invalid bailout id. |
2829 BuildVariableAssignment(rest, object, Token::ASSIGN, BailoutId::None()); | 2864 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
| 2865 BuildVariableAssignment(states, rest, object, Token::ASSIGN, |
| 2866 BailoutId::None()); |
2830 | 2867 |
2831 return object; | 2868 return object; |
2832 } | 2869 } |
2833 | 2870 |
2834 | 2871 |
2835 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole, | 2872 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole, |
2836 Node* not_hole) { | 2873 Node* not_hole) { |
2837 Node* the_hole = jsgraph()->TheHoleConstant(); | 2874 Node* the_hole = jsgraph()->TheHoleConstant(); |
2838 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); | 2875 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); |
2839 return NewNode(common()->Select(kMachAnyTagged, BranchHint::kFalse), check, | 2876 return NewNode(common()->Select(kMachAnyTagged, BranchHint::kFalse), check, |
(...skipping 28 matching lines...) Expand all Loading... |
2868 prototype_check.Then(); | 2905 prototype_check.Then(); |
2869 Node* error = BuildThrowStaticPrototypeError(bailout_id); | 2906 Node* error = BuildThrowStaticPrototypeError(bailout_id); |
2870 environment()->Push(error); | 2907 environment()->Push(error); |
2871 prototype_check.Else(); | 2908 prototype_check.Else(); |
2872 environment()->Push(name); | 2909 environment()->Push(name); |
2873 prototype_check.End(); | 2910 prototype_check.End(); |
2874 return environment()->Pop(); | 2911 return environment()->Pop(); |
2875 } | 2912 } |
2876 | 2913 |
2877 | 2914 |
2878 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, | 2915 Node* AstGraphBuilder::BuildVariableLoad(FrameStateBeforeAndAfter& states, |
| 2916 Variable* variable, |
2879 BailoutId bailout_id, | 2917 BailoutId bailout_id, |
2880 const VectorSlotPair& feedback, | 2918 const VectorSlotPair& feedback, |
| 2919 OutputFrameStateCombine combine, |
2881 ContextualMode contextual_mode) { | 2920 ContextualMode contextual_mode) { |
2882 Node* the_hole = jsgraph()->TheHoleConstant(); | 2921 Node* the_hole = jsgraph()->TheHoleConstant(); |
2883 VariableMode mode = variable->mode(); | 2922 VariableMode mode = variable->mode(); |
2884 switch (variable->location()) { | 2923 switch (variable->location()) { |
2885 case Variable::UNALLOCATED: { | 2924 case Variable::UNALLOCATED: { |
2886 // Global var, const, or let variable. | 2925 // Global var, const, or let variable. |
2887 Node* global = BuildLoadGlobalObject(); | 2926 Node* global = BuildLoadGlobalObject(); |
2888 Handle<Name> name = variable->name(); | 2927 Handle<Name> name = variable->name(); |
2889 Node* node = BuildNamedLoad(global, name, feedback, | 2928 Node* node = BuildNamedLoad(global, name, feedback, |
2890 TypeFeedbackId::None(), contextual_mode); | 2929 TypeFeedbackId::None(), contextual_mode); |
2891 PrepareFrameState(node, bailout_id, OutputFrameStateCombine::Push()); | 2930 states.AddToNode(node, bailout_id, combine); |
2892 return node; | 2931 return node; |
2893 } | 2932 } |
2894 case Variable::PARAMETER: | 2933 case Variable::PARAMETER: |
2895 case Variable::LOCAL: { | 2934 case Variable::LOCAL: { |
2896 // Local var, const, or let variable. | 2935 // Local var, const, or let variable. |
2897 Node* value = environment()->Lookup(variable); | 2936 Node* value = environment()->Lookup(variable); |
2898 if (mode == CONST_LEGACY) { | 2937 if (mode == CONST_LEGACY) { |
2899 // Perform check for uninitialized legacy const variables. | 2938 // Perform check for uninitialized legacy const variables. |
2900 if (value->op() == the_hole->op()) { | 2939 if (value->op() == the_hole->op()) { |
2901 value = jsgraph()->UndefinedConstant(); | 2940 value = jsgraph()->UndefinedConstant(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2944 Node* pair = NewNode(op, current_context(), name); | 2983 Node* pair = NewNode(op, current_context(), name); |
2945 PrepareFrameState(pair, bailout_id, OutputFrameStateCombine::Push(1)); | 2984 PrepareFrameState(pair, bailout_id, OutputFrameStateCombine::Push(1)); |
2946 return NewNode(common()->Projection(0), pair); | 2985 return NewNode(common()->Projection(0), pair); |
2947 } | 2986 } |
2948 } | 2987 } |
2949 UNREACHABLE(); | 2988 UNREACHABLE(); |
2950 return NULL; | 2989 return NULL; |
2951 } | 2990 } |
2952 | 2991 |
2953 | 2992 |
2954 Node* AstGraphBuilder::BuildVariableDelete( | 2993 Node* AstGraphBuilder::BuildVariableDelete(Variable* variable, |
2955 Variable* variable, BailoutId bailout_id, | 2994 BailoutId bailout_id, |
2956 OutputFrameStateCombine state_combine) { | 2995 OutputFrameStateCombine combine) { |
2957 switch (variable->location()) { | 2996 switch (variable->location()) { |
2958 case Variable::UNALLOCATED: { | 2997 case Variable::UNALLOCATED: { |
2959 // Global var, const, or let variable. | 2998 // Global var, const, or let variable. |
2960 Node* global = BuildLoadGlobalObject(); | 2999 Node* global = BuildLoadGlobalObject(); |
2961 Node* name = jsgraph()->Constant(variable->name()); | 3000 Node* name = jsgraph()->Constant(variable->name()); |
2962 const Operator* op = javascript()->DeleteProperty(language_mode()); | 3001 const Operator* op = javascript()->DeleteProperty(language_mode()); |
2963 Node* result = NewNode(op, global, name); | 3002 Node* result = NewNode(op, global, name); |
2964 PrepareFrameState(result, bailout_id, state_combine); | 3003 PrepareFrameState(result, bailout_id, combine); |
2965 return result; | 3004 return result; |
2966 } | 3005 } |
2967 case Variable::PARAMETER: | 3006 case Variable::PARAMETER: |
2968 case Variable::LOCAL: | 3007 case Variable::LOCAL: |
2969 case Variable::CONTEXT: | 3008 case Variable::CONTEXT: |
2970 // Local var, const, or let variable or context variable. | 3009 // Local var, const, or let variable or context variable. |
2971 return jsgraph()->BooleanConstant(variable->is_this()); | 3010 return jsgraph()->BooleanConstant(variable->is_this()); |
2972 case Variable::LOOKUP: { | 3011 case Variable::LOOKUP: { |
2973 // Dynamic lookup of context variable (anywhere in the chain). | 3012 // Dynamic lookup of context variable (anywhere in the chain). |
2974 Node* name = jsgraph()->Constant(variable->name()); | 3013 Node* name = jsgraph()->Constant(variable->name()); |
2975 const Operator* op = | 3014 const Operator* op = |
2976 javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2); | 3015 javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2); |
2977 Node* result = NewNode(op, current_context(), name); | 3016 Node* result = NewNode(op, current_context(), name); |
2978 PrepareFrameState(result, bailout_id, state_combine); | 3017 PrepareFrameState(result, bailout_id, combine); |
2979 return result; | 3018 return result; |
2980 } | 3019 } |
2981 } | 3020 } |
2982 UNREACHABLE(); | 3021 UNREACHABLE(); |
2983 return NULL; | 3022 return NULL; |
2984 } | 3023 } |
2985 | 3024 |
2986 | 3025 |
2987 Node* AstGraphBuilder::BuildVariableAssignment( | 3026 Node* AstGraphBuilder::BuildVariableAssignment( |
2988 Variable* variable, Node* value, Token::Value op, BailoutId bailout_id, | 3027 FrameStateBeforeAndAfter& states, Variable* variable, Node* value, |
2989 OutputFrameStateCombine combine) { | 3028 Token::Value op, BailoutId bailout_id, OutputFrameStateCombine combine) { |
2990 Node* the_hole = jsgraph()->TheHoleConstant(); | 3029 Node* the_hole = jsgraph()->TheHoleConstant(); |
2991 VariableMode mode = variable->mode(); | 3030 VariableMode mode = variable->mode(); |
2992 switch (variable->location()) { | 3031 switch (variable->location()) { |
2993 case Variable::UNALLOCATED: { | 3032 case Variable::UNALLOCATED: { |
2994 // Global var, const, or let variable. | 3033 // Global var, const, or let variable. |
2995 Node* global = BuildLoadGlobalObject(); | 3034 Node* global = BuildLoadGlobalObject(); |
2996 Handle<Name> name = variable->name(); | 3035 Handle<Name> name = variable->name(); |
2997 Node* store = | 3036 Node* store = |
2998 BuildNamedStore(global, name, value, TypeFeedbackId::None()); | 3037 BuildNamedStore(global, name, value, TypeFeedbackId::None()); |
2999 PrepareFrameState(store, bailout_id, combine); | 3038 states.AddToNode(store, bailout_id, combine); |
3000 return store; | 3039 return store; |
3001 } | 3040 } |
3002 case Variable::PARAMETER: | 3041 case Variable::PARAMETER: |
3003 case Variable::LOCAL: | 3042 case Variable::LOCAL: |
3004 // Local var, const, or let variable. | 3043 // Local var, const, or let variable. |
3005 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { | 3044 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { |
3006 // Perform an initialization check for legacy const variables. | 3045 // Perform an initialization check for legacy const variables. |
3007 Node* current = environment()->Lookup(variable); | 3046 Node* current = environment()->Lookup(variable); |
3008 if (current->op() != the_hole->op()) { | 3047 if (current->op() != the_hole->op()) { |
3009 value = BuildHoleCheckSilent(current, value, current); | 3048 value = BuildHoleCheckSilent(current, value, current); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3208 Node* name = NewNode(javascript()->ToName(), input); | 3247 Node* name = NewNode(javascript()->ToName(), input); |
3209 PrepareFrameState(name, bailout_id); | 3248 PrepareFrameState(name, bailout_id); |
3210 return name; | 3249 return name; |
3211 } | 3250 } |
3212 | 3251 |
3213 | 3252 |
3214 Node* AstGraphBuilder::BuildSetHomeObject(Node* value, Node* home_object, | 3253 Node* AstGraphBuilder::BuildSetHomeObject(Node* value, Node* home_object, |
3215 Expression* expr) { | 3254 Expression* expr) { |
3216 if (!FunctionLiteral::NeedsHomeObject(expr)) return value; | 3255 if (!FunctionLiteral::NeedsHomeObject(expr)) return value; |
3217 Handle<Name> name = isolate()->factory()->home_object_symbol(); | 3256 Handle<Name> name = isolate()->factory()->home_object_symbol(); |
| 3257 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
3218 Node* store = | 3258 Node* store = |
3219 BuildNamedStore(value, name, home_object, TypeFeedbackId::None()); | 3259 BuildNamedStore(value, name, home_object, TypeFeedbackId::None()); |
3220 PrepareFrameState(store, BailoutId::None()); | 3260 states.AddToNode(store, BailoutId::None(), OutputFrameStateCombine::Ignore()); |
3221 return store; | 3261 return store; |
3222 } | 3262 } |
3223 | 3263 |
3224 | 3264 |
3225 Node* AstGraphBuilder::BuildThrowError(Node* exception, BailoutId bailout_id) { | 3265 Node* AstGraphBuilder::BuildThrowError(Node* exception, BailoutId bailout_id) { |
3226 const Operator* op = javascript()->CallRuntime(Runtime::kThrow, 1); | 3266 const Operator* op = javascript()->CallRuntime(Runtime::kThrow, 1); |
3227 Node* call = NewNode(op, exception); | 3267 Node* call = NewNode(op, exception); |
3228 PrepareFrameState(call, bailout_id); | 3268 PrepareFrameState(call, bailout_id); |
3229 Node* control = NewNode(common()->Throw(), call); | 3269 Node* control = NewNode(common()->Throw(), call); |
3230 UpdateControlDependencyToLeaveFunction(control); | 3270 UpdateControlDependencyToLeaveFunction(control); |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3639 // Phi does not exist yet, introduce one. | 3679 // Phi does not exist yet, introduce one. |
3640 value = NewPhi(inputs, value, control); | 3680 value = NewPhi(inputs, value, control); |
3641 value->ReplaceInput(inputs - 1, other); | 3681 value->ReplaceInput(inputs - 1, other); |
3642 } | 3682 } |
3643 return value; | 3683 return value; |
3644 } | 3684 } |
3645 | 3685 |
3646 } // namespace compiler | 3686 } // namespace compiler |
3647 } // namespace internal | 3687 } // namespace internal |
3648 } // namespace v8 | 3688 } // namespace v8 |
OLD | NEW |