[typedarray] Implement TypedArray.p.sort using Torque.

This CL implements TypedArray.p.sort in Torque. The Torque
version works basically the same as the existing JS builtin:

When no comparison function is provided, the C++ fast path builtin
is used. Otherwise a quicksort written in Torque is used, with
a InsertionSort fallback for smaller arrays.

The JS quicksort implementation also containes a more elaborate
third pivot calculation for larger arrays. This is currently not done.

Reported benchmark results are only for those, where a custom
comparison function is provided. The numbers for the C++ path stayed
the same.

Benchmark   Current (JS)       Torque    Speedup

IntTypes            83.9        263.7        3.1
BigIntTypes         32.1         54.6        1.7
FloatTypes          99.3        138.7        1.4

R=danno@chromium.org, jgruber@chromium.org

Bug: v8:7382
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: I7abe7ceff525bab24f302d2f06b5961cca770d24
Reviewed-on: https://chromium-review.googlesource.com/1021691
Commit-Queue: Simon Zünd <szuend@google.com>
Reviewed-by: Daniel Clifford <danno@chromium.org>
Reviewed-by: Peter Marshall <petermarshall@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52776}
This commit is contained in:
Simon Zünd 2018-04-25 10:14:09 +02:00 committed by Commit Bot
parent 2393710a27
commit 3ea1ad234c
13 changed files with 446 additions and 52 deletions

View File

