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 1678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1689 | 1689 |
1690 // Set the constructor to have fast properties. | 1690 // Set the constructor to have fast properties. |
1691 prototype = environment()->Pop(); | 1691 prototype = environment()->Pop(); |
1692 literal = environment()->Pop(); | 1692 literal = environment()->Pop(); |
1693 const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties); | 1693 const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties); |
1694 literal = NewNode(op, literal); | 1694 literal = NewNode(op, literal); |
1695 | 1695 |
1696 // Assign to class variable. | 1696 // Assign to class variable. |
1697 if (expr->class_variable_proxy() != nullptr) { | 1697 if (expr->class_variable_proxy() != nullptr) { |
1698 Variable* var = expr->class_variable_proxy()->var(); | 1698 Variable* var = expr->class_variable_proxy()->var(); |
1699 FrameStateBeforeAndAfter states(this, BailoutId::None()); | |
1700 VectorSlotPair feedback = CreateVectorSlotPair( | 1699 VectorSlotPair feedback = CreateVectorSlotPair( |
1701 expr->NeedsProxySlot() ? expr->ProxySlot() | 1700 expr->NeedsProxySlot() ? expr->ProxySlot() |
1702 : FeedbackVectorSlot::Invalid()); | 1701 : FeedbackVectorSlot::Invalid()); |
1703 BuildVariableAssignment(var, literal, Token::INIT, feedback, | 1702 BuildVariableAssignment(var, literal, Token::INIT, feedback, |
1704 BailoutId::None(), states); | 1703 BailoutId::None()); |
1705 } | 1704 } |
1706 ast_context()->ProduceValue(literal); | 1705 ast_context()->ProduceValue(literal); |
1707 } | 1706 } |
1708 | 1707 |
1709 | 1708 |
1710 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { | 1709 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { |
1711 UNREACHABLE(); | 1710 UNREACHABLE(); |
1712 } | 1711 } |
1713 | 1712 |
1714 | 1713 |
(...skipping 14 matching lines...) Expand all Loading... |
1729 compare_if.Else(); | 1728 compare_if.Else(); |
1730 Visit(expr->else_expression()); | 1729 Visit(expr->else_expression()); |
1731 compare_if.End(); | 1730 compare_if.End(); |
1732 ast_context()->ReplaceValue(); | 1731 ast_context()->ReplaceValue(); |
1733 } | 1732 } |
1734 | 1733 |
1735 | 1734 |
1736 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 1735 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
1737 VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot()); | 1736 VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot()); |
1738 FrameStateBeforeAndAfter states(this, BeforeId(expr)); | 1737 FrameStateBeforeAndAfter states(this, BeforeId(expr)); |
1739 Node* value = BuildVariableLoad(expr->var(), expr->id(), states, pair, | 1738 Node* value = BuildVariableLoad(expr->var(), expr->id(), pair, |
1740 ast_context()->GetStateCombine()); | 1739 ast_context()->GetStateCombine()); |
1741 ast_context()->ProduceValue(value); | 1740 ast_context()->ProduceValue(value); |
1742 } | 1741 } |
1743 | 1742 |
1744 | 1743 |
1745 void AstGraphBuilder::VisitLiteral(Literal* expr) { | 1744 void AstGraphBuilder::VisitLiteral(Literal* expr) { |
1746 Node* value = jsgraph()->Constant(expr->value()); | 1745 Node* value = jsgraph()->Constant(expr->value()); |
1747 ast_context()->ProduceValue(value); | 1746 ast_context()->ProduceValue(value); |
1748 } | 1747 } |
1749 | 1748 |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2027 LhsKind assign_type = Property::GetAssignType(property); | 2026 LhsKind assign_type = Property::GetAssignType(property); |
2028 | 2027 |
2029 // Evaluate LHS expression and store the value. | 2028 // Evaluate LHS expression and store the value. |
2030 switch (assign_type) { | 2029 switch (assign_type) { |
2031 case VARIABLE: { | 2030 case VARIABLE: { |
2032 Variable* var = expr->AsVariableProxy()->var(); | 2031 Variable* var = expr->AsVariableProxy()->var(); |
2033 environment()->Push(value); | 2032 environment()->Push(value); |
2034 FrameStateBeforeAndAfter states(this, bailout_id_before); | 2033 FrameStateBeforeAndAfter states(this, bailout_id_before); |
2035 value = environment()->Pop(); | 2034 value = environment()->Pop(); |
2036 BuildVariableAssignment(var, value, Token::ASSIGN, feedback, | 2035 BuildVariableAssignment(var, value, Token::ASSIGN, feedback, |
2037 bailout_id_after, states); | 2036 bailout_id_after); |
2038 break; | 2037 break; |
2039 } | 2038 } |
2040 case NAMED_PROPERTY: { | 2039 case NAMED_PROPERTY: { |
2041 environment()->Push(value); | 2040 environment()->Push(value); |
2042 VisitForValue(property->obj()); | 2041 VisitForValue(property->obj()); |
2043 FrameStateBeforeAndAfter states(this, property->obj()->id()); | 2042 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
2044 Node* object = environment()->Pop(); | 2043 Node* object = environment()->Pop(); |
2045 value = environment()->Pop(); | 2044 value = environment()->Pop(); |
2046 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2045 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2047 Node* store = BuildNamedStore(object, name, value, feedback); | 2046 Node* store = BuildNamedStore(object, name, value, feedback); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2136 // Evaluate the value and potentially handle compound assignments by loading | 2135 // Evaluate the value and potentially handle compound assignments by loading |
2137 // the left-hand side value and performing a binary operation. | 2136 // the left-hand side value and performing a binary operation. |
2138 if (expr->is_compound()) { | 2137 if (expr->is_compound()) { |
2139 Node* old_value = nullptr; | 2138 Node* old_value = nullptr; |
2140 switch (assign_type) { | 2139 switch (assign_type) { |
2141 case VARIABLE: { | 2140 case VARIABLE: { |
2142 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 2141 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
2143 VectorSlotPair pair = | 2142 VectorSlotPair pair = |
2144 CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 2143 CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
2145 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); | 2144 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); |
2146 old_value = | 2145 old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair, |
2147 BuildVariableLoad(proxy->var(), expr->target()->id(), states, pair, | 2146 OutputFrameStateCombine::Push()); |
2148 OutputFrameStateCombine::Push()); | |
2149 break; | 2147 break; |
2150 } | 2148 } |
2151 case NAMED_PROPERTY: { | 2149 case NAMED_PROPERTY: { |
2152 Node* object = environment()->Top(); | 2150 Node* object = environment()->Top(); |
2153 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2151 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2154 VectorSlotPair pair = | 2152 VectorSlotPair pair = |
2155 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2153 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2156 FrameStateBeforeAndAfter states(this, property->obj()->id()); | 2154 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
2157 old_value = BuildNamedLoad(object, name, pair); | 2155 old_value = BuildNamedLoad(object, name, pair); |
2158 states.AddToNode(old_value, property->LoadId(), | 2156 states.AddToNode(old_value, property->LoadId(), |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2220 } | 2218 } |
2221 | 2219 |
2222 FrameStateBeforeAndAfter store_states(this, before_store_id); | 2220 FrameStateBeforeAndAfter store_states(this, before_store_id); |
2223 // Store the value. | 2221 // Store the value. |
2224 Node* value = environment()->Pop(); | 2222 Node* value = environment()->Pop(); |
2225 VectorSlotPair feedback = CreateVectorSlotPair(expr->AssignmentSlot()); | 2223 VectorSlotPair feedback = CreateVectorSlotPair(expr->AssignmentSlot()); |
2226 switch (assign_type) { | 2224 switch (assign_type) { |
2227 case VARIABLE: { | 2225 case VARIABLE: { |
2228 Variable* variable = expr->target()->AsVariableProxy()->var(); | 2226 Variable* variable = expr->target()->AsVariableProxy()->var(); |
2229 BuildVariableAssignment(variable, value, expr->op(), feedback, expr->id(), | 2227 BuildVariableAssignment(variable, value, expr->op(), feedback, expr->id(), |
2230 store_states, ast_context()->GetStateCombine()); | 2228 ast_context()->GetStateCombine()); |
2231 break; | 2229 break; |
2232 } | 2230 } |
2233 case NAMED_PROPERTY: { | 2231 case NAMED_PROPERTY: { |
2234 Node* object = environment()->Pop(); | 2232 Node* object = environment()->Pop(); |
2235 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2233 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2236 Node* store = BuildNamedStore(object, name, value, feedback); | 2234 Node* store = BuildNamedStore(object, name, value, feedback); |
2237 store_states.AddToNode(store, expr->id(), | 2235 store_states.AddToNode(store, expr->id(), |
2238 ast_context()->GetStateCombine()); | 2236 ast_context()->GetStateCombine()); |
2239 break; | 2237 break; |
2240 } | 2238 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2348 // the semantics of the underlying call type. | 2346 // the semantics of the underlying call type. |
2349 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; | 2347 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; |
2350 Node* receiver_value = nullptr; | 2348 Node* receiver_value = nullptr; |
2351 Node* callee_value = nullptr; | 2349 Node* callee_value = nullptr; |
2352 bool possibly_eval = false; | 2350 bool possibly_eval = false; |
2353 switch (call_type) { | 2351 switch (call_type) { |
2354 case Call::GLOBAL_CALL: { | 2352 case Call::GLOBAL_CALL: { |
2355 VariableProxy* proxy = callee->AsVariableProxy(); | 2353 VariableProxy* proxy = callee->AsVariableProxy(); |
2356 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 2354 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
2357 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); | 2355 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); |
2358 callee_value = | 2356 callee_value = BuildVariableLoad(proxy->var(), expr->expression()->id(), |
2359 BuildVariableLoad(proxy->var(), expr->expression()->id(), states, | 2357 pair, OutputFrameStateCombine::Push()); |
2360 pair, OutputFrameStateCombine::Push()); | |
2361 receiver_hint = ConvertReceiverMode::kNullOrUndefined; | 2358 receiver_hint = ConvertReceiverMode::kNullOrUndefined; |
2362 receiver_value = jsgraph()->UndefinedConstant(); | 2359 receiver_value = jsgraph()->UndefinedConstant(); |
2363 break; | 2360 break; |
2364 } | 2361 } |
2365 case Call::LOOKUP_SLOT_CALL: { | 2362 case Call::LOOKUP_SLOT_CALL: { |
2366 Variable* variable = callee->AsVariableProxy()->var(); | 2363 Variable* variable = callee->AsVariableProxy()->var(); |
2367 DCHECK(variable->location() == VariableLocation::LOOKUP); | 2364 DCHECK(variable->location() == VariableLocation::LOOKUP); |
2368 Node* name = jsgraph()->Constant(variable->name()); | 2365 Node* name = jsgraph()->Constant(variable->name()); |
2369 const Operator* op = | 2366 const Operator* op = |
2370 javascript()->CallRuntime(Runtime::kLoadLookupSlotForCall); | 2367 javascript()->CallRuntime(Runtime::kLoadLookupSlotForCall); |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2656 } | 2653 } |
2657 | 2654 |
2658 // Evaluate LHS expression and get old value. | 2655 // Evaluate LHS expression and get old value. |
2659 Node* old_value = nullptr; | 2656 Node* old_value = nullptr; |
2660 int stack_depth = -1; | 2657 int stack_depth = -1; |
2661 switch (assign_type) { | 2658 switch (assign_type) { |
2662 case VARIABLE: { | 2659 case VARIABLE: { |
2663 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 2660 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
2664 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 2661 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
2665 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); | 2662 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); |
2666 old_value = | 2663 old_value = BuildVariableLoad(proxy->var(), expr->expression()->id(), |
2667 BuildVariableLoad(proxy->var(), expr->expression()->id(), states, | 2664 pair, OutputFrameStateCombine::Push()); |
2668 pair, OutputFrameStateCombine::Push()); | |
2669 stack_depth = 0; | 2665 stack_depth = 0; |
2670 break; | 2666 break; |
2671 } | 2667 } |
2672 case NAMED_PROPERTY: { | 2668 case NAMED_PROPERTY: { |
2673 VisitForValue(property->obj()); | 2669 VisitForValue(property->obj()); |
2674 FrameStateBeforeAndAfter states(this, property->obj()->id()); | 2670 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
2675 Node* object = environment()->Top(); | 2671 Node* object = environment()->Top(); |
2676 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2672 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2677 VectorSlotPair pair = | 2673 VectorSlotPair pair = |
2678 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2674 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2757 binop_states.AddToNode(value, BailoutId::None(), | 2753 binop_states.AddToNode(value, BailoutId::None(), |
2758 OutputFrameStateCombine::Ignore()); | 2754 OutputFrameStateCombine::Ignore()); |
2759 | 2755 |
2760 // Store the value. | 2756 // Store the value. |
2761 VectorSlotPair feedback = CreateVectorSlotPair(expr->CountSlot()); | 2757 VectorSlotPair feedback = CreateVectorSlotPair(expr->CountSlot()); |
2762 switch (assign_type) { | 2758 switch (assign_type) { |
2763 case VARIABLE: { | 2759 case VARIABLE: { |
2764 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 2760 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
2765 environment()->Push(value); | 2761 environment()->Push(value); |
2766 BuildVariableAssignment(variable, value, expr->op(), feedback, | 2762 BuildVariableAssignment(variable, value, expr->op(), feedback, |
2767 expr->AssignmentId(), store_states); | 2763 expr->AssignmentId()); |
2768 environment()->Pop(); | 2764 environment()->Pop(); |
2769 break; | 2765 break; |
2770 } | 2766 } |
2771 case NAMED_PROPERTY: { | 2767 case NAMED_PROPERTY: { |
2772 Node* object = environment()->Pop(); | 2768 Node* object = environment()->Pop(); |
2773 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2769 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2774 Node* store = BuildNamedStore(object, name, value, feedback); | 2770 Node* store = BuildNamedStore(object, name, value, feedback); |
2775 environment()->Push(value); | 2771 environment()->Push(value); |
2776 store_states.AddToNode(store, expr->AssignmentId(), | 2772 store_states.AddToNode(store, expr->AssignmentId(), |
2777 OutputFrameStateCombine::Ignore()); | 2773 OutputFrameStateCombine::Ignore()); |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3051 } | 3047 } |
3052 | 3048 |
3053 void AstGraphBuilder::VisitTypeofExpression(Expression* expr) { | 3049 void AstGraphBuilder::VisitTypeofExpression(Expression* expr) { |
3054 if (expr->IsVariableProxy()) { | 3050 if (expr->IsVariableProxy()) { |
3055 // Typeof does not throw a reference error on global variables, hence we | 3051 // Typeof does not throw a reference error on global variables, hence we |
3056 // perform a non-contextual load in case the operand is a variable proxy. | 3052 // perform a non-contextual load in case the operand is a variable proxy. |
3057 VariableProxy* proxy = expr->AsVariableProxy(); | 3053 VariableProxy* proxy = expr->AsVariableProxy(); |
3058 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 3054 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
3059 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); | 3055 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); |
3060 Node* load = | 3056 Node* load = |
3061 BuildVariableLoad(proxy->var(), expr->id(), states, pair, | 3057 BuildVariableLoad(proxy->var(), expr->id(), pair, |
3062 OutputFrameStateCombine::Push(), INSIDE_TYPEOF); | 3058 OutputFrameStateCombine::Push(), INSIDE_TYPEOF); |
3063 environment()->Push(load); | 3059 environment()->Push(load); |
3064 } else { | 3060 } else { |
3065 VisitForValue(expr); | 3061 VisitForValue(expr); |
3066 } | 3062 } |
3067 } | 3063 } |
3068 | 3064 |
3069 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) { | 3065 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) { |
3070 VisitTypeofExpression(expr->expression()); | 3066 VisitTypeofExpression(expr->expression()); |
3071 Node* value = NewNode(javascript()->TypeOf(), environment()->Pop()); | 3067 Node* value = NewNode(javascript()->TypeOf(), environment()->Pop()); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3270 is_strict(language_mode()) || !info()->has_simple_parameters() | 3266 is_strict(language_mode()) || !info()->has_simple_parameters() |
3271 ? CreateArgumentsType::kUnmappedArguments | 3267 ? CreateArgumentsType::kUnmappedArguments |
3272 : CreateArgumentsType::kMappedArguments; | 3268 : CreateArgumentsType::kMappedArguments; |
3273 const Operator* op = javascript()->CreateArguments(type); | 3269 const Operator* op = javascript()->CreateArguments(type); |
3274 Node* object = NewNode(op, GetFunctionClosure()); | 3270 Node* object = NewNode(op, GetFunctionClosure()); |
3275 PrepareFrameState(object, BailoutId::None()); | 3271 PrepareFrameState(object, BailoutId::None()); |
3276 | 3272 |
3277 // Assign the object to the {arguments} variable. This should never lazy | 3273 // Assign the object to the {arguments} variable. This should never lazy |
3278 // deopt, so it is fine to send invalid bailout id. | 3274 // deopt, so it is fine to send invalid bailout id. |
3279 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); | 3275 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); |
3280 FrameStateBeforeAndAfter states(this, BailoutId::None()); | |
3281 BuildVariableAssignment(arguments, object, Token::ASSIGN, VectorSlotPair(), | 3276 BuildVariableAssignment(arguments, object, Token::ASSIGN, VectorSlotPair(), |
3282 BailoutId::None(), states); | 3277 BailoutId::None()); |
3283 return object; | 3278 return object; |
3284 } | 3279 } |
3285 | 3280 |
3286 | 3281 |
3287 Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest, int index) { | 3282 Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest, int index) { |
3288 if (rest == nullptr) return nullptr; | 3283 if (rest == nullptr) return nullptr; |
3289 | 3284 |
3290 // Allocate and initialize a new arguments object. | 3285 // Allocate and initialize a new arguments object. |
3291 CreateArgumentsType type = CreateArgumentsType::kRestParameter; | 3286 CreateArgumentsType type = CreateArgumentsType::kRestParameter; |
3292 const Operator* op = javascript()->CreateArguments(type); | 3287 const Operator* op = javascript()->CreateArguments(type); |
3293 Node* object = NewNode(op, GetFunctionClosure()); | 3288 Node* object = NewNode(op, GetFunctionClosure()); |
3294 PrepareFrameState(object, BailoutId::None()); | 3289 PrepareFrameState(object, BailoutId::None()); |
3295 | 3290 |
3296 // Assign the object to the {rest} variable. This should never lazy | 3291 // Assign the object to the {rest} variable. This should never lazy |
3297 // deopt, so it is fine to send invalid bailout id. | 3292 // deopt, so it is fine to send invalid bailout id. |
3298 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); | 3293 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); |
3299 FrameStateBeforeAndAfter states(this, BailoutId::None()); | |
3300 BuildVariableAssignment(rest, object, Token::ASSIGN, VectorSlotPair(), | 3294 BuildVariableAssignment(rest, object, Token::ASSIGN, VectorSlotPair(), |
3301 BailoutId::None(), states); | 3295 BailoutId::None()); |
3302 return object; | 3296 return object; |
3303 } | 3297 } |
3304 | 3298 |
3305 | 3299 |
3306 Node* AstGraphBuilder::BuildThisFunctionVariable(Variable* this_function_var) { | 3300 Node* AstGraphBuilder::BuildThisFunctionVariable(Variable* this_function_var) { |
3307 if (this_function_var == nullptr) return nullptr; | 3301 if (this_function_var == nullptr) return nullptr; |
3308 | 3302 |
3309 // Retrieve the closure we were called with. | 3303 // Retrieve the closure we were called with. |
3310 Node* this_function = GetFunctionClosure(); | 3304 Node* this_function = GetFunctionClosure(); |
3311 | 3305 |
3312 // Assign the object to the {.this_function} variable. This should never lazy | 3306 // Assign the object to the {.this_function} variable. This should never lazy |
3313 // deopt, so it is fine to send invalid bailout id. | 3307 // deopt, so it is fine to send invalid bailout id. |
3314 FrameStateBeforeAndAfter states(this, BailoutId::None()); | |
3315 BuildVariableAssignment(this_function_var, this_function, Token::INIT, | 3308 BuildVariableAssignment(this_function_var, this_function, Token::INIT, |
3316 VectorSlotPair(), BailoutId::None(), states); | 3309 VectorSlotPair(), BailoutId::None()); |
3317 return this_function; | 3310 return this_function; |
3318 } | 3311 } |
3319 | 3312 |
3320 | 3313 |
3321 Node* AstGraphBuilder::BuildNewTargetVariable(Variable* new_target_var) { | 3314 Node* AstGraphBuilder::BuildNewTargetVariable(Variable* new_target_var) { |
3322 if (new_target_var == nullptr) return nullptr; | 3315 if (new_target_var == nullptr) return nullptr; |
3323 | 3316 |
3324 // Retrieve the new target we were called with. | 3317 // Retrieve the new target we were called with. |
3325 Node* object = GetNewTarget(); | 3318 Node* object = GetNewTarget(); |
3326 | 3319 |
3327 // Assign the object to the {new.target} variable. This should never lazy | 3320 // Assign the object to the {new.target} variable. This should never lazy |
3328 // deopt, so it is fine to send invalid bailout id. | 3321 // deopt, so it is fine to send invalid bailout id. |
3329 FrameStateBeforeAndAfter states(this, BailoutId::None()); | |
3330 BuildVariableAssignment(new_target_var, object, Token::INIT, VectorSlotPair(), | 3322 BuildVariableAssignment(new_target_var, object, Token::INIT, VectorSlotPair(), |
3331 BailoutId::None(), states); | 3323 BailoutId::None()); |
3332 return object; | 3324 return object; |
3333 } | 3325 } |
3334 | 3326 |
3335 | 3327 |
3336 Node* AstGraphBuilder::BuildHoleCheckThenThrow(Node* value, Variable* variable, | 3328 Node* AstGraphBuilder::BuildHoleCheckThenThrow(Node* value, Variable* variable, |
3337 Node* not_hole, | 3329 Node* not_hole, |
3338 BailoutId bailout_id) { | 3330 BailoutId bailout_id) { |
3339 IfBuilder hole_check(this); | 3331 IfBuilder hole_check(this); |
3340 Node* the_hole = jsgraph()->TheHoleConstant(); | 3332 Node* the_hole = jsgraph()->TheHoleConstant(); |
3341 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); | 3333 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3379 environment()->Push(error); | 3371 environment()->Push(error); |
3380 prototype_check.Else(); | 3372 prototype_check.Else(); |
3381 environment()->Push(name); | 3373 environment()->Push(name); |
3382 prototype_check.End(); | 3374 prototype_check.End(); |
3383 return environment()->Pop(); | 3375 return environment()->Pop(); |
3384 } | 3376 } |
3385 | 3377 |
3386 | 3378 |
3387 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, | 3379 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, |
3388 BailoutId bailout_id, | 3380 BailoutId bailout_id, |
3389 FrameStateBeforeAndAfter& states, | |
3390 const VectorSlotPair& feedback, | 3381 const VectorSlotPair& feedback, |
3391 OutputFrameStateCombine combine, | 3382 OutputFrameStateCombine combine, |
3392 TypeofMode typeof_mode) { | 3383 TypeofMode typeof_mode) { |
3393 Node* the_hole = jsgraph()->TheHoleConstant(); | 3384 Node* the_hole = jsgraph()->TheHoleConstant(); |
3394 VariableMode mode = variable->mode(); | 3385 VariableMode mode = variable->mode(); |
3395 switch (variable->location()) { | 3386 switch (variable->location()) { |
3396 case VariableLocation::GLOBAL: | 3387 case VariableLocation::GLOBAL: |
3397 case VariableLocation::UNALLOCATED: { | 3388 case VariableLocation::UNALLOCATED: { |
3398 // Global var, const, or let variable. | 3389 // Global var, const, or let variable. |
3399 Handle<Name> name = variable->name(); | 3390 Handle<Name> name = variable->name(); |
3400 if (Node* node = TryLoadGlobalConstant(name)) return node; | 3391 if (Node* node = TryLoadGlobalConstant(name)) return node; |
3401 Node* value = BuildGlobalLoad(name, feedback, typeof_mode); | 3392 Node* value = BuildGlobalLoad(name, feedback, typeof_mode); |
3402 states.AddToNode(value, bailout_id, combine); | 3393 PrepareFrameState(value, bailout_id, combine); |
3403 return value; | 3394 return value; |
3404 } | 3395 } |
3405 case VariableLocation::PARAMETER: | 3396 case VariableLocation::PARAMETER: |
3406 case VariableLocation::LOCAL: { | 3397 case VariableLocation::LOCAL: { |
3407 // Local var, const, or let variable. | 3398 // Local var, const, or let variable. |
3408 Node* value = environment()->Lookup(variable); | 3399 Node* value = environment()->Lookup(variable); |
3409 if (mode == LET || mode == CONST) { | 3400 if (mode == LET || mode == CONST) { |
3410 // Perform check for uninitialized let/const variables. | 3401 // Perform check for uninitialized let/const variables. |
3411 if (value->op() == the_hole->op()) { | 3402 if (value->op() == the_hole->op()) { |
3412 value = BuildThrowReferenceError(variable, bailout_id); | 3403 value = BuildThrowReferenceError(variable, bailout_id); |
(...skipping 15 matching lines...) Expand all Loading... |
3428 // Maybe specializer should be a parameter to the graph builder? | 3419 // Maybe specializer should be a parameter to the graph builder? |
3429 if (mode == LET || mode == CONST) { | 3420 if (mode == LET || mode == CONST) { |
3430 // Perform check for uninitialized let/const variables. | 3421 // Perform check for uninitialized let/const variables. |
3431 value = BuildHoleCheckThenThrow(value, variable, value, bailout_id); | 3422 value = BuildHoleCheckThenThrow(value, variable, value, bailout_id); |
3432 } | 3423 } |
3433 return value; | 3424 return value; |
3434 } | 3425 } |
3435 case VariableLocation::LOOKUP: { | 3426 case VariableLocation::LOOKUP: { |
3436 // Dynamic lookup of context variable (anywhere in the chain). | 3427 // Dynamic lookup of context variable (anywhere in the chain). |
3437 Handle<String> name = variable->name(); | 3428 Handle<String> name = variable->name(); |
3438 if (Node* node = | 3429 if (Node* node = TryLoadDynamicVariable(variable, name, bailout_id, |
3439 TryLoadDynamicVariable(variable, name, bailout_id, states, | 3430 feedback, combine, typeof_mode)) { |
3440 feedback, combine, typeof_mode)) { | |
3441 return node; | 3431 return node; |
3442 } | 3432 } |
3443 Node* value = BuildDynamicLoad(name, typeof_mode); | 3433 Node* value = BuildDynamicLoad(name, typeof_mode); |
3444 states.AddToNode(value, bailout_id, combine); | 3434 PrepareFrameState(value, bailout_id, combine); |
3445 return value; | 3435 return value; |
3446 } | 3436 } |
3447 } | 3437 } |
3448 UNREACHABLE(); | 3438 UNREACHABLE(); |
3449 return nullptr; | 3439 return nullptr; |
3450 } | 3440 } |
3451 | 3441 |
3452 | 3442 |
3453 Node* AstGraphBuilder::BuildVariableDelete(Variable* variable, | 3443 Node* AstGraphBuilder::BuildVariableDelete(Variable* variable, |
3454 BailoutId bailout_id, | 3444 BailoutId bailout_id, |
(...skipping 22 matching lines...) Expand all Loading... |
3477 javascript()->CallRuntime(Runtime::kDeleteLookupSlot); | 3467 javascript()->CallRuntime(Runtime::kDeleteLookupSlot); |
3478 Node* result = NewNode(op, name); | 3468 Node* result = NewNode(op, name); |
3479 PrepareFrameState(result, bailout_id, combine); | 3469 PrepareFrameState(result, bailout_id, combine); |
3480 return result; | 3470 return result; |
3481 } | 3471 } |
3482 } | 3472 } |
3483 UNREACHABLE(); | 3473 UNREACHABLE(); |
3484 return nullptr; | 3474 return nullptr; |
3485 } | 3475 } |
3486 | 3476 |
3487 | |
3488 Node* AstGraphBuilder::BuildVariableAssignment( | 3477 Node* AstGraphBuilder::BuildVariableAssignment( |
3489 Variable* variable, Node* value, Token::Value op, | 3478 Variable* variable, Node* value, Token::Value op, |
3490 const VectorSlotPair& feedback, BailoutId bailout_id, | 3479 const VectorSlotPair& feedback, BailoutId bailout_id, |
3491 FrameStateBeforeAndAfter& states, OutputFrameStateCombine combine) { | 3480 OutputFrameStateCombine combine) { |
3492 Node* the_hole = jsgraph()->TheHoleConstant(); | 3481 Node* the_hole = jsgraph()->TheHoleConstant(); |
3493 VariableMode mode = variable->mode(); | 3482 VariableMode mode = variable->mode(); |
3494 switch (variable->location()) { | 3483 switch (variable->location()) { |
3495 case VariableLocation::GLOBAL: | 3484 case VariableLocation::GLOBAL: |
3496 case VariableLocation::UNALLOCATED: { | 3485 case VariableLocation::UNALLOCATED: { |
3497 // Global var, const, or let variable. | 3486 // Global var, const, or let variable. |
3498 Handle<Name> name = variable->name(); | 3487 Handle<Name> name = variable->name(); |
3499 Node* store = BuildGlobalStore(name, value, feedback); | 3488 Node* store = BuildGlobalStore(name, value, feedback); |
3500 states.AddToNode(store, bailout_id, combine); | 3489 PrepareFrameState(store, bailout_id, combine); |
3501 return store; | 3490 return store; |
3502 } | 3491 } |
3503 case VariableLocation::PARAMETER: | 3492 case VariableLocation::PARAMETER: |
3504 case VariableLocation::LOCAL: | 3493 case VariableLocation::LOCAL: |
3505 // Local var, const, or let variable. | 3494 // Local var, const, or let variable. |
3506 if (mode == CONST_LEGACY && op != Token::INIT) { | 3495 if (mode == CONST_LEGACY && op != Token::INIT) { |
3507 // Non-initializing assignment to legacy const is | 3496 // Non-initializing assignment to legacy const is |
3508 // - exception in strict mode. | 3497 // - exception in strict mode. |
3509 // - ignored in sloppy mode. | 3498 // - ignored in sloppy mode. |
3510 if (is_strict(language_mode())) { | 3499 if (is_strict(language_mode())) { |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3750 return object; | 3739 return object; |
3751 } | 3740 } |
3752 | 3741 |
3753 | 3742 |
3754 Node* AstGraphBuilder::BuildSetHomeObject(Node* value, Node* home_object, | 3743 Node* AstGraphBuilder::BuildSetHomeObject(Node* value, Node* home_object, |
3755 ObjectLiteralProperty* property, | 3744 ObjectLiteralProperty* property, |
3756 int slot_number) { | 3745 int slot_number) { |
3757 Expression* expr = property->value(); | 3746 Expression* expr = property->value(); |
3758 if (!FunctionLiteral::NeedsHomeObject(expr)) return value; | 3747 if (!FunctionLiteral::NeedsHomeObject(expr)) return value; |
3759 Handle<Name> name = isolate()->factory()->home_object_symbol(); | 3748 Handle<Name> name = isolate()->factory()->home_object_symbol(); |
3760 FrameStateBeforeAndAfter states(this, BailoutId::None()); | |
3761 VectorSlotPair feedback = | 3749 VectorSlotPair feedback = |
3762 CreateVectorSlotPair(property->GetSlot(slot_number)); | 3750 CreateVectorSlotPair(property->GetSlot(slot_number)); |
3763 Node* store = BuildNamedStore(value, name, home_object, feedback); | 3751 Node* store = BuildNamedStore(value, name, home_object, feedback); |
3764 states.AddToNode(store, BailoutId::None(), OutputFrameStateCombine::Ignore()); | 3752 PrepareFrameState(store, BailoutId::None(), |
| 3753 OutputFrameStateCombine::Ignore()); |
3765 return store; | 3754 return store; |
3766 } | 3755 } |
3767 | 3756 |
3768 | 3757 |
3769 Node* AstGraphBuilder::BuildThrowError(Node* exception, BailoutId bailout_id) { | 3758 Node* AstGraphBuilder::BuildThrowError(Node* exception, BailoutId bailout_id) { |
3770 const Operator* op = javascript()->CallRuntime(Runtime::kThrow); | 3759 const Operator* op = javascript()->CallRuntime(Runtime::kThrow); |
3771 Node* call = NewNode(op, exception); | 3760 Node* call = NewNode(op, exception); |
3772 PrepareFrameState(call, bailout_id); | 3761 PrepareFrameState(call, bailout_id); |
3773 Node* control = NewNode(common()->Throw(), call); | 3762 Node* control = NewNode(common()->Throw(), call); |
3774 UpdateControlDependencyToLeaveFunction(control); | 3763 UpdateControlDependencyToLeaveFunction(control); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3891 } | 3880 } |
3892 | 3881 |
3893 | 3882 |
3894 Node* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) { | 3883 Node* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) { |
3895 // Optimize global constants like "undefined", "Infinity", and "NaN". | 3884 // Optimize global constants like "undefined", "Infinity", and "NaN". |
3896 Handle<Object> constant_value = isolate()->factory()->GlobalConstantFor(name); | 3885 Handle<Object> constant_value = isolate()->factory()->GlobalConstantFor(name); |
3897 if (!constant_value.is_null()) return jsgraph()->Constant(constant_value); | 3886 if (!constant_value.is_null()) return jsgraph()->Constant(constant_value); |
3898 return nullptr; | 3887 return nullptr; |
3899 } | 3888 } |
3900 | 3889 |
3901 | 3890 Node* AstGraphBuilder::TryLoadDynamicVariable(Variable* variable, |
3902 Node* AstGraphBuilder::TryLoadDynamicVariable( | 3891 Handle<String> name, |
3903 Variable* variable, Handle<String> name, BailoutId bailout_id, | 3892 BailoutId bailout_id, |
3904 FrameStateBeforeAndAfter& states, const VectorSlotPair& feedback, | 3893 const VectorSlotPair& feedback, |
3905 OutputFrameStateCombine combine, TypeofMode typeof_mode) { | 3894 OutputFrameStateCombine combine, |
| 3895 TypeofMode typeof_mode) { |
3906 VariableMode mode = variable->mode(); | 3896 VariableMode mode = variable->mode(); |
3907 | 3897 |
3908 if (mode == DYNAMIC_GLOBAL) { | 3898 if (mode == DYNAMIC_GLOBAL) { |
3909 uint32_t bitset = ComputeBitsetForDynamicGlobal(variable); | 3899 uint32_t bitset = ComputeBitsetForDynamicGlobal(variable); |
3910 if (bitset == kFullCheckRequired) return nullptr; | 3900 if (bitset == kFullCheckRequired) return nullptr; |
3911 | 3901 |
3912 // We are using two blocks to model fast and slow cases. | 3902 // We are using two blocks to model fast and slow cases. |
3913 BlockBuilder fast_block(this); | 3903 BlockBuilder fast_block(this); |
3914 BlockBuilder slow_block(this); | 3904 BlockBuilder slow_block(this); |
3915 environment()->Push(jsgraph()->TheHoleConstant()); | 3905 environment()->Push(jsgraph()->TheHoleConstant()); |
(...skipping 12 matching lines...) Expand all Loading... |
3928 jsgraph()->TheHoleConstant()); | 3918 jsgraph()->TheHoleConstant()); |
3929 fast_block.BreakUnless(check, BranchHint::kTrue); | 3919 fast_block.BreakUnless(check, BranchHint::kTrue); |
3930 } | 3920 } |
3931 | 3921 |
3932 // Fast case, because variable is not shadowed. | 3922 // Fast case, because variable is not shadowed. |
3933 if (Node* constant = TryLoadGlobalConstant(name)) { | 3923 if (Node* constant = TryLoadGlobalConstant(name)) { |
3934 environment()->Push(constant); | 3924 environment()->Push(constant); |
3935 } else { | 3925 } else { |
3936 // Perform global slot load. | 3926 // Perform global slot load. |
3937 Node* fast = BuildGlobalLoad(name, feedback, typeof_mode); | 3927 Node* fast = BuildGlobalLoad(name, feedback, typeof_mode); |
3938 states.AddToNode(fast, bailout_id, combine); | 3928 PrepareFrameState(fast, bailout_id, combine); |
3939 environment()->Push(fast); | 3929 environment()->Push(fast); |
3940 } | 3930 } |
3941 slow_block.Break(); | 3931 slow_block.Break(); |
3942 environment()->Pop(); | 3932 environment()->Pop(); |
3943 fast_block.EndBlock(); | 3933 fast_block.EndBlock(); |
3944 | 3934 |
3945 // Slow case, because variable potentially shadowed. Perform dynamic lookup. | 3935 // Slow case, because variable potentially shadowed. Perform dynamic lookup. |
3946 Node* slow = BuildDynamicLoad(name, typeof_mode); | 3936 Node* slow = BuildDynamicLoad(name, typeof_mode); |
3947 states.AddToNode(slow, bailout_id, combine); | 3937 PrepareFrameState(slow, bailout_id, combine); |
3948 environment()->Push(slow); | 3938 environment()->Push(slow); |
3949 slow_block.EndBlock(); | 3939 slow_block.EndBlock(); |
3950 | 3940 |
3951 return environment()->Pop(); | 3941 return environment()->Pop(); |
3952 } | 3942 } |
3953 | 3943 |
3954 if (mode == DYNAMIC_LOCAL) { | 3944 if (mode == DYNAMIC_LOCAL) { |
3955 uint32_t bitset = ComputeBitsetForDynamicContext(variable); | 3945 uint32_t bitset = ComputeBitsetForDynamicContext(variable); |
3956 if (bitset == kFullCheckRequired) return nullptr; | 3946 if (bitset == kFullCheckRequired) return nullptr; |
3957 | 3947 |
(...skipping 13 matching lines...) Expand all Loading... |
3971 javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false), | 3961 javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false), |
3972 current_context()); | 3962 current_context()); |
3973 Node* check = NewNode(javascript()->StrictEqual(), load, | 3963 Node* check = NewNode(javascript()->StrictEqual(), load, |
3974 jsgraph()->TheHoleConstant()); | 3964 jsgraph()->TheHoleConstant()); |
3975 fast_block.BreakUnless(check, BranchHint::kTrue); | 3965 fast_block.BreakUnless(check, BranchHint::kTrue); |
3976 } | 3966 } |
3977 | 3967 |
3978 // Fast case, because variable is not shadowed. Perform context slot load. | 3968 // Fast case, because variable is not shadowed. Perform context slot load. |
3979 Variable* local = variable->local_if_not_shadowed(); | 3969 Variable* local = variable->local_if_not_shadowed(); |
3980 DCHECK(local->location() == VariableLocation::CONTEXT); // Must be context. | 3970 DCHECK(local->location() == VariableLocation::CONTEXT); // Must be context. |
3981 Node* fast = BuildVariableLoad(local, bailout_id, states, feedback, combine, | 3971 Node* fast = |
3982 typeof_mode); | 3972 BuildVariableLoad(local, bailout_id, feedback, combine, typeof_mode); |
3983 environment()->Push(fast); | 3973 environment()->Push(fast); |
3984 slow_block.Break(); | 3974 slow_block.Break(); |
3985 environment()->Pop(); | 3975 environment()->Pop(); |
3986 fast_block.EndBlock(); | 3976 fast_block.EndBlock(); |
3987 | 3977 |
3988 // Slow case, because variable potentially shadowed. Perform dynamic lookup. | 3978 // Slow case, because variable potentially shadowed. Perform dynamic lookup. |
3989 Node* slow = BuildDynamicLoad(name, typeof_mode); | 3979 Node* slow = BuildDynamicLoad(name, typeof_mode); |
3990 states.AddToNode(slow, bailout_id, combine); | 3980 PrepareFrameState(slow, bailout_id, combine); |
3991 environment()->Push(slow); | 3981 environment()->Push(slow); |
3992 slow_block.EndBlock(); | 3982 slow_block.EndBlock(); |
3993 | 3983 |
3994 return environment()->Pop(); | 3984 return environment()->Pop(); |
3995 } | 3985 } |
3996 | 3986 |
3997 return nullptr; | 3987 return nullptr; |
3998 } | 3988 } |
3999 | 3989 |
4000 | 3990 |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4375 // Phi does not exist yet, introduce one. | 4365 // Phi does not exist yet, introduce one. |
4376 value = NewPhi(inputs, value, control); | 4366 value = NewPhi(inputs, value, control); |
4377 value->ReplaceInput(inputs - 1, other); | 4367 value->ReplaceInput(inputs - 1, other); |
4378 } | 4368 } |
4379 return value; | 4369 return value; |
4380 } | 4370 } |
4381 | 4371 |
4382 } // namespace compiler | 4372 } // namespace compiler |
4383 } // namespace internal | 4373 } // namespace internal |
4384 } // namespace v8 | 4374 } // namespace v8 |
OLD | NEW |