Commit 68ba8574 authored by Z Duong Nguyen-Huu's avatar Z Duong Nguyen-Huu Committed by Commit Bot

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/+/1565470Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#60831}
parent 1f6d27e8
...@@ -1211,6 +1211,9 @@ Object Slow_ArrayConcat(BuiltinArguments* args, Handle<Object> species, ...@@ -1211,6 +1211,9 @@ Object Slow_ArrayConcat(BuiltinArguments* args, Handle<Object> species,
if (length_estimate != 0) { if (length_estimate != 0) {
ElementsKind array_kind = ElementsKind array_kind =
GetPackedElementsKind(array->GetElementsKind()); GetPackedElementsKind(array->GetElementsKind());
if (IsPackedFrozenOrSealedElementsKind(array_kind)) {
array_kind = PACKED_ELEMENTS;
}
kind = GetMoreGeneralElementsKind(kind, array_kind); kind = GetMoreGeneralElementsKind(kind, array_kind);
} }
element_estimate = EstimateElementCount(isolate, array); element_estimate = EstimateElementCount(isolate, array);
......
...@@ -5897,7 +5897,7 @@ TNode<BoolT> CodeStubAssembler::IsExtensibleMap(SloppyTNode<Map> map) { ...@@ -5897,7 +5897,7 @@ TNode<BoolT> CodeStubAssembler::IsExtensibleMap(SloppyTNode<Map> map) {
return IsSetWord32<Map::IsExtensibleBit>(LoadMapBitField2(map)); return IsSetWord32<Map::IsExtensibleBit>(LoadMapBitField2(map));
} }
TNode<BoolT> CodeStubAssembler::IsFrozenOrSealedElementsKindMap( TNode<BoolT> CodeStubAssembler::IsPackedFrozenOrSealedElementsKindMap(
SloppyTNode<Map> map) { SloppyTNode<Map> map) {
CSA_ASSERT(this, IsMap(map)); CSA_ASSERT(this, IsMap(map));
return IsElementsKindInRange(LoadMapElementsKind(map), PACKED_SEALED_ELEMENTS, return IsElementsKindInRange(LoadMapElementsKind(map), PACKED_SEALED_ELEMENTS,
......
...@@ -2148,7 +2148,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -2148,7 +2148,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsNameDictionary(SloppyTNode<HeapObject> object); TNode<BoolT> IsNameDictionary(SloppyTNode<HeapObject> object);
TNode<BoolT> IsGlobalDictionary(SloppyTNode<HeapObject> object); TNode<BoolT> IsGlobalDictionary(SloppyTNode<HeapObject> object);
TNode<BoolT> IsExtensibleMap(SloppyTNode<Map> map); 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> IsExtensibleNonPrototypeMap(TNode<Map> map);
TNode<BoolT> IsExternalStringInstanceType(SloppyTNode<Int32T> instance_type); TNode<BoolT> IsExternalStringInstanceType(SloppyTNode<Int32T> instance_type);
TNode<BoolT> IsFeedbackCell(SloppyTNode<HeapObject> object); TNode<BoolT> IsFeedbackCell(SloppyTNode<HeapObject> object);
......
...@@ -153,7 +153,7 @@ inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) { ...@@ -153,7 +153,7 @@ inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) {
return IsDoubleElementsKind(kind) || IsFixedFloatElementsKind(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); return IsInRange(kind, PACKED_SEALED_ELEMENTS, PACKED_FROZEN_ELEMENTS);
} }
......
...@@ -1353,7 +1353,8 @@ class ElementsAccessorBase : public InternalElementsAccessor { ...@@ -1353,7 +1353,8 @@ class ElementsAccessorBase : public InternalElementsAccessor {
static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject holder, static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject holder,
FixedArrayBase backing_store, FixedArrayBase backing_store,
uint32_t index, PropertyFilter filter) { uint32_t index, PropertyFilter filter) {
DCHECK(IsFastElementsKind(kind()) || IsFrozenOrSealedElementsKind(kind())); DCHECK(IsFastElementsKind(kind()) ||
IsPackedFrozenOrSealedElementsKind(kind()));
uint32_t length = Subclass::GetMaxIndex(holder, backing_store); uint32_t length = Subclass::GetMaxIndex(holder, backing_store);
if (IsHoleyElementsKind(kind())) { if (IsHoleyElementsKind(kind())) {
return index < length && return index < length &&
...@@ -2333,7 +2334,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { ...@@ -2333,7 +2334,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
return Just(false); return Just(false);
} }
} else if (!IsObjectElementsKind(Subclass::kind()) && } else if (!IsObjectElementsKind(Subclass::kind()) &&
!IsFrozenOrSealedElementsKind(Subclass::kind())) { !IsPackedFrozenOrSealedElementsKind(Subclass::kind())) {
// Search for non-number, non-Undefined value, with either // Search for non-number, non-Undefined value, with either
// PACKED_SMI_ELEMENTS, PACKED_DOUBLE_ELEMENTS, HOLEY_SMI_ELEMENTS or // PACKED_SMI_ELEMENTS, PACKED_DOUBLE_ELEMENTS, HOLEY_SMI_ELEMENTS or
// HOLEY_DOUBLE_ELEMENTS. Guaranteed to return false, since these // HOLEY_DOUBLE_ELEMENTS. Guaranteed to return false, since these
...@@ -2343,7 +2344,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { ...@@ -2343,7 +2344,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
// Search for non-number, non-Undefined value with either // Search for non-number, non-Undefined value with either
// PACKED_ELEMENTS or HOLEY_ELEMENTS. // PACKED_ELEMENTS or HOLEY_ELEMENTS.
DCHECK(IsObjectElementsKind(Subclass::kind()) || DCHECK(IsObjectElementsKind(Subclass::kind()) ||
IsFrozenOrSealedElementsKind(Subclass::kind())); IsPackedFrozenOrSealedElementsKind(Subclass::kind()));
auto elements = FixedArray::cast(receiver->elements()); auto elements = FixedArray::cast(receiver->elements());
for (uint32_t k = start_from; k < length; ++k) { for (uint32_t k = start_from; k < length; ++k) {
...@@ -2638,7 +2639,7 @@ class FastSmiOrObjectElementsAccessor ...@@ -2638,7 +2639,7 @@ class FastSmiOrObjectElementsAccessor
// Only FAST_{,HOLEY_}ELEMENTS can store non-numbers. // Only FAST_{,HOLEY_}ELEMENTS can store non-numbers.
if (!value->IsNumber() && !IsObjectElementsKind(Subclass::kind()) && if (!value->IsNumber() && !IsObjectElementsKind(Subclass::kind()) &&
!IsFrozenOrSealedElementsKind(Subclass::kind())) { !IsPackedFrozenOrSealedElementsKind(Subclass::kind())) {
return Just<int64_t>(-1); return Just<int64_t>(-1);
} }
// NaN can never be found by strict equality. // NaN can never be found by strict equality.
......
...@@ -1191,7 +1191,7 @@ Handle<Object> KeyedLoadIC::LoadElementHandler(Handle<Map> receiver_map, ...@@ -1191,7 +1191,7 @@ Handle<Object> KeyedLoadIC::LoadElementHandler(Handle<Map> receiver_map,
is_js_array, load_mode); is_js_array, load_mode);
} }
DCHECK(IsFastElementsKind(elements_kind) || DCHECK(IsFastElementsKind(elements_kind) ||
IsFrozenOrSealedElementsKind(elements_kind) || IsPackedFrozenOrSealedElementsKind(elements_kind) ||
IsFixedTypedArrayElementsKind(elements_kind)); IsFixedTypedArrayElementsKind(elements_kind));
bool convert_hole_to_undefined = bool convert_hole_to_undefined =
(elements_kind == HOLEY_SMI_ELEMENTS || (elements_kind == HOLEY_SMI_ELEMENTS ||
......
...@@ -332,7 +332,7 @@ MapUpdater::State MapUpdater::FindRootMap() { ...@@ -332,7 +332,7 @@ MapUpdater::State MapUpdater::FindRootMap() {
DCHECK(to_kind == DICTIONARY_ELEMENTS || DCHECK(to_kind == DICTIONARY_ELEMENTS ||
to_kind == SLOW_STRING_WRAPPER_ELEMENTS || to_kind == SLOW_STRING_WRAPPER_ELEMENTS ||
IsFixedTypedArrayElementsKind(to_kind) || IsFixedTypedArrayElementsKind(to_kind) ||
IsFrozenOrSealedElementsKind(to_kind)); IsPackedFrozenOrSealedElementsKind(to_kind));
to_kind = integrity_source_map_->elements_kind(); to_kind = integrity_source_map_->elements_kind();
} }
......
...@@ -752,7 +752,8 @@ ElementsKind JSObject::GetElementsKind() const { ...@@ -752,7 +752,8 @@ ElementsKind JSObject::GetElementsKind() const {
DCHECK(fixed_array->IsFixedArray()); DCHECK(fixed_array->IsFixedArray());
DCHECK(fixed_array->IsDictionary()); DCHECK(fixed_array->IsDictionary());
} else { } else {
DCHECK(kind > DICTIONARY_ELEMENTS || IsFrozenOrSealedElementsKind(kind)); DCHECK(kind > DICTIONARY_ELEMENTS ||
IsPackedFrozenOrSealedElementsKind(kind));
} }
DCHECK(!IsSloppyArgumentsElementsKind(kind) || DCHECK(!IsSloppyArgumentsElementsKind(kind) ||
(elements()->IsFixedArray() && elements()->length() >= 2)); (elements()->IsFixedArray() && elements()->length() >= 2));
...@@ -796,7 +797,7 @@ bool JSObject::HasPackedElements() { ...@@ -796,7 +797,7 @@ bool JSObject::HasPackedElements() {
} }
bool JSObject::HasFrozenOrSealedElements() { bool JSObject::HasFrozenOrSealedElements() {
return IsFrozenOrSealedElementsKind(GetElementsKind()); return IsPackedFrozenOrSealedElementsKind(GetElementsKind());
} }
bool JSObject::HasFastArgumentsElements() { bool JSObject::HasFastArgumentsElements() {
......
...@@ -501,7 +501,7 @@ bool Map::has_dictionary_elements() const { ...@@ -501,7 +501,7 @@ bool Map::has_dictionary_elements() const {
} }
bool Map::is_frozen_or_sealed_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) { void Map::set_is_dictionary_map(bool value) {
......
...@@ -545,3 +545,12 @@ assertThrows(function() { ...@@ -545,3 +545,12 @@ assertThrows(function() {
value: obj, value: obj,
}); });
}, TypeError); }, 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']);
...@@ -250,3 +250,12 @@ arr.fill('d'); ...@@ -250,3 +250,12 @@ arr.fill('d');
assertEquals(arr.join(''), "ddd"); assertEquals(arr.join(''), "ddd");
arr.pop(); arr.pop();
assertEquals(arr.join(''), "dd"); 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']);
...@@ -521,3 +521,12 @@ assertThrows(function() { ...@@ -521,3 +521,12 @@ assertThrows(function() {
value: obj, value: obj,
}); });
}, TypeError); }, 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']);
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