Fix C++ type of Factory::NewFixedDoubleArray.
authorjarin@chromium.org <jarin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 24 Apr 2014 05:29:00 +0000 (05:29 +0000)
committerjarin@chromium.org <jarin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 24 Apr 2014 05:29:00 +0000 (05:29 +0000)
The change fixes the C++ type of Factory::NewFixedDoubleArray to
reflect the empty array case, where we return an empty
FixedArray (rather than FixedDoubleArray).

R=mvstanton@chromium.org
BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20918 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/builtins.cc
src/factory.cc
src/factory.h
src/runtime.cc
test/mjsunit/regress/regress-empty-fixed-double-array.js [new file with mode: 0644]

index f4ce991..c4ac278 100644 (file)
@@ -470,7 +470,10 @@ BUILTIN(ArrayPush) {
     if (new_length > elms_len) {
       // New backing storage is needed.
       int capacity = new_length + (new_length >> 1) + 16;
-      new_elms = isolate->factory()->NewFixedDoubleArray(capacity);
+      // Create new backing store; since capacity > 0, we can
+      // safely cast to FixedDoubleArray.
+      new_elms = Handle<FixedDoubleArray>::cast(
+          isolate->factory()->NewFixedDoubleArray(capacity));
 
       ElementsAccessor* accessor = array->GetElementsAccessor();
       accessor->CopyElements(
index 2f5d1bd..2e405bc 100644 (file)
@@ -88,23 +88,27 @@ Handle<FixedArray> Factory::NewUninitializedFixedArray(int size) {
 }
 
 
-Handle<FixedDoubleArray> Factory::NewFixedDoubleArray(int size,
+Handle<FixedArrayBase> Factory::NewFixedDoubleArray(int size,
                                                       PretenureFlag pretenure) {
   ASSERT(0 <= size);
   CALL_HEAP_FUNCTION(
       isolate(),
       isolate()->heap()->AllocateUninitializedFixedDoubleArray(size, pretenure),
-      FixedDoubleArray);
+      FixedArrayBase);
 }
 
 
-Handle<FixedDoubleArray> Factory::NewFixedDoubleArrayWithHoles(
+Handle<FixedArrayBase> Factory::NewFixedDoubleArrayWithHoles(
     int size,
     PretenureFlag pretenure) {
   ASSERT(0 <= size);
-  Handle<FixedDoubleArray> array = NewFixedDoubleArray(size, pretenure);
-  for (int i = 0; i < size; ++i) {
-    array->set_the_hole(i);
+  Handle<FixedArrayBase> array = NewFixedDoubleArray(size, pretenure);
+  if (size > 0) {
+    Handle<FixedDoubleArray> double_array =
+        Handle<FixedDoubleArray>::cast(array);
+    for (int i = 0; i < size; ++i) {
+      double_array->set_the_hole(i);
+    }
   }
   return array;
 }
index a19f297..caabac8 100644 (file)
@@ -33,12 +33,14 @@ class Factory V8_FINAL {
   Handle<FixedArray> NewUninitializedFixedArray(int size);
 
   // Allocate a new uninitialized fixed double array.
-  Handle<FixedDoubleArray> NewFixedDoubleArray(
+  // The function returns a pre-allocated empty fixed array for capacity = 0,
+  // so the return type must be the general fixed array class.
+  Handle<FixedArrayBase> NewFixedDoubleArray(
       int size,
       PretenureFlag pretenure = NOT_TENURED);
 
   // Allocate a new fixed double array with hole values.
-  Handle<FixedDoubleArray> NewFixedDoubleArrayWithHoles(
+  Handle<FixedArrayBase> NewFixedDoubleArrayWithHoles(
       int size,
       PretenureFlag pretenure = NOT_TENURED);
 
index ef7a748..b45f6e3 100644 (file)
@@ -10484,12 +10484,13 @@ RUNTIME_FUNCTION(Runtime_ArrayConcat) {
   // dictionary.
   bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length;
 
-  Handle<FixedArray> storage;
-  if (fast_case) {
-    if (kind == FAST_DOUBLE_ELEMENTS) {
+  if (fast_case && kind == FAST_DOUBLE_ELEMENTS) {
+    Handle<FixedArrayBase> storage =
+        isolate->factory()->NewFixedDoubleArray(estimate_result_length);
+    int j = 0;
+    if (estimate_result_length > 0) {
       Handle<FixedDoubleArray> double_storage =
-          isolate->factory()->NewFixedDoubleArray(estimate_result_length);
-      int j = 0;
+          Handle<FixedDoubleArray>::cast(storage);
       bool failure = false;
       for (int i = 0; i < argument_count; i++) {
         Handle<Object> obj(elements->get(i), isolate);
@@ -10545,15 +10546,19 @@ RUNTIME_FUNCTION(Runtime_ArrayConcat) {
         }
         if (failure) break;
       }
-      Handle<JSArray> array = isolate->factory()->NewJSArray(0);
-      Smi* length = Smi::FromInt(j);
-      Handle<Map> map;
-      map = JSObject::GetElementsTransitionMap(array, kind);
-      array->set_map(*map);
-      array->set_length(length);
-      array->set_elements(*double_storage);
-      return *array;
     }
+    Handle<JSArray> array = isolate->factory()->NewJSArray(0);
+    Smi* length = Smi::FromInt(j);
+    Handle<Map> map;
+    map = JSObject::GetElementsTransitionMap(array, kind);
+    array->set_map(*map);
+    array->set_length(length);
+    array->set_elements(*storage);
+    return *array;
+  }
+
+  Handle<FixedArray> storage;
+  if (fast_case) {
     // The backing storage array must have non-existing elements to preserve
     // holes across concat operations.
     storage = isolate->factory()->NewFixedArrayWithHoles(
diff --git a/test/mjsunit/regress/regress-empty-fixed-double-array.js b/test/mjsunit/regress/regress-empty-fixed-double-array.js
new file mode 100644 (file)
index 0000000..1db9e2b
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --enable-slow-asserts
+
+function f(a, x) {
+  a.shift();
+  a[0] = x;
+}
+
+f([1], 1.1);
+f([1], 1.1);
+%OptimizeFunctionOnNextCall(f);
+f([1], 1.1);