Reviewers: Benedikt Meurer, Michael Starzinger,
Description:
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
[email protected],[email protected]
LOG=y
Please review this at https://codereview.chromium.org/1144393003/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+50, -37 lines):
M src/factory.h
M src/factory.cc
M src/heap/heap.h
M src/heap/heap.cc
M src/hydrogen.h
M src/hydrogen.cc
M src/layout-descriptor-inl.h
M src/runtime/runtime.h
M src/runtime/runtime-typedarray.cc
M src/typedarray.js
M test/cctest/test-heap.cc
M test/cctest/test-typedarrays.cc
Index: src/factory.cc
diff --git a/src/factory.cc b/src/factory.cc
index
f4b609a7f94fd882faacfe89847d8c495cf58456..47de1e6a78b3d03962da7a193be6e743a39ad011
100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -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);
}
@@ -1962,7 +1958,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;
}
Index: src/factory.h
diff --git a/src/factory.h b/src/factory.h
index
076f81d8978ded82ef5c48bc995789da15e070c1..dc6c7ff33c934fff174f121798379b9deb77d634
100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -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);
Index: src/heap/heap.cc
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index
76209c42b5ec1cd198118589b78909cf3329478a..877b21d2eb123aae3b6303575d142a5edc869264
100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -3730,6 +3730,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;
@@ -3747,7 +3748,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;
}
@@ -4317,7 +4318,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);
}
Index: src/heap/heap.h
diff --git a/src/heap/heap.h b/src/heap/heap.h
index
b42f7b8efc073a49256e4518dba42350fc7437a4..8574d55993d9dc523dc233170b3c667ebefe7c26
100644
--- a/src/heap/heap.h
+++ b/src/heap/heap.h
@@ -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);
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index
809640fb437aa303c39e0d51e087e59b3e210b29..ee051aa24a87c2d9aae5d9b0bb3636fc592fdc77
100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -9875,8 +9875,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;
@@ -9915,7 +9915,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(
@@ -9938,7 +9938,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);
@@ -9987,6 +9988,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);
@@ -10034,9 +10040,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);
@@ -10050,6 +10056,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);
}
Index: src/hydrogen.h
diff --git a/src/hydrogen.h b/src/hydrogen.h
index
0feef24e6b91f82032ac01d6abb30e22cdec533c..4c6e3899ca50228d25b9977cddbf1121f3902a29
100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -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);
Index: src/layout-descriptor-inl.h
diff --git a/src/layout-descriptor-inl.h b/src/layout-descriptor-inl.h
index
ba76704d5fc1f5c8883838a61de046268129c0d9..77671328b4c1b745a55bbfea1f99d9bb9e0f05e4
100644
--- a/src/layout-descriptor-inl.h
+++ b/src/layout-descriptor-inl.h
@@ -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));
}
Index: src/runtime/runtime-typedarray.cc
diff --git a/src/runtime/runtime-typedarray.cc
b/src/runtime/runtime-typedarray.cc
index
a92a642bbc936cb8129386ef692acf73324060e7..03bee385bff6368f8ab678a2fa86ae0c64aaec1f
100644
--- a/src/runtime/runtime-typedarray.cc
+++ b/src/runtime/runtime-typedarray.cc
@@ -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();
Index: src/runtime/runtime.h
diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h
index
ea5570ec596e501b0d3a872a5c4bc739fb748d98..cad31d9791ba89f338b489ef2c76befd876876a9
100644
--- a/src/runtime/runtime.h
+++ b/src/runtime/runtime.h
@@ -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) \
Index: src/typedarray.js
diff --git a/src/typedarray.js b/src/typedarray.js
index
cb68c1b8d0d2fbf405c6b6d07ada6b842d836226..65659147ee7777cf1e8bc69196d4fc09a4beee89
100644
--- a/src/typedarray.js
+++ b/src/typedarray.js
@@ -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.
Index: test/cctest/test-heap.cc
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index
da19f09f7cc22f6202ade9172d4edefeb943975b..79ced70618330252e00f1a2076f6bf6c567ff9ce
100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -5441,7 +5441,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);
Index: test/cctest/test-typedarrays.cc
diff --git a/test/cctest/test-typedarrays.cc
b/test/cctest/test-typedarrays.cc
index
d371673b9ea8f5806a273d837deec07f459e41fb..394f6194fd297145eb989ce6fa5f171042a68f45
100644
--- a/test/cctest/test-typedarrays.cc
+++ b/test/cctest/test-typedarrays.cc
@@ -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);
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.