Allocation type info advice consumed in bailout path leads to assert failure.
authormvstanton@chromium.org <mvstanton@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 6 Jun 2013 09:26:30 +0000 (09:26 +0000)
committermvstanton@chromium.org <mvstanton@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 6 Jun 2013 09:26:30 +0000 (09:26 +0000)
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=
R=danno@chromium.org

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

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

src/builtins.cc
test/mjsunit/allocation-site-info.js

index b42fd5a5db40caf6d407d72ac7bef7ad8fe1c144..addda0854cdf200be523f78654d0f8807da101ab 100644 (file)
@@ -200,16 +200,29 @@ static MaybeObject* ArrayConstructorStubFailureCommon(
     Handle<Object> type_info,
     Arguments* caller_args) {
   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 can_use_type_feedback = true;
+  if (caller_args->length() == 1) {
+    Object* argument_one = (*caller_args)[0];
+    if (argument_one->IsSmi()) {
+      int value = Smi::cast(argument_one)->value();
+      if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) {
+        // the array is a dictionary in this case.
+        can_use_type_feedback = false;
+      } else if (value != 0) {
+        holey = true;
+      }
+    } else {
+      // Non-smi length argument produces a dictionary
+      can_use_type_feedback = false;
+    }
   }
 
   JSArray* array;
   MaybeObject* maybe_array;
   if (!type_info.is_null() &&
       *type_info != isolate->heap()->undefined_value() &&
-      JSGlobalPropertyCell::cast(*type_info)->value()->IsSmi()) {
+      JSGlobalPropertyCell::cast(*type_info)->value()->IsSmi() &&
+      can_use_type_feedback) {
     JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(*type_info);
     Smi* smi = Smi::cast(cell->value());
     ElementsKind to_kind = static_cast<ElementsKind>(smi->value());
index 45605317fea69bfd116897c75e9a1a08fc5a9bdb..f533d617384992694ed52113cf961c623f651bdf 100644 (file)
@@ -281,6 +281,23 @@ 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);
+    obj = newarraycase_onearg(0, 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();