Commit 40b0be49 authored by peterwmwong's avatar peterwmwong Committed by Peter Wong

[builtins] Port TypedArray ConstructByIterable/ConstructByTypedArray to Torque

This is part of an effort to improve the performance of TA#subarray.

Bug: v8:7161
Change-Id: I1579ee45a810e1f2d0279fef9e18bad09e1fc3d9
Reviewed-on: https://chromium-review.googlesource.com/c/1426107Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59048}
parent 08df2ebe
......@@ -416,6 +416,8 @@ extern macro Construct(implicit context: Context)(
Constructor, Object, Object): JSReceiver;
extern macro Construct(implicit context: Context)(
Constructor, Object, Object, Object): JSReceiver;
extern macro SpeciesConstructor(implicit context: Context)(
Object, JSReceiver): JSReceiver;
extern builtin ToObject(Context, Object): JSReceiver;
extern macro ToObject_Inline(Context, Object): JSReceiver;
......
......@@ -450,64 +450,6 @@ void TypedArrayBuiltinsAssembler::ConstructByArrayBuffer(
BIND(&done);
}
void TypedArrayBuiltinsAssembler::ConstructByTypedArray(
TNode<Context> context, TNode<JSTypedArray> holder,
TNode<JSTypedArray> typed_array, TNode<Smi> element_size) {
CSA_ASSERT(this, TaggedIsPositiveSmi(element_size));
TNode<JSFunction> const default_constructor = CAST(LoadContextElement(
LoadNativeContext(context), Context::ARRAY_BUFFER_FUN_INDEX));
Label construct(this), if_detached(this), if_notdetached(this),
check_for_sab(this), if_buffernotshared(this), check_prototype(this),
done(this);
TVARIABLE(JSReceiver, buffer_constructor, default_constructor);
TNode<JSArrayBuffer> source_buffer = LoadObjectField<JSArrayBuffer>(
typed_array, JSArrayBufferView::kBufferOffset);
Branch(IsDetachedBuffer(source_buffer), &if_detached, &if_notdetached);
// TODO(petermarshall): Throw on detached typedArray.
TVARIABLE(Smi, source_length);
BIND(&if_detached);
source_length = SmiConstant(0);
Goto(&check_for_sab);
BIND(&if_notdetached);
source_length = LoadJSTypedArrayLength(typed_array);
Goto(&check_for_sab);
// The spec requires that constructing a typed array using a SAB-backed typed
// array use the ArrayBuffer constructor, not the species constructor. See
// https://tc39.github.io/ecma262/#sec-typedarray-typedarray.
BIND(&check_for_sab);
TNode<Uint32T> bitfield =
LoadObjectField<Uint32T>(source_buffer, JSArrayBuffer::kBitFieldOffset);
Branch(IsSetWord32<JSArrayBuffer::IsSharedBit>(bitfield), &construct,
&if_buffernotshared);
BIND(&if_buffernotshared);
{
buffer_constructor =
SpeciesConstructor(context, source_buffer, default_constructor);
// TODO(petermarshall): Throw on detached typedArray.
GotoIfNot(IsDetachedBuffer(source_buffer), &construct);
source_length = SmiConstant(0);
Goto(&construct);
}
BIND(&construct);
{
TypedArrayBuiltinsFromDSLAssembler(this->state())
.ConstructByArrayLike(context, holder, typed_array,
source_length.value(), element_size,
buffer_constructor.value());
Goto(&done);
}
BIND(&done);
}
Node* TypedArrayBuiltinsAssembler::LoadDataPtr(Node* typed_array) {
CSA_ASSERT(this, IsJSTypedArray(typed_array));
Node* elements = LoadElements(typed_array);
......@@ -538,25 +480,6 @@ TNode<BoolT> TypedArrayBuiltinsAssembler::ByteLengthIsValid(
return is_valid.value();
}
void TypedArrayBuiltinsAssembler::ConstructByIterable(
TNode<Context> context, TNode<JSTypedArray> holder,
TNode<JSReceiver> iterable, TNode<JSReceiver> iterator_fn,
TNode<Smi> element_size) {
Label fast_path(this), slow_path(this), done(this);
CSA_ASSERT(this, IsCallable(iterator_fn));
TNode<JSArray> array_like =
CAST(CallBuiltin(Builtins::kIterableToListMayPreserveHoles, context,
iterable, iterator_fn));
TNode<Object> initial_length = LoadJSArrayLength(array_like);
TNode<JSFunction> default_constructor = CAST(LoadContextElement(
LoadNativeContext(context), Context::ARRAY_BUFFER_FUN_INDEX));
TypedArrayBuiltinsFromDSLAssembler(this->state())
.ConstructByArrayLike(context, holder, array_like, initial_length,
element_size, default_constructor);
}
TF_BUILTIN(TypedArrayBaseConstructor, TypedArrayBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
ThrowTypeError(context, MessageTemplate::kConstructAbstractClass,
......@@ -615,7 +538,8 @@ TF_BUILTIN(CreateTypedArray, TypedArrayBuiltinsAssembler) {
BIND(&if_arg1istypedarray);
{
TNode<JSTypedArray> typed_array = CAST(arg1_heap_object);
ConstructByTypedArray(context, result, typed_array, element_size);
TypedArrayBuiltinsFromDSLAssembler(state()).ConstructByTypedArray(
context, result, typed_array, element_size);
Goto(&return_result);
}
......@@ -629,9 +553,9 @@ TF_BUILTIN(CreateTypedArray, TypedArrayBuiltinsAssembler) {
&if_iteratorundefined));
GotoIf(TaggedIsSmi(iteratorFn), &if_iteratornotcallable);
GotoIfNot(IsCallable(CAST(iteratorFn)), &if_iteratornotcallable);
ConstructByIterable(context, result, CAST(arg1_heap_object),
CAST(iteratorFn), element_size);
TypedArrayBuiltinsFromDSLAssembler(state()).ConstructByIterable(
context, result, CAST(arg1_heap_object), CAST(iteratorFn),
element_size);
Goto(&return_result);
BIND(&if_iteratorundefined);
......@@ -642,9 +566,9 @@ TF_BUILTIN(CreateTypedArray, TypedArrayBuiltinsAssembler) {
TNode<JSFunction> default_constructor = CAST(LoadContextElement(
LoadNativeContext(context), Context::ARRAY_BUFFER_FUN_INDEX));
TypedArrayBuiltinsFromDSLAssembler(this->state())
.ConstructByArrayLike(context, result, array_like, initial_length,
element_size, default_constructor);
TypedArrayBuiltinsFromDSLAssembler(state()).ConstructByArrayLike(
context, result, array_like, initial_length, element_size,
default_constructor);
Goto(&return_result);
}
......@@ -656,8 +580,8 @@ TF_BUILTIN(CreateTypedArray, TypedArrayBuiltinsAssembler) {
// a number. https://tc39.github.io/ecma262/#sec-typedarray-length
BIND(&if_arg1isnumber);
{
TypedArrayBuiltinsFromDSLAssembler(this->state())
.ConstructByLength(context, result, arg1, element_size);
TypedArrayBuiltinsFromDSLAssembler(state()).ConstructByLength(
context, result, arg1, element_size);
Goto(&return_result);
}
......@@ -1136,6 +1060,13 @@ void TypedArrayBuiltinsAssembler::DispatchTypedArrayByElementsKind(
BIND(&next);
}
TNode<BoolT> TypedArrayBuiltinsAssembler::IsSharedArrayBuffer(
TNode<JSArrayBuffer> buffer) {
TNode<Uint32T> bitfield =
LoadObjectField<Uint32T>(buffer, JSArrayBuffer::kBitFieldOffset);
return IsSetWord32<JSArrayBuffer::IsSharedBit>(bitfield);
}
// ES #sec-get-%typedarray%.prototype.set
TF_BUILTIN(TypedArrayPrototypeSet, TypedArrayBuiltinsAssembler) {
const char* method_name = "%TypedArray%.prototype.set";
......
......@@ -35,13 +35,6 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
TNode<JSArrayBuffer> buffer,
TNode<Object> byte_offset, TNode<Object> length,
TNode<Smi> element_size);
void ConstructByTypedArray(TNode<Context> context, TNode<JSTypedArray> holder,
TNode<JSTypedArray> typed_array,
TNode<Smi> element_size);
void ConstructByIterable(TNode<Context> context, TNode<JSTypedArray> holder,
TNode<JSReceiver> iterable,
TNode<JSReceiver> iterator_fn,
TNode<Smi> element_size);
void SetupTypedArray(TNode<JSTypedArray> holder, TNode<Smi> length,
TNode<UintPtrT> byte_offset,
......@@ -123,6 +116,8 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
void DispatchTypedArrayByElementsKind(
TNode<Word32T> elements_kind, const TypedArraySwitchCase& case_function);
TNode<BoolT> IsSharedArrayBuffer(TNode<JSArrayBuffer> buffer);
};
} // namespace internal
......
......@@ -3,12 +3,16 @@
// found in the LICENSE file.
namespace typed_array {
extern builtin IterableToListMayPreserveHoles(Context, Object, Callable):
JSArray;
extern builtin TypedArrayInitialize(implicit context: Context)(
JSTypedArray, PositiveSmi, PositiveSmi, Boolean, JSReceiver): void;
extern macro TypedArrayBuiltinsAssembler::ByteLengthIsValid(Number): bool;
extern macro TypedArrayBuiltinsAssembler::CallCMemcpy(
RawPtr, RawPtr, uintptr): void;
extern macro TypedArrayBuiltinsAssembler::IsSharedArrayBuffer(JSArrayBuffer):
bool;
extern runtime TypedArrayCopyElements(Context, JSTypedArray, Object, Number):
void;
......@@ -70,4 +74,37 @@ namespace typed_array {
}
}
}
// 22.2.4.4 TypedArray ( object )
// ES #sec-typedarray-object
macro ConstructByIterable(implicit context: Context)(
typedArray: JSTypedArray, iterable: JSReceiver, iteratorFn: Callable,
elementSize: Smi): void {
const array: JSArray =
IterableToListMayPreserveHoles(context, iterable, iteratorFn);
ConstructByArrayLike(
typedArray, array, array.length, elementSize, GetArrayBufferFunction());
}
// 22.2.4.3 TypedArray ( typedArray )
// ES #sec-typedarray-typedarray
macro ConstructByTypedArray(implicit context: Context)(
typedArray: JSTypedArray, srcTypedArray: JSTypedArray,
elementSize: Smi): void {
let bufferConstructor: JSReceiver = GetArrayBufferFunction();
const srcBuffer: JSArrayBuffer = srcTypedArray.buffer;
// TODO(petermarshall): Throw on detached typedArray.
let length: Smi = IsDetachedBuffer(srcBuffer) ? 0 : srcTypedArray.length;
// The spec requires that constructing a typed array using a SAB-backed
// typed array use the ArrayBuffer constructor, not the species constructor.
// See https://tc39.github.io/ecma262/#sec-typedarray-typedarray.
if (!IsSharedArrayBuffer(srcBuffer)) {
bufferConstructor = SpeciesConstructor(srcBuffer, bufferConstructor);
// TODO(petermarshall): Throw on detached typedArray.
if (IsDetachedBuffer(srcBuffer)) length = 0;
}
ConstructByArrayLike(
typedArray, srcTypedArray, length, elementSize, bufferConstructor);
}
}
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