Commit a6c71508 authored by Simon Zünd's avatar Simon Zünd Committed by Commit Bot

[typedarray] Change TypedArray.p.sort implementation.

This CL uses the new function pointers and generic features of Torque
to improve the performance of TypedArray.p.sort.

Instead of one Load/Store builtin that dispatches at runtime based on
the element kind, there are now many small builtins (one for each
element kind). The sorting algorithm then uses function pointers to
those small builtins, which get set once.

Changes in the relevant benchmarks:

Benchmark   Original (JS)   Current   This CL
IntTypes             83.9     202.3     240.7
BigIntTypes          32.1      47.2      53.3
FloatTypes           99.3     109.3     129.3

Bug: v8:7382
Change-Id: I8684410524d546615b19f6edcbfdc615068196aa
Reviewed-on: https://chromium-review.googlesource.com/1070069
Commit-Queue: Simon Zünd <szuend@google.com>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53322}
parent 94313abc
...@@ -33,6 +33,10 @@ type FixedArrayBase extends HeapObject generates 'TNode<FixedArrayBase>'; ...@@ -33,6 +33,10 @@ type FixedArrayBase extends HeapObject generates 'TNode<FixedArrayBase>';
type FixedArray extends FixedArrayBase generates 'TNode<FixedArray>'; type FixedArray extends FixedArrayBase generates 'TNode<FixedArray>';
type FixedDoubleArray extends FixedArrayBase generates type FixedDoubleArray extends FixedArrayBase generates
'TNode<FixedDoubleArray>'; 'TNode<FixedDoubleArray>';
type FixedTypedArrayBase extends FixedArrayBase generates
'TNode<FixedTypedArrayBase>';
type FixedTypedArray extends FixedTypedArrayBase generates
'TNode<FixedTypedArray>';
type JSArrayBuffer extends Object generates 'TNode<JSArrayBuffer>'; type JSArrayBuffer extends Object generates 'TNode<JSArrayBuffer>';
type JSArrayBufferView extends Object generates 'TNode<JSArrayBufferView>'; type JSArrayBufferView extends Object generates 'TNode<JSArrayBufferView>';
...@@ -47,6 +51,8 @@ type ExtractFixedArrayFlags generates ...@@ -47,6 +51,8 @@ type ExtractFixedArrayFlags generates
type MessageTemplate; type MessageTemplate;
type HasPropertyFlag generates 'HasPropertyLookupMode'; type HasPropertyFlag generates 'HasPropertyLookupMode';
const NO_ELEMENTS: constexpr ElementsKind = 'NO_ELEMENTS';
const PACKED_SMI_ELEMENTS: constexpr ElementsKind = 'PACKED_SMI_ELEMENTS'; const PACKED_SMI_ELEMENTS: constexpr ElementsKind = 'PACKED_SMI_ELEMENTS';
const HOLEY_SMI_ELEMENTS: constexpr ElementsKind = 'HOLEY_SMI_ELEMENTS'; const HOLEY_SMI_ELEMENTS: constexpr ElementsKind = 'HOLEY_SMI_ELEMENTS';
const PACKED_ELEMENTS: constexpr ElementsKind = 'PACKED_ELEMENTS'; const PACKED_ELEMENTS: constexpr ElementsKind = 'PACKED_ELEMENTS';
...@@ -66,6 +72,18 @@ const UINT8_CLAMPED_ELEMENTS: constexpr ElementsKind = 'UINT8_CLAMPED_ELEMENTS'; ...@@ -66,6 +72,18 @@ const UINT8_CLAMPED_ELEMENTS: constexpr ElementsKind = 'UINT8_CLAMPED_ELEMENTS';
const BIGUINT64_ELEMENTS: constexpr ElementsKind = 'BIGUINT64_ELEMENTS'; const BIGUINT64_ELEMENTS: constexpr ElementsKind = 'BIGUINT64_ELEMENTS';
const BIGINT64_ELEMENTS: constexpr ElementsKind = 'BIGINT64_ELEMENTS'; const BIGINT64_ELEMENTS: constexpr ElementsKind = 'BIGINT64_ELEMENTS';
type FixedUint8Array extends FixedTypedArray;
type FixedInt8Array extends FixedTypedArray;
type FixedUint16Array extends FixedTypedArray;
type FixedInt16Array extends FixedTypedArray;
type FixedUint32Array extends FixedTypedArray;
type FixedInt32Array extends FixedTypedArray;
type FixedFloat32Array extends FixedTypedArray;
type FixedFloat64Array extends FixedTypedArray;
type FixedUint8ClampedArray extends FixedTypedArray;
type FixedBigUint64Array extends FixedTypedArray;
type FixedBigInt64Array extends FixedTypedArray;
const kAllFixedArrays: constexpr ExtractFixedArrayFlags = const kAllFixedArrays: constexpr ExtractFixedArrayFlags =
'ExtractFixedArrayFlag::kAllFixedArrays'; 'ExtractFixedArrayFlag::kAllFixedArrays';
...@@ -223,7 +241,8 @@ extern implicit operator ...@@ -223,7 +241,8 @@ extern implicit operator
extern implicit operator 'convert<>' macro BoolConstant(constexpr bool): bool; extern implicit operator 'convert<>' macro BoolConstant(constexpr bool): bool;
extern implicit operator 'convert<>' macro LanguageModeConstant( extern implicit operator 'convert<>' macro LanguageModeConstant(
constexpr LanguageMode): LanguageMode; constexpr LanguageMode): LanguageMode;
extern operator
'convert<>' macro Int32Constant(constexpr ElementsKind): ElementsKind;
extern implicit operator 'convert<>' macro SmiFromInt32(ElementsKind): Smi; extern implicit operator 'convert<>' macro SmiFromInt32(ElementsKind): Smi;
extern operator 'convert<>' macro ChangeInt32ToTagged(int32): Number; extern operator 'convert<>' macro ChangeInt32ToTagged(int32): Number;
......
...@@ -1147,8 +1147,6 @@ namespace internal { ...@@ -1147,8 +1147,6 @@ namespace internal {
TFJ(TypedArrayOf, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \ TFJ(TypedArrayOf, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 %TypedArray%.from */ \ /* ES6 %TypedArray%.from */ \
TFJ(TypedArrayFrom, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \ TFJ(TypedArrayFrom, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
TFS(TypedArrayLoadElementAsTagged, kArray, kKind, kIndex) \
TFS(TypedArrayStoreElementFromTagged, kArray, kKind, kIndex, kValue) \
\ \
/* Wasm */ \ /* Wasm */ \
ASM(WasmCompileLazy) \ ASM(WasmCompileLazy) \
......
...@@ -873,42 +873,6 @@ TNode<IntPtrT> TypedArrayBuiltinsAssembler::GetTypedArrayElementSize( ...@@ -873,42 +873,6 @@ TNode<IntPtrT> TypedArrayBuiltinsAssembler::GetTypedArrayElementSize(
return element_size.value(); return element_size.value();
} }
TF_BUILTIN(TypedArrayLoadElementAsTagged, TypedArrayBuiltinsAssembler) {
TVARIABLE(Object, result);
TNode<JSTypedArray> array = CAST(Parameter(Descriptor::kArray));
TNode<Smi> kind = CAST(Parameter(Descriptor::kKind));
TNode<Smi> index_node = CAST(Parameter(Descriptor::kIndex));
TNode<RawPtrT> data_pointer = UncheckedCast<RawPtrT>(LoadDataPtr(array));
TNode<Int32T> elements_kind = SmiToInt32(kind);
DispatchTypedArrayByElementsKind(
elements_kind, [&](ElementsKind el_kind, int, int) {
result = CAST(LoadFixedTypedArrayElementAsTagged(
data_pointer, index_node, el_kind, SMI_PARAMETERS));
});
Return(result.value());
}
TF_BUILTIN(TypedArrayStoreElementFromTagged, TypedArrayBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<JSTypedArray> array = CAST(Parameter(Descriptor::kArray));
TNode<Smi> kind = CAST(Parameter(Descriptor::kKind));
TNode<Smi> index_node = CAST(Parameter(Descriptor::kIndex));
TNode<Object> value = CAST(Parameter(Descriptor::kValue));
TNode<FixedTypedArrayBase> elements = CAST(LoadElements(array));
TNode<Int32T> elements_kind = SmiToInt32(kind);
DispatchTypedArrayByElementsKind(
elements_kind, [&](ElementsKind el_kind, int, int) {
StoreFixedTypedArrayElementFromTagged(context, elements, index_node,
value, el_kind, SMI_PARAMETERS);
});
Return(UndefinedConstant());
}
TNode<Object> TypedArrayBuiltinsAssembler::GetDefaultConstructor( TNode<Object> TypedArrayBuiltinsAssembler::GetDefaultConstructor(
TNode<Context> context, TNode<JSTypedArray> exemplar) { TNode<Context> context, TNode<JSTypedArray> exemplar) {
TVARIABLE(IntPtrT, context_slot); TVARIABLE(IntPtrT, context_slot);
......
...@@ -141,6 +141,12 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler { ...@@ -141,6 +141,12 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
// Returns true iff number is NaN. // Returns true iff number is NaN.
// TOOD(szuend): Remove when UncheckedCasts are supported in Torque. // TOOD(szuend): Remove when UncheckedCasts are supported in Torque.
TNode<BoolT> NumberIsNaN(TNode<Number> number); TNode<BoolT> NumberIsNaN(TNode<Number> number);
// TODO(szuend): Remove when UncheckedCasts are supported in Torque.
TNode<FixedTypedArrayBase> UncheckedCastFixedArrayBaseToFixedTypedArrayBase(
TNode<FixedArrayBase> array) {
return CAST(array);
}
}; };
} // namespace internal } // namespace internal
......
...@@ -9,13 +9,74 @@ module typed_array { ...@@ -9,13 +9,74 @@ module typed_array {
const kTypedArrayProtoSort: MethodName = '\"%TypedArray%.prototype.sort\"'; const kTypedArrayProtoSort: MethodName = '\"%TypedArray%.prototype.sort\"';
extern macro ValidateTypedArray(Context, Object, MethodName): JSTypedArray; extern macro ValidateTypedArray(Context, Object, MethodName): JSTypedArray;
extern builtin TypedArrayLoadElementAsTagged(
Context, JSTypedArray, Smi, Smi): Object;
extern builtin TypedArrayStoreElementFromTagged(
Context, JSTypedArray, Smi, Smi, Object);
extern macro NumberIsNaN(Number): bool; extern macro NumberIsNaN(Number): bool;
type ParameterMode constexpr 'ParameterMode';
const SMI_PARAMETERS: constexpr ParameterMode = 'SMI_PARAMETERS';
extern macro LoadFixedTypedArrayElementAsTagged(
RawPtr, Smi, constexpr ElementsKind, constexpr ParameterMode): Object;
extern macro StoreFixedTypedArrayElementFromTagged(
Context, FixedArrayBase, Smi, Object, constexpr ElementsKind,
constexpr ParameterMode);
type LoadFn = builtin(Context, JSTypedArray, Smi) => Object;
type StoreFn = builtin(Context, JSTypedArray, Smi, Object) => Object;
macro KindForArrayType<T : type>(): constexpr ElementsKind;
KindForArrayType<FixedUint8Array>(): constexpr ElementsKind {
return UINT8_ELEMENTS;
}
KindForArrayType<FixedInt8Array>(): constexpr ElementsKind {
return INT8_ELEMENTS;
}
KindForArrayType<FixedUint16Array>(): constexpr ElementsKind {
return UINT16_ELEMENTS;
}
KindForArrayType<FixedInt16Array>(): constexpr ElementsKind {
return INT16_ELEMENTS;
}
KindForArrayType<FixedUint32Array>(): constexpr ElementsKind {
return UINT32_ELEMENTS;
}
KindForArrayType<FixedInt32Array>(): constexpr ElementsKind {
return INT32_ELEMENTS;
}
KindForArrayType<FixedFloat32Array>(): constexpr ElementsKind {
return FLOAT32_ELEMENTS;
}
KindForArrayType<FixedFloat64Array>(): constexpr ElementsKind {
return FLOAT64_ELEMENTS;
}
KindForArrayType<FixedUint8ClampedArray>(): constexpr ElementsKind {
return UINT8_CLAMPED_ELEMENTS;
}
KindForArrayType<FixedBigUint64Array>(): constexpr ElementsKind {
return BIGUINT64_ELEMENTS;
}
KindForArrayType<FixedBigInt64Array>(): constexpr ElementsKind {
return BIGINT64_ELEMENTS;
}
extern operator
'convert<>' macro UncheckedCastFixedArrayBaseToFixedTypedArrayBase(
FixedArrayBase): FixedTypedArrayBase;
builtin LoadFixedElement<T : type>(
context: Context, array: JSTypedArray, index: Smi): Object {
return LoadFixedTypedArrayElementAsTagged(
array.data_ptr, index, KindForArrayType<T>(), SMI_PARAMETERS);
}
builtin StoreFixedElement<T : type>(
context: Context, array: JSTypedArray, index: Smi,
value: Object): Object {
let elements: FixedTypedArrayBase =
convert<FixedTypedArrayBase>(array.elements);
StoreFixedTypedArrayElementFromTagged(
context, elements, index, value, KindForArrayType<T>(), SMI_PARAMETERS);
return Undefined;
}
macro CallCompareWithDetachedCheck( macro CallCompareWithDetachedCheck(
context: Context, array: JSTypedArray, comparefn: Callable, a: Object, context: Context, array: JSTypedArray, comparefn: Callable, a: Object,
b: Object): Number labels Detached { b: Object): Number labels Detached {
...@@ -33,32 +94,10 @@ module typed_array { ...@@ -33,32 +94,10 @@ module typed_array {
return v; return v;
} }
// Wrapped CSA macro for better readability. Ideally we want to map this
// as the array operator "[]".
// TODO(szuend): Change Load/Store macros so they use function pointers to
// the correct builtins as soon as they are available in Torque.
//
// Currently the dispatch to the correct load/store instruction
// is done during runtime in a builtin. This costs around 20%
// performance in relevant benchmarks, but greatly reduces the
// code size - compared to sort macro "copies" for each
// ElementsKind that inline the correct load/store.
macro Load(
context: Context, array: JSTypedArray, kind: Smi, index: Smi): Object {
return TypedArrayLoadElementAsTagged(context, array, kind, index);
}
// Wrapped array store CSA macro for better readability.
macro Store(
context: Context, array: JSTypedArray, kind: Smi, index: Smi,
value: Object) {
TypedArrayStoreElementFromTagged(context, array, kind, index, value);
}
// InsertionSort is used for smaller arrays. // InsertionSort is used for smaller arrays.
macro TypedArrayInsertionSort( macro TypedArrayInsertionSort(
context: Context, array: JSTypedArray, kind: Smi, from_arg: Smi, context: Context, array: JSTypedArray, from_arg: Smi, to_arg: Smi,
to_arg: Smi, comparefn: Callable) comparefn: Callable, Load: LoadFn, Store: StoreFn)
labels Detached { labels Detached {
let from: Smi = from_arg; let from: Smi = from_arg;
let to: Smi = to_arg; let to: Smi = to_arg;
...@@ -66,25 +105,25 @@ module typed_array { ...@@ -66,25 +105,25 @@ module typed_array {
if (IsDetachedBuffer(array.buffer)) goto Detached; if (IsDetachedBuffer(array.buffer)) goto Detached;
for (let i: Smi = from + 1; i < to; ++i) { for (let i: Smi = from + 1; i < to; ++i) {
let element: Object = Load(context, array, kind, i); let element: Object = Load(context, array, i);
let j: Smi = i - 1; let j: Smi = i - 1;
for (; j >= from; --j) { for (; j >= from; --j) {
let tmp: Object = Load(context, array, kind, j); let tmp: Object = Load(context, array, j);
let order: Number = CallCompareWithDetachedCheck( let order: Number = CallCompareWithDetachedCheck(
context, array, comparefn, tmp, element) otherwise Detached; context, array, comparefn, tmp, element) otherwise Detached;
if (order > 0) { if (order > 0) {
Store(context, array, kind, j + 1, tmp); Store(context, array, j + 1, tmp);
} else { } else {
break; break;
} }
} }
Store(context, array, kind, j + 1, element); Store(context, array, j + 1, element);
} }
} }
macro TypedArrayQuickSortImpl( macro TypedArrayQuickSortImpl(
context: Context, array: JSTypedArray, kind: Smi, from_arg: Smi, context: Context, array: JSTypedArray, from_arg: Smi, to_arg: Smi,
to_arg: Smi, comparefn: Callable) comparefn: Callable, Load: LoadFn, Store: StoreFn)
labels Detached { labels Detached {
let from: Smi = from_arg; let from: Smi = from_arg;
let to: Smi = to_arg; let to: Smi = to_arg;
...@@ -94,7 +133,8 @@ module typed_array { ...@@ -94,7 +133,8 @@ module typed_array {
// TODO(szuend): Investigate InsertionSort removal. // TODO(szuend): Investigate InsertionSort removal.
// Currently it does not make any difference when the // Currently it does not make any difference when the
// benchmarks are run locally. // benchmarks are run locally.
TypedArrayInsertionSort(context, array, kind, from, to, comparefn) TypedArrayInsertionSort(
context, array, from, to, comparefn, Load, Store)
otherwise Detached; otherwise Detached;
break; break;
} }
...@@ -106,9 +146,9 @@ module typed_array { ...@@ -106,9 +146,9 @@ module typed_array {
if (IsDetachedBuffer(array.buffer)) goto Detached; if (IsDetachedBuffer(array.buffer)) goto Detached;
// Find a pivot as the median of first, last and middle element. // Find a pivot as the median of first, last and middle element.
let v0: Object = Load(context, array, kind, from); let v0: Object = Load(context, array, from);
let v1: Object = Load(context, array, kind, to - 1); let v1: Object = Load(context, array, to - 1);
let v2: Object = Load(context, array, kind, third_index); let v2: Object = Load(context, array, third_index);
let c01: Number = CallCompareWithDetachedCheck( let c01: Number = CallCompareWithDetachedCheck(
context, array, comparefn, v0, v1) otherwise Detached; context, array, comparefn, v0, v1) otherwise Detached;
...@@ -140,28 +180,28 @@ module typed_array { ...@@ -140,28 +180,28 @@ module typed_array {
} }
// v0 <= v1 <= v2. // v0 <= v1 <= v2.
Store(context, array, kind, from, v0); Store(context, array, from, v0);
Store(context, array, kind, to - 1, v2); Store(context, array, to - 1, v2);
let pivot: Object = v1; let pivot: Object = v1;
let low_end: Smi = from + 1; // Upper bound of elems lower than pivot. let low_end: Smi = from + 1; // Upper bound of elems lower than pivot.
let high_start: Smi = to - 1; // Lower bound of elems greater than pivot. let high_start: Smi = to - 1; // Lower bound of elems greater than pivot.
let low_end_value: Object = Load(context, array, kind, low_end); let low_end_value: Object = Load(context, array, low_end);
Store(context, array, kind, third_index, low_end_value); Store(context, array, third_index, low_end_value);
Store(context, array, kind, low_end, pivot); Store(context, array, low_end, pivot);
// From low_end to idx are elements equal to pivot. // From low_end to idx are elements equal to pivot.
// From idx to high_start are elements that haven"t been compared yet. // From idx to high_start are elements that haven"t been compared yet.
for (let idx: Smi = low_end + 1; idx < high_start; idx++) { for (let idx: Smi = low_end + 1; idx < high_start; idx++) {
let element: Object = Load(context, array, kind, idx); let element: Object = Load(context, array, idx);
let order: Number = CallCompareWithDetachedCheck( let order: Number = CallCompareWithDetachedCheck(
context, array, comparefn, element, pivot) otherwise Detached; context, array, comparefn, element, pivot) otherwise Detached;
if (order < 0) { if (order < 0) {
low_end_value = Load(context, array, kind, low_end); low_end_value = Load(context, array, low_end);
Store(context, array, kind, idx, low_end_value); Store(context, array, idx, low_end_value);
Store(context, array, kind, low_end, element); Store(context, array, low_end, element);
low_end++; low_end++;
} else if (order > 0) { } else if (order > 0) {
let break_for: bool = false; let break_for: bool = false;
...@@ -173,7 +213,7 @@ module typed_array { ...@@ -173,7 +213,7 @@ module typed_array {
break; break;
} }
let top_elem: Object = Load(context, array, kind, high_start); let top_elem: Object = Load(context, array, high_start);
order = CallCompareWithDetachedCheck( order = CallCompareWithDetachedCheck(
context, array, comparefn, top_elem, pivot) otherwise Detached; context, array, comparefn, top_elem, pivot) otherwise Detached;
} }
...@@ -182,36 +222,38 @@ module typed_array { ...@@ -182,36 +222,38 @@ module typed_array {
break; break;
} }
let high_start_value: Object = Load(context, array, kind, high_start); let high_start_value: Object = Load(context, array, high_start);
Store(context, array, kind, idx, high_start_value); Store(context, array, idx, high_start_value);
Store(context, array, kind, high_start, element); Store(context, array, high_start, element);
if (order < 0) { if (order < 0) {
element = Load(context, array, kind, idx); element = Load(context, array, idx);
low_end_value = Load(context, array, kind, low_end); low_end_value = Load(context, array, low_end);
Store(context, array, kind, idx, low_end_value); Store(context, array, idx, low_end_value);
Store(context, array, kind, low_end, element); Store(context, array, low_end, element);
low_end++; low_end++;
} }
} }
} }
if ((to - high_start) < (low_end - from)) { if ((to - high_start) < (low_end - from)) {
TypedArrayQuickSort(context, array, kind, high_start, to, comparefn); TypedArrayQuickSort(
context, array, high_start, to, comparefn, Load, Store);
to = low_end; to = low_end;
} else { } else {
TypedArrayQuickSort(context, array, kind, from, low_end, comparefn); TypedArrayQuickSort(
context, array, from, low_end, comparefn, Load, Store);
from = high_start; from = high_start;
} }
} }
} }
builtin TypedArrayQuickSort( builtin TypedArrayQuickSort(
context: Context, array: JSTypedArray, kind: Smi, from: Smi, to: Smi, context: Context, array: JSTypedArray, from: Smi, to: Smi,
comparefn: Callable): JSTypedArray { comparefn: Callable, Load: LoadFn, Store: StoreFn): JSTypedArray {
try { try {
TypedArrayQuickSortImpl(context, array, kind, from, to, comparefn) TypedArrayQuickSortImpl(context, array, from, to, comparefn, Load, Store)
otherwise Detached; otherwise Detached;
} }
label Detached { label Detached {
...@@ -250,8 +292,56 @@ module typed_array { ...@@ -250,8 +292,56 @@ module typed_array {
try { try {
let comparefn: Callable = let comparefn: Callable =
cast<Callable>(comparefn_obj) otherwise CastError; cast<Callable>(comparefn_obj) otherwise CastError;
let elements_kind: Smi = convert<Smi>(array.elements_kind); let loadfn: LoadFn;
TypedArrayQuickSort(context, array, elements_kind, 0, len, comparefn); let storefn: StoreFn;
let elements_kind: ElementsKind = array.elements_kind;
if (IsElementsKindGreaterThan(elements_kind, UINT32_ELEMENTS)) {
if (elements_kind == convert<ElementsKind>(INT32_ELEMENTS)) {
loadfn = LoadFixedElement<FixedInt32Array>;
storefn = StoreFixedElement<FixedInt32Array>;
} else if (elements_kind == convert<ElementsKind>(FLOAT32_ELEMENTS)) {
loadfn = LoadFixedElement<FixedFloat32Array>;
storefn = StoreFixedElement<FixedFloat32Array>;
} else if (elements_kind == convert<ElementsKind>(FLOAT64_ELEMENTS)) {
loadfn = LoadFixedElement<FixedFloat64Array>;
storefn = StoreFixedElement<FixedFloat64Array>;
} else if (
elements_kind == convert<ElementsKind>(UINT8_CLAMPED_ELEMENTS)) {
loadfn = LoadFixedElement<FixedUint8ClampedArray>;
storefn = StoreFixedElement<FixedUint8ClampedArray>;
} else if (elements_kind == convert<ElementsKind>(BIGUINT64_ELEMENTS)) {
loadfn = LoadFixedElement<FixedBigUint64Array>;
storefn = StoreFixedElement<FixedBigUint64Array>;
} else if (elements_kind == convert<ElementsKind>(BIGINT64_ELEMENTS)) {
loadfn = LoadFixedElement<FixedBigInt64Array>;
storefn = StoreFixedElement<FixedBigInt64Array>;
} else {
unreachable;
}
} else {
if (elements_kind == convert<ElementsKind>(UINT8_ELEMENTS)) {
loadfn = LoadFixedElement<FixedUint8Array>;
storefn = StoreFixedElement<FixedUint8Array>;
} else if (elements_kind == convert<ElementsKind>(INT8_ELEMENTS)) {
loadfn = LoadFixedElement<FixedInt8Array>;
storefn = StoreFixedElement<FixedInt8Array>;
} else if (elements_kind == convert<ElementsKind>(UINT16_ELEMENTS)) {
loadfn = LoadFixedElement<FixedUint16Array>;
storefn = StoreFixedElement<FixedUint16Array>;
} else if (elements_kind == convert<ElementsKind>(INT16_ELEMENTS)) {
loadfn = LoadFixedElement<FixedInt16Array>;
storefn = StoreFixedElement<FixedInt16Array>;
} else if (elements_kind == convert<ElementsKind>(UINT32_ELEMENTS)) {
loadfn = LoadFixedElement<FixedUint32Array>;
storefn = StoreFixedElement<FixedUint32Array>;
} else {
unreachable;
}
}
TypedArrayQuickSort(context, array, 0, len, comparefn, loadfn, storefn);
} }
label CastError { label CastError {
unreachable; unreachable;
......
...@@ -97,6 +97,7 @@ let constructorsWithArrays = [ ...@@ -97,6 +97,7 @@ let constructorsWithArrays = [
ctor: Float64Array, ctor: Float64Array,
array: [2 ** 53, 2 ** 53 - 1, 1, 0, -1, -(2 ** 53 - 1), -(2 ** 53)] array: [2 ** 53, 2 ** 53 - 1, 1, 0, -1, -(2 ** 53 - 1), -(2 ** 53)]
}, },
{ctor: Uint8ClampedArray, array: [255, 254, 4, 3, 2, 1, 0]},
{ {
ctor: BigUint64Array, ctor: BigUint64Array,
array: [2n ** 64n - 1n, 2n ** 64n - 2n, 4n, 3n, 2n, 1n, 0n] array: [2n ** 64n - 1n, 2n ** 64n - 2n, 4n, 3n, 2n, 1n, 0n]
......
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