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.

Reply via email to