[crankshaft] Fix deoptimization loop w/ non-monomorphic arguments access.

In Crankshaft we unconditionally assume that accesses to arguments[i] will
be in-bounds and don't take into account IC feedback that would eventually
teach us about out-of-bounds accesses that have happened in the past, so
there's no real guard to protect the bounds check in optimized code.

TEST=mjsunit/compiler/deopt-arguments-oob
R=jarin@chromium.org
BUG=v8:5606

Review-Url: https://codereview.chromium.org/2481053002
Cr-Commit-Position: refs/heads/master@{#40787}
This commit is contained in:
bmeurer 2016-11-06 22:38:50 -08:00 committed by Commit bot
parent 9e3eafdd28
commit d6ff45afad
2 changed files with 30 additions and 0 deletions

View File

@ -7452,6 +7452,9 @@ bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) {
result = New<HConstant>(argument_count);
}
} else {
// We need to take into account the KEYED_LOAD_IC feedback to guard the
// HBoundsCheck instructions below.
if (!expr->IsMonomorphic()) return false;
CHECK_ALIVE_OR_RETURN(VisitForValue(expr->obj(), ARGUMENTS_ALLOWED), true);
CHECK_ALIVE_OR_RETURN(VisitForValue(expr->key()), true);
HValue* key = Pop();

View File

@ -0,0 +1,27 @@
// 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() { return arguments[0]; }
// Warm up with monomorphic access.
foo(0);
foo(1);
%BaselineFunctionOnNextCall(foo);
foo(2);
foo(3);
%OptimizeFunctionOnNextCall(foo);
// Mess with out-of-bounds accesses.
for (var i = 0; i < 50000; ++i) {
foo();
}
// Optimization shall stabilize now.
var count = %GetOptimizationCount(foo);
for (var i = 0; i < 50000; ++i) {
foo();
}
assertEquals(count, %GetOptimizationCount(foo));