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 7403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7414 push_argument->InsertAfter(insert_after); | 7414 push_argument->InsertAfter(insert_after); |
7415 insert_after = push_argument; | 7415 insert_after = push_argument; |
7416 } | 7416 } |
7417 | 7417 |
7418 HArgumentsElements* arguments_elements = New<HArgumentsElements>(true); | 7418 HArgumentsElements* arguments_elements = New<HArgumentsElements>(true); |
7419 arguments_elements->ClearFlag(HValue::kUseGVN); | 7419 arguments_elements->ClearFlag(HValue::kUseGVN); |
7420 arguments_elements->InsertAfter(insert_after); | 7420 arguments_elements->InsertAfter(insert_after); |
7421 function_state()->set_arguments_elements(arguments_elements); | 7421 function_state()->set_arguments_elements(arguments_elements); |
7422 } | 7422 } |
7423 | 7423 |
| 7424 bool HOptimizedGraphBuilder::IsAnyParameterContextAllocated() { |
| 7425 int count = current_info()->scope()->num_parameters(); |
| 7426 for (int i = 0; i < count; ++i) { |
| 7427 if (current_info()->scope()->parameter(i)->location() == |
| 7428 VariableLocation::CONTEXT) { |
| 7429 return true; |
| 7430 } |
| 7431 } |
| 7432 return false; |
| 7433 } |
7424 | 7434 |
7425 bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { | 7435 bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { |
7426 VariableProxy* proxy = expr->obj()->AsVariableProxy(); | 7436 VariableProxy* proxy = expr->obj()->AsVariableProxy(); |
7427 if (proxy == NULL) return false; | 7437 if (proxy == NULL) return false; |
7428 if (!proxy->var()->IsStackAllocated()) return false; | 7438 if (!proxy->var()->IsStackAllocated()) return false; |
7429 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { | 7439 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { |
7430 return false; | 7440 return false; |
7431 } | 7441 } |
7432 | 7442 |
7433 HInstruction* result = NULL; | 7443 HInstruction* result = NULL; |
(...skipping 14 matching lines...) Expand all Loading... |
7448 } else { | 7458 } else { |
7449 // Number of arguments without receiver. | 7459 // Number of arguments without receiver. |
7450 int argument_count = environment()-> | 7460 int argument_count = environment()-> |
7451 arguments_environment()->parameter_count() - 1; | 7461 arguments_environment()->parameter_count() - 1; |
7452 result = New<HConstant>(argument_count); | 7462 result = New<HConstant>(argument_count); |
7453 } | 7463 } |
7454 } else { | 7464 } else { |
7455 // We need to take into account the KEYED_LOAD_IC feedback to guard the | 7465 // We need to take into account the KEYED_LOAD_IC feedback to guard the |
7456 // HBoundsCheck instructions below. | 7466 // HBoundsCheck instructions below. |
7457 if (!expr->IsMonomorphic()) return false; | 7467 if (!expr->IsMonomorphic()) return false; |
| 7468 if (IsAnyParameterContextAllocated()) return false; |
7458 CHECK_ALIVE_OR_RETURN(VisitForValue(expr->obj(), ARGUMENTS_ALLOWED), true); | 7469 CHECK_ALIVE_OR_RETURN(VisitForValue(expr->obj(), ARGUMENTS_ALLOWED), true); |
7459 CHECK_ALIVE_OR_RETURN(VisitForValue(expr->key()), true); | 7470 CHECK_ALIVE_OR_RETURN(VisitForValue(expr->key()), true); |
7460 HValue* key = Pop(); | 7471 HValue* key = Pop(); |
7461 Drop(1); // Arguments object. | 7472 Drop(1); // Arguments object. |
7462 if (function_state()->outer() == NULL) { | 7473 if (function_state()->outer() == NULL) { |
7463 HInstruction* elements = Add<HArgumentsElements>(false); | 7474 HInstruction* elements = Add<HArgumentsElements>(false); |
7464 HInstruction* length = Add<HArgumentsLength>(elements); | 7475 HInstruction* length = Add<HArgumentsLength>(elements); |
7465 HInstruction* checked_key = Add<HBoundsCheck>(key, length); | 7476 HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
7466 result = New<HAccessArgumentsAt>(elements, length, checked_key); | 7477 result = New<HAccessArgumentsAt>(elements, length, checked_key); |
7467 } else { | 7478 } else { |
(...skipping 2996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10464 HandleGlobalVariableAssignment(var, after, expr->CountSlot(), | 10475 HandleGlobalVariableAssignment(var, after, expr->CountSlot(), |
10465 expr->AssignmentId()); | 10476 expr->AssignmentId()); |
10466 break; | 10477 break; |
10467 | 10478 |
10468 case VariableLocation::PARAMETER: | 10479 case VariableLocation::PARAMETER: |
10469 case VariableLocation::LOCAL: | 10480 case VariableLocation::LOCAL: |
10470 BindIfLive(var, after); | 10481 BindIfLive(var, after); |
10471 break; | 10482 break; |
10472 | 10483 |
10473 case VariableLocation::CONTEXT: { | 10484 case VariableLocation::CONTEXT: { |
10474 // Bail out if we try to mutate a parameter value in a function | |
10475 // using the arguments object. We do not (yet) correctly handle the | |
10476 // arguments property of the function. | |
10477 if (current_info()->scope()->arguments() != NULL) { | |
10478 // Parameters will rewrite to context slots. We have no direct | |
10479 // way to detect that the variable is a parameter so we use a | |
10480 // linear search of the parameter list. | |
10481 int count = current_info()->scope()->num_parameters(); | |
10482 for (int i = 0; i < count; ++i) { | |
10483 if (var == current_info()->scope()->parameter(i)) { | |
10484 return Bailout(kAssignmentToParameterInArgumentsObject); | |
10485 } | |
10486 } | |
10487 } | |
10488 | |
10489 HValue* context = BuildContextChainWalk(var); | 10485 HValue* context = BuildContextChainWalk(var); |
10490 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) | 10486 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) |
10491 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; | 10487 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; |
10492 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), | 10488 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), |
10493 mode, after); | 10489 mode, after); |
10494 if (instr->HasObservableSideEffects()) { | 10490 if (instr->HasObservableSideEffects()) { |
10495 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); | 10491 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); |
10496 } | 10492 } |
10497 break; | 10493 break; |
10498 } | 10494 } |
(...skipping 2550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13049 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13045 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13050 } | 13046 } |
13051 | 13047 |
13052 #ifdef DEBUG | 13048 #ifdef DEBUG |
13053 graph_->Verify(false); // No full verify. | 13049 graph_->Verify(false); // No full verify. |
13054 #endif | 13050 #endif |
13055 } | 13051 } |
13056 | 13052 |
13057 } // namespace internal | 13053 } // namespace internal |
13058 } // namespace v8 | 13054 } // namespace v8 |
OLD | NEW |