Commit ff8b1abb authored by Peter Marshall's avatar Peter Marshall Committed by Commit Bot

[builtins] Reland of Port TypedArrayInitialize to CodeStubAssembler.

Turbofan is a lot slower than Crankshaft at constructing TypedArrays,
because we always go to the C++ builtin. Port the builtin to CSA
to improve performance, and to clean up the implementation, which is
split across multiple files and pieces at the moment.

This CL increases the performance with --future to roughly the same
as with crankshaft.

BUG=v8:5977

Change-Id: Id0d91a4592de41a3a308846d79bd44a608931762
Reviewed-on: https://chromium-review.googlesource.com/448537Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Commit-Queue: Peter Marshall <petermarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43548}
parent d7cb3cfc
...@@ -1546,6 +1546,14 @@ ExternalReference ExternalReference::libc_memchr_function(Isolate* isolate) { ...@@ -1546,6 +1546,14 @@ ExternalReference ExternalReference::libc_memchr_function(Isolate* isolate) {
return ExternalReference(Redirect(isolate, FUNCTION_ADDR(libc_memchr))); return ExternalReference(Redirect(isolate, FUNCTION_ADDR(libc_memchr)));
} }
void* libc_memset(void* string, int character, size_t n) {
return memset(string, character, n);
}
ExternalReference ExternalReference::libc_memset_function(Isolate* isolate) {
return ExternalReference(Redirect(isolate, FUNCTION_ADDR(libc_memset)));
}
ExternalReference ExternalReference::page_flags(Page* page) { ExternalReference ExternalReference::page_flags(Page* page) {
return ExternalReference(reinterpret_cast<Address>(page) + return ExternalReference(reinterpret_cast<Address>(page) +
MemoryChunk::kFlagsOffset); MemoryChunk::kFlagsOffset);
......
...@@ -978,6 +978,7 @@ class ExternalReference BASE_EMBEDDED { ...@@ -978,6 +978,7 @@ class ExternalReference BASE_EMBEDDED {
static ExternalReference ieee754_tanh_function(Isolate* isolate); static ExternalReference ieee754_tanh_function(Isolate* isolate);
static ExternalReference libc_memchr_function(Isolate* isolate); static ExternalReference libc_memchr_function(Isolate* isolate);
static ExternalReference libc_memset_function(Isolate* isolate);
static ExternalReference page_flags(Page* page); static ExternalReference page_flags(Page* page);
......
...@@ -2620,6 +2620,13 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, ...@@ -2620,6 +2620,13 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
} }
TYPED_ARRAYS(INSTALL_TYPED_ARRAY) TYPED_ARRAYS(INSTALL_TYPED_ARRAY)
#undef INSTALL_TYPED_ARRAY #undef INSTALL_TYPED_ARRAY
// %typed_array_initialize
Handle<JSFunction> typed_array_initialize = SimpleCreateFunction(
isolate, factory->NewStringFromAsciiChecked("typedArrayInitialize"),
Builtins::kTypedArrayInitialize, 6, false);
InstallWithIntrinsicDefaultProto(isolate, typed_array_initialize,
Context::TYPED_ARRAY_INITIALIZE_INDEX);
} }
{ // -- D a t a V i e w { // -- D a t a V i e w
......
This diff is collapsed.
...@@ -805,6 +805,7 @@ class Isolate; ...@@ -805,6 +805,7 @@ class Isolate;
TFJ(SymbolPrototypeValueOf, 0) \ TFJ(SymbolPrototypeValueOf, 0) \
\ \
/* TypedArray */ \ /* TypedArray */ \
TFJ(TypedArrayInitialize, 6) \
CPP(TypedArrayPrototypeBuffer) \ CPP(TypedArrayPrototypeBuffer) \
/* ES6 section 22.2.3.2 get %TypedArray%.prototype.byteLength */ \ /* ES6 section 22.2.3.2 get %TypedArray%.prototype.byteLength */ \
TFJ(TypedArrayPrototypeByteLength, 0) \ TFJ(TypedArrayPrototypeByteLength, 0) \
......
...@@ -68,6 +68,7 @@ enum ContextLookupFlags { ...@@ -68,6 +68,7 @@ enum ContextLookupFlags {
V(REFLECT_DELETE_PROPERTY_INDEX, JSFunction, reflect_delete_property) \ V(REFLECT_DELETE_PROPERTY_INDEX, JSFunction, reflect_delete_property) \
V(SPREAD_ARGUMENTS_INDEX, JSFunction, spread_arguments) \ V(SPREAD_ARGUMENTS_INDEX, JSFunction, spread_arguments) \
V(SPREAD_ITERABLE_INDEX, JSFunction, spread_iterable) \ V(SPREAD_ITERABLE_INDEX, JSFunction, spread_iterable) \
V(TYPED_ARRAY_INITIALIZE_INDEX, JSFunction, typed_array_initialize) \
V(MATH_FLOOR_INDEX, JSFunction, math_floor) \ V(MATH_FLOOR_INDEX, JSFunction, math_floor) \
V(MATH_POW_INDEX, JSFunction, math_pow) \ V(MATH_POW_INDEX, JSFunction, math_pow) \
V(NEW_PROMISE_CAPABILITY_INDEX, JSFunction, new_promise_capability) \ V(NEW_PROMISE_CAPABILITY_INDEX, JSFunction, new_promise_capability) \
......
...@@ -233,6 +233,8 @@ void ExternalReferenceTable::AddReferences(Isolate* isolate) { ...@@ -233,6 +233,8 @@ void ExternalReferenceTable::AddReferences(Isolate* isolate) {
"wasm::call_trap_callback_for_testing"); "wasm::call_trap_callback_for_testing");
Add(ExternalReference::libc_memchr_function(isolate).address(), Add(ExternalReference::libc_memchr_function(isolate).address(),
"libc_memchr"); "libc_memchr");
Add(ExternalReference::libc_memset_function(isolate).address(),
"libc_memset");
Add(ExternalReference::log_enter_external_function(isolate).address(), Add(ExternalReference::log_enter_external_function(isolate).address(),
"Logger::EnterExternal"); "Logger::EnterExternal");
Add(ExternalReference::log_leave_external_function(isolate).address(), Add(ExternalReference::log_leave_external_function(isolate).address(),
......
...@@ -2017,23 +2017,20 @@ Handle<JSSetIterator> Factory::NewJSSetIterator() { ...@@ -2017,23 +2017,20 @@ Handle<JSSetIterator> Factory::NewJSSetIterator() {
JSSetIterator); JSSetIterator);
} }
ExternalArrayType Factory::GetArrayTypeFromElementsKind(ElementsKind kind) {
namespace { switch (kind) {
ElementsKind GetExternalArrayElementsKind(ExternalArrayType type) {
switch (type) {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
case kExternal##Type##Array: \ case TYPE##_ELEMENTS: \
return TYPE##_ELEMENTS; return kExternal##Type##Array;
TYPED_ARRAYS(TYPED_ARRAY_CASE) TYPED_ARRAYS(TYPED_ARRAY_CASE)
default:
UNREACHABLE();
return kExternalInt8Array;
} }
UNREACHABLE();
return FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND;
#undef TYPED_ARRAY_CASE #undef TYPED_ARRAY_CASE
} }
size_t Factory::GetExternalArrayElementSize(ExternalArrayType type) {
size_t GetExternalArrayElementSize(ExternalArrayType type) {
switch (type) { switch (type) {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
case kExternal##Type##Array: \ case kExternal##Type##Array: \
...@@ -2046,30 +2043,29 @@ size_t GetExternalArrayElementSize(ExternalArrayType type) { ...@@ -2046,30 +2043,29 @@ size_t GetExternalArrayElementSize(ExternalArrayType type) {
#undef TYPED_ARRAY_CASE #undef TYPED_ARRAY_CASE
} }
namespace {
size_t GetFixedTypedArraysElementSize(ElementsKind kind) { ElementsKind GetExternalArrayElementsKind(ExternalArrayType type) {
switch (kind) { switch (type) {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
case TYPE##_ELEMENTS: \ case kExternal##Type##Array: \
return size; return TYPE##_ELEMENTS;
TYPED_ARRAYS(TYPED_ARRAY_CASE) TYPED_ARRAYS(TYPED_ARRAY_CASE)
default:
UNREACHABLE();
return 0;
} }
UNREACHABLE();
return FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND;
#undef TYPED_ARRAY_CASE #undef TYPED_ARRAY_CASE
} }
size_t GetFixedTypedArraysElementSize(ElementsKind kind) {
ExternalArrayType GetArrayTypeFromElementsKind(ElementsKind kind) {
switch (kind) { switch (kind) {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
case TYPE##_ELEMENTS: \ case TYPE##_ELEMENTS: \
return kExternal##Type##Array; return size;
TYPED_ARRAYS(TYPED_ARRAY_CASE) TYPED_ARRAYS(TYPED_ARRAY_CASE)
default: default:
UNREACHABLE(); UNREACHABLE();
return kExternalInt8Array; return 0;
} }
#undef TYPED_ARRAY_CASE #undef TYPED_ARRAY_CASE
} }
......
...@@ -536,6 +536,9 @@ class V8_EXPORT_PRIVATE Factory final { ...@@ -536,6 +536,9 @@ class V8_EXPORT_PRIVATE Factory final {
SharedFlag shared = SharedFlag::kNotShared, SharedFlag shared = SharedFlag::kNotShared,
PretenureFlag pretenure = NOT_TENURED); PretenureFlag pretenure = NOT_TENURED);
ExternalArrayType GetArrayTypeFromElementsKind(ElementsKind kind);
size_t GetExternalArrayElementSize(ExternalArrayType type);
Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type, Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type,
PretenureFlag pretenure = NOT_TENURED); PretenureFlag pretenure = NOT_TENURED);
......
...@@ -169,13 +169,14 @@ function NAMEConstructByArrayBuffer(obj, buffer, byteOffset, length) { ...@@ -169,13 +169,14 @@ function NAMEConstructByArrayBuffer(obj, buffer, byteOffset, length) {
throw %make_range_error(kInvalidTypedArrayLength); throw %make_range_error(kInvalidTypedArrayLength);
} }
} }
%_TypedArrayInitialize(obj, ARRAY_ID, buffer, offset, newByteLength, true); var newLength = newByteLength / ELEMENT_SIZE;
%typed_array_initialize(obj, newLength, buffer, offset, newByteLength, true);
} }
function NAMEConstructByLength(obj, length) { function NAMEConstructByLength(obj, length) {
var l = IS_UNDEFINED(length) ? var l = IS_UNDEFINED(length) ?
0 : ToIndex(length, kInvalidTypedArrayLength); 0 : ToIndex(length, kInvalidTypedArrayLength);
if (length > %_MaxSmi()) { if (l > %_MaxSmi()) {
// Note: this is not per spec, but rather a constraint of our current // Note: this is not per spec, but rather a constraint of our current
// representation (which uses smi's). // representation (which uses smi's).
throw %make_range_error(kInvalidTypedArrayLength); throw %make_range_error(kInvalidTypedArrayLength);
...@@ -183,9 +184,9 @@ function NAMEConstructByLength(obj, length) { ...@@ -183,9 +184,9 @@ function NAMEConstructByLength(obj, length) {
var byteLength = l * ELEMENT_SIZE; var byteLength = l * ELEMENT_SIZE;
if (byteLength > %_TypedArrayMaxSizeInHeap()) { if (byteLength > %_TypedArrayMaxSizeInHeap()) {
var buffer = new GlobalArrayBuffer(byteLength); var buffer = new GlobalArrayBuffer(byteLength);
%_TypedArrayInitialize(obj, ARRAY_ID, buffer, 0, byteLength, true); %typed_array_initialize(obj, l, buffer, 0, byteLength, true);
} else { } else {
%_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength, true); %typed_array_initialize(obj, l, null, 0, byteLength, true);
} }
} }
...@@ -198,7 +199,7 @@ function NAMEConstructByArrayLike(obj, arrayLike, length) { ...@@ -198,7 +199,7 @@ function NAMEConstructByArrayLike(obj, arrayLike, length) {
var initialized = false; var initialized = false;
var byteLength = l * ELEMENT_SIZE; var byteLength = l * ELEMENT_SIZE;
if (byteLength <= %_TypedArrayMaxSizeInHeap()) { if (byteLength <= %_TypedArrayMaxSizeInHeap()) {
%_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength, false); %typed_array_initialize(obj, l, null, 0, byteLength, false);
} else { } else {
initialized = initialized =
%TypedArrayInitializeFromArrayLike(obj, ARRAY_ID, arrayLike, l); %TypedArrayInitializeFromArrayLike(obj, ARRAY_ID, arrayLike, l);
......
...@@ -822,3 +822,12 @@ function TestNonConfigurableProperties(constructor) { ...@@ -822,3 +822,12 @@ function TestNonConfigurableProperties(constructor) {
for(i = 0; i < typedArrayConstructors.length; i++) { for(i = 0; i < typedArrayConstructors.length; i++) {
TestNonConfigurableProperties(typedArrayConstructors[i]); TestNonConfigurableProperties(typedArrayConstructors[i]);
} }
(function TestInitialization() {
for (var i = 0; i <= 128; i++) {
var arr = new Uint8Array(i);
for (var j = 0; j < i; j++) {
assertEquals(0, arr[j]);
}
}
})();
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