[typedarray] Share SpeciesCreateByLength between CSA code.
Move the class declaration for SpeciesCreateByLength to a header file so that we can share more TypedArray CSA code. Delete the C++ implementation of species create for typed arrays because it is no longer used. Change-Id: I7c43b8ef144ba9a8ce12516f7cb8fb570491cb26 Reviewed-on: https://chromium-review.googlesource.com/904987 Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Peter Marshall <petermarshall@chromium.org> Cr-Commit-Position: refs/heads/master@{#51139}
This commit is contained in:
parent
54f1b2019b
commit
a2aac98ddf
1
BUILD.gn
1
BUILD.gn
@ -1076,6 +1076,7 @@ v8_source_set("v8_initializers") {
|
||||
"src/builtins/builtins-string-gen.h",
|
||||
"src/builtins/builtins-symbol-gen.cc",
|
||||
"src/builtins/builtins-typedarray-gen.cc",
|
||||
"src/builtins/builtins-typedarray-gen.h",
|
||||
"src/builtins/builtins-utils-gen.h",
|
||||
"src/builtins/builtins-wasm-gen.cc",
|
||||
"src/builtins/growable-fixed-array-gen.cc",
|
||||
|
@ -193,6 +193,7 @@
|
||||
'../src/builtins/builtins-string-gen.h',
|
||||
'../src/builtins/builtins-symbol-gen.cc',
|
||||
'../src/builtins/builtins-typedarray-gen.cc',
|
||||
'../src/builtins/builtins-typedarray-gen.h',
|
||||
'../src/builtins/builtins-utils-gen.h',
|
||||
'../src/builtins/builtins-wasm-gen.cc',
|
||||
'../src/builtins/growable-fixed-array-gen.cc',
|
||||
|
@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/builtins/builtins-string-gen.h"
|
||||
#include "src/builtins/builtins-typedarray-gen.h"
|
||||
#include "src/builtins/builtins-utils-gen.h"
|
||||
#include "src/builtins/builtins.h"
|
||||
#include "src/code-stub-assembler.h"
|
||||
@ -200,7 +201,13 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) {
|
||||
|
||||
void ArrayBuiltinsAssembler::TypedArrayMapResultGenerator() {
|
||||
// 6. Let A be ? TypedArraySpeciesCreate(O, len).
|
||||
Node* a = TypedArraySpeciesCreateByLength(context(), o(), len_);
|
||||
TNode<JSTypedArray> original_array = CAST(o());
|
||||
TNode<Smi> length = CAST(len_);
|
||||
const char* method_name = "%TypedArray%.prototype.map";
|
||||
|
||||
TypedArrayBuiltinsAssembler typedarray_asm(state());
|
||||
TNode<JSTypedArray> a = typedarray_asm.SpeciesCreateByLength(
|
||||
CAST(context()), original_array, length, method_name);
|
||||
// In the Spec and our current implementation, the length check is already
|
||||
// performed in TypedArraySpeciesCreate.
|
||||
CSA_ASSERT(this,
|
||||
|
@ -2,12 +2,13 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/builtins/builtins-typedarray-gen.h"
|
||||
|
||||
#include "src/builtins/builtins-constructor-gen.h"
|
||||
#include "src/builtins/builtins-iterator-gen.h"
|
||||
#include "src/builtins/builtins-utils-gen.h"
|
||||
#include "src/builtins/builtins.h"
|
||||
#include "src/builtins/growable-fixed-array-gen.h"
|
||||
#include "src/code-stub-assembler.h"
|
||||
#include "src/handles-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -26,111 +27,6 @@ using TNode = compiler::TNode<T>;
|
||||
// -----------------------------------------------------------------------------
|
||||
// ES6 section 22.2 TypedArray Objects
|
||||
|
||||
class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
|
||||
public:
|
||||
explicit TypedArrayBuiltinsAssembler(compiler::CodeAssemblerState* state)
|
||||
: CodeStubAssembler(state) {}
|
||||
|
||||
protected:
|
||||
void GenerateTypedArrayPrototypeGetter(Node* context, Node* receiver,
|
||||
const char* method_name,
|
||||
int object_offset);
|
||||
void GenerateTypedArrayPrototypeIterationMethod(Node* context, Node* receiver,
|
||||
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,
|
||||
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 ConstructByArrayLike(TNode<Context> context, TNode<JSTypedArray> holder,
|
||||
TNode<HeapObject> array_like,
|
||||
TNode<Object> initial_length,
|
||||
TNode<Smi> element_size);
|
||||
void ConstructByIterable(TNode<Context> context, TNode<JSTypedArray> holder,
|
||||
TNode<JSReceiver> iterable,
|
||||
TNode<Object> iterator_fn, TNode<Smi> element_size);
|
||||
|
||||
void SetupTypedArray(TNode<JSTypedArray> holder, TNode<Smi> length,
|
||||
TNode<Number> byte_offset, TNode<Number> byte_length);
|
||||
void AttachBuffer(TNode<JSTypedArray> holder, TNode<JSArrayBuffer> buffer,
|
||||
TNode<Map> map, TNode<Smi> length,
|
||||
TNode<Number> byte_offset);
|
||||
|
||||
TNode<Map> LoadMapForType(TNode<JSTypedArray> array);
|
||||
TNode<UintPtrT> CalculateExternalPointer(TNode<UintPtrT> backing_store,
|
||||
TNode<Number> byte_offset);
|
||||
Node* LoadDataPtr(Node* typed_array);
|
||||
TNode<BoolT> ByteLengthIsValid(TNode<Number> byte_length);
|
||||
|
||||
// Returns true if kind is either UINT8_ELEMENTS or UINT8_CLAMPED_ELEMENTS.
|
||||
TNode<Word32T> IsUint8ElementsKind(TNode<Word32T> kind);
|
||||
|
||||
// Loads the element kind of TypedArray instance.
|
||||
TNode<Word32T> LoadElementsKind(TNode<Object> typed_array);
|
||||
|
||||
// Returns the byte size of an element for a TypedArray elements kind.
|
||||
TNode<IntPtrT> GetTypedArrayElementSize(TNode<Word32T> elements_kind);
|
||||
|
||||
TNode<Object> GetDefaultConstructor(TNode<Context> context,
|
||||
TNode<JSTypedArray> exemplar);
|
||||
|
||||
TNode<Object> TypedArraySpeciesConstructor(TNode<Context> context,
|
||||
TNode<JSTypedArray> exemplar);
|
||||
|
||||
TNode<JSTypedArray> SpeciesCreateByArrayBuffer(TNode<Context> context,
|
||||
TNode<JSTypedArray> exemplar,
|
||||
TNode<JSArrayBuffer> buffer,
|
||||
TNode<Number> byte_offset,
|
||||
TNode<Smi> len,
|
||||
const char* method_name);
|
||||
|
||||
TNode<JSTypedArray> SpeciesCreateByLength(TNode<Context> context,
|
||||
TNode<JSTypedArray> exemplar,
|
||||
TNode<Smi> len,
|
||||
const char* method_name);
|
||||
|
||||
TNode<JSArrayBuffer> GetBuffer(TNode<Context> context,
|
||||
TNode<JSTypedArray> array);
|
||||
|
||||
TNode<JSTypedArray> ValidateTypedArray(TNode<Context> context,
|
||||
TNode<Object> obj,
|
||||
const char* method_name);
|
||||
|
||||
// Fast path for setting a TypedArray (source) onto another TypedArray
|
||||
// (target) at an element offset.
|
||||
void SetTypedArraySource(TNode<Context> context, TNode<JSTypedArray> source,
|
||||
TNode<JSTypedArray> target, TNode<IntPtrT> offset,
|
||||
Label* call_runtime, Label* if_source_too_large);
|
||||
|
||||
void SetJSArraySource(TNode<Context> context, TNode<JSArray> source,
|
||||
TNode<JSTypedArray> target, TNode<IntPtrT> offset,
|
||||
Label* call_runtime, Label* if_source_too_large);
|
||||
|
||||
void CallCMemmove(TNode<IntPtrT> dest_ptr, TNode<IntPtrT> src_ptr,
|
||||
TNode<IntPtrT> byte_length);
|
||||
|
||||
void CallCCopyFastNumberJSArrayElementsToTypedArray(
|
||||
TNode<Context> context, TNode<JSArray> source, TNode<JSTypedArray> dest,
|
||||
TNode<IntPtrT> source_length, TNode<IntPtrT> offset);
|
||||
|
||||
void CallCCopyTypedArrayElementsToTypedArray(TNode<JSTypedArray> source,
|
||||
TNode<JSTypedArray> dest,
|
||||
TNode<IntPtrT> source_length,
|
||||
TNode<IntPtrT> offset);
|
||||
|
||||
typedef std::function<void(ElementsKind, int, int)> TypedArraySwitchCase;
|
||||
|
||||
void DispatchTypedArrayByElementsKind(
|
||||
TNode<Word32T> elements_kind, const TypedArraySwitchCase& case_function);
|
||||
};
|
||||
|
||||
TNode<Map> TypedArrayBuiltinsAssembler::LoadMapForType(
|
||||
TNode<JSTypedArray> array) {
|
||||
TVARIABLE(Map, var_typed_map);
|
||||
|
121
src/builtins/builtins-typedarray-gen.h
Normal file
121
src/builtins/builtins-typedarray-gen.h
Normal file
@ -0,0 +1,121 @@
|
||||
// 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.
|
||||
|
||||
#ifndef V8_BUILTINS_BUILTINS_TYPEDARRAY_GEN_H_
|
||||
#define V8_BUILTINS_BUILTINS_TYPEDARRAY_GEN_H_
|
||||
|
||||
#include "src/code-stub-assembler.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
|
||||
public:
|
||||
explicit TypedArrayBuiltinsAssembler(compiler::CodeAssemblerState* state)
|
||||
: CodeStubAssembler(state) {}
|
||||
|
||||
TNode<JSTypedArray> SpeciesCreateByLength(TNode<Context> context,
|
||||
TNode<JSTypedArray> exemplar,
|
||||
TNode<Smi> len,
|
||||
const char* method_name);
|
||||
|
||||
protected:
|
||||
void GenerateTypedArrayPrototypeGetter(Node* context, Node* receiver,
|
||||
const char* method_name,
|
||||
int object_offset);
|
||||
void GenerateTypedArrayPrototypeIterationMethod(Node* context, Node* receiver,
|
||||
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,
|
||||
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 ConstructByArrayLike(TNode<Context> context, TNode<JSTypedArray> holder,
|
||||
TNode<HeapObject> array_like,
|
||||
TNode<Object> initial_length,
|
||||
TNode<Smi> element_size);
|
||||
void ConstructByIterable(TNode<Context> context, TNode<JSTypedArray> holder,
|
||||
TNode<JSReceiver> iterable,
|
||||
TNode<Object> iterator_fn, TNode<Smi> element_size);
|
||||
|
||||
void SetupTypedArray(TNode<JSTypedArray> holder, TNode<Smi> length,
|
||||
TNode<Number> byte_offset, TNode<Number> byte_length);
|
||||
void AttachBuffer(TNode<JSTypedArray> holder, TNode<JSArrayBuffer> buffer,
|
||||
TNode<Map> map, TNode<Smi> length,
|
||||
TNode<Number> byte_offset);
|
||||
|
||||
TNode<Map> LoadMapForType(TNode<JSTypedArray> array);
|
||||
TNode<UintPtrT> CalculateExternalPointer(TNode<UintPtrT> backing_store,
|
||||
TNode<Number> byte_offset);
|
||||
Node* LoadDataPtr(Node* typed_array);
|
||||
TNode<BoolT> ByteLengthIsValid(TNode<Number> byte_length);
|
||||
|
||||
// Returns true if kind is either UINT8_ELEMENTS or UINT8_CLAMPED_ELEMENTS.
|
||||
TNode<Word32T> IsUint8ElementsKind(TNode<Word32T> kind);
|
||||
|
||||
// Loads the element kind of TypedArray instance.
|
||||
TNode<Word32T> LoadElementsKind(TNode<Object> typed_array);
|
||||
|
||||
// Returns the byte size of an element for a TypedArray elements kind.
|
||||
TNode<IntPtrT> GetTypedArrayElementSize(TNode<Word32T> elements_kind);
|
||||
|
||||
TNode<Object> GetDefaultConstructor(TNode<Context> context,
|
||||
TNode<JSTypedArray> exemplar);
|
||||
|
||||
TNode<Object> TypedArraySpeciesConstructor(TNode<Context> context,
|
||||
TNode<JSTypedArray> exemplar);
|
||||
|
||||
TNode<JSTypedArray> SpeciesCreateByArrayBuffer(TNode<Context> context,
|
||||
TNode<JSTypedArray> exemplar,
|
||||
TNode<JSArrayBuffer> buffer,
|
||||
TNode<Number> byte_offset,
|
||||
TNode<Smi> len,
|
||||
const char* method_name);
|
||||
|
||||
TNode<JSArrayBuffer> GetBuffer(TNode<Context> context,
|
||||
TNode<JSTypedArray> array);
|
||||
|
||||
TNode<JSTypedArray> ValidateTypedArray(TNode<Context> context,
|
||||
TNode<Object> obj,
|
||||
const char* method_name);
|
||||
|
||||
// Fast path for setting a TypedArray (source) onto another TypedArray
|
||||
// (target) at an element offset.
|
||||
void SetTypedArraySource(TNode<Context> context, TNode<JSTypedArray> source,
|
||||
TNode<JSTypedArray> target, TNode<IntPtrT> offset,
|
||||
Label* call_runtime, Label* if_source_too_large);
|
||||
|
||||
void SetJSArraySource(TNode<Context> context, TNode<JSArray> source,
|
||||
TNode<JSTypedArray> target, TNode<IntPtrT> offset,
|
||||
Label* call_runtime, Label* if_source_too_large);
|
||||
|
||||
void CallCMemmove(TNode<IntPtrT> dest_ptr, TNode<IntPtrT> src_ptr,
|
||||
TNode<IntPtrT> byte_length);
|
||||
|
||||
void CallCCopyFastNumberJSArrayElementsToTypedArray(
|
||||
TNode<Context> context, TNode<JSArray> source, TNode<JSTypedArray> dest,
|
||||
TNode<IntPtrT> source_length, TNode<IntPtrT> offset);
|
||||
|
||||
void CallCCopyTypedArrayElementsToTypedArray(TNode<JSTypedArray> source,
|
||||
TNode<JSTypedArray> dest,
|
||||
TNode<IntPtrT> source_length,
|
||||
TNode<IntPtrT> offset);
|
||||
|
||||
typedef std::function<void(ElementsKind, int, int)> TypedArraySwitchCase;
|
||||
|
||||
void DispatchTypedArrayByElementsKind(
|
||||
TNode<Word32T> elements_kind, const TypedArraySwitchCase& case_function);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_BUILTINS_BUILTINS_TYPEDARRAY_GEN_H_
|
@ -10522,15 +10522,6 @@ Node* CodeStubAssembler::AllocateJSIteratorResultForEntry(Node* context,
|
||||
return result;
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::TypedArraySpeciesCreateByLength(Node* context,
|
||||
Node* originalArray,
|
||||
Node* len) {
|
||||
// TODO(tebbi): Install a fast path as well, which avoids the runtime
|
||||
// call.
|
||||
return CallRuntime(Runtime::kTypedArraySpeciesCreateByLength, context,
|
||||
originalArray, len);
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsDetachedBuffer(Node* buffer) {
|
||||
CSA_ASSERT(this, HasInstanceType(buffer, JS_ARRAY_BUFFER_TYPE));
|
||||
|
||||
|
@ -836,9 +836,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
Node* AllocateJSIteratorResult(Node* context, Node* value, Node* done);
|
||||
Node* AllocateJSIteratorResultForEntry(Node* context, Node* key, Node* value);
|
||||
|
||||
Node* TypedArraySpeciesCreateByLength(Node* context, Node* originalArray,
|
||||
Node* len);
|
||||
|
||||
void FillFixedArrayWithValue(ElementsKind kind, Node* array, Node* from_index,
|
||||
Node* to_index,
|
||||
Heap::RootListIndex value_root_index,
|
||||
|
@ -16727,33 +16727,6 @@ MaybeHandle<JSTypedArray> JSTypedArray::Create(Isolate* isolate,
|
||||
return new_array;
|
||||
}
|
||||
|
||||
// static
|
||||
MaybeHandle<JSTypedArray> JSTypedArray::SpeciesCreate(
|
||||
Isolate* isolate, Handle<JSTypedArray> exemplar, int argc,
|
||||
Handle<Object>* argv, const char* method_name) {
|
||||
// 1. Assert: exemplar is an Object that has a [[TypedArrayName]] internal
|
||||
// slot.
|
||||
DCHECK(exemplar->IsJSTypedArray());
|
||||
|
||||
// 2. Let defaultConstructor be the intrinsic object listed in column one of
|
||||
// Table 51 for exemplar.[[TypedArrayName]].
|
||||
Handle<JSFunction> default_ctor =
|
||||
JSTypedArray::DefaultConstructor(isolate, exemplar);
|
||||
|
||||
// 3. Let constructor be ? SpeciesConstructor(exemplar, defaultConstructor).
|
||||
Handle<Object> ctor = default_ctor;
|
||||
if (!exemplar->HasJSTypedArrayPrototype(isolate) ||
|
||||
!isolate->IsSpeciesLookupChainIntact()) {
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, ctor,
|
||||
Object::SpeciesConstructor(isolate, exemplar, default_ctor),
|
||||
JSTypedArray);
|
||||
}
|
||||
|
||||
// 4. Return ? TypedArrayCreate(constructor, argumentList).
|
||||
return Create(isolate, ctor, argc, argv, method_name);
|
||||
}
|
||||
|
||||
void JSGlobalObject::InvalidatePropertyCell(Handle<JSGlobalObject> global,
|
||||
Handle<Name> name) {
|
||||
// Regardless of whether the property is there or not invalidate
|
||||
|
@ -310,11 +310,6 @@ class JSTypedArray : public JSArrayBufferView {
|
||||
Handle<Object> default_ctor, int argc,
|
||||
Handle<Object>* argv,
|
||||
const char* method_name);
|
||||
// ES7 section 22.2.4.7 TypedArraySpeciesCreate ( exemplar, argumentList )
|
||||
static MaybeHandle<JSTypedArray> SpeciesCreate(Isolate* isolate,
|
||||
Handle<JSTypedArray> exemplar,
|
||||
int argc, Handle<Object>* argv,
|
||||
const char* method_name);
|
||||
|
||||
// Dispatched behavior.
|
||||
DECL_PRINTER(JSTypedArray)
|
||||
|
@ -197,22 +197,6 @@ RUNTIME_FUNCTION(Runtime_IsSharedInteger32TypedArray) {
|
||||
obj->type() == kExternalInt32Array);
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_TypedArraySpeciesCreateByLength) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(args.length(), 2);
|
||||
Handle<JSTypedArray> exemplar = args.at<JSTypedArray>(0);
|
||||
Handle<Object> length = args.at(1);
|
||||
int argc = 1;
|
||||
ScopedVector<Handle<Object>> argv(argc);
|
||||
argv[0] = length;
|
||||
Handle<JSTypedArray> result_array;
|
||||
// TODO(tebbi): Pass correct method name.
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, result_array,
|
||||
JSTypedArray::SpeciesCreate(isolate, exemplar, argc, argv.start(), ""));
|
||||
return *result_array;
|
||||
}
|
||||
|
||||
// 22.2.3.23 %TypedArray%.prototype.set ( overloaded [ , offset ] )
|
||||
RUNTIME_FUNCTION(Runtime_TypedArraySet) {
|
||||
HandleScope scope(isolate);
|
||||
|
@ -645,8 +645,7 @@ namespace internal {
|
||||
F(IsTypedArray, 1, 1) \
|
||||
F(IsSharedTypedArray, 1, 1) \
|
||||
F(IsSharedIntegerTypedArray, 1, 1) \
|
||||
F(IsSharedInteger32TypedArray, 1, 1) \
|
||||
F(TypedArraySpeciesCreateByLength, 2, 1)
|
||||
F(IsSharedInteger32TypedArray, 1, 1)
|
||||
|
||||
#define FOR_EACH_INTRINSIC_WASM(F) \
|
||||
F(WasmGrowMemory, 1, 1) \
|
||||
|
Loading…
Reference in New Issue
Block a user