[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:
Peter Marshall 2018-02-07 11:40:30 +01:00 committed by Commit Bot
parent 54f1b2019b
commit a2aac98ddf
11 changed files with 134 additions and 169 deletions

View File

@ -1076,6 +1076,7 @@ v8_source_set("v8_initializers") {
"src/builtins/builtins-string-gen.h", "src/builtins/builtins-string-gen.h",
"src/builtins/builtins-symbol-gen.cc", "src/builtins/builtins-symbol-gen.cc",
"src/builtins/builtins-typedarray-gen.cc", "src/builtins/builtins-typedarray-gen.cc",
"src/builtins/builtins-typedarray-gen.h",
"src/builtins/builtins-utils-gen.h", "src/builtins/builtins-utils-gen.h",
"src/builtins/builtins-wasm-gen.cc", "src/builtins/builtins-wasm-gen.cc",
"src/builtins/growable-fixed-array-gen.cc", "src/builtins/growable-fixed-array-gen.cc",

View File

@ -193,6 +193,7 @@
'../src/builtins/builtins-string-gen.h', '../src/builtins/builtins-string-gen.h',
'../src/builtins/builtins-symbol-gen.cc', '../src/builtins/builtins-symbol-gen.cc',
'../src/builtins/builtins-typedarray-gen.cc', '../src/builtins/builtins-typedarray-gen.cc',
'../src/builtins/builtins-typedarray-gen.h',
'../src/builtins/builtins-utils-gen.h', '../src/builtins/builtins-utils-gen.h',
'../src/builtins/builtins-wasm-gen.cc', '../src/builtins/builtins-wasm-gen.cc',
'../src/builtins/growable-fixed-array-gen.cc', '../src/builtins/growable-fixed-array-gen.cc',

View File

@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "src/builtins/builtins-string-gen.h" #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-utils-gen.h"
#include "src/builtins/builtins.h" #include "src/builtins/builtins.h"
#include "src/code-stub-assembler.h" #include "src/code-stub-assembler.h"
@ -200,7 +201,13 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) {
void ArrayBuiltinsAssembler::TypedArrayMapResultGenerator() { void ArrayBuiltinsAssembler::TypedArrayMapResultGenerator() {
// 6. Let A be ? TypedArraySpeciesCreate(O, len). // 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 // In the Spec and our current implementation, the length check is already
// performed in TypedArraySpeciesCreate. // performed in TypedArraySpeciesCreate.
CSA_ASSERT(this, CSA_ASSERT(this,

View File

@ -2,12 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "src/builtins/builtins-typedarray-gen.h"
#include "src/builtins/builtins-constructor-gen.h" #include "src/builtins/builtins-constructor-gen.h"
#include "src/builtins/builtins-iterator-gen.h" #include "src/builtins/builtins-iterator-gen.h"
#include "src/builtins/builtins-utils-gen.h" #include "src/builtins/builtins-utils-gen.h"
#include "src/builtins/builtins.h" #include "src/builtins/builtins.h"
#include "src/builtins/growable-fixed-array-gen.h" #include "src/builtins/growable-fixed-array-gen.h"
#include "src/code-stub-assembler.h"
#include "src/handles-inl.h" #include "src/handles-inl.h"
namespace v8 { namespace v8 {
@ -26,111 +27,6 @@ using TNode = compiler::TNode<T>;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// ES6 section 22.2 TypedArray Objects // 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<Map> TypedArrayBuiltinsAssembler::LoadMapForType(
TNode<JSTypedArray> array) { TNode<JSTypedArray> array) {
TVARIABLE(Map, var_typed_map); TVARIABLE(Map, var_typed_map);

View 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_

View File

@ -10522,15 +10522,6 @@ Node* CodeStubAssembler::AllocateJSIteratorResultForEntry(Node* context,
return result; 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) { Node* CodeStubAssembler::IsDetachedBuffer(Node* buffer) {
CSA_ASSERT(this, HasInstanceType(buffer, JS_ARRAY_BUFFER_TYPE)); CSA_ASSERT(this, HasInstanceType(buffer, JS_ARRAY_BUFFER_TYPE));

View File

@ -836,9 +836,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* AllocateJSIteratorResult(Node* context, Node* value, Node* done); Node* AllocateJSIteratorResult(Node* context, Node* value, Node* done);
Node* AllocateJSIteratorResultForEntry(Node* context, Node* key, Node* value); 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, void FillFixedArrayWithValue(ElementsKind kind, Node* array, Node* from_index,
Node* to_index, Node* to_index,
Heap::RootListIndex value_root_index, Heap::RootListIndex value_root_index,

View File

@ -16727,33 +16727,6 @@ MaybeHandle<JSTypedArray> JSTypedArray::Create(Isolate* isolate,
return new_array; 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, void JSGlobalObject::InvalidatePropertyCell(Handle<JSGlobalObject> global,
Handle<Name> name) { Handle<Name> name) {
// Regardless of whether the property is there or not invalidate // Regardless of whether the property is there or not invalidate

View File

@ -310,11 +310,6 @@ class JSTypedArray : public JSArrayBufferView {
Handle<Object> default_ctor, int argc, Handle<Object> default_ctor, int argc,
Handle<Object>* argv, Handle<Object>* argv,
const char* method_name); 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. // Dispatched behavior.
DECL_PRINTER(JSTypedArray) DECL_PRINTER(JSTypedArray)

View File

@ -197,22 +197,6 @@ RUNTIME_FUNCTION(Runtime_IsSharedInteger32TypedArray) {
obj->type() == kExternalInt32Array); 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 ] ) // 22.2.3.23 %TypedArray%.prototype.set ( overloaded [ , offset ] )
RUNTIME_FUNCTION(Runtime_TypedArraySet) { RUNTIME_FUNCTION(Runtime_TypedArraySet) {
HandleScope scope(isolate); HandleScope scope(isolate);

View File

@ -645,8 +645,7 @@ namespace internal {
F(IsTypedArray, 1, 1) \ F(IsTypedArray, 1, 1) \
F(IsSharedTypedArray, 1, 1) \ F(IsSharedTypedArray, 1, 1) \
F(IsSharedIntegerTypedArray, 1, 1) \ F(IsSharedIntegerTypedArray, 1, 1) \
F(IsSharedInteger32TypedArray, 1, 1) \ F(IsSharedInteger32TypedArray, 1, 1)
F(TypedArraySpeciesCreateByLength, 2, 1)
#define FOR_EACH_INTRINSIC_WASM(F) \ #define FOR_EACH_INTRINSIC_WASM(F) \
F(WasmGrowMemory, 1, 1) \ F(WasmGrowMemory, 1, 1) \