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 |