[builtins] Port TypedArray ConstructByLength to Torque

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

Bug: v8:7161
Change-Id: Iae84d16a037386bebfeaa7e8fb0648da295653b4
Reviewed-on: https://chromium-review.googlesource.com/c/1419225
Commit-Queue: Peter Wong <peter.wm.wong@gmail.com>
Reviewed-by: Peter Marshall <petermarshall@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58947}
This commit is contained in:
peterwmwong 2019-01-18 08:51:18 -06:00 committed by Commit Bot
parent 5aa361ffca
commit 945e2b8f7b
6 changed files with 57 additions and 41 deletions

View File

@ -876,6 +876,7 @@ torque_files = [
"src/builtins/object-fromentries.tq",
"src/builtins/iterator.tq",
"src/builtins/typed-array.tq",
"src/builtins/typed-array-createtypedarray.tq",
"test/torque/test-torque.tq",
"third_party/v8/builtins/array-sort.tq",
]

View File

@ -18,6 +18,9 @@ type never;
type Tagged generates 'TNode<Object>' constexpr 'ObjectPtr';
type Smi extends Tagged generates 'TNode<Smi>' constexpr 'Smi';
// A Smi that is greater than or equal to 0. See TaggedIsPositiveSmi.
type PositiveSmi extends Smi generates 'TNode<Smi>';
class HeapObject extends Tagged {
map_untyped: Tagged;
}
@ -147,6 +150,8 @@ intrinsic %RawPointerCast<A: type>(p: RawPtr): A;
intrinsic %RawConstexprCast<To: type, From: type>(f: From): To;
type NativeContextSlot generates 'TNode<IntPtrT>' constexpr 'int32_t';
const ARRAY_BUFFER_FUN_INDEX: constexpr NativeContextSlot
generates 'Context::ARRAY_BUFFER_FUN_INDEX';
const ARRAY_JOIN_STACK_INDEX: constexpr NativeContextSlot
generates 'Context::ARRAY_JOIN_STACK_INDEX';
const OBJECT_FUNCTION_INDEX: constexpr NativeContextSlot
@ -265,6 +270,8 @@ const kCalledNonCallable: constexpr MessageTemplate
generates 'MessageTemplate::kCalledNonCallable';
const kCalledOnNullOrUndefined: constexpr MessageTemplate
generates 'MessageTemplate::kCalledOnNullOrUndefined';
const kInvalidTypedArrayLength: constexpr MessageTemplate
generates 'MessageTemplate::kInvalidTypedArrayLength';
const kIteratorValueNotAnObject: constexpr MessageTemplate
generates 'MessageTemplate::kIteratorValueNotAnObject';
const kNotIterable: constexpr MessageTemplate
@ -376,6 +383,7 @@ extern transitioning macro HasProperty_Inline(implicit context: Context)(
JSReceiver, Object): Boolean;
extern macro ThrowRangeError(Context, constexpr MessageTemplate): never;
extern macro ThrowRangeError(Context, constexpr MessageTemplate, Object): never;
extern macro ThrowTypeError(Context, constexpr MessageTemplate): never;
extern macro ThrowTypeError(Context, constexpr MessageTemplate, Object): never;
extern macro ThrowTypeError(
@ -595,6 +603,8 @@ extern macro TaggedToHeapObject(Object): HeapObject
labels CastError;
extern macro TaggedToSmi(Object): Smi
labels CastError;
extern macro TaggedToPositiveSmi(Object): PositiveSmi
labels CastError;
extern macro HeapObjectToJSArray(HeapObject): JSArray
labels CastError;
extern macro HeapObjectToCallable(HeapObject): Callable
@ -805,6 +815,11 @@ Cast<Smi>(o: Object): Smi
return TaggedToSmi(o) otherwise CastError;
}
Cast<PositiveSmi>(o: Object): PositiveSmi
labels CastError {
return TaggedToPositiveSmi(o) otherwise CastError;
}
Cast<Number>(o: Object): Number
labels CastError {
return TaggedToNumber(o) otherwise CastError;
@ -1178,6 +1193,10 @@ macro GetObjectFunction(implicit context: Context)(): JSFunction {
return UnsafeCast<JSFunction>(
LoadNativeContext(context)[OBJECT_FUNCTION_INDEX]);
}
macro GetArrayBufferFunction(implicit context: Context)(): JSFunction {
return UnsafeCast<JSFunction>(
LoadNativeContext(context)[ARRAY_BUFFER_FUN_INDEX]);
}
macro GetFastPackedSmiElementsJSArrayMap(implicit context: Context)(): Map {
return UnsafeCast<Map>(

View File

@ -10,6 +10,7 @@
#include "src/builtins/growable-fixed-array-gen.h"
#include "src/handles-inl.h"
#include "src/heap/factory-inl.h"
#include "torque-generated/builtins-typed-array-from-dsl-gen.h"
namespace v8 {
namespace internal {
@ -317,44 +318,6 @@ TF_BUILTIN(TypedArrayInitialize, TypedArrayBuiltinsAssembler) {
Return(UndefinedConstant());
}
// ES6 #sec-typedarray-length
void TypedArrayBuiltinsAssembler::ConstructByLength(TNode<Context> context,
TNode<JSTypedArray> holder,
TNode<Object> length,
TNode<Smi> element_size) {
// TODO(7881): support larger-than-smi typed array lengths
CSA_ASSERT(this, TaggedIsPositiveSmi(element_size));
Label invalid_length(this, Label::kDeferred), done(this);
TNode<Number> converted_length =
ToInteger_Inline(context, length, CodeStubAssembler::kTruncateMinusZero);
// The maximum length of a TypedArray is MaxSmi().
// Note: this is not per spec, but rather a constraint of our current
// representation (which uses Smis).
// TODO(7881): support larger-than-smi typed array lengths
GotoIf(TaggedIsNotSmi(converted_length), &invalid_length);
// The goto above ensures that byte_length is a Smi.
TNode<Smi> smi_converted_length = CAST(converted_length);
GotoIf(SmiLessThan(smi_converted_length, SmiConstant(0)), &invalid_length);
Node* initialize = TrueConstant();
TNode<JSFunction> default_constructor = CAST(LoadContextElement(
LoadNativeContext(context), Context::ARRAY_BUFFER_FUN_INDEX));
CallBuiltin(Builtins::kTypedArrayInitialize, context, holder,
converted_length, element_size, initialize, default_constructor);
Goto(&done);
BIND(&invalid_length);
{
ThrowRangeError(context, MessageTemplate::kInvalidTypedArrayLength,
converted_length);
}
BIND(&done);
}
// ES6 #sec-typedarray-buffer-byteoffset-length
void TypedArrayBuiltinsAssembler::ConstructByArrayBuffer(
TNode<Context> context, TNode<JSTypedArray> holder,
@ -758,7 +721,8 @@ TF_BUILTIN(CreateTypedArray, TypedArrayBuiltinsAssembler) {
// a number. https://tc39.github.io/ecma262/#sec-typedarray-length
BIND(&if_arg1isnumber);
{
ConstructByLength(context, result, arg1, element_size);
TypedArrayBuiltinsFromDSLAssembler(this->state())
.ConstructByLength(context, result, arg1, element_size);
Goto(&return_result);
}

View File

@ -30,8 +30,6 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
const char* method_name,
IterationKind iteration_kind);
void ConstructByLength(TNode<Context> context, TNode<JSTypedArray> holder,
TNode<Object> length, TNode<Smi> element_size);
void ConstructByArrayBuffer(TNode<Context> context,
TNode<JSTypedArray> holder,
TNode<JSArrayBuffer> buffer,

View File

@ -0,0 +1,29 @@
// Copyright 2019 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.
namespace typed_array {
extern builtin TypedArrayInitialize(implicit context: Context)(
JSTypedArray, PositiveSmi, PositiveSmi, Boolean, JSReceiver): void;
// 22.2.4.2 TypedArray ( length )
// ES #sec-typedarray-length
macro ConstructByLength(implicit context: Context)(
typedArray: JSTypedArray, length: Object, elementSize: Smi): void {
const positiveElementSize: PositiveSmi =
Cast<PositiveSmi>(elementSize) otherwise unreachable;
const convertedLength: Number =
ToInteger_Inline(context, length, kTruncateMinusZero);
// The maximum length of a TypedArray is MaxSmi().
// Note: this is not per spec, but rather a constraint of our current
// representation (which uses Smis).
// TODO(7881): support larger-than-smi typed array lengths
const positiveLength: PositiveSmi = Cast<PositiveSmi>(convertedLength)
otherwise ThrowRangeError(context, kInvalidTypedArrayLength, length);
const defaultConstructor: JSFunction = GetArrayBufferFunction();
const initialize: Boolean = True;
TypedArrayInitialize(
typedArray, positiveLength, positiveElementSize, initialize,
defaultConstructor);
}
}

View File

@ -317,6 +317,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
return UncheckedCast<Smi>(value);
}
TNode<Smi> TaggedToPositiveSmi(TNode<Object> value, Label* fail) {
GotoIfNot(TaggedIsPositiveSmi(value), fail);
return UncheckedCast<Smi>(value);
}
TNode<Number> TaggedToNumber(TNode<Object> value, Label* fail) {
GotoIfNot(IsNumber(value), fail);
return UncheckedCast<Number>(value);