Force small array literals to have FAST_ELEMENTs
authordanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 23 Nov 2012 13:23:39 +0000 (13:23 +0000)
committerdanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 23 Nov 2012 13:23:39 +0000 (13:23 +0000)
R=verwaest@chromium.org

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

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

src/parser.cc
test/mjsunit/array-natives-elements.js

index a7bb4e7985f7a3ac75de531d41415a4d73f47b5a..75fd7b73667eb611dd1393f26c1dc559addeff67 100644 (file)
@@ -3718,6 +3718,7 @@ Expression* Parser::ParseArrayLiteral(bool* ok) {
       isolate()->factory()->NewFixedArray(values->length(), TENURED);
   Handle<FixedDoubleArray> double_literals;
   ElementsKind elements_kind = FAST_SMI_ELEMENTS;
+  bool has_only_undefined_values = true;
   bool has_hole_values = false;
 
   // Fill in the literals.
@@ -3749,6 +3750,7 @@ Expression* Parser::ParseArrayLiteral(bool* ok) {
       // FAST_DOUBLE_ELEMENTS and FAST_ELEMENTS as necessary.  Always remember
       // the tagged value, no matter what the ElementsKind is in case we
       // ultimately end up in FAST_ELEMENTS.
+      has_only_undefined_values = false;
       object_literals->set(i, *boilerplate_value);
       if (elements_kind == FAST_SMI_ELEMENTS) {
         // Smi only elements. Notice if a transition to FAST_DOUBLE_ELEMENTS or
@@ -3787,6 +3789,13 @@ Expression* Parser::ParseArrayLiteral(bool* ok) {
     }
   }
 
+  // Very small array literals that don't have a concrete hint about their type
+  // from a constant value should default to the slow case to avoid lots of
+  // elements transitions on really small objects.
+  if (has_only_undefined_values && values->length() <= 2) {
+    elements_kind = FAST_ELEMENTS;
+  }
+
   // Simple and shallow arrays can be lazily copied, we transform the
   // elements array to a copy-on-write array.
   if (is_simple && depth == 1 && values->length() > 0 &&
index 96a8cb5d1984fd6a54089b103fb90190befd7fa1..dde33a552bc9d4b88b09729c4c7f220a9e838715 100644 (file)
@@ -49,7 +49,7 @@ function get(foo) { return foo; }  // Used to generate dynamic values.
 function array_natives_test() {
 
   // Ensure small array literals start in specific element kind mode.
-  assertTrue(%HasFastSmiElements([]));
+  assertTrue(%HasFastObjectElements([]));
   assertTrue(%HasFastSmiElements([1]));
   assertTrue(%HasFastSmiElements([1,2]));
   assertTrue(%HasFastDoubleElements([1.1]));
@@ -73,7 +73,7 @@ function array_natives_test() {
   // Concat
   var a1;
   a1 = [1,2,3].concat([]);
-  assertTrue(%HasFastSmiElements(a1));
+  assertTrue(%HasFastObjectElements(a1));
   assertEquals([1,2,3], a1);
   a1 = [1,2,3].concat([4,5,6]);
   assertTrue(%HasFastSmiElements(a1));
@@ -82,7 +82,7 @@ function array_natives_test() {
   assertTrue(%HasFastSmiElements(a1));
   assertEquals([1,2,3,4,5,6,7,8,9], a1);
   a1 = [1.1,2,3].concat([]);
-  assertTrue(%HasFastDoubleElements(a1));
+  assertTrue(%HasFastObjectElements(a1));
   assertEquals([1.1,2,3], a1);
   a1 = [1,2,3].concat([1.1, 2]);
   assertTrue(%HasFastDoubleElements(a1));
@@ -173,7 +173,7 @@ function array_natives_test() {
   a3r = a3.splice(0, 0, 2);
   // Commented out since handled in js, which takes the best fit.
   // assertTrue(%HasFastDoubleElements(a3r));
-  assertTrue(%HasFastSmiElements(a3r));
+  assertTrue(%HasFastObjectElements(a3r));
   assertTrue(%HasFastDoubleElements(a3));
   assertEquals([], a3r);
   assertEquals([2, 1.1, 2, 3], a3);
@@ -187,7 +187,7 @@ function array_natives_test() {
   a3r = a3.splice(0, 0, 2.1);
   // Commented out since handled in js, which takes the best fit.
   // assertTrue(%HasFastDoubleElements(a3r));
-  assertTrue(%HasFastSmiElements(a3r));
+  assertTrue(%HasFastObjectElements(a3r));
   assertTrue(%HasFastDoubleElements(a3));
   assertEquals([], a3r);
   assertEquals([2.1, 1.1, 2, 3], a3);
@@ -201,7 +201,7 @@ function array_natives_test() {
   a3r = a3.splice(0, 0, 2.1);
   // Commented out since handled in js, which takes the best fit.
   // assertTrue(%HasFastDoubleElements(a3r));
-  assertTrue(%HasFastSmiElements(a3r));
+  assertTrue(%HasFastObjectElements(a3r));
   assertTrue(%HasFastDoubleElements(a3));
   assertEquals([], a3r);
   assertEquals([2.1, 1, 2, 3], a3);