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