Commit 5e725575 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[ic] Fix undefined/null receivers not leaving UNINITIALIZED state.

The (KEYED_)LOAD/STORE_ICs didn't properly leave the UNINITIALIZED as
long as the receiver was always null/undefined. This leads to
deoptimization loops in TurboFan, because the compiler always put in a
SOFT deoptimization at this point.

Bug: v8:6989
Change-Id: I1a32bfb722f121f8b593e8972e657290d7b0531d
Reviewed-on: https://chromium-review.googlesource.com/735319Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48854}
parent 6452b26a
......@@ -377,7 +377,7 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
// If the object is undefined or null it's illegal to try to get any
// of its properties; throw a TypeError in that case.
if (object->IsNullOrUndefined(isolate())) {
if (FLAG_use_ic && state() != UNINITIALIZED && state() != PREMONOMORPHIC) {
if (FLAG_use_ic && state() != PREMONOMORPHIC) {
// Ensure the IC state progresses.
TRACE_HANDLER_STATS(isolate(), LoadIC_NonReceiver);
update_receiver_map(object);
......@@ -1265,7 +1265,7 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
// If the object is undefined or null it's illegal to try to set any
// properties on it; throw a TypeError in that case.
if (object->IsNullOrUndefined(isolate())) {
if (FLAG_use_ic && state() != UNINITIALIZED && state() != PREMONOMORPHIC) {
if (FLAG_use_ic && state() != PREMONOMORPHIC) {
// Ensure the IC state progresses.
TRACE_HANDLER_STATS(isolate(), StoreIC_NonReceiver);
update_receiver_map(object);
......
// 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 --opt
(function() {
function foo(o) { o["x"] = 1; }
assertThrows(() => foo(undefined));
assertThrows(() => foo(undefined));
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(undefined));
assertOptimized(foo);
})();
(function() {
function foo(o) { o["x"] = 1; }
assertThrows(() => foo(null));
assertThrows(() => foo(null));
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(null));
assertOptimized(foo);
})();
(function() {
function foo(o) { return o["x"]; }
assertThrows(() => foo(undefined));
assertThrows(() => foo(undefined));
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(undefined));
assertOptimized(foo);
})();
(function() {
function foo(o) { return o["x"]; }
assertThrows(() => foo(null));
assertThrows(() => foo(null));
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(null));
assertOptimized(foo);
})();
(function() {
function foo(o) { o.x = 1; }
assertThrows(() => foo(undefined));
assertThrows(() => foo(undefined));
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(undefined));
assertOptimized(foo);
})();
(function() {
function foo(o) { o.x = 1; }
assertThrows(() => foo(null));
assertThrows(() => foo(null));
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(null));
assertOptimized(foo);
})();
(function() {
function foo(o) { return o.x; }
assertThrows(() => foo(undefined));
assertThrows(() => foo(undefined));
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(undefined));
assertOptimized(foo);
})();
(function() {
function foo(o) { return o.x; }
assertThrows(() => foo(null));
assertThrows(() => foo(null));
%OptimizeFunctionOnNextCall(foo);
assertThrows(() => foo(null));
assertOptimized(foo);
})();
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