@ -865,6 +865,7 @@ action("run_torque") {
inputs = [
"src/builtins/base.tq",
"src/builtins/array.tq",
"src/builtins/typed-array.tq",
]
outputs = [
@ -873,6 +874,8 @@ action("run_torque") {
"$target_gen_dir/builtins-array-from-dsl-gen.h",
"$target_gen_dir/builtins-base-from-dsl-gen.cc",
"$target_gen_dir/builtins-base-from-dsl-gen.h",
"$target_gen_dir/builtins-typed-array-from-dsl-gen.cc",
"$target_gen_dir/builtins-typed-array-from-dsl-gen.h",
]
args = [
@ -883,6 +886,7 @@ action("run_torque") {
rebase_path("$target_gen_dir", root_build_dir),
rebase_path("src/builtins/base.tq", root_build_dir),
rebase_path("src/builtins/array.tq", root_build_dir),
rebase_path("src/builtins/typed-array.tq", root_build_dir),
]
}
@ -1196,6 +1200,7 @@ v8_source_set("v8_initializers") {
sources = [
"$target_gen_dir/builtins-array-from-dsl-gen.cc",
"$target_gen_dir/builtins-base-from-dsl-gen.cc",
"$target_gen_dir/builtins-typed-array-from-dsl-gen.cc",
### gcmole(all) ###
"src/builtins/builtins-arguments-gen.cc",

View File

@ -2919,6 +2919,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
Builtins::kTypedArrayPrototypeSlice, 2, false);
SimpleInstallFunction(prototype, "some", Builtins::kTypedArrayPrototypeSome,
1, false);
SimpleInstallFunction(prototype, "sort", Builtins::kTypedArrayPrototypeSort,
1, false);
SimpleInstallFunction(prototype, "subarray",
Builtins::kTypedArrayPrototypeSubArray, 2, false);
}

View File

@ -13,6 +13,7 @@ type float64 generates 'TNode<Float64T>';
type bit generates 'TNode<BoolT>';
type int31 extends int32 generates 'TNode<Int32T>';
type RawPtr generates 'TNode<RawPtrT>';
type Number extends Object generates 'TNode<Number>';
type Smi extends Number generates 'TNode<Smi>';
type HeapObject extends Object generates 'TNode<HeapObject>';
@ -29,12 +30,16 @@ type FixedArray extends FixedArrayBase generates 'TNode<FixedArray>';
type FixedDoubleArray extends FixedArrayBase generates
'TNode<FixedDoubleArray>';
type JSArrayBuffer extends Object generates 'TNode<JSArrayBuffer>';
type JSArrayBufferView extends Object generates 'TNode<JSArrayBufferView>';
type JSTypedArray extends JSArrayBufferView generates 'TNode<JSTypedArray>';
type const_int32 generates 'int32_t';
type const_int31 extends const_int32 generates 'int32_t';
type const_float64 generates 'double';
type InstanceType extends int32 generates 'TNode<Int32T>';
type ElementsKind generates 'ElementsKind';
type ElementsKind extends const_int32 generates 'ElementsKind';
type LanguageMode extends Smi;
type ExtractFixedArrayFlags;
@ -49,6 +54,18 @@ const HOLEY_ELEMENTS: ElementsKind = 'HOLEY_ELEMENTS';
const PACKED_DOUBLE_ELEMENTS: ElementsKind = 'PACKED_DOUBLE_ELEMENTS';
const HOLEY_DOUBLE_ELEMENTS: ElementsKind = 'HOLEY_DOUBLE_ELEMENTS';
const UINT8_ELEMENTS: ElementsKind = 'UINT8_ELEMENTS';
const INT8_ELEMENTS: ElementsKind = 'INT8_ELEMENTS';
const UINT16_ELEMENTS: ElementsKind = 'UINT16_ELEMENTS';
const INT16_ELEMENTS: ElementsKind = 'INT16_ELEMENTS';
const UINT32_ELEMENTS: ElementsKind = 'UINT32_ELEMENTS';
const INT32_ELEMENTS: ElementsKind = 'INT32_ELEMENTS';
const FLOAT32_ELEMENTS: ElementsKind = 'FLOAT32_ELEMENTS';
const FLOAT64_ELEMENTS: ElementsKind = 'FLOAT64_ELEMENTS';
const UINT8_CLAMPED_ELEMENTS: ElementsKind = 'UINT8_CLAMPED_ELEMENTS';
const BIGUINT64_ELEMENTS: ElementsKind = 'BIGUINT64_ELEMENTS';
const BIGINT64_ELEMENTS: ElementsKind = 'BIGINT64_ELEMENTS';
const kOperationLessThan: CompareOperator = 'Operation::kLessThan';
const kOperationLessThanEqual: CompareOperator = 'Operation::kLessThanEqual';
const kOperationGreaterThan: CompareOperator = 'Operation::kGreaterThan';
@ -69,6 +86,12 @@ const kHasProperty: HasPropertyFlag = 'kHasProperty';
const kMaxSafeInteger: const_float64 = 'kMaxSafeInteger';
const kNotTypedArray: MessageTemplate = 'MessageTemplate::kNotTypedArray';
const kDetachedOperation: MessageTemplate =
'MessageTemplate::kDetachedOperation';
const kBadSortComparisonFunction: MessageTemplate =
'MessageTemplate::kBadSortComparisonFunction';
const hole: Object = 'TheHoleConstant()';
const null: Oddball = 'NullConstant()';
const undefined: Oddball = 'UndefinedConstant()';
@ -89,10 +112,13 @@ extern macro Print(String, Object);
extern macro DebugBreak();
extern macro ToInteger_Inline(Context, Object): Number;
extern macro ToLength_Inline(Context, Object): Number;
extern macro ToNumber_Inline(Context, Object): Number;
extern macro ToString_Inline(Context, Object): String;
extern macro GetProperty(Context, Object, Object): Object;
extern macro HasProperty(HeapObject, Object, Context, HasPropertyFlag): Oddball;
extern macro ThrowRangeError(Context, MessageTemplate): never;
extern macro ThrowTypeError(Context, MessageTemplate): never;
extern macro ThrowTypeError(Context, MessageTemplate, Object): never;
extern macro ArraySpeciesCreate(Context, Object, Number): Object;
extern macro EnsureArrayPushable(Map): int32 labels Bailout;
@ -127,6 +153,8 @@ extern operator '>' macro IntPtrGreaterThan(intptr, intptr): bit;
extern operator '<=' macro IntPtrLessThanOrEqual(intptr, intptr): bit;
extern operator '>=' macro IntPtrGreaterThanOrEqual(intptr, intptr): bit;
extern operator '==' macro Float64Equal(float64, float64): bit;
extern operator
'<' macro BranchIfNumberLessThan(Number, Number): never labels True, False;
extern operator
@ -143,9 +171,11 @@ extern operator '!=' macro WordNotEqual(Object, Object): bit;
extern operator '+' macro SmiAdd(Smi, Smi): Smi;
extern operator '-' macro SmiSub(Smi, Smi): Smi;
extern operator '>>>' macro SmiShr(Smi, const_int31): Smi;
extern operator '+' macro IntPtrAdd(intptr, intptr): intptr;
extern operator '-' macro IntPtrSub(intptr, intptr): intptr;
extern operator '>>>' macro WordShr(intptr, intptr): intptr;
extern operator '+' macro NumberAdd(Number, Number): Number;
extern operator '-' macro NumberSub(Number, Number): Number;
@ -194,6 +224,7 @@ extern operator 'convert<>' macro TruncateWordToWord32(intptr): int32;
extern operator 'convert<>' macro SmiTag(intptr): Smi;
extern operator 'convert<>' macro SmiUntag(Smi): intptr;
extern macro BranchIfFastJSArray(Object, Context): never labels True, False;
extern macro BranchIfNotFastJSArray(Object, Context): never labels True, False;
@ -203,11 +234,18 @@ extern macro IsArraySpeciesProtectorCellInvalid(): bit;
extern macro IsTypedArraySpeciesProtectorCellInvalid(): bit;
extern macro IsPromiseSpeciesProtectorCellInvalid(): bit;
extern operator
'.buffer' macro LoadTypedArrayBuffer(JSTypedArray): JSArrayBuffer;
extern operator '.data_ptr' macro LoadDataPtr(JSTypedArray): RawPtr;
extern operator '.elements_kind' macro LoadMapElementsKind(Map): int32;
extern operator '.elements_kind' macro LoadElementsKind(JSTypedArray): int32;
extern operator '.elements' macro LoadElements(Object): FixedArrayBase;
extern operator '.elements=' macro StoreElements(Object, FixedArrayBase);
extern operator '.length' macro LoadTypedArrayLength(JSTypedArray): Smi;
extern operator '.length' macro LoadJSArrayLength(JSArray): Number;
extern operator '.length=' macro StoreJSArrayLength(JSArray, Smi);
@ -251,3 +289,13 @@ macro HasPropertyObject(
return false;
}
}
extern macro IsCallable(Object): bit;
extern macro IsDetachedBuffer(JSArrayBuffer): bit;
type ParameterMode;
const kSmiParameters: ParameterMode = 'ParameterMode::SMI_PARAMETERS';
extern macro LoadFixedTypedArrayElementAsTagged(
RawPtr, Smi, ElementsKind, ParameterMode): Object;
extern macro StoreFixedTypedArrayElementFromTagged(
Context, RawPtr, Smi, Object, ElementsKind, ParameterMode);

View File

@ -1196,6 +1196,27 @@ void TypedArrayBuiltinsAssembler::DispatchTypedArrayByElementsKind(
BIND(&next);
}
TNode<BoolT> TypedArrayBuiltinsAssembler::NumberIsNaN(TNode<Number> value) {
Label is_heapnumber(this), done(this);
TVARIABLE(BoolT, result);
GotoIf(TaggedIsNotSmi(value), &is_heapnumber);
result = Int32FalseConstant();
Goto(&done);
BIND(&is_heapnumber);
{
CSA_ASSERT(this, IsHeapNumber(value));
TNode<Float64T> value_f = LoadHeapNumberValue(CAST(value));
result = Float64NotEqual(value_f, value_f);
Goto(&done);
}
BIND(&done);
return result.value();
}
// ES #sec-get-%typedarray%.prototype.set
TF_BUILTIN(TypedArrayPrototypeSet, TypedArrayBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));

