Version 3.27.34.8 (merged r22616, r22617)

In GrowMode, force the value to the right representation to avoid deopts between storing the length and storing the value.

Smi arrays are only guaranteed to be initialized in non-holey case

BUG=16459193
LOG=y
R=ishell@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/3.27@22736 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index f1720f4..47ce499 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -6906,19 +6906,28 @@
     }
 
     ASSERT_EQ(index, 2);
-    if (IsDoubleOrFloatElementsKind(elements_kind())) {
+    return RequiredValueRepresentation(elements_kind_, store_mode_);
+  }
+
+  static Representation RequiredValueRepresentation(
+      ElementsKind kind, StoreFieldOrKeyedMode mode) {
+    if (IsDoubleOrFloatElementsKind(kind)) {
       return Representation::Double();
     }
-    if (SmiValuesAre32Bits() && store_mode_ == STORE_TO_INITIALIZED_ENTRY) {
+
+    if (kind == FAST_SMI_ELEMENTS && SmiValuesAre32Bits() &&
+        mode == STORE_TO_INITIALIZED_ENTRY) {
       return Representation::Integer32();
     }
-    if (IsFastSmiElementsKind(elements_kind())) {
+
+    if (IsFastSmiElementsKind(kind)) {
       return Representation::Smi();
     }
 
-    return is_external() || is_fixed_typed_array()
-        ? Representation::Integer32()
-        : Representation::Tagged();
+    return IsExternalArrayElementsKind(kind) ||
+                   IsFixedTypedArrayElementsKind(kind)
+               ? Representation::Integer32()
+               : Representation::Tagged();
   }
 
   bool is_external() const {
@@ -6938,20 +6947,10 @@
     if (IsUninitialized()) {
       return Representation::None();
     }
-    if (IsDoubleOrFloatElementsKind(elements_kind())) {
-      return Representation::Double();
-    }
-    if (SmiValuesAre32Bits() && store_mode_ == STORE_TO_INITIALIZED_ENTRY) {
-      return Representation::Integer32();
-    }
-    if (IsFastSmiElementsKind(elements_kind())) {
-      return Representation::Smi();
-    }
-    if (is_typed_elements()) {
-      return Representation::Integer32();
-    }
+    Representation r = RequiredValueRepresentation(elements_kind_, store_mode_);
     // For fast object elements kinds, don't assume anything.
-    return Representation::None();
+    if (r.IsTagged()) return Representation::None();
+    return r;
   }
 
   HValue* elements() const { return OperandAt(0); }
@@ -7031,9 +7030,6 @@
     SetOperandAt(1, key);
     SetOperandAt(2, val);
 
-    ASSERT(store_mode != STORE_TO_INITIALIZED_ENTRY ||
-           elements_kind == FAST_SMI_ELEMENTS);
-
     if (IsFastObjectElementsKind(elements_kind)) {
       SetFlag(kTrackSideEffectDominators);
       SetDependsOnFlag(kNewSpacePromotion);
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 6e5ea74..8fff497 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -2405,6 +2405,9 @@
 
   if (IsGrowStoreMode(store_mode)) {
     NoObservableSideEffectsScope no_effects(this);
+    Representation representation = HStoreKeyed::RequiredValueRepresentation(
+        elements_kind, STORE_TO_INITIALIZED_ENTRY);
+    val = AddUncasted<HForceRepresentation>(val, representation);
     elements = BuildCheckForCapacityGrow(checked_object, elements,
                                          elements_kind, length, key,
                                          is_js_array, access_type);
@@ -2601,9 +2604,7 @@
       val = Add<HClampToUint8>(val);
     }
     return Add<HStoreKeyed>(elements, checked_key, val, elements_kind,
-                            elements_kind == FAST_SMI_ELEMENTS
-                              ? STORE_TO_INITIALIZED_ENTRY
-                              : INITIALIZING_STORE);
+                            STORE_TO_INITIALIZED_ENTRY);
   }
 
   ASSERT(access_type == LOAD);
diff --git a/src/version.cc b/src/version.cc
index 21200e7..2e972ba 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     27
 #define BUILD_NUMBER      34
-#define PATCH_LEVEL       7
+#define PATCH_LEVEL       8
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
diff --git a/test/mjsunit/regress/regress-grow-deopt.js b/test/mjsunit/regress/regress-grow-deopt.js
new file mode 100644
index 0000000..df3a83f
--- /dev/null
+++ b/test/mjsunit/regress/regress-grow-deopt.js
@@ -0,0 +1,16 @@
+// 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
+
+function f(a, v) {
+  a[a.length] = v;
+}
+
+var a = [1.4];
+f(a, 1);
+f(a, 2);
+%OptimizeFunctionOnNextCall(f);
+f(a, {});
+assertEquals(4, a.length);