In GrowMode, force the value to the right representation to avoid deopts between...
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 25 Jul 2014 11:48:25 +0000 (11:48 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 25 Jul 2014 11:48:25 +0000 (11:48 +0000)
BUG=16459193
LOG=n
R=danno@chromium.org

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

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

src/hydrogen-instructions.h
src/hydrogen.cc
test/mjsunit/regress/regress-grow-deopt.js [new file with mode: 0644]

index a596873..fdbcff0 100644 (file)
@@ -6972,19 +6972,26 @@ class HStoreKeyed V8_FINAL
     }
 
     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) {
-      return Representation::Integer32();
-    }
-    if (IsFastSmiElementsKind(elements_kind())) {
+
+    if (IsFastSmiElementsKind(kind)) {
+      if (SmiValuesAre32Bits() && mode == STORE_TO_INITIALIZED_ENTRY) {
+        return Representation::Integer32();
+      }
       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 {
@@ -7004,20 +7011,10 @@ class HStoreKeyed V8_FINAL
     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); }
@@ -7088,9 +7085,6 @@ class HStoreKeyed V8_FINAL
     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);
index d653ff5..4eb8141 100644 (file)
@@ -2479,6 +2479,9 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
 
   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);
@@ -2675,9 +2678,7 @@ HInstruction* HGraphBuilder::AddElementAccess(
       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/test/mjsunit/regress/regress-grow-deopt.js b/test/mjsunit/regress/regress-grow-deopt.js
new file mode 100644 (file)
index 0000000..df3a83f
--- /dev/null
@@ -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);