Commit ea55b873 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[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: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45384}
parent 6bd1aeee
...@@ -270,12 +270,14 @@ bool AccessInfoFactory::ComputeElementAccessInfos( ...@@ -270,12 +270,14 @@ bool AccessInfoFactory::ComputeElementAccessInfos(
MapTransitionList transitions(maps.size()); MapTransitionList transitions(maps.size());
for (Handle<Map> map : maps) { for (Handle<Map> map : maps) {
if (Map::TryUpdate(map).ToHandle(&map)) { if (Map::TryUpdate(map).ToHandle(&map)) {
Map* transition_target = // Don't generate elements kind transitions from stable maps.
map->FindElementsKindTransitionedMap(possible_transition_targets); Map* transition_target = map->is_stable()
? nullptr
: map->FindElementsKindTransitionedMap(
possible_transition_targets);
if (transition_target == nullptr) { if (transition_target == nullptr) {
receiver_maps.push_back(map); receiver_maps.push_back(map);
} else { } else {
DCHECK(!map->is_stable());
transitions.push_back(std::make_pair(map, handle(transition_target))); transitions.push_back(std::make_pair(map, handle(transition_target)));
} }
} }
......
...@@ -6940,10 +6940,12 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( ...@@ -6940,10 +6940,12 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
// Get transition target for each map (NULL == no transition). // Get transition target for each map (NULL == no transition).
for (int i = 0; i < maps->length(); ++i) { for (int i = 0; i < maps->length(); ++i) {
Handle<Map> map = maps->at(i); Handle<Map> map = maps->at(i);
// Don't generate elements kind transitions from stable maps.
Map* transitioned_map = Map* transitioned_map =
map->FindElementsKindTransitionedMap(possible_transitioned_maps); map->is_stable()
? nullptr
: map->FindElementsKindTransitionedMap(possible_transitioned_maps);
if (transitioned_map != nullptr) { if (transitioned_map != nullptr) {
DCHECK(!map->is_stable());
transition_target.push_back(handle(transitioned_map)); transition_target.push_back(handle(transitioned_map));
} else { } else {
transition_target.push_back(Handle<Map>()); transition_target.push_back(Handle<Map>());
......
// 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));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment