| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 | 9 |
| 10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
| (...skipping 4225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4236 { BreakAndContinueScope push(&break_info, this); | 4236 { BreakAndContinueScope push(&break_info, this); |
| 4237 if (scope != NULL) { | 4237 if (scope != NULL) { |
| 4238 if (scope->NeedsContext()) { | 4238 if (scope->NeedsContext()) { |
| 4239 // Load the function object. | 4239 // Load the function object. |
| 4240 DeclarationScope* declaration_scope = scope->GetDeclarationScope(); | 4240 DeclarationScope* declaration_scope = scope->GetDeclarationScope(); |
| 4241 HInstruction* function; | 4241 HInstruction* function; |
| 4242 HValue* outer_context = environment()->context(); | 4242 HValue* outer_context = environment()->context(); |
| 4243 if (declaration_scope->is_script_scope() || | 4243 if (declaration_scope->is_script_scope() || |
| 4244 declaration_scope->is_eval_scope()) { | 4244 declaration_scope->is_eval_scope()) { |
| 4245 function = new (zone()) | 4245 function = new (zone()) |
| 4246 HLoadContextSlot(outer_context, Context::CLOSURE_INDEX, | 4246 HLoadContextSlot(outer_context, Context::CLOSURE_INDEX); |
| 4247 HLoadContextSlot::kNoCheck); | |
| 4248 } else { | 4247 } else { |
| 4249 function = New<HThisFunction>(); | 4248 function = New<HThisFunction>(); |
| 4250 } | 4249 } |
| 4251 AddInstruction(function); | 4250 AddInstruction(function); |
| 4252 // Allocate a block context and store it to the stack frame. | 4251 // Allocate a block context and store it to the stack frame. |
| 4253 HValue* scope_info = Add<HConstant>(scope->scope_info()); | 4252 HValue* scope_info = Add<HConstant>(scope->scope_info()); |
| 4254 Add<HPushArguments>(scope_info, function); | 4253 Add<HPushArguments>(scope_info, function); |
| 4255 HInstruction* inner_context = Add<HCallRuntime>( | 4254 HInstruction* inner_context = Add<HCallRuntime>( |
| 4256 Runtime::FunctionForId(Runtime::kPushBlockContext), 2); | 4255 Runtime::FunctionForId(Runtime::kPushBlockContext), 2); |
| 4257 inner_context->SetFlag(HValue::kHasNoObservableSideEffects); | 4256 inner_context->SetFlag(HValue::kHasNoObservableSideEffects); |
| (...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5229 instr->SetDependsOnFlag(kGlobalVars); | 5228 instr->SetDependsOnFlag(kGlobalVars); |
| 5230 return ast_context()->ReturnInstruction(instr, ast_id); | 5229 return ast_context()->ReturnInstruction(instr, ast_id); |
| 5231 } | 5230 } |
| 5232 } | 5231 } |
| 5233 | 5232 |
| 5234 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 5233 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
| 5235 DCHECK(!HasStackOverflow()); | 5234 DCHECK(!HasStackOverflow()); |
| 5236 DCHECK(current_block() != NULL); | 5235 DCHECK(current_block() != NULL); |
| 5237 DCHECK(current_block()->HasPredecessor()); | 5236 DCHECK(current_block()->HasPredecessor()); |
| 5238 Variable* variable = expr->var(); | 5237 Variable* variable = expr->var(); |
| 5238 DCHECK(!variable->binding_needs_init()); |
| 5239 switch (variable->location()) { | 5239 switch (variable->location()) { |
| 5240 case VariableLocation::UNALLOCATED: { | 5240 case VariableLocation::UNALLOCATED: { |
| 5241 if (IsLexicalVariableMode(variable->mode())) { | |
| 5242 // TODO(rossberg): should this be an DCHECK? | |
| 5243 return Bailout(kReferenceToGlobalLexicalVariable); | |
| 5244 } | |
| 5245 // Handle known global constants like 'undefined' specially to avoid a | 5241 // Handle known global constants like 'undefined' specially to avoid a |
| 5246 // load from a global cell for them. | 5242 // load from a global cell for them. |
| 5247 Handle<Object> constant_value = | 5243 Handle<Object> constant_value = |
| 5248 isolate()->factory()->GlobalConstantFor(variable->name()); | 5244 isolate()->factory()->GlobalConstantFor(variable->name()); |
| 5249 if (!constant_value.is_null()) { | 5245 if (!constant_value.is_null()) { |
| 5250 HConstant* instr = New<HConstant>(constant_value); | 5246 HConstant* instr = New<HConstant>(constant_value); |
| 5251 return ast_context()->ReturnInstruction(instr, expr->id()); | 5247 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 5252 } | 5248 } |
| 5253 | 5249 |
| 5254 Handle<JSGlobalObject> global(current_info()->global_object()); | 5250 Handle<JSGlobalObject> global(current_info()->global_object()); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5296 HCallWithDescriptor* instr = New<HCallWithDescriptor>( | 5292 HCallWithDescriptor* instr = New<HCallWithDescriptor>( |
| 5297 Code::LOAD_GLOBAL_IC, stub, 0, callable.descriptor(), | 5293 Code::LOAD_GLOBAL_IC, stub, 0, callable.descriptor(), |
| 5298 ArrayVector(values)); | 5294 ArrayVector(values)); |
| 5299 return ast_context()->ReturnInstruction(instr, expr->id()); | 5295 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 5300 } | 5296 } |
| 5301 } | 5297 } |
| 5302 | 5298 |
| 5303 case VariableLocation::PARAMETER: | 5299 case VariableLocation::PARAMETER: |
| 5304 case VariableLocation::LOCAL: { | 5300 case VariableLocation::LOCAL: { |
| 5305 HValue* value = LookupAndMakeLive(variable); | 5301 HValue* value = LookupAndMakeLive(variable); |
| 5306 if (value == graph()->GetConstantHole()) { | |
| 5307 DCHECK(IsDeclaredVariableMode(variable->mode()) && | |
| 5308 variable->mode() != VAR); | |
| 5309 return Bailout(kReferenceToUninitializedVariable); | |
| 5310 } | |
| 5311 return ast_context()->ReturnValue(value); | 5302 return ast_context()->ReturnValue(value); |
| 5312 } | 5303 } |
| 5313 | 5304 |
| 5314 case VariableLocation::CONTEXT: { | 5305 case VariableLocation::CONTEXT: { |
| 5315 HValue* context = BuildContextChainWalk(variable); | 5306 HValue* context = BuildContextChainWalk(variable); |
| 5316 HLoadContextSlot::Mode mode; | |
| 5317 switch (variable->mode()) { | |
| 5318 case LET: | |
| 5319 case CONST: | |
| 5320 mode = HLoadContextSlot::kCheckDeoptimize; | |
| 5321 break; | |
| 5322 default: | |
| 5323 mode = HLoadContextSlot::kNoCheck; | |
| 5324 break; | |
| 5325 } | |
| 5326 HLoadContextSlot* instr = | 5307 HLoadContextSlot* instr = |
| 5327 new(zone()) HLoadContextSlot(context, variable->index(), mode); | 5308 new (zone()) HLoadContextSlot(context, variable->index()); |
| 5328 return ast_context()->ReturnInstruction(instr, expr->id()); | 5309 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 5329 } | 5310 } |
| 5330 | 5311 |
| 5331 case VariableLocation::LOOKUP: | 5312 case VariableLocation::LOOKUP: |
| 5332 return Bailout(kReferenceToAVariableWhichRequiresDynamicLookup); | 5313 return Bailout(kReferenceToAVariableWhichRequiresDynamicLookup); |
| 5333 | 5314 |
| 5334 case VariableLocation::MODULE: | 5315 case VariableLocation::MODULE: |
| 5335 UNREACHABLE(); | 5316 UNREACHABLE(); |
| 5336 } | 5317 } |
| 5337 } | 5318 } |
| (...skipping 1197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6535 VariableProxy* proxy = target->AsVariableProxy(); | 6516 VariableProxy* proxy = target->AsVariableProxy(); |
| 6536 Property* prop = target->AsProperty(); | 6517 Property* prop = target->AsProperty(); |
| 6537 DCHECK(proxy == NULL || prop == NULL); | 6518 DCHECK(proxy == NULL || prop == NULL); |
| 6538 | 6519 |
| 6539 // We have a second position recorded in the FullCodeGenerator to have | 6520 // We have a second position recorded in the FullCodeGenerator to have |
| 6540 // type feedback for the binary operation. | 6521 // type feedback for the binary operation. |
| 6541 BinaryOperation* operation = expr->binary_operation(); | 6522 BinaryOperation* operation = expr->binary_operation(); |
| 6542 | 6523 |
| 6543 if (proxy != NULL) { | 6524 if (proxy != NULL) { |
| 6544 Variable* var = proxy->var(); | 6525 Variable* var = proxy->var(); |
| 6545 if (var->mode() == LET) { | 6526 DCHECK(!var->binding_needs_init()); |
| 6546 return Bailout(kUnsupportedLetCompoundAssignment); | |
| 6547 } | |
| 6548 | 6527 |
| 6549 CHECK_ALIVE(VisitForValue(operation)); | 6528 CHECK_ALIVE(VisitForValue(operation)); |
| 6550 | 6529 |
| 6551 switch (var->location()) { | 6530 switch (var->location()) { |
| 6552 case VariableLocation::UNALLOCATED: | 6531 case VariableLocation::UNALLOCATED: |
| 6553 HandleGlobalVariableAssignment(var, Top(), expr->AssignmentSlot(), | 6532 HandleGlobalVariableAssignment(var, Top(), expr->AssignmentSlot(), |
| 6554 expr->AssignmentId()); | 6533 expr->AssignmentId()); |
| 6555 break; | 6534 break; |
| 6556 | 6535 |
| 6557 case VariableLocation::PARAMETER: | 6536 case VariableLocation::PARAMETER: |
| (...skipping 13 matching lines...) Expand all Loading... |
| 6571 // direct way to detect that the variable is a parameter so we do | 6550 // direct way to detect that the variable is a parameter so we do |
| 6572 // a linear search of the parameter variables. | 6551 // a linear search of the parameter variables. |
| 6573 int count = current_info()->scope()->num_parameters(); | 6552 int count = current_info()->scope()->num_parameters(); |
| 6574 for (int i = 0; i < count; ++i) { | 6553 for (int i = 0; i < count; ++i) { |
| 6575 if (var == current_info()->scope()->parameter(i)) { | 6554 if (var == current_info()->scope()->parameter(i)) { |
| 6576 Bailout(kAssignmentToParameterFunctionUsesArgumentsObject); | 6555 Bailout(kAssignmentToParameterFunctionUsesArgumentsObject); |
| 6577 } | 6556 } |
| 6578 } | 6557 } |
| 6579 } | 6558 } |
| 6580 | 6559 |
| 6581 HStoreContextSlot::Mode mode; | 6560 if (var->mode() == CONST) { |
| 6582 | 6561 if (var->throw_on_const_assignment(function_language_mode())) { |
| 6583 switch (var->mode()) { | 6562 return Bailout(kNonInitializerAssignmentToConst); |
| 6584 case LET: | 6563 } else { |
| 6585 mode = HStoreContextSlot::kCheckDeoptimize; | 6564 return ast_context()->ReturnValue(Pop()); |
| 6586 break; | 6565 } |
| 6587 case CONST: | |
| 6588 if (var->throw_on_const_assignment(function_language_mode())) { | |
| 6589 return Bailout(kNonInitializerAssignmentToConst); | |
| 6590 } else { | |
| 6591 return ast_context()->ReturnValue(Pop()); | |
| 6592 } | |
| 6593 default: | |
| 6594 mode = HStoreContextSlot::kNoCheck; | |
| 6595 } | 6566 } |
| 6596 | 6567 |
| 6597 HValue* context = BuildContextChainWalk(var); | 6568 HValue* context = BuildContextChainWalk(var); |
| 6598 HStoreContextSlot* instr = Add<HStoreContextSlot>( | 6569 HStoreContextSlot* instr = |
| 6599 context, var->index(), mode, Top()); | 6570 Add<HStoreContextSlot>(context, var->index(), Top()); |
| 6600 if (instr->HasObservableSideEffects()) { | 6571 if (instr->HasObservableSideEffects()) { |
| 6601 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); | 6572 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); |
| 6602 } | 6573 } |
| 6603 break; | 6574 break; |
| 6604 } | 6575 } |
| 6605 | 6576 |
| 6606 case VariableLocation::LOOKUP: | 6577 case VariableLocation::LOOKUP: |
| 6607 return Bailout(kCompoundAssignmentToLookupSlot); | 6578 return Bailout(kCompoundAssignmentToLookupSlot); |
| 6608 | 6579 |
| 6609 case VariableLocation::MODULE: | 6580 case VariableLocation::MODULE: |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6647 | 6618 |
| 6648 if (expr->is_compound()) { | 6619 if (expr->is_compound()) { |
| 6649 HandleCompoundAssignment(expr); | 6620 HandleCompoundAssignment(expr); |
| 6650 return; | 6621 return; |
| 6651 } | 6622 } |
| 6652 | 6623 |
| 6653 if (prop != NULL) { | 6624 if (prop != NULL) { |
| 6654 HandlePropertyAssignment(expr); | 6625 HandlePropertyAssignment(expr); |
| 6655 } else if (proxy != NULL) { | 6626 } else if (proxy != NULL) { |
| 6656 Variable* var = proxy->var(); | 6627 Variable* var = proxy->var(); |
| 6628 DCHECK(!var->binding_needs_init()); |
| 6657 | 6629 |
| 6658 if (var->mode() == CONST) { | 6630 if (var->mode() == CONST && expr->op() != Token::INIT) { |
| 6659 if (expr->op() != Token::INIT) { | 6631 if (var->throw_on_const_assignment(function_language_mode())) { |
| 6660 if (var->throw_on_const_assignment(function_language_mode())) { | 6632 return Bailout(kNonInitializerAssignmentToConst); |
| 6661 return Bailout(kNonInitializerAssignmentToConst); | 6633 } else { |
| 6662 } else { | 6634 CHECK_ALIVE(VisitForValue(expr->value())); |
| 6663 CHECK_ALIVE(VisitForValue(expr->value())); | 6635 return ast_context()->ReturnValue(Pop()); |
| 6664 return ast_context()->ReturnValue(Pop()); | |
| 6665 } | |
| 6666 } | 6636 } |
| 6667 } | 6637 } |
| 6668 | 6638 |
| 6669 // Handle the assignment. | 6639 // Handle the assignment. |
| 6670 switch (var->location()) { | 6640 switch (var->location()) { |
| 6671 case VariableLocation::UNALLOCATED: | 6641 case VariableLocation::UNALLOCATED: |
| 6672 CHECK_ALIVE(VisitForValue(expr->value())); | 6642 CHECK_ALIVE(VisitForValue(expr->value())); |
| 6673 HandleGlobalVariableAssignment(var, Top(), expr->AssignmentSlot(), | 6643 HandleGlobalVariableAssignment(var, Top(), expr->AssignmentSlot(), |
| 6674 expr->AssignmentId()); | 6644 expr->AssignmentId()); |
| 6675 return ast_context()->ReturnValue(Pop()); | 6645 return ast_context()->ReturnValue(Pop()); |
| 6676 | 6646 |
| 6677 case VariableLocation::PARAMETER: | 6647 case VariableLocation::PARAMETER: |
| 6678 case VariableLocation::LOCAL: { | 6648 case VariableLocation::LOCAL: { |
| 6679 // Perform an initialization check for let declared variables | |
| 6680 // or parameters. | |
| 6681 if (var->mode() == LET && expr->op() == Token::ASSIGN) { | |
| 6682 HValue* env_value = environment()->Lookup(var); | |
| 6683 if (env_value == graph()->GetConstantHole()) { | |
| 6684 return Bailout(kAssignmentToLetVariableBeforeInitialization); | |
| 6685 } | |
| 6686 } | |
| 6687 // We do not allow the arguments object to occur in a context where it | 6649 // We do not allow the arguments object to occur in a context where it |
| 6688 // may escape, but assignments to stack-allocated locals are | 6650 // may escape, but assignments to stack-allocated locals are |
| 6689 // permitted. | 6651 // permitted. |
| 6690 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); | 6652 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); |
| 6691 HValue* value = Pop(); | 6653 HValue* value = Pop(); |
| 6692 BindIfLive(var, value); | 6654 BindIfLive(var, value); |
| 6693 return ast_context()->ReturnValue(value); | 6655 return ast_context()->ReturnValue(value); |
| 6694 } | 6656 } |
| 6695 | 6657 |
| 6696 case VariableLocation::CONTEXT: { | 6658 case VariableLocation::CONTEXT: { |
| 6697 // Bail out if we try to mutate a parameter value in a function using | 6659 // Bail out if we try to mutate a parameter value in a function using |
| 6698 // the arguments object. We do not (yet) correctly handle the | 6660 // the arguments object. We do not (yet) correctly handle the |
| 6699 // arguments property of the function. | 6661 // arguments property of the function. |
| 6700 if (current_info()->scope()->arguments() != NULL) { | 6662 if (current_info()->scope()->arguments() != NULL) { |
| 6701 // Parameters will rewrite to context slots. We have no direct way | 6663 // Parameters will rewrite to context slots. We have no direct way |
| 6702 // to detect that the variable is a parameter. | 6664 // to detect that the variable is a parameter. |
| 6703 int count = current_info()->scope()->num_parameters(); | 6665 int count = current_info()->scope()->num_parameters(); |
| 6704 for (int i = 0; i < count; ++i) { | 6666 for (int i = 0; i < count; ++i) { |
| 6705 if (var == current_info()->scope()->parameter(i)) { | 6667 if (var == current_info()->scope()->parameter(i)) { |
| 6706 return Bailout(kAssignmentToParameterInArgumentsObject); | 6668 return Bailout(kAssignmentToParameterInArgumentsObject); |
| 6707 } | 6669 } |
| 6708 } | 6670 } |
| 6709 } | 6671 } |
| 6710 | 6672 |
| 6711 CHECK_ALIVE(VisitForValue(expr->value())); | 6673 CHECK_ALIVE(VisitForValue(expr->value())); |
| 6712 HStoreContextSlot::Mode mode; | |
| 6713 if (expr->op() == Token::ASSIGN) { | |
| 6714 switch (var->mode()) { | |
| 6715 case LET: | |
| 6716 mode = HStoreContextSlot::kCheckDeoptimize; | |
| 6717 break; | |
| 6718 case CONST: | |
| 6719 // If we reached this point, the only possibility | |
| 6720 // is a sloppy assignment to a function name. | |
| 6721 DCHECK(function_language_mode() == SLOPPY && | |
| 6722 !var->throw_on_const_assignment(SLOPPY)); | |
| 6723 return ast_context()->ReturnValue(Pop()); | |
| 6724 default: | |
| 6725 mode = HStoreContextSlot::kNoCheck; | |
| 6726 } | |
| 6727 } else { | |
| 6728 DCHECK_EQ(Token::INIT, expr->op()); | |
| 6729 mode = HStoreContextSlot::kNoCheck; | |
| 6730 } | |
| 6731 | |
| 6732 HValue* context = BuildContextChainWalk(var); | 6674 HValue* context = BuildContextChainWalk(var); |
| 6733 HStoreContextSlot* instr = Add<HStoreContextSlot>( | 6675 HStoreContextSlot* instr = |
| 6734 context, var->index(), mode, Top()); | 6676 Add<HStoreContextSlot>(context, var->index(), Top()); |
| 6735 if (instr->HasObservableSideEffects()) { | 6677 if (instr->HasObservableSideEffects()) { |
| 6736 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); | 6678 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); |
| 6737 } | 6679 } |
| 6738 return ast_context()->ReturnValue(Pop()); | 6680 return ast_context()->ReturnValue(Pop()); |
| 6739 } | 6681 } |
| 6740 | 6682 |
| 6741 case VariableLocation::LOOKUP: | 6683 case VariableLocation::LOOKUP: |
| 6742 return Bailout(kAssignmentToLOOKUPVariable); | 6684 return Bailout(kAssignmentToLOOKUPVariable); |
| 6743 | 6685 |
| 6744 case VariableLocation::MODULE: | 6686 case VariableLocation::MODULE: |
| (...skipping 3675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10420 // Match the full code generator stack by simulating an extra stack | 10362 // Match the full code generator stack by simulating an extra stack |
| 10421 // element for postfix operations in a non-effect context. The return | 10363 // element for postfix operations in a non-effect context. The return |
| 10422 // value is ToNumber(input). | 10364 // value is ToNumber(input). |
| 10423 bool returns_original_input = | 10365 bool returns_original_input = |
| 10424 expr->is_postfix() && !ast_context()->IsEffect(); | 10366 expr->is_postfix() && !ast_context()->IsEffect(); |
| 10425 HValue* input = NULL; // ToNumber(original_input). | 10367 HValue* input = NULL; // ToNumber(original_input). |
| 10426 HValue* after = NULL; // The result after incrementing or decrementing. | 10368 HValue* after = NULL; // The result after incrementing or decrementing. |
| 10427 | 10369 |
| 10428 if (proxy != NULL) { | 10370 if (proxy != NULL) { |
| 10429 Variable* var = proxy->var(); | 10371 Variable* var = proxy->var(); |
| 10372 DCHECK(!var->binding_needs_init()); |
| 10430 if (var->mode() == CONST) { | 10373 if (var->mode() == CONST) { |
| 10431 return Bailout(kNonInitializerAssignmentToConst); | 10374 return Bailout(kNonInitializerAssignmentToConst); |
| 10432 } | 10375 } |
| 10433 // Argument of the count operation is a variable, not a property. | 10376 // Argument of the count operation is a variable, not a property. |
| 10434 DCHECK(prop == NULL); | 10377 DCHECK(prop == NULL); |
| 10435 CHECK_ALIVE(VisitForValue(target)); | 10378 CHECK_ALIVE(VisitForValue(target)); |
| 10436 | 10379 |
| 10437 after = BuildIncrement(expr); | 10380 after = BuildIncrement(expr); |
| 10438 input = returns_original_input ? Top() : Pop(); | 10381 input = returns_original_input ? Top() : Pop(); |
| 10439 Push(after); | 10382 Push(after); |
| 10440 | 10383 |
| 10441 switch (var->location()) { | 10384 switch (var->location()) { |
| 10442 case VariableLocation::UNALLOCATED: | 10385 case VariableLocation::UNALLOCATED: |
| 10443 HandleGlobalVariableAssignment(var, after, expr->CountSlot(), | 10386 HandleGlobalVariableAssignment(var, after, expr->CountSlot(), |
| 10444 expr->AssignmentId()); | 10387 expr->AssignmentId()); |
| 10445 break; | 10388 break; |
| 10446 | 10389 |
| 10447 case VariableLocation::PARAMETER: | 10390 case VariableLocation::PARAMETER: |
| 10448 case VariableLocation::LOCAL: | 10391 case VariableLocation::LOCAL: |
| 10449 BindIfLive(var, after); | 10392 BindIfLive(var, after); |
| 10450 break; | 10393 break; |
| 10451 | 10394 |
| 10452 case VariableLocation::CONTEXT: { | 10395 case VariableLocation::CONTEXT: { |
| 10453 HValue* context = BuildContextChainWalk(var); | 10396 HValue* context = BuildContextChainWalk(var); |
| 10454 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) | 10397 HStoreContextSlot* instr = |
| 10455 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; | 10398 Add<HStoreContextSlot>(context, var->index(), after); |
| 10456 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), | |
| 10457 mode, after); | |
| 10458 if (instr->HasObservableSideEffects()) { | 10399 if (instr->HasObservableSideEffects()) { |
| 10459 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); | 10400 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); |
| 10460 } | 10401 } |
| 10461 break; | 10402 break; |
| 10462 } | 10403 } |
| 10463 | 10404 |
| 10464 case VariableLocation::LOOKUP: | 10405 case VariableLocation::LOOKUP: |
| 10465 return Bailout(kLookupVariableInCountOperation); | 10406 return Bailout(kLookupVariableInCountOperation); |
| 10466 | 10407 |
| 10467 case VariableLocation::MODULE: | 10408 case VariableLocation::MODULE: |
| (...skipping 1361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11829 Add<HDeclareGlobals>(array, flags, vector); | 11770 Add<HDeclareGlobals>(array, flags, vector); |
| 11830 globals_.Rewind(0); | 11771 globals_.Rewind(0); |
| 11831 } | 11772 } |
| 11832 } | 11773 } |
| 11833 | 11774 |
| 11834 | 11775 |
| 11835 void HOptimizedGraphBuilder::VisitVariableDeclaration( | 11776 void HOptimizedGraphBuilder::VisitVariableDeclaration( |
| 11836 VariableDeclaration* declaration) { | 11777 VariableDeclaration* declaration) { |
| 11837 VariableProxy* proxy = declaration->proxy(); | 11778 VariableProxy* proxy = declaration->proxy(); |
| 11838 Variable* variable = proxy->var(); | 11779 Variable* variable = proxy->var(); |
| 11780 DCHECK(!variable->binding_needs_init()); |
| 11839 switch (variable->location()) { | 11781 switch (variable->location()) { |
| 11840 case VariableLocation::UNALLOCATED: { | 11782 case VariableLocation::UNALLOCATED: { |
| 11841 DCHECK(!variable->binding_needs_init()); | |
| 11842 globals_.Add(variable->name(), zone()); | 11783 globals_.Add(variable->name(), zone()); |
| 11843 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); | 11784 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); |
| 11844 DCHECK(!slot.IsInvalid()); | 11785 DCHECK(!slot.IsInvalid()); |
| 11845 globals_.Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); | 11786 globals_.Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); |
| 11846 globals_.Add(isolate()->factory()->undefined_value(), zone()); | 11787 globals_.Add(isolate()->factory()->undefined_value(), zone()); |
| 11847 return; | 11788 return; |
| 11848 } | 11789 } |
| 11849 case VariableLocation::PARAMETER: | 11790 case VariableLocation::PARAMETER: |
| 11850 case VariableLocation::LOCAL: | 11791 case VariableLocation::LOCAL: |
| 11851 if (variable->binding_needs_init()) { | |
| 11852 HValue* value = graph()->GetConstantHole(); | |
| 11853 environment()->Bind(variable, value); | |
| 11854 } | |
| 11855 break; | |
| 11856 case VariableLocation::CONTEXT: | 11792 case VariableLocation::CONTEXT: |
| 11857 if (variable->binding_needs_init()) { | |
| 11858 HValue* value = graph()->GetConstantHole(); | |
| 11859 HValue* context = environment()->context(); | |
| 11860 HStoreContextSlot* store = Add<HStoreContextSlot>( | |
| 11861 context, variable->index(), HStoreContextSlot::kNoCheck, value); | |
| 11862 if (store->HasObservableSideEffects()) { | |
| 11863 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); | |
| 11864 } | |
| 11865 } | |
| 11866 break; | 11793 break; |
| 11867 case VariableLocation::LOOKUP: | 11794 case VariableLocation::LOOKUP: |
| 11868 return Bailout(kUnsupportedLookupSlotInDeclaration); | 11795 return Bailout(kUnsupportedLookupSlotInDeclaration); |
| 11869 case VariableLocation::MODULE: | 11796 case VariableLocation::MODULE: |
| 11870 UNREACHABLE(); | 11797 UNREACHABLE(); |
| 11871 } | 11798 } |
| 11872 } | 11799 } |
| 11873 | 11800 |
| 11874 | 11801 |
| 11875 void HOptimizedGraphBuilder::VisitFunctionDeclaration( | 11802 void HOptimizedGraphBuilder::VisitFunctionDeclaration( |
| (...skipping 17 matching lines...) Expand all Loading... |
| 11893 case VariableLocation::LOCAL: { | 11820 case VariableLocation::LOCAL: { |
| 11894 CHECK_ALIVE(VisitForValue(declaration->fun())); | 11821 CHECK_ALIVE(VisitForValue(declaration->fun())); |
| 11895 HValue* value = Pop(); | 11822 HValue* value = Pop(); |
| 11896 BindIfLive(variable, value); | 11823 BindIfLive(variable, value); |
| 11897 break; | 11824 break; |
| 11898 } | 11825 } |
| 11899 case VariableLocation::CONTEXT: { | 11826 case VariableLocation::CONTEXT: { |
| 11900 CHECK_ALIVE(VisitForValue(declaration->fun())); | 11827 CHECK_ALIVE(VisitForValue(declaration->fun())); |
| 11901 HValue* value = Pop(); | 11828 HValue* value = Pop(); |
| 11902 HValue* context = environment()->context(); | 11829 HValue* context = environment()->context(); |
| 11903 HStoreContextSlot* store = Add<HStoreContextSlot>( | 11830 HStoreContextSlot* store = |
| 11904 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 11831 Add<HStoreContextSlot>(context, variable->index(), value); |
| 11905 if (store->HasObservableSideEffects()) { | 11832 if (store->HasObservableSideEffects()) { |
| 11906 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); | 11833 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); |
| 11907 } | 11834 } |
| 11908 break; | 11835 break; |
| 11909 } | 11836 } |
| 11910 case VariableLocation::LOOKUP: | 11837 case VariableLocation::LOOKUP: |
| 11911 return Bailout(kUnsupportedLookupSlotInDeclaration); | 11838 return Bailout(kUnsupportedLookupSlotInDeclaration); |
| 11912 case VariableLocation::MODULE: | 11839 case VariableLocation::MODULE: |
| 11913 UNREACHABLE(); | 11840 UNREACHABLE(); |
| 11914 } | 11841 } |
| (...skipping 1093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13008 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12935 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13009 } | 12936 } |
| 13010 | 12937 |
| 13011 #ifdef DEBUG | 12938 #ifdef DEBUG |
| 13012 graph_->Verify(false); // No full verify. | 12939 graph_->Verify(false); // No full verify. |
| 13013 #endif | 12940 #endif |
| 13014 } | 12941 } |
| 13015 | 12942 |
| 13016 } // namespace internal | 12943 } // namespace internal |
| 13017 } // namespace v8 | 12944 } // namespace v8 |
| OLD | NEW |