View File

@ -71,6 +71,15 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
// Returns the byte size of an element for a TypedArray elements kind.
TNode<IntPtrT> GetTypedArrayElementSize(TNode<Word32T> elements_kind);
TNode<Smi> LoadTypedArrayLength(TNode<JSTypedArray> typed_array) {
return LoadObjectField<Smi>(typed_array, JSTypedArray::kLengthOffset);
}
TNode<JSArrayBuffer> LoadTypedArrayBuffer(TNode<JSTypedArray> typed_array) {
return LoadObjectField<JSArrayBuffer>(typed_array,
JSTypedArray::kBufferOffset);
}
TNode<Object> GetDefaultConstructor(TNode<Context> context,
TNode<JSTypedArray> exemplar);
@ -126,6 +135,14 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
void DispatchTypedArrayByElementsKind(
TNode<Word32T> elements_kind, const TypedArraySwitchCase& case_function);
// Returns true iff number is NaN.
// TOOD(szuend): Remove when UncheckedCasts are supported in Torque.
TNode<BoolT> NumberIsNaN(TNode<Number> number);
// Always CSA_ASSERTs false.
// TODO(szuend): Remove when Unreachable is supported in Torque.
void AssertUnreachable() { CSA_ASSERT(this, Int32FalseConstant()); }
};
} // namespace internal

