From ea55b873f2ed8336604540a532cbd460eeb66430 Mon Sep 17 00:00:00 2001 From: Igor Sheludko Date: Wed, 17 May 2017 23:22:19 +0200 Subject: [PATCH] [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 Reviewed-by: Benedikt Meurer Cr-Commit-Position: refs/heads/master@{#45384} --- src/compiler/access-info.cc | 8 +++++--- src/crankshaft/hydrogen.cc | 6 ++++-- test/mjsunit/regress/regress-crbug-723455.js | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 test/mjsunit/regress/regress-crbug-723455.js diff --git a/src/compiler/access-info.cc b/src/compiler/access-info.cc index 0acc6d1d56..196bf9e896 100644 --- a/src/compiler/access-info.cc +++ b/src/compiler/access-info.cc @@ -270,12 +270,14 @@ bool AccessInfoFactory::ComputeElementAccessInfos( MapTransitionList transitions(maps.size()); for (Handle 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 1374e60865..5a110f4aa8 100644 --- a/src/crankshaft/hydrogen.cc +++ b/src/crankshaft/hydrogen.cc @@ -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 = 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()); diff --git a/test/mjsunit/regress/regress-crbug-723455.js b/test/mjsunit/regress/regress-crbug-723455.js new file mode 100644 index 0000000000..85f5e3c1d5 --- /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));