[turbofan][crankshaft] Don't generate elements kind transitions from stable maps.

IC system does its best to properly mark stable transition source maps
as unstable (see https://chromium-review.googlesource.com/483442)
however an already recorded map can be deprecated later and the
optimizing compiler may try to generate an elements kind transition
from the updated version of deprecated map which can "become" stable
again.

Bug: chromium:723455
Change-Id: Ic0c392f153587c3cd7c7623a3a6ea85ec72ad5bd
Reviewed-on: https://chromium-review.googlesource.com/507887
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45384}
diff --git a/src/compiler/access-info.cc b/src/compiler/access-info.cc
index 0acc6d1..196bf9e 100644
--- a/src/compiler/access-info.cc
+++ b/src/compiler/access-info.cc
@@ -270,12 +270,14 @@
   MapTransitionList transitions(maps.size());
   for (Handle<Map> map : maps) {
     if (Map::TryUpdate(map).ToHandle(&map)) {
-      Map* transition_target =
-          map->FindElementsKindTransitionedMap(possible_transition_targets);
+      // Don't generate elements kind transitions from stable maps.
+      Map* transition_target = map->is_stable()
+                                   ? nullptr
+                                   : map->FindElementsKindTransitionedMap(
+                                         possible_transition_targets);
       if (transition_target == nullptr) {
         receiver_maps.push_back(map);
       } else {
-        DCHECK(!map->is_stable());
         transitions.push_back(std::make_pair(map, handle(transition_target)));
       }
     }
diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc
index 1374e60..5a110f4 100644
--- a/src/crankshaft/hydrogen.cc
+++ b/src/crankshaft/hydrogen.cc
@@ -6940,10 +6940,12 @@
   // Get transition target for each map (NULL == no transition).
   for (int i = 0; i < maps->length(); ++i) {
     Handle<Map> map = maps->at(i);
+    // Don't generate elements kind transitions from stable maps.
     Map* transitioned_map =
-        map->FindElementsKindTransitionedMap(possible_transitioned_maps);
+        map->is_stable()
+            ? nullptr
+            : map->FindElementsKindTransitionedMap(possible_transitioned_maps);
     if (transitioned_map != nullptr) {
-      DCHECK(!map->is_stable());
       transition_target.push_back(handle(transitioned_map));
     } else {
       transition_target.push_back(Handle<Map>());
diff --git a/test/mjsunit/regress/regress-crbug-723455.js b/test/mjsunit/regress/regress-crbug-723455.js
new file mode 100644
index 0000000..85f5e3c
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-723455.js
@@ -0,0 +1,18 @@
+// Copyright 2017 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 --verify-heap
+
+function f(a) {
+  a.x = 0;
+  a[0] = 0.1;
+  a.x = {};
+}
+
+f(new Array(1));
+f(new Array(1));
+f(new Array());
+
+%OptimizeFunctionOnNextCall(f);
+f(new Array(1));