304
src/builtins/typed-array.tq Normal file
View File

@ -0,0 +1,304 @@
// Copyright 2018 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.
module typed_array {
extern runtime TypedArraySortFast(Context, Object): JSTypedArray;
type MethodName;
const kTypedArrayProtoSort: MethodName = '\"%TypedArray%.prototype.sort\"';
extern macro ValidateTypedArray(Context, Object, MethodName): JSTypedArray;
extern macro AssertUnreachable();
extern macro NumberIsNaN(Number): bit;
macro CallCompareWithDetachedCheck(
context: Context, array: JSTypedArray, comparefn: Callable, a: Object,
b: Object): Number labels Detached {
// a. Let v be ? ToNumber(? Call(comparefn, undefined, x, y)).
let v: Number =
ToNumber_Inline(context, Call(context, comparefn, undefined, a, b));
// b. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
if (IsDetachedBuffer(array.buffer)) goto Detached;
// c. If v is NaN, return +0.
if (NumberIsNaN(v)) return 0;
// d. return v.
return v;
}
// Wrapped CSA macro for better readability. Ideally we want to map this
// as the array operator "[]".
macro Load(backing_store: RawPtr, index: Smi, kind: ElementsKind): Object {
return LoadFixedTypedArrayElementAsTagged(
backing_store, index, kind, kSmiParameters);
}
// Wrapped array store CSA macro for better readability.
macro Store(
context: Context, backing_store: RawPtr, index: Smi, value: Object,
kind: ElementsKind) {
StoreFixedTypedArrayElementFromTagged(
context, backing_store, index, value, kind, kSmiParameters);
}
// InsertionSort is used for smaller arrays.
macro TypedArrayInsertionSort(
context: Context, array: JSTypedArray, kind: ElementsKind, from_arg: Smi,
to_arg: Smi, comparefn: Callable)
labels Detached {
let from: Smi = from_arg;
let to: Smi = to_arg;
let backing_store: RawPtr = array.data_ptr;
if (IsDetachedBuffer(array.buffer)) goto Detached;
for (let i: Smi = from + 1; i < to; ++i) {
let element: Object = Load(backing_store, i, kind);
let j: Smi = i - 1;
for (; j >= from; --j) {
let tmp: Object = Load(backing_store, j, kind);
let order: Number = CallCompareWithDetachedCheck(
context, array, comparefn, tmp, element) otherwise Detached;
backing_store = array.data_ptr; // Force reload.
if (order > 0) {
Store(context, backing_store, j + 1, tmp, kind);
} else {
break;
}
}
Store(context, backing_store, j + 1, element, kind);
}
}
macro TypedArrayQuickSortImpl(
context: Context, array: JSTypedArray, kind: ElementsKind, from_arg: Smi,
to_arg: Smi, comparefn: Callable)
labels Detached {
let from: Smi = from_arg;
let to: Smi = to_arg;
while (to - from > 1) {
if (to - from <= 10) {
// TODO(szuend): Investigate InsertionSort removal.
// Currently it does not make any difference when the
// benchmarks are run locally.
TypedArrayInsertionSort(context, array, kind, from, to, comparefn)
otherwise Detached;
break;
}
// TODO(szuend): Check if a more involved third_index calculation is
// worth it for very large arrays.
let third_index: Smi = from + ((to - from) >>> 1);
// TODO(szuend): Investigate possible performance impact by caching the
// backing_store ptr for off-heap buffers.
let backing_store: RawPtr = array.data_ptr;
if (IsDetachedBuffer(array.buffer)) goto Detached;
// Find a pivot as the median of first, last and middle element.
let v0: Object = Load(backing_store, from, kind);
let v1: Object = Load(backing_store, to - 1, kind);
let v2: Object = Load(backing_store, third_index, kind);
let c01: Number = CallCompareWithDetachedCheck(
context, array, comparefn, v0, v1) otherwise Detached;
if (c01 > 0) {
// v1 < v0, so swap them.
let tmp: Object = v0;
v0 = v1;
v1 = tmp;
}
// v0 <= v1.
let c02: Number = CallCompareWithDetachedCheck(
context, array, comparefn, v0, v2) otherwise Detached;
if (c02 >= 0) {
// v2 <= v0 <= v1.
let tmp: Object = v0;
v0 = v2;
v2 = v1;
v1 = tmp;
} else {
// v0 <= v1 && v0 < v2.
let c12: Number = CallCompareWithDetachedCheck(
context, array, comparefn, v1, v2) otherwise Detached;
if (c12 > 0) {
// v0 <= v2 < v1.
let tmp: Object = v1;
v1 = v2;
v2 = tmp;
}
}
// v0 <= v1 <= v2.
backing_store = array.data_ptr; // Force reload.
Store(context, backing_store, from, v0, kind);
Store(context, backing_store, to - 1, v2, kind);
let pivot: Object = v1;
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 low_end_value: Object = Load(backing_store, low_end, kind);
Store(context, backing_store, third_index, low_end_value, kind);
Store(context, backing_store, low_end, pivot, kind);
// From low_end to idx are elements equal to pivot.
// From idx to high_start are elements that haven"t been compared yet.
for (let idx: Smi = low_end + 1; idx < high_start; idx++) {
let element: Object = Load(backing_store, idx, kind);
let order: Number = CallCompareWithDetachedCheck(
context, array, comparefn, element, pivot) otherwise Detached;
backing_store = array.data_ptr; // Force reload.
if (order < 0) {
low_end_value = Load(backing_store, low_end, kind);
Store(context, backing_store, idx, low_end_value, kind);
Store(context, backing_store, low_end, element, kind);
low_end++;
} else if (order > 0) {
let break_for: bit = no;
while (order > 0) {
high_start--;
if (high_start == idx) {
break_for = yes;
break;
}
let top_elem: Object = Load(backing_store, high_start, kind);
order = CallCompareWithDetachedCheck(
context, array, comparefn, top_elem, pivot) otherwise Detached;
backing_store = array.data_ptr; // Force reload.
}
if (break_for) {
break;
}
let high_start_value: Object = Load(backing_store, high_start, kind);
Store(context, backing_store, idx, high_start_value, kind);
Store(context, backing_store, high_start, element, kind);
if (order < 0) {
element = Load(backing_store, idx, kind);
low_end_value = Load(backing_store, low_end, kind);
Store(context, backing_store, idx, low_end_value, kind);
Store(context, backing_store, low_end, element, kind);
low_end++;
}
}
}
if ((to - high_start) < (low_end - from)) {
TypedArrayQuickSort(context, array, high_start, to, comparefn);
to = low_end;
} else {
TypedArrayQuickSort(context, array, from, low_end, comparefn);
from = high_start;
}
}
}
builtin TypedArrayQuickSort(
context: Context, array: JSTypedArray, from: Smi, to: Smi,
comparefn: Callable): JSTypedArray {
let element_kind: int32 = array.elements_kind;
try {
if (element_kind == convert<int32>(UINT8_ELEMENTS)) {
TypedArrayQuickSortImpl(
context, array, UINT8_ELEMENTS, from, to, comparefn)
otherwise Detached;
} else if (element_kind == convert<int32>(INT8_ELEMENTS)) {
TypedArrayQuickSortImpl(
context, array, INT8_ELEMENTS, from, to, comparefn)
otherwise Detached;
} else if (element_kind == convert<int32>(UINT16_ELEMENTS)) {
TypedArrayQuickSortImpl(
context, array, UINT16_ELEMENTS, from, to, comparefn)
otherwise Detached;
} else if (element_kind == convert<int32>(INT16_ELEMENTS)) {
TypedArrayQuickSortImpl(
context, array, INT16_ELEMENTS, from, to, comparefn)
otherwise Detached;
} else if (element_kind == convert<int32>(UINT32_ELEMENTS)) {
TypedArrayQuickSortImpl(
context, array, UINT32_ELEMENTS, from, to, comparefn)
otherwise Detached;
} else if (element_kind == convert<int32>(INT32_ELEMENTS)) {
TypedArrayQuickSortImpl(
context, array, INT32_ELEMENTS, from, to, comparefn)
otherwise Detached;
} else if (element_kind == convert<int32>(UINT8_CLAMPED_ELEMENTS)) {
TypedArrayQuickSortImpl(
context, array, UINT8_CLAMPED_ELEMENTS, from, to, comparefn)
otherwise Detached;
} else if (element_kind == convert<int32>(FLOAT32_ELEMENTS)) {
TypedArrayQuickSortImpl(
context, array, FLOAT32_ELEMENTS, from, to, comparefn)
otherwise Detached;
} else if (element_kind == convert<int32>(FLOAT64_ELEMENTS)) {
TypedArrayQuickSortImpl(
context, array, FLOAT64_ELEMENTS, from, to, comparefn)
otherwise Detached;
} else if (element_kind == convert<int32>(BIGUINT64_ELEMENTS)) {
TypedArrayQuickSortImpl(
context, array, BIGUINT64_ELEMENTS, from, to, comparefn)
otherwise Detached;
} else if (element_kind == convert<int32>(BIGINT64_ELEMENTS)) {
TypedArrayQuickSortImpl(
context, array, BIGINT64_ELEMENTS, from, to, comparefn)
otherwise Detached;
}
}
label Detached {
ThrowTypeError(
context, kDetachedOperation, '%TypedArray%.prototype.sort');
}
return array;
}
// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.sort
javascript builtin TypedArrayPrototypeSort(
context: Context, receiver: Object, ...arguments): JSTypedArray {
// 1. If comparefn is not undefined and IsCallable(comparefn) is false,
// throw a TypeError exception.
let comparefn_obj: Object = arguments.length > 0 ? arguments[0] : undefined;
if (comparefn_obj != undefined &&
(TaggedIsSmi(comparefn_obj) || !IsCallable(comparefn_obj))) {
ThrowTypeError(context, kBadSortComparisonFunction, comparefn_obj);
}
// 2. Let obj be the this value.
let obj: Object = receiver;
// 3. Let buffer be ? ValidateTypedArray(obj).
// ValidateTypedArray currently returns the array, not the ViewBuffer.
let array: JSTypedArray =
ValidateTypedArray(context, obj, kTypedArrayProtoSort);
// Default sorting is done in C++ using std::sort
if (comparefn_obj == undefined) {
return TypedArraySortFast(context, obj);
}
// 4. Let len be obj.[[ArrayLength]].
let len: Smi = array.length;
try {
let comparefn: Callable =
cast<Callable>(comparefn_obj) otherwise CastError;
TypedArrayQuickSort(context, array, 0, len, comparefn);
}
label CastError {
// TODO(szuend): Replace with Unreachable() when its supported in Torque.
AssertUnreachable();
}
return array;
}
}

