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

Revert "[builtins] Port TypedArrayInitialize to CodeStubAssembler."

This reverts commit b23b2c10.

Reason for revert: Makes Linux debug bot sad

Original change's description:
> [builtins] 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: I5a4c4b544a735a56290b85bf33c2f3718df7e2b8
> Reviewed-on: https://chromium-review.googlesource.com/445717
> Commit-Queue: Peter Marshall <petermarshall@chromium.org>
> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
> Reviewed-by: Camillo Bruni <cbruni@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#43518}

TBR=cbruni@chromium.org,petermarshall@chromium.org,bmeurer@chromium.org,v8-reviews@googlegroups.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:5977

Change-Id: I5d5bc8b4677a405c716d78e688af80ae9c737b4a
Reviewed-on: https://chromium-review.googlesource.com/448558Reviewed-by: 's avatarPeter Marshall <petermarshall@chromium.org>
Commit-Queue: Peter Marshall <petermarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43520}
parent c45d065e
......@@ -1546,14 +1546,6 @@ ExternalReference ExternalReference::libc_memchr_function(Isolate* isolate) {
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) {
return ExternalReference(reinterpret_cast<Address>(page) +
MemoryChunk::kFlagsOffset);
......
......@@ -978,7 +978,6 @@ class ExternalReference BASE_EMBEDDED {
static ExternalReference ieee754_tanh_function(Isolate* isolate);
static ExternalReference libc_memchr_function(Isolate* isolate);
static ExternalReference libc_memset_function(Isolate* isolate);
static ExternalReference page_flags(Page* page);
......
......@@ -2620,13 +2620,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
}
TYPED_ARRAYS(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
......
......@@ -21,235 +21,8 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
int object_offset);
template <IterationKind kIterationKind>
void GenerateTypedArrayPrototypeIterationMethod(const char* method_name);
void LoadMapAndElementsSize(Node* array, Variable* typed_map, Variable* size);
};
void TypedArrayBuiltinsAssembler::LoadMapAndElementsSize(Node* array,
Variable* typed_map,
Variable* size) {
Label unreachable(this), done(this);
Label uint8_elements(this), uint8_clamped_elements(this), int8_elements(this),
uint16_elements(this), int16_elements(this), uint32_elements(this),
int32_elements(this), float32_elements(this), float64_elements(this);
Label* elements_kind_labels[] = {
&uint8_elements, &uint8_clamped_elements, &int8_elements,
&uint16_elements, &int16_elements, &uint32_elements,
&int32_elements, &float32_elements, &float64_elements};
int32_t elements_kinds[] = {
UINT8_ELEMENTS, UINT8_CLAMPED_ELEMENTS, INT8_ELEMENTS,
UINT16_ELEMENTS, INT16_ELEMENTS, UINT32_ELEMENTS,
INT32_ELEMENTS, FLOAT32_ELEMENTS, FLOAT64_ELEMENTS};
const size_t kTypedElementsKindCount = LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND -
FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND +
1;
DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kinds));
DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kind_labels));
Node* array_map = LoadMap(array);
Node* elements_kind = LoadMapElementsKind(array_map);
Switch(elements_kind, &unreachable, elements_kinds, elements_kind_labels,
kTypedElementsKindCount);
for (int i = 0; i < static_cast<int>(kTypedElementsKindCount); i++) {
Bind(elements_kind_labels[i]);
{
ElementsKind kind = static_cast<ElementsKind>(elements_kinds[i]);
ExternalArrayType type =
isolate()->factory()->GetArrayTypeFromElementsKind(kind);
Handle<Map> map(isolate()->heap()->MapForFixedTypedArray(type));
typed_map->Bind(HeapConstant(map));
size->Bind(SmiConstant(static_cast<int>(
isolate()->factory()->GetExternalArrayElementSize(type))));
Goto(&done);
}
}
Bind(&unreachable);
{ Unreachable(); }
Bind(&done);
}
TF_BUILTIN(TypedArrayInitialize, TypedArrayBuiltinsAssembler) {
Node* holder = Parameter(1);
Node* length = Parameter(2);
Node* maybe_buffer = Parameter(3);
Node* byte_offset = Parameter(4);
Node* byte_length = Parameter(5);
Node* initialize = Parameter(6);
Node* context = Parameter(9);
static const int32_t fta_base_data_offset =
FixedTypedArrayBase::kDataOffset - kHeapObjectTag;
Label setup_holder(this), alloc_array_buffer(this), aligned(this),
allocate_elements(this), attach_buffer(this), done(this);
Variable fixed_typed_map(this, MachineRepresentation::kTagged);
Variable element_size(this, MachineRepresentation::kTagged);
Variable total_size(this, MachineType::PointerRepresentation());
// Make sure length is a Smi. The caller guarantees this is the case.
length = ToInteger(context, length, CodeStubAssembler::kTruncateMinusZero);
CSA_ASSERT(this, TaggedIsSmi(length));
byte_offset =
ToInteger(context, byte_offset, CodeStubAssembler::kTruncateMinusZero);
CSA_ASSERT(this, TaggedIsSmi(byte_offset));
// byte_length can be -0, get rid of it.
byte_length =
ToInteger(context, byte_length, CodeStubAssembler::kTruncateMinusZero);
GotoIfNot(IsNull(maybe_buffer), &setup_holder);
// If the buffer is null, then we need a Smi byte_length. The caller
// guarantees this is the case, because when byte_length >
// TypedArrayMaxSizeInHeap, a buffer is allocated and passed in here.
CSA_ASSERT(this, TaggedIsSmi(byte_length));
Goto(&setup_holder);
Bind(&setup_holder);
{
LoadMapAndElementsSize(holder, &fixed_typed_map, &element_size);
// Setup the holder (JSArrayBufferView).
// - Set the length.
// - Set the byte_offset.
// - Set the byte_length.
// - Set InternalFields to 0.
StoreObjectFieldNoWriteBarrier(holder, JSTypedArray::kLengthOffset, length);
StoreObjectFieldNoWriteBarrier(holder, JSArrayBufferView::kByteOffsetOffset,
byte_offset);
StoreObjectFieldNoWriteBarrier(holder, JSArrayBufferView::kByteLengthOffset,
byte_length);
for (int offset = JSTypedArray::kSize;
offset < JSTypedArray::kSizeWithInternalFields;
offset += kPointerSize) {
StoreObjectFieldNoWriteBarrier(holder, offset, SmiConstant(Smi::kZero));
}
Branch(IsNull(maybe_buffer), &alloc_array_buffer, &attach_buffer);
}
Bind(&alloc_array_buffer);
{
// Allocate a new ArrayBuffer and initialize it with empty properties and
// elements.
Node* const native_context = LoadNativeContext(context);
Node* const map =
LoadContextElement(native_context, Context::ARRAY_BUFFER_MAP_INDEX);
Node* empty_fixed_array = LoadRoot(Heap::kEmptyFixedArrayRootIndex);
Node* buffer = Allocate(JSArrayBuffer::kSizeWithInternalFields);
StoreMapNoWriteBarrier(buffer, map);
StoreObjectFieldNoWriteBarrier(buffer, JSArray::kPropertiesOffset,
empty_fixed_array);
StoreObjectFieldNoWriteBarrier(buffer, JSArray::kElementsOffset,
empty_fixed_array);
// Setup the ArrayBuffer.
// - Set BitField to 0.
// - Set IsExternal and IsNeuterable bits of BitFieldSlot.
// - Set the byte_length field to byte_length.
// - Set backing_store to null/Smi(0).
// - Set all internal fields to Smi(0).
StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kBitFieldSlot,
SmiConstant(Smi::kZero));
int32_t bitfield_value = (1 << JSArrayBuffer::IsExternal::kShift) |
(1 << JSArrayBuffer::IsNeuterable::kShift);
StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kBitFieldOffset,
Int32Constant(bitfield_value),
MachineRepresentation::kWord32);
StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kByteLengthOffset,
byte_length);
StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kBackingStoreOffset,
SmiConstant(Smi::kZero));
for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
int offset = JSArrayBuffer::kSize + i * kPointerSize;
StoreObjectFieldNoWriteBarrier(buffer, offset, SmiConstant(Smi::kZero));
}
StoreObjectFieldNoWriteBarrier(holder, JSArrayBufferView::kBufferOffset,
buffer);
// Check the alignment.
GotoIf(SmiEqual(SmiMod(element_size.value(), SmiConstant(kObjectAlignment)),
SmiConstant(0)),
&aligned);
// Fix alignment if needed.
DCHECK_EQ(0, FixedTypedArrayBase::kHeaderSize & kObjectAlignmentMask);
Node* aligned_header_size =
IntPtrConstant(FixedTypedArrayBase::kHeaderSize + kObjectAlignmentMask);
Node* size = IntPtrAdd(SmiToWord(byte_length), aligned_header_size);
total_size.Bind(WordAnd(size, IntPtrConstant(~kObjectAlignmentMask)));
Goto(&allocate_elements);
}
Bind(&aligned);
{
Node* header_size = IntPtrConstant(FixedTypedArrayBase::kHeaderSize);
total_size.Bind(IntPtrAdd(SmiToWord(byte_length), header_size));
Goto(&allocate_elements);
}
Bind(&allocate_elements);
{
// Allocate a FixedTypedArray and set the length, base pointer and external
// pointer.
CSA_ASSERT(this, IsRegularHeapObjectSize(total_size.value()));
Node* elements = Allocate(total_size.value());
StoreMapNoWriteBarrier(elements, fixed_typed_map.value());
StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, length);
StoreObjectFieldNoWriteBarrier(
elements, FixedTypedArrayBase::kBasePointerOffset, elements);
StoreObjectFieldNoWriteBarrier(elements,
FixedTypedArrayBase::kExternalPointerOffset,
IntPtrConstant(fta_base_data_offset),
MachineType::PointerRepresentation());
StoreObjectFieldNoWriteBarrier(holder, JSObject::kElementsOffset, elements);
GotoIf(IsFalse(initialize), &done);
// Initialize the backing store by filling it with 0s.
Node* backing_store = IntPtrAdd(BitcastTaggedToWord(elements),
IntPtrConstant(fta_base_data_offset));
// Call out to memset to perform initialization.
Node* memset =
ExternalConstant(ExternalReference::libc_memset_function(isolate()));
CallCFunction3(MachineType::AnyTagged(), MachineType::Pointer(),
MachineType::IntPtr(), MachineType::UintPtr(), memset,
backing_store, IntPtrConstant(0), SmiToWord(byte_length));
Goto(&done);
}
Bind(&attach_buffer);
{
StoreObjectFieldNoWriteBarrier(holder, JSArrayBufferView::kBufferOffset,
maybe_buffer);
Node* elements = Allocate(FixedTypedArrayBase::kHeaderSize);
StoreMapNoWriteBarrier(elements, fixed_typed_map.value());
StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, length);
StoreObjectFieldNoWriteBarrier(
elements, FixedTypedArrayBase::kBasePointerOffset, SmiConstant(0));
Node* backing_store =
LoadObjectField(maybe_buffer, JSArrayBuffer::kBackingStoreOffset,
MachineType::Pointer());
Node* external_pointer = IntPtrAdd(backing_store, SmiToWord(byte_offset));
StoreObjectFieldNoWriteBarrier(
elements, FixedTypedArrayBase::kExternalPointerOffset, external_pointer,
MachineType::PointerRepresentation());
StoreObjectFieldNoWriteBarrier(holder, JSObject::kElementsOffset, elements);
Goto(&done);
}
Bind(&done);
{ Return(UndefinedConstant()); }
}
// -----------------------------------------------------------------------------
// ES6 section 22.2 TypedArray Objects
......
......@@ -805,7 +805,6 @@ class Isolate;
TFJ(SymbolPrototypeValueOf, 0) \
\
/* TypedArray */ \
TFJ(TypedArrayInitialize, 6) \
CPP(TypedArrayPrototypeBuffer) \
/* ES6 section 22.2.3.2 get %TypedArray%.prototype.byteLength */ \
TFJ(TypedArrayPrototypeByteLength, 0) \
......
......@@ -68,7 +68,6 @@ enum ContextLookupFlags {
V(REFLECT_DELETE_PROPERTY_INDEX, JSFunction, reflect_delete_property) \
V(SPREAD_ARGUMENTS_INDEX, JSFunction, spread_arguments) \
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_POW_INDEX, JSFunction, math_pow) \
V(NEW_PROMISE_CAPABILITY_INDEX, JSFunction, new_promise_capability) \
......
......@@ -233,8 +233,6 @@ void ExternalReferenceTable::AddReferences(Isolate* isolate) {
"wasm::call_trap_callback_for_testing");
Add(ExternalReference::libc_memchr_function(isolate).address(),
"libc_memchr");
Add(ExternalReference::libc_memset_function(isolate).address(),
"libc_memset");
Add(ExternalReference::log_enter_external_function(isolate).address(),
"Logger::EnterExternal");
Add(ExternalReference::log_leave_external_function(isolate).address(),
......
......@@ -2017,20 +2017,23 @@ Handle<JSSetIterator> Factory::NewJSSetIterator() {
JSSetIterator);
}
ExternalArrayType Factory::GetArrayTypeFromElementsKind(ElementsKind kind) {
switch (kind) {
namespace {
ElementsKind GetExternalArrayElementsKind(ExternalArrayType type) {
switch (type) {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
case TYPE##_ELEMENTS: \
return kExternal##Type##Array;
case kExternal##Type##Array: \
return TYPE##_ELEMENTS;
TYPED_ARRAYS(TYPED_ARRAY_CASE)
default:
UNREACHABLE();
return kExternalInt8Array;
}
UNREACHABLE();
return FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND;
#undef TYPED_ARRAY_CASE
}
size_t Factory::GetExternalArrayElementSize(ExternalArrayType type) {
size_t GetExternalArrayElementSize(ExternalArrayType type) {
switch (type) {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
case kExternal##Type##Array: \
......@@ -2043,29 +2046,30 @@ size_t Factory::GetExternalArrayElementSize(ExternalArrayType type) {
#undef TYPED_ARRAY_CASE
}
namespace {
ElementsKind GetExternalArrayElementsKind(ExternalArrayType type) {
switch (type) {
size_t GetFixedTypedArraysElementSize(ElementsKind kind) {
switch (kind) {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
case kExternal##Type##Array: \
return TYPE##_ELEMENTS;
case TYPE##_ELEMENTS: \
return size;
TYPED_ARRAYS(TYPED_ARRAY_CASE)
}
default:
UNREACHABLE();
return FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND;
return 0;
}
#undef TYPED_ARRAY_CASE
}
size_t GetFixedTypedArraysElementSize(ElementsKind kind) {
ExternalArrayType GetArrayTypeFromElementsKind(ElementsKind kind) {
switch (kind) {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
case TYPE##_ELEMENTS: \
return size;
return kExternal##Type##Array;
TYPED_ARRAYS(TYPED_ARRAY_CASE)
default:
UNREACHABLE();
return 0;
return kExternalInt8Array;
}
#undef TYPED_ARRAY_CASE
}
......
......@@ -536,9 +536,6 @@ class V8_EXPORT_PRIVATE Factory final {
SharedFlag shared = SharedFlag::kNotShared,
PretenureFlag pretenure = NOT_TENURED);
ExternalArrayType GetArrayTypeFromElementsKind(ElementsKind kind);
size_t GetExternalArrayElementSize(ExternalArrayType type);
Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type,
PretenureFlag pretenure = NOT_TENURED);
......
......@@ -169,14 +169,13 @@ function NAMEConstructByArrayBuffer(obj, buffer, byteOffset, length) {
throw %make_range_error(kInvalidTypedArrayLength);
}
}
var newLength = newByteLength / ELEMENT_SIZE;
%typed_array_initialize(obj, newLength, buffer, offset, newByteLength, true);
%_TypedArrayInitialize(obj, ARRAY_ID, buffer, offset, newByteLength, true);
}
function NAMEConstructByLength(obj, length) {
var l = IS_UNDEFINED(length) ?
0 : ToIndex(length, kInvalidTypedArrayLength);
if (l > %_MaxSmi()) {
if (length > %_MaxSmi()) {
// Note: this is not per spec, but rather a constraint of our current
// representation (which uses smi's).
throw %make_range_error(kInvalidTypedArrayLength);
......@@ -184,9 +183,9 @@ function NAMEConstructByLength(obj, length) {
var byteLength = l * ELEMENT_SIZE;
if (byteLength > %_TypedArrayMaxSizeInHeap()) {
var buffer = new GlobalArrayBuffer(byteLength);
%typed_array_initialize(obj, l, buffer, 0, byteLength, true);
%_TypedArrayInitialize(obj, ARRAY_ID, buffer, 0, byteLength, true);
} else {
%typed_array_initialize(obj, l, null, 0, byteLength, true);
%_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength, true);
}
}
......@@ -199,7 +198,7 @@ function NAMEConstructByArrayLike(obj, arrayLike, length) {
var initialized = false;
var byteLength = l * ELEMENT_SIZE;
if (byteLength <= %_TypedArrayMaxSizeInHeap()) {
%typed_array_initialize(obj, l, null, 0, byteLength, false);
%_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength, false);
} else {
initialized =
%TypedArrayInitializeFromArrayLike(obj, ARRAY_ID, arrayLike, l);
......
......@@ -822,12 +822,3 @@ function TestNonConfigurableProperties(constructor) {
for(i = 0; i < typedArrayConstructors.length; 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