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 |