Reviewers: danno,

Message:
Hi Danno, here is the bugfix I referred to earlier today. I also added a test.
Without the fix, the test fails with an assert under
JSObject::GetElementsCapacityAndUsage() in the bailout.

Description:
Allocation type info advice consumed in bailout path leads to assert failure.

If the runtime is taken for a constructor like "new Array(100000)", where
allocation site info already led to an elements kind of DOUBLE, then the runtime would fail to transition the array to dictionary mode. Better to recognize this case and avoid wasting time by following the advice. Furthermore, it offers a way to recognize that the array should be in dictionary mode (though a future
checkin will capitalize on that).

BUG=

Please review this at https://codereview.chromium.org/15993012/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/builtins.cc
  M test/mjsunit/allocation-site-info.js


Index: src/builtins.cc
diff --git a/src/builtins.cc b/src/builtins.cc
index 37ba1e5301a9e17a9e5f4f026e0ad902bb03fd9d..8a4ae71ff0a229daa97dfed558eb1da94716328f 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -209,15 +209,25 @@ RUNTIME_FUNCTION(MaybeObject*, ArrayConstructor_StubFailure) {
   Handle<Object> type_info = args.at<Object>(parameters_start + 1);

   bool holey = false;
-  if (caller_args->length() == 1 && (*caller_args)[0]->IsSmi()) {
-    int value = Smi::cast((*caller_args)[0])->value();
-    holey = (value > 0 && value < JSObject::kInitialMaxFastElementArray);
+  bool ignore_advice = false;
+  if (caller_args->length() == 1) {
+    Object* argument_one = (*caller_args)[0];
+    if (argument_one->IsSmi()) {
+      int value = Smi::cast(argument_one)->value();
+      holey = (value > 0 && value < JSObject::kInitialMaxFastElementArray);
+    }
+
+    // If we have a single argument, and we failed to set holey above,
+    // then we'll be forced down the dictionary path. In this case it's
+    // useless to consume allocation site info advice, even if we have it.
+    ignore_advice = !holey;
   }

   JSArray* array;
   MaybeObject* maybe_array;
   if (*type_info != isolate->heap()->undefined_value() &&
-      JSGlobalPropertyCell::cast(*type_info)->value()->IsSmi()) {
+      JSGlobalPropertyCell::cast(*type_info)->value()->IsSmi() &&
+      !ignore_advice) {
     JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(*type_info);
     Smi* smi = Smi::cast(cell->value());
     ElementsKind to_kind = static_cast<ElementsKind>(smi->value());
Index: test/mjsunit/allocation-site-info.js
diff --git a/test/mjsunit/allocation-site-info.js b/test/mjsunit/allocation-site-info.js index 45605317fea69bfd116897c75e9a1a08fc5a9bdb..5af4598494398b30bf5370a6a08047c7a0c4ae7c 100644
--- a/test/mjsunit/allocation-site-info.js
+++ b/test/mjsunit/allocation-site-info.js
@@ -281,6 +281,21 @@ if (support_smi_only_arrays) {
     obj = newarraycase_list_smiobj(2);
     assertKind(elements_kind.fast, obj);

+    function newarraycase_onearg(len, value) {
+      var a = new Array(len);
+      a[0] = value;
+      return a;
+    }
+
+    obj = newarraycase_onearg(5, 3.5);
+    assertKind(elements_kind.fast_double, obj);
+    obj = newarraycase_onearg(10, 5);
+    assertKind(elements_kind.fast_double, obj);
+    // Now pass a length that forces the dictionary path.
+    obj = newarraycase_onearg(100000, 5);
+    assertKind(elements_kind.dictionary, obj);
+    assertTrue(obj.length == 100000);
+
     // Verify that cross context calls work
     var realmA = Realm.current();
     var realmB = Realm.create();


--
--
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/groups/opt_out.


Reply via email to