Commit 7f801ff3 authored by jarin's avatar jarin Committed by Commit bot

[crankshaft] Do not optimize argument access if any parameter is context-allocated.

Note: This CL might regress code that relies on such arguments access.
In that case, we could still optimize the access if it accesses at
constant index (and the argument at that index is not context-allocated).

If any code relies on a general access to context-allocated arguments,
we would need to analyze the function for assignment to the arguments - this
might be quite tricky.

BUG=chromium:662845

Review-Url: https://codereview.chromium.org/2484723002
Cr-Commit-Position: refs/heads/master@{#40813}
parent c57e54b3
...@@ -7421,6 +7421,16 @@ void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { ...@@ -7421,6 +7421,16 @@ void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() {
function_state()->set_arguments_elements(arguments_elements); function_state()->set_arguments_elements(arguments_elements);
} }
bool HOptimizedGraphBuilder::IsAnyParameterContextAllocated() {
int count = current_info()->scope()->num_parameters();
for (int i = 0; i < count; ++i) {
if (current_info()->scope()->parameter(i)->location() ==
VariableLocation::CONTEXT) {
return true;
}
}
return false;
}
bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) {
VariableProxy* proxy = expr->obj()->AsVariableProxy(); VariableProxy* proxy = expr->obj()->AsVariableProxy();
...@@ -7455,6 +7465,7 @@ bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { ...@@ -7455,6 +7465,7 @@ bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) {
// We need to take into account the KEYED_LOAD_IC feedback to guard the // We need to take into account the KEYED_LOAD_IC feedback to guard the
// HBoundsCheck instructions below. // HBoundsCheck instructions below.
if (!expr->IsMonomorphic()) return false; if (!expr->IsMonomorphic()) return false;
if (IsAnyParameterContextAllocated()) return false;
CHECK_ALIVE_OR_RETURN(VisitForValue(expr->obj(), ARGUMENTS_ALLOWED), true); CHECK_ALIVE_OR_RETURN(VisitForValue(expr->obj(), ARGUMENTS_ALLOWED), true);
CHECK_ALIVE_OR_RETURN(VisitForValue(expr->key()), true); CHECK_ALIVE_OR_RETURN(VisitForValue(expr->key()), true);
HValue* key = Pop(); HValue* key = Pop();
...@@ -10471,21 +10482,6 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { ...@@ -10471,21 +10482,6 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
break; break;
case VariableLocation::CONTEXT: { case VariableLocation::CONTEXT: {
// Bail out if we try to mutate a parameter value in a function
// using the arguments object. We do not (yet) correctly handle the
// arguments property of the function.
if (current_info()->scope()->arguments() != NULL) {
// Parameters will rewrite to context slots. We have no direct
// way to detect that the variable is a parameter so we use a
// linear search of the parameter list.
int count = current_info()->scope()->num_parameters();
for (int i = 0; i < count; ++i) {
if (var == current_info()->scope()->parameter(i)) {
return Bailout(kAssignmentToParameterInArgumentsObject);
}
}
}
HValue* context = BuildContextChainWalk(var); HValue* context = BuildContextChainWalk(var);
HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode())
? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck;
......
...@@ -2800,6 +2800,8 @@ class HOptimizedGraphBuilder : public HGraphBuilder, ...@@ -2800,6 +2800,8 @@ class HOptimizedGraphBuilder : public HGraphBuilder,
bool CanBeFunctionApplyArguments(Call* expr); bool CanBeFunctionApplyArguments(Call* expr);
bool IsAnyParameterContextAllocated();
// The translation state of the currently-being-translated function. // The translation state of the currently-being-translated function.
FunctionState* function_state_; FunctionState* function_state_;
......
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
function foo(x) {
(function() { x = 1; })()
return arguments[0];
}
assertEquals(1, foo(42));
assertEquals(1, foo(42));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1, foo(42));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment