[ic] Always use generic ICs for growing element stores on arguments
In certain corner-cases we would grow a FAST_ELEMENTS packed backing store of a JS_ARGUMENTS_TYPE object without converting to holey elements kinds. As a side effect you could then read out the_hole. BUG=v8:5772 Review-Url: https://codereview.chromium.org/2597013004 Cr-Commit-Position: refs/heads/master@{#41921}
This commit is contained in:
parent
b9b6e0b06d
commit
f73973092c
11
src/ic/ic.cc
11
src/ic/ic.cc
@ -2422,17 +2422,14 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
|
||||
}
|
||||
|
||||
Handle<Map> old_receiver_map;
|
||||
bool sloppy_arguments_elements = false;
|
||||
bool is_arguments = false;
|
||||
bool key_is_valid_index = false;
|
||||
KeyedAccessStoreMode store_mode = STANDARD_STORE;
|
||||
if (use_ic && object->IsJSObject()) {
|
||||
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
|
||||
old_receiver_map = handle(receiver->map(), isolate());
|
||||
sloppy_arguments_elements =
|
||||
!is_sloppy(language_mode()) &&
|
||||
receiver->elements()->map() ==
|
||||
isolate()->heap()->sloppy_arguments_elements_map();
|
||||
if (!sloppy_arguments_elements) {
|
||||
is_arguments = receiver->IsJSArgumentsObject();
|
||||
if (!is_arguments) {
|
||||
key_is_valid_index = key->IsSmi() && Smi::cast(*key)->value() >= 0;
|
||||
if (key_is_valid_index) {
|
||||
uint32_t index = static_cast<uint32_t>(Smi::cast(*key)->value());
|
||||
@ -2449,7 +2446,7 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
|
||||
|
||||
if (use_ic) {
|
||||
if (!old_receiver_map.is_null()) {
|
||||
if (sloppy_arguments_elements) {
|
||||
if (is_arguments) {
|
||||
TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver");
|
||||
} else if (key_is_valid_index) {
|
||||
// We should go generic if receiver isn't a dictionary, but our
|
||||
|
@ -138,8 +138,9 @@ TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
|
||||
TYPE_CHECKER(Foreign, FOREIGN_TYPE)
|
||||
TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
|
||||
TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
|
||||
TYPE_CHECKER(JSArrayBuffer, JS_ARRAY_BUFFER_TYPE)
|
||||
TYPE_CHECKER(JSArgumentsObject, JS_ARGUMENTS_TYPE)
|
||||
TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
|
||||
TYPE_CHECKER(JSArrayBuffer, JS_ARRAY_BUFFER_TYPE)
|
||||
TYPE_CHECKER(JSBoundFunction, JS_BOUND_FUNCTION_TYPE)
|
||||
TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
|
||||
TYPE_CHECKER(JSDataView, JS_DATA_VIEW_TYPE)
|
||||
@ -148,14 +149,14 @@ TYPE_CHECKER(JSError, JS_ERROR_TYPE)
|
||||
TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
|
||||
TYPE_CHECKER(JSGeneratorObject, JS_GENERATOR_OBJECT_TYPE)
|
||||
TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
|
||||
TYPE_CHECKER(JSMapIterator, JS_MAP_ITERATOR_TYPE)
|
||||
TYPE_CHECKER(JSMap, JS_MAP_TYPE)
|
||||
TYPE_CHECKER(JSMapIterator, JS_MAP_ITERATOR_TYPE)
|
||||
TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
|
||||
TYPE_CHECKER(JSModuleNamespace, JS_MODULE_NAMESPACE_TYPE)
|
||||
TYPE_CHECKER(JSPromise, JS_PROMISE_TYPE)
|
||||
TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
|
||||
TYPE_CHECKER(JSSetIterator, JS_SET_ITERATOR_TYPE)
|
||||
TYPE_CHECKER(JSSet, JS_SET_TYPE)
|
||||
TYPE_CHECKER(JSSetIterator, JS_SET_ITERATOR_TYPE)
|
||||
TYPE_CHECKER(JSStringIterator, JS_STRING_ITERATOR_TYPE)
|
||||
TYPE_CHECKER(JSTypedArray, JS_TYPED_ARRAY_TYPE)
|
||||
TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
|
||||
|
@ -1043,6 +1043,7 @@ template <class C> inline bool Is(Object* obj);
|
||||
V(FreeSpace) \
|
||||
V(JSReceiver) \
|
||||
V(JSObject) \
|
||||
V(JSArgumentsObject) \
|
||||
V(JSContextExtensionObject) \
|
||||
V(JSGeneratorObject) \
|
||||
V(JSModuleNamespace) \
|
||||
|
42
test/mjsunit/regress/regress-5772.js
Normal file
42
test/mjsunit/regress/regress-5772.js
Normal file
@ -0,0 +1,42 @@
|
||||
// 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 sloppyPackedArguments() {
|
||||
function f(a) {
|
||||
for (var i = 0; i < 2; i++) {
|
||||
a[i] = 0;
|
||||
}
|
||||
}
|
||||
var boom;
|
||||
function g() {
|
||||
var a = arguments;
|
||||
f(a);
|
||||
boom = a[5];
|
||||
assertEquals(undefined, boom);
|
||||
}
|
||||
|
||||
f([]);
|
||||
g(1);
|
||||
})();
|
||||
|
||||
(function strictPackedArguments() {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
for (var i = 0; i < 2; i++) {
|
||||
a[i] = 0;
|
||||
}
|
||||
}
|
||||
var boom;
|
||||
function g() {
|
||||
var a = arguments;
|
||||
f(a);
|
||||
boom = a[5];
|
||||
assertEquals(undefined, boom);
|
||||
}
|
||||
|
||||
f([]);
|
||||
g(1);
|
||||
})();
|
Loading…
Reference in New Issue
Block a user