Fix array.concat with double for sealed, frozen object

Treat packed sealed, frozen element as packed element.
Also rename to IsPackedFrozenOrSealedElementsKind.

Bug: chromium:951988
Change-Id: Ia636f0a14a229e4c44772627728927db1b877f27
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1565470
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#60831}
This commit is contained in:
Z Duong Nguyen-Huu 2019-04-11 15:35:04 -07:00 committed by Commit Bot
parent 1f6d27e8df
commit 68ba8574f6
12 changed files with 44 additions and 12 deletions

View File

@ -1211,6 +1211,9 @@ Object Slow_ArrayConcat(BuiltinArguments* args, Handle<Object> species,
if (length_estimate != 0) {
ElementsKind array_kind =
GetPackedElementsKind(array->GetElementsKind());
if (IsPackedFrozenOrSealedElementsKind(array_kind)) {
array_kind = PACKED_ELEMENTS;
}
kind = GetMoreGeneralElementsKind(kind, array_kind);
}
element_estimate = EstimateElementCount(isolate, array);

View File

@ -5897,7 +5897,7 @@ TNode<BoolT> CodeStubAssembler::IsExtensibleMap(SloppyTNode<Map> map) {
return IsSetWord32<Map::IsExtensibleBit>(LoadMapBitField2(map));
}
TNode<BoolT> CodeStubAssembler::IsFrozenOrSealedElementsKindMap(
TNode<BoolT> CodeStubAssembler::IsPackedFrozenOrSealedElementsKindMap(
SloppyTNode<Map> map) {
CSA_ASSERT(this, IsMap(map));
return IsElementsKindInRange(LoadMapElementsKind(map), PACKED_SEALED_ELEMENTS,

View File

@ -2148,7 +2148,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsNameDictionary(SloppyTNode<HeapObject> object);
TNode<BoolT> IsGlobalDictionary(SloppyTNode<HeapObject> object);
TNode<BoolT> IsExtensibleMap(SloppyTNode<Map> map);
TNode<BoolT> IsFrozenOrSealedElementsKindMap(SloppyTNode<Map> map);
TNode<BoolT> IsPackedFrozenOrSealedElementsKindMap(SloppyTNode<Map> map);
TNode<BoolT> IsExtensibleNonPrototypeMap(TNode<Map> map);
TNode<BoolT> IsExternalStringInstanceType(SloppyTNode<Int32T> instance_type);
TNode<BoolT> IsFeedbackCell(SloppyTNode<HeapObject> object);

View File

@ -153,7 +153,7 @@ inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) {
return IsDoubleElementsKind(kind) || IsFixedFloatElementsKind(kind);
}
inline bool IsFrozenOrSealedElementsKind(ElementsKind kind) {
inline bool IsPackedFrozenOrSealedElementsKind(ElementsKind kind) {
return IsInRange(kind, PACKED_SEALED_ELEMENTS, PACKED_FROZEN_ELEMENTS);
}

View File

@ -1353,7 +1353,8 @@ class ElementsAccessorBase : public InternalElementsAccessor {
static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject holder,
FixedArrayBase backing_store,
uint32_t index, PropertyFilter filter) {
DCHECK(IsFastElementsKind(kind()) || IsFrozenOrSealedElementsKind(kind()));
DCHECK(IsFastElementsKind(kind()) ||
IsPackedFrozenOrSealedElementsKind(kind()));
uint32_t length = Subclass::GetMaxIndex(holder, backing_store);
if (IsHoleyElementsKind(kind())) {
return index < length &&
@ -2333,7 +2334,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
return Just(false);
}
} else if (!IsObjectElementsKind(Subclass::kind()) &&
!IsFrozenOrSealedElementsKind(Subclass::kind())) {
!IsPackedFrozenOrSealedElementsKind(Subclass::kind())) {
// Search for non-number, non-Undefined value, with either
// PACKED_SMI_ELEMENTS, PACKED_DOUBLE_ELEMENTS, HOLEY_SMI_ELEMENTS or
// HOLEY_DOUBLE_ELEMENTS. Guaranteed to return false, since these
@ -2343,7 +2344,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
// Search for non-number, non-Undefined value with either
// PACKED_ELEMENTS or HOLEY_ELEMENTS.
DCHECK(IsObjectElementsKind(Subclass::kind()) ||
IsFrozenOrSealedElementsKind(Subclass::kind()));
IsPackedFrozenOrSealedElementsKind(Subclass::kind()));
auto elements = FixedArray::cast(receiver->elements());
for (uint32_t k = start_from; k < length; ++k) {
@ -2638,7 +2639,7 @@ class FastSmiOrObjectElementsAccessor
// Only FAST_{,HOLEY_}ELEMENTS can store non-numbers.
if (!value->IsNumber() && !IsObjectElementsKind(Subclass::kind()) &&
!IsFrozenOrSealedElementsKind(Subclass::kind())) {
!IsPackedFrozenOrSealedElementsKind(Subclass::kind())) {
return Just<int64_t>(-1);
}
// NaN can never be found by strict equality.

View File

@ -1191,7 +1191,7 @@ Handle<Object> KeyedLoadIC::LoadElementHandler(Handle<Map> receiver_map,
is_js_array, load_mode);
}
DCHECK(IsFastElementsKind(elements_kind) ||
IsFrozenOrSealedElementsKind(elements_kind) ||
IsPackedFrozenOrSealedElementsKind(elements_kind) ||
IsFixedTypedArrayElementsKind(elements_kind));
bool convert_hole_to_undefined =
(elements_kind == HOLEY_SMI_ELEMENTS ||

View File

@ -332,7 +332,7 @@ MapUpdater::State MapUpdater::FindRootMap() {
DCHECK(to_kind == DICTIONARY_ELEMENTS ||
to_kind == SLOW_STRING_WRAPPER_ELEMENTS ||
IsFixedTypedArrayElementsKind(to_kind) ||
IsFrozenOrSealedElementsKind(to_kind));
IsPackedFrozenOrSealedElementsKind(to_kind));
to_kind = integrity_source_map_->elements_kind();
}

View File

@ -752,7 +752,8 @@ ElementsKind JSObject::GetElementsKind() const {
DCHECK(fixed_array->IsFixedArray());
DCHECK(fixed_array->IsDictionary());
} else {
DCHECK(kind > DICTIONARY_ELEMENTS || IsFrozenOrSealedElementsKind(kind));
DCHECK(kind > DICTIONARY_ELEMENTS ||
IsPackedFrozenOrSealedElementsKind(kind));
}
DCHECK(!IsSloppyArgumentsElementsKind(kind) ||
(elements()->IsFixedArray() && elements()->length() >= 2));
@ -796,7 +797,7 @@ bool JSObject::HasPackedElements() {
}
bool JSObject::HasFrozenOrSealedElements() {
return IsFrozenOrSealedElementsKind(GetElementsKind());
return IsPackedFrozenOrSealedElementsKind(GetElementsKind());
}
bool JSObject::HasFastArgumentsElements() {

View File

@ -501,7 +501,7 @@ bool Map::has_dictionary_elements() const {
}
bool Map::is_frozen_or_sealed_elements() const {
return IsFrozenOrSealedElementsKind(elements_kind());
return IsPackedFrozenOrSealedElementsKind(elements_kind());
}
void Map::set_is_dictionary_map(bool value) {

View File

@ -545,3 +545,12 @@ assertThrows(function() {
value: obj,
});
}, TypeError);
// Test regression Array.concat with double
var arr = ['a'];
Object.freeze(arr);
arr = arr.concat(0.5);
assertEquals(arr, ['a', 0.5]);
Object.freeze(arr);
arr = arr.concat([1.5, 'b']);
assertEquals(arr, ['a', 0.5, 1.5, 'b']);

View File

@ -250,3 +250,12 @@ arr.fill('d');
assertEquals(arr.join(''), "ddd");
arr.pop();
assertEquals(arr.join(''), "dd");
// Test regression Array.concat with double
var arr = ['a'];
Object.preventExtensions(arr);
arr = arr.concat(0.5);
assertEquals(arr, ['a', 0.5]);
Object.preventExtensions(arr);
arr = arr.concat([1.5, 'b']);
assertEquals(arr, ['a', 0.5, 1.5, 'b']);

View File

@ -521,3 +521,12 @@ assertThrows(function() {
value: obj,
});
}, TypeError);
// Test regression Array.concat with double
var arr = ['a'];
Object.seal(arr);
arr = arr.concat(0.5);
assertEquals(arr, ['a', 0.5]);
Object.seal(arr);
arr = arr.concat([1.5, 'b']);
assertEquals(arr, ['a', 0.5, 1.5, 'b']);