View File

@ -394,6 +394,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
template <class... TArgs>
TNode<Object> Call(TNode<Context> context, TNode<Object> callable,
TNode<Object> receiver, TArgs... args) {
if (IsUndefinedConstant(receiver) || IsNullConstant(receiver)) {
return UncheckedCast<Object>(CallJS(
CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
context, callable, receiver, args...));
}
return UncheckedCast<Object>(CallJS(CodeFactory::Call(isolate()), context,
callable, receiver, args...));
}

View File

@ -422,6 +422,16 @@ bool CodeAssembler::ToIntPtrConstant(Node* node, intptr_t& out_value) {
return m.HasValue();
}
bool CodeAssembler::IsUndefinedConstant(TNode<Object> node) {
compiler::HeapObjectMatcher m(node);
return m.Is(isolate()->factory()->undefined_value());
}
bool CodeAssembler::IsNullConstant(TNode<Object> node) {
compiler::HeapObjectMatcher m(node);
return m.Is(isolate()->factory()->null_value());
}
Node* CodeAssembler::Parameter(int value) {
return raw_assembler()->Parameter(value);
}

View File

@ -406,6 +406,7 @@ class SloppyTNode : public TNode<T> {
V(Float32GreaterThan, BoolT, Float32T, Float32T) \
V(Float32GreaterThanOrEqual, BoolT, Float32T, Float32T) \
V(Float64Equal, BoolT, Float64T, Float64T) \
V(Float64NotEqual, BoolT, Float64T, Float64T) \
V(Float64LessThan, BoolT, Float64T, Float64T) \
V(Float64LessThanOrEqual, BoolT, Float64T, Float64T) \
V(Float64GreaterThan, BoolT, Float64T, Float64T) \
@ -699,6 +700,9 @@ class V8_EXPORT_PRIVATE CodeAssembler {
bool ToSmiConstant(Node* node, Smi*& out_value);
bool ToIntPtrConstant(Node* node, intptr_t& out_value);
bool IsUndefinedConstant(TNode<Object> node);
bool IsNullConstant(TNode<Object> node);
TNode<Int32T> Signed(TNode<Word32T> x) { return UncheckedCast<Int32T>(x); }
TNode<IntPtrT> Signed(TNode<WordT> x) { return UncheckedCast<IntPtrT>(x); }
TNode<Uint32T> Unsigned(TNode<Word32T> x) {

View File

@ -14,7 +14,6 @@
// array.js has to come before typedarray.js for this to work
var ArrayToString = utils.ImportNow("ArrayToString");
var InnerArrayJoin;
var InnerArraySort;
var InnerArrayToLocaleString;
macro TYPED_ARRAYS(FUNCTION)
@ -45,7 +44,6 @@ var GlobalTypedArray = %object_get_prototype_of(GlobalUint8Array);
utils.Import(function(from) {
InnerArrayJoin = from.InnerArrayJoin;
InnerArraySort = from.InnerArraySort;
InnerArrayToLocaleString = from.InnerArrayToLocaleString;
});
@ -59,26 +57,6 @@ function ValidateTypedArray(array, methodName) {
throw %make_type_error(kDetachedOperation, methodName);
}
// ES6 draft 05-18-15, section 22.2.3.25
DEFINE_METHOD(
GlobalTypedArray.prototype,
sort(comparefn) {
ValidateTypedArray(this, "%TypedArray%.prototype.sort");
if (!IS_UNDEFINED(comparefn) && !IS_CALLABLE(comparefn)) {
throw %make_type_error(kBadSortComparisonFunction, comparefn);
}
var length = %_TypedArrayGetLength(this);
if (IS_UNDEFINED(comparefn)) {
return %TypedArraySortFast(this);
}
return InnerArraySort(this, length, comparefn);
}
);
// ES6 section 22.2.3.27
DEFINE_METHOD(

View File

@ -136,8 +136,6 @@
'built-ins/TypedArray/prototype/reduceRight/BigInt/callbackfn-detachbuffer': [FAIL],
'built-ins/TypedArray/prototype/some/callbackfn-detachbuffer': [FAIL],
'built-ins/TypedArray/prototype/some/BigInt/callbackfn-detachbuffer': [FAIL],
'built-ins/TypedArray/prototype/sort/detached-buffer-comparefn': [FAIL],
'built-ins/TypedArray/prototype/sort/BigInt/detached-buffer-comparefn': [FAIL],
# DataView functions should also throw on detached buffers
'built-ins/ArrayBuffer/prototype/byteLength/detached-buffer': [FAIL],
'built-ins/DataView/detached-buffer': [FAIL],

View File

@ -28,6 +28,8 @@ group("v8_run_gcmole") {
"$target_gen_dir/../../builtins-array-from-dsl-gen.h",
"$target_gen_dir/../../builtins-base-from-dsl-gen.cc",
"$target_gen_dir/../../builtins-base-from-dsl-gen.h",
"$target_gen_dir/../../builtins-typed-array-from-dsl-gen.cc",
"$target_gen_dir/../../builtins-typed-array-from-dsl-gen.h",
]
deps = [

View File

@ -172,33 +172,33 @@ KNOWN_MAPS = {
("RO_SPACE", 0x02921): (173, "Tuple2Map"),
("RO_SPACE", 0x02999): (171, "ScriptMap"),
("RO_SPACE", 0x02a01): (163, "InterceptorInfoMap"),
("RO_SPACE", 0x06891): (154, "AccessorInfoMap"),
("RO_SPACE", 0x06aa1): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x06b09): (155, "AccessorPairMap"),
("RO_SPACE", 0x06b71): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x06bd9): (157, "AllocationMementoMap"),
("RO_SPACE", 0x06c41): (158, "AllocationSiteMap"),
("RO_SPACE", 0x06ca9): (159, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x06d11): (160, "ContextExtensionMap"),
("RO_SPACE", 0x06d79): (161, "DebugInfoMap"),
("RO_SPACE", 0x06de1): (162, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x06e49): (164, "InterpreterDataMap"),
("RO_SPACE", 0x06eb1): (165, "ModuleInfoEntryMap"),
("RO_SPACE", 0x06f19): (166, "ModuleMap"),
("RO_SPACE", 0x06f81): (167, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x06fe9): (168, "PromiseCapabilityMap"),
("RO_SPACE", 0x07051): (169, "PromiseReactionMap"),
("RO_SPACE", 0x070b9): (170, "PrototypeInfoMap"),
("RO_SPACE", 0x07121): (172, "StackFrameInfoMap"),
("RO_SPACE", 0x07189): (174, "Tuple3Map"),
("RO_SPACE", 0x071f1): (175, "WasmCompiledModuleMap"),
("RO_SPACE", 0x07259): (176, "WasmDebugInfoMap"),
("RO_SPACE", 0x072c1): (177, "WasmSharedModuleDataMap"),
("RO_SPACE", 0x07329): (178, "CallableTaskMap"),
("RO_SPACE", 0x07391): (179, "CallbackTaskMap"),
("RO_SPACE", 0x073f9): (180, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x07461): (181, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x074c9): (182, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x068c9): (154, "AccessorInfoMap"),
("RO_SPACE", 0x06ad9): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x06b41): (155, "AccessorPairMap"),
("RO_SPACE", 0x06ba9): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x06c11): (157, "AllocationMementoMap"),
("RO_SPACE", 0x06c79): (158, "AllocationSiteMap"),
("RO_SPACE", 0x06ce1): (159, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x06d49): (160, "ContextExtensionMap"),
("RO_SPACE", 0x06db1): (161, "DebugInfoMap"),
("RO_SPACE", 0x06e19): (162, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x06e81): (164, "InterpreterDataMap"),
("RO_SPACE", 0x06ee9): (165, "ModuleInfoEntryMap"),
("RO_SPACE", 0x06f51): (166, "ModuleMap"),
("RO_SPACE", 0x06fb9): (167, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x07021): (168, "PromiseCapabilityMap"),
("RO_SPACE", 0x07089): (169, "PromiseReactionMap"),
("RO_SPACE", 0x070f1): (170, "PrototypeInfoMap"),
("RO_SPACE", 0x07159): (172, "StackFrameInfoMap"),
("RO_SPACE", 0x071c1): (174, "Tuple3Map"),
("RO_SPACE", 0x07229): (175, "WasmCompiledModuleMap"),
("RO_SPACE", 0x07291): (176, "WasmDebugInfoMap"),
("RO_SPACE", 0x072f9): (177, "WasmSharedModuleDataMap"),
("RO_SPACE", 0x07361): (178, "CallableTaskMap"),
("RO_SPACE", 0x073c9): (179, "CallbackTaskMap"),
("RO_SPACE", 0x07431): (180, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x07499): (181, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x07501): (182, "PromiseResolveThenableJobTaskMap"),
("MAP_SPACE", 0x02201): (138, "FreeSpaceMap"),
("MAP_SPACE", 0x02259): (152, "OnePointerFillerMap"),
("MAP_SPACE", 0x022b1): (152, "TwoPointerFillerMap"),