Commit 1d1df96d authored by jochen's avatar jochen Committed by Commit bot

Also allocate small typed arrays on heap when initialized from an array-like

This means something like new Float32Array([23, 42]) will be allocated on heap.

BUG=v8:3996
R=bmeurer@chromium.org,mstarzinger@chromium.org
LOG=y

Review URL: https://codereview.chromium.org/1144393003

Cr-Commit-Position: refs/heads/master@{#28780}
parent 251816ab
......@@ -917,16 +917,12 @@ Handle<ExternalArray> Factory::NewExternalArray(int length,
Handle<FixedTypedArrayBase> Factory::NewFixedTypedArray(
int length,
ExternalArrayType array_type,
int length, ExternalArrayType array_type, bool initialize,
PretenureFlag pretenure) {
DCHECK(0 <= length && length <= Smi::kMaxValue);
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateFixedTypedArray(length,
array_type,
pretenure),
FixedTypedArrayBase);
CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateFixedTypedArray(
length, array_type, initialize, pretenure),
FixedTypedArrayBase);
}
......@@ -1965,7 +1961,7 @@ Handle<JSTypedArray> Factory::NewJSTypedArray(ElementsKind elements_kind,
obj->set_buffer(*buffer);
Handle<FixedTypedArrayBase> elements =
isolate()->factory()->NewFixedTypedArray(
static_cast<int>(number_of_elements), array_type);
static_cast<int>(number_of_elements), array_type, true);
obj->set_elements(*elements);
return obj;
}
......
......@@ -298,8 +298,7 @@ class Factory final {
PretenureFlag pretenure = NOT_TENURED);
Handle<FixedTypedArrayBase> NewFixedTypedArray(
int length,
ExternalArrayType array_type,
int length, ExternalArrayType array_type, bool initialize,
PretenureFlag pretenure = NOT_TENURED);
Handle<Cell> NewCell(Handle<Object> value);
......
......@@ -3735,6 +3735,7 @@ static void ForFixedTypedArray(ExternalArrayType array_type, int* element_size,
AllocationResult Heap::AllocateFixedTypedArray(int length,
ExternalArrayType array_type,
bool initialize,
PretenureFlag pretenure) {
int element_size;
ElementsKind elements_kind;
......@@ -3752,7 +3753,7 @@ AllocationResult Heap::AllocateFixedTypedArray(int length,
object->set_map(MapForFixedTypedArray(array_type));
FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(object);
elements->set_length(length);
memset(elements->DataPtr(), 0, elements->DataSize());
if (initialize) memset(elements->DataPtr(), 0, elements->DataSize());
return elements;
}
......@@ -4322,7 +4323,7 @@ AllocationResult Heap::CopyAndTenureFixedCOWArray(FixedArray* src) {
AllocationResult Heap::AllocateEmptyFixedTypedArray(
ExternalArrayType array_type) {
return AllocateFixedTypedArray(0, array_type, TENURED);
return AllocateFixedTypedArray(0, array_type, false, TENURED);
}
......
......@@ -1999,8 +1999,8 @@ class Heap {
// Allocates a fixed typed array of the specified length and type.
MUST_USE_RESULT AllocationResult
AllocateFixedTypedArray(int length, ExternalArrayType array_type,
PretenureFlag pretenure);
AllocateFixedTypedArray(int length, ExternalArrayType array_type,
bool initialize, PretenureFlag pretenure);
// Make a copy of src and return it.
MUST_USE_RESULT AllocationResult CopyAndTenureFixedCOWArray(FixedArray* src);
......
......@@ -9874,8 +9874,8 @@ HValue* HOptimizedGraphBuilder::BuildAllocateExternalElements(
HValue* HOptimizedGraphBuilder::BuildAllocateFixedTypedArray(
ExternalArrayType array_type, size_t element_size,
ElementsKind fixed_elements_kind,
HValue* byte_length, HValue* length) {
ElementsKind fixed_elements_kind, HValue* byte_length, HValue* length,
bool initialize) {
STATIC_ASSERT(
(FixedTypedArrayBase::kHeaderSize & kObjectAlignmentMask) == 0);
HValue* total_size;
......@@ -9914,7 +9914,7 @@ HValue* HOptimizedGraphBuilder::BuildAllocateFixedTypedArray(
HValue* filler = Add<HConstant>(static_cast<int32_t>(0));
{
if (initialize) {
LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement);
HValue* key = builder.BeginBody(
......@@ -9937,7 +9937,8 @@ void HOptimizedGraphBuilder::GenerateTypedArrayInitialize(
static const int kBufferArg = 2;
static const int kByteOffsetArg = 3;
static const int kByteLengthArg = 4;
static const int kArgsLength = 5;
static const int kInitializeArg = 5;
static const int kArgsLength = 6;
DCHECK(arguments->length() == kArgsLength);
......@@ -9986,6 +9987,11 @@ void HOptimizedGraphBuilder::GenerateTypedArrayInitialize(
CHECK_ALIVE(VisitForValue(arguments->at(kByteLengthArg)));
HValue* byte_length = Pop();
CHECK(arguments->at(kInitializeArg)->IsLiteral());
bool initialize = static_cast<Literal*>(arguments->at(kInitializeArg))
->value()
->BooleanValue();
NoObservableSideEffectsScope scope(this);
IfBuilder byte_offset_smi(this);
......@@ -10033,9 +10039,9 @@ void HOptimizedGraphBuilder::GenerateTypedArrayInitialize(
AddStoreMapConstant(obj, obj_map);
} else {
DCHECK(is_zero_byte_offset);
elements = BuildAllocateFixedTypedArray(
array_type, element_size, fixed_elements_kind,
byte_length, length);
elements = BuildAllocateFixedTypedArray(array_type, element_size,
fixed_elements_kind, byte_length,
length, initialize);
}
Add<HStoreNamedField>(
obj, HObjectAccess::ForElementsPointer(), elements);
......@@ -10049,6 +10055,7 @@ void HOptimizedGraphBuilder::GenerateTypedArrayInitialize(
Push(buffer);
Push(byte_offset);
Push(byte_length);
CHECK_ALIVE(VisitForValue(arguments->at(kInitializeArg)));
PushArgumentsFromEnvironment(kArgsLength);
Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength);
}
......
......@@ -2466,10 +2466,11 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
ExternalArrayType array_type,
bool is_zero_byte_offset,
HValue* buffer, HValue* byte_offset, HValue* length);
HValue* BuildAllocateFixedTypedArray(
ExternalArrayType array_type, size_t element_size,
ElementsKind fixed_elements_kind,
HValue* byte_length, HValue* length);
HValue* BuildAllocateFixedTypedArray(ExternalArrayType array_type,
size_t element_size,
ElementsKind fixed_elements_kind,
HValue* byte_length, HValue* length,
bool initialize);
// TODO(adamk): Move all OrderedHashTable functions to their own class.
HValue* BuildOrderedHashTableHashToBucket(HValue* hash, HValue* num_buckets);
......
......@@ -21,8 +21,8 @@ Handle<LayoutDescriptor> LayoutDescriptor::New(Isolate* isolate, int length) {
return handle(LayoutDescriptor::FromSmi(Smi::FromInt(0)), isolate);
}
length = GetSlowModeBackingStoreLength(length);
return Handle<LayoutDescriptor>::cast(
isolate->factory()->NewFixedTypedArray(length, kExternalUint32Array));
return Handle<LayoutDescriptor>::cast(isolate->factory()->NewFixedTypedArray(
length, kExternalUint32Array, true));
}
......
......@@ -180,12 +180,13 @@ void Runtime::ArrayIdToTypeAndSize(int arrayId, ExternalArrayType* array_type,
RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
HandleScope scope(isolate);
DCHECK(args.length() == 5);
DCHECK(args.length() == 6);
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
CONVERT_SMI_ARG_CHECKED(arrayId, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
CONVERT_BOOLEAN_ARG_CHECKED(initialize, 5);
RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
arrayId <= Runtime::ARRAY_ID_LAST);
......@@ -252,7 +253,7 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
holder->set_buffer(*buffer);
Handle<FixedTypedArrayBase> elements =
isolate->factory()->NewFixedTypedArray(static_cast<int>(length),
array_type);
array_type, initialize);
holder->set_elements(*elements);
}
return isolate->heap()->undefined_value();
......
......@@ -644,7 +644,7 @@ namespace internal {
F(ArrayBufferSliceImpl, 3, 1) \
F(ArrayBufferIsView, 1, 1) \
F(ArrayBufferNeuter, 1, 1) \
F(TypedArrayInitialize, 5, 1) \
F(TypedArrayInitialize, 6, 1) \
F(TypedArrayInitializeFromArrayLike, 4, 1) \
F(ArrayBufferViewGetByteLength, 1, 1) \
F(ArrayBufferViewGetByteOffset, 1, 1) \
......
......@@ -88,7 +88,7 @@ function NAMEConstructByArrayBuffer(obj, buffer, byteOffset, length) {
|| (newLength > %_MaxSmi())) {
throw MakeRangeError(kInvalidTypedArrayLength);
}
%_TypedArrayInitialize(obj, ARRAY_ID, buffer, offset, newByteLength);
%_TypedArrayInitialize(obj, ARRAY_ID, buffer, offset, newByteLength, true);
}
function NAMEConstructByLength(obj, length) {
......@@ -100,9 +100,9 @@ function NAMEConstructByLength(obj, length) {
var byteLength = l * ELEMENT_SIZE;
if (byteLength > %_TypedArrayMaxSizeInHeap()) {
var buffer = new GlobalArrayBuffer(byteLength);
%_TypedArrayInitialize(obj, ARRAY_ID, buffer, 0, byteLength);
%_TypedArrayInitialize(obj, ARRAY_ID, buffer, 0, byteLength, true);
} else {
%_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength);
%_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength, true);
}
}
......@@ -113,7 +113,15 @@ function NAMEConstructByArrayLike(obj, arrayLike) {
if (l > %_MaxSmi()) {
throw MakeRangeError(kInvalidTypedArrayLength);
}
if(!%TypedArrayInitializeFromArrayLike(obj, ARRAY_ID, arrayLike, l)) {
var initialized = false;
var byteLength = l * ELEMENT_SIZE;
if (byteLength <= %_TypedArrayMaxSizeInHeap()) {
%_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength, false);
} else {
initialized =
%TypedArrayInitializeFromArrayLike(obj, ARRAY_ID, arrayLike, l);
}
if (!initialized) {
for (var i = 0; i < l; i++) {
// It is crucial that we let any execptions from arrayLike[i]
// propagate outside the function.
......
......@@ -5550,7 +5550,7 @@ static void TestRightTrimFixedTypedArray(i::ExternalArrayType type,
Heap* heap = isolate->heap();
Handle<FixedTypedArrayBase> array =
factory->NewFixedTypedArray(initial_length, type);
factory->NewFixedTypedArray(initial_length, type, true);
int old_size = array->size();
heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(*array,
elements_to_trim);
......
......@@ -48,7 +48,7 @@ TEST(CopyContentsArray) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
CompileRun("var a = new Uint8Array([0, 1, 2, 3]);");
TestArrayBufferViewContents(env, true);
TestArrayBufferViewContents(env, false);
}
......
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