diff --git a/src/builtins/array-reverse.tq b/src/builtins/array-reverse.tq index 7cfef719db..8db542ddef 100644 --- a/src/builtins/array-reverse.tq +++ b/src/builtins/array-reverse.tq @@ -143,14 +143,25 @@ module array { return object; } + macro EnsureWriteableFastElements(array: JSArray) { + const elements: FixedArrayBase = array.elements; + if (elements.map != kCOWMap) return; + + // There are no COW *_DOUBLE_ELEMENTS arrays, so we are allowed to always + // extract FixedArrays and don't have to worry about FixedDoubleArrays. + assert(IsFastSmiOrTaggedElementsKind(array.map.elements_kind)); + + const length: Smi = array.length_fast; + array.elements = ExtractFixedArray( + unsafe_cast(elements), 0, length, length, kFixedArrays); + } + macro TryFastPackedArrayReverse(receiver: Object) labels Slow { const array: JSArray = cast(receiver) otherwise Slow; - const map: Map = array.map; + EnsureWriteableFastElements(array); + assert(array.elements.map != kCOWMap); - if (!IsExtensibleMap(map)) goto Slow; - if (array.elements.map == kCOWMap) goto Slow; - - const kind: ElementsKind = map.elements_kind; + const kind: ElementsKind = array.map.elements_kind; if (kind == PACKED_SMI_ELEMENTS) { FastPackedArrayReverse( array.elements, array.length_fast); diff --git a/src/builtins/base.tq b/src/builtins/base.tq index 0707632b0b..1b9d577f10 100644 --- a/src/builtins/base.tq +++ b/src/builtins/base.tq @@ -109,6 +109,8 @@ type FixedBigInt64Array extends FixedTypedArray; const kAllFixedArrays: constexpr ExtractFixedArrayFlags generates 'ExtractFixedArrayFlag::kAllFixedArrays'; +const kFixedArrays: constexpr ExtractFixedArrayFlags generates +'ExtractFixedArrayFlag::kFixedArrays'; const kFixedCOWArrayMapRootIndex: constexpr RootListIndex generates 'Heap::kFixedCOWArrayMapRootIndex';