Commit 9987221c authored by mvstanton's avatar mvstanton Committed by Commit bot

Make sure builtins preserve guarantees about empty element array prototypes.

We have a bottleneck around storing elements in the array and object prototypes,
but the Push() and Unshift() builtins don't respect them.

Fix this exactly to the level of existing support for stores.

BUG=v8:4043
LOG=N
NOTRY=true

Review URL: https://codereview.chromium.org/1066003003

Cr-Commit-Position: refs/heads/master@{#27943}
parent ad854ea1
......@@ -234,6 +234,12 @@ static inline MaybeHandle<FixedArrayBase> EnsureJSArrayWithWritableFastElements(
return MaybeHandle<FixedArrayBase>();
}
// Adding elements to the array prototype would break code that makes sure
// it has no elements. Handle that elsewhere.
if (array->GetIsolate()->is_initial_array_prototype(*array)) {
return MaybeHandle<FixedArrayBase>();
}
// Need to ensure that the arguments passed in args can be contained in
// the array.
int args_length = args->length();
......
......@@ -8451,6 +8451,13 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype()));
BuildCheckPrototypeMaps(prototype, Handle<JSObject>());
// Protect against adding elements to the Array prototype, which needs to
// route through appropriate bottlenecks.
if (isolate()->IsFastArrayConstructorPrototypeChainIntact() &&
!prototype->IsJSArray()) {
return false;
}
const int argc = args_count_no_receiver;
if (argc != 1) return false;
......
// Copyright 2015 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 f1(a, i) {
return a[i] + 0.5;
}
var arr = [,0.0,2.5];
assertEquals(0.5, f1(arr, 1));
assertEquals(0.5, f1(arr, 1));
%OptimizeFunctionOnNextCall(f1);
assertEquals(0.5, f1(arr, 1));
// Trick crankshaft into accepting feedback with the array prototype
// map even though a call on that map was never made. optopush should
// refuse to inline the push call based on the danger that it's modifying
// the array prototype.
var push = Array.prototype.push;
var array_prototype = Array.prototype;
function optopush(a) {
push.call(a, 1);
}
function foo() {
optopush(array_prototype);
}
optopush([]);
optopush([]);
optopush([]);
%OptimizeFunctionOnNextCall(foo);
foo();
assertEquals(1.5, f1(arr, 0));
// Copyright 2015 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 f1(a, i) {
return a[i] + 0.5;
}
var arr = [,0.0,2.5];
assertEquals(0.5, f1(arr, 1));
assertEquals(0.5, f1(arr, 1));
%OptimizeFunctionOnNextCall(f1);
assertEquals(0.5, f1(arr, 1));
Array.prototype.unshift(1.5);
assertEquals(2, f1(arr, 0));
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