From f73973092c780ba6c2c6988fce777472eb95a58f Mon Sep 17 00:00:00 2001 From: cbruni Date: Thu, 22 Dec 2016 06:10:51 -0800 Subject: [PATCH] [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} --- src/ic/ic.cc | 11 +++----- src/objects-inl.h | 7 +++-- src/objects.h | 1 + test/mjsunit/regress/regress-5772.js | 42 ++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 test/mjsunit/regress/regress-5772.js diff --git a/src/ic/ic.cc b/src/ic/ic.cc index 5a04fe89e2..dfa3d64389 100644 --- a/src/ic/ic.cc +++ b/src/ic/ic.cc @@ -2422,17 +2422,14 @@ MaybeHandle KeyedStoreIC::Store(Handle object, } Handle 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 receiver = Handle::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(Smi::cast(*key)->value()); @@ -2449,7 +2446,7 @@ MaybeHandle KeyedStoreIC::Store(Handle 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 diff --git a/src/objects-inl.h b/src/objects-inl.h index 2614c05b64..8177d6d21e 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -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) diff --git a/src/objects.h b/src/objects.h index 9760007051..b3b2366219 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1043,6 +1043,7 @@ template inline bool Is(Object* obj); V(FreeSpace) \ V(JSReceiver) \ V(JSObject) \ + V(JSArgumentsObject) \ V(JSContextExtensionObject) \ V(JSGeneratorObject) \ V(JSModuleNamespace) \ diff --git a/test/mjsunit/regress/regress-5772.js b/test/mjsunit/regress/regress-5772.js new file mode 100644 index 0000000000..e1f68f80ef --- /dev/null +++ b/test/mjsunit/regress/regress-5772.js @@ -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); +})();