[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}
This commit is contained in:
Igor Sheludko 2017-05-17 23:22:19 +02:00 committed by Commit Bot
parent 6bd1aeee00
commit ea55b873f2
3 changed files with 27 additions and 5 deletions

View File

@ -270,12 +270,14 @@ bool AccessInfoFactory::ComputeElementAccessInfos(
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)));
}
}

View File

@ -6940,10 +6940,12 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
// 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>());

View File

@ -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));