Commit 0b355643 authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[Turboprop] Fix deprecated map migration in dynamic map check builtin.

The TryMigrateInstance should be passed the instance object to migrate,
not the map of the object. Also make the runtime function explicitly
check for JSObjects.

BUG=v8:9684

Change-Id: I03605d9f3103b618243c12ad0b63035484ef4134
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2487270
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran  <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70731}
parent eb6b3b49
...@@ -50,8 +50,7 @@ type Zero extends PositiveSmi; ...@@ -50,8 +50,7 @@ type Zero extends PositiveSmi;
type Uninitialized extends Tagged; type Uninitialized extends Tagged;
extern macro MakeWeak(HeapObject): WeakHeapObject; extern macro MakeWeak(HeapObject): WeakHeapObject;
extern macro GetHeapObjectAssumeWeak(WeakHeapObject): extern macro GetHeapObjectAssumeWeak(MaybeObject): HeapObject labels IfCleared;
HeapObject labels ClearedWeakPointer;
extern macro GetHeapObjectIfStrong(MaybeObject): HeapObject labels IfNotStrong; extern macro GetHeapObjectIfStrong(MaybeObject): HeapObject labels IfNotStrong;
extern macro IsWeakOrCleared(MaybeObject): bool; extern macro IsWeakOrCleared(MaybeObject): bool;
extern macro IsWeakReferenceToObject(MaybeObject, Object): bool; extern macro IsWeakReferenceToObject(MaybeObject, Object): bool;
......
...@@ -84,9 +84,9 @@ macro PerformPolymorphicCheck( ...@@ -84,9 +84,9 @@ macro PerformPolymorphicCheck(
} }
macro PerformMonomorphicCheck( macro PerformMonomorphicCheck(
feedbackVector: FeedbackVector, slotIndex: intptr, maybeMap: MaybeObject, feedbackVector: FeedbackVector, slotIndex: intptr, expectedMap: HeapObject,
actualMap: Map, actualHandler: Smi|DataHandler): int32 { actualMap: Map, actualHandler: Smi|DataHandler): int32 {
if (IsWeakReferenceToObject(maybeMap, actualMap)) { if (TaggedEqual(expectedMap, actualMap)) {
const handlerIndex = slotIndex + 1; const handlerIndex = slotIndex + 1;
assert(handlerIndex < feedbackVector.length_intptr); assert(handlerIndex < feedbackVector.length_intptr);
const maybeHandler = const maybeHandler =
...@@ -135,17 +135,20 @@ builtin DynamicMapChecks(implicit context: Context)( ...@@ -135,17 +135,20 @@ builtin DynamicMapChecks(implicit context: Context)(
return PerformPolymorphicCheck( return PerformPolymorphicCheck(
maybePolymorphicArray, actualMap, actualHandler); maybePolymorphicArray, actualMap, actualHandler);
} label MigrateAndDoMonomorphicCheck { } label MigrateAndDoMonomorphicCheck {
const expectedMap = GetHeapObjectAssumeWeak(feedback) otherwise Deopt;
if (IsDeprecatedMap(actualMap)) { if (IsDeprecatedMap(actualMap)) {
// TODO(gsathya): Should this migration happen before the // TODO(gsathya): Should this migration happen before the
// polymorphic check? // polymorphic check?
const result = TryMigrateInstance(actualMap); const result = TryMigrateInstance(actualValue);
if (TaggedIsSmi(result)) { if (TaggedIsSmi(result)) {
return kDeopt; return kDeopt;
} }
actualMap = actualValue.map; actualMap = actualValue.map;
} }
return PerformMonomorphicCheck( return PerformMonomorphicCheck(
feedbackVector, slotIndex, feedback, actualMap, actualHandler); feedbackVector, slotIndex, expectedMap, actualMap, actualHandler);
} label Deopt {
return kDeopt;
} }
} }
......
...@@ -859,9 +859,7 @@ RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTrackingForMap) { ...@@ -859,9 +859,7 @@ RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTrackingForMap) {
RUNTIME_FUNCTION(Runtime_TryMigrateInstance) { RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK_EQ(1, args.length()); DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
if (!object->IsJSObject()) return Smi::zero();
Handle<JSObject> js_object = Handle<JSObject>::cast(object);
// It could have been a DCHECK but we call this function directly from tests. // It could have been a DCHECK but we call this function directly from tests.
if (!js_object->map().is_deprecated()) return Smi::zero(); if (!js_object->map().is_deprecated()) return Smi::zero();
// This call must not cause lazy deopts, because it's called from deferred // This call must not cause lazy deopts, because it's called from deferred
...@@ -869,7 +867,7 @@ RUNTIME_FUNCTION(Runtime_TryMigrateInstance) { ...@@ -869,7 +867,7 @@ RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
// ID. So we just try migration and signal failure if necessary, // ID. So we just try migration and signal failure if necessary,
// which will also trigger a deopt. // which will also trigger a deopt.
if (!JSObject::TryMigrateInstance(isolate, js_object)) return Smi::zero(); if (!JSObject::TryMigrateInstance(isolate, js_object)) return Smi::zero();
return *object; return *js_object;
} }
static bool IsValidAccessor(Isolate* isolate, Handle<Object> obj) { static bool IsValidAccessor(Isolate* isolate, Handle<Object> obj) {
......
// Copyright 2020 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 --turboprop --dynamic-map-checks --opt
// Flags: --no-always-opt
function b(a) { return a; }
function f(o, should_bailout) {
b(o.a);
let did_bailout = (%GetOptimizationStatus(f) &
V8OptimizationStatus.kTopmostFrameIsTurboFanned) == 0;
assertEquals(should_bailout, did_bailout);
}
var o = {a:10, b:20, c:30};
var o1 = {a:10, b:20, c:30};
var o2 = {a:10, b:20, c:30};
%PrepareFunctionForOptimization(f);
f(o, true);
%OptimizeFunctionOnNextCall(f);
f(o, false);
assertOptimized(f);
// Transition o to a new map and deprecate the old one (which is embedded in the
// optimized code for the dynamic map check).
o.b = 10.23;
f(o, true);
f(o1, false);
f(o2, false);
assertOptimized(f);
// Deprecate o's new map again and update the feedback vector but don't migrate
// o.
o1.c = 20.23;
f(o1, true);
assertOptimized(f);
// We should migrates o's map without bailing out.
f(o, false);
f(o1, false);
f(o2, false);
assertOptimized(f);
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