[maglev] Check maps in TryBuildFastInstanceOf

Add a map check for the RHS of instanceof checks (i.e. the class) when
loading its hasInstance method. We were previously confirming the value
of the RHS, to make sure that it's a constant, but not considering the
case that the map of that class could change (e.g. because of a
prototype change or field definition).

Bug: v8:7700
Change-Id: Ia2923b99dd0524670bebcc57e4c0c209f8835d04
Fixed: chromium:1407959
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4173568
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#85336}
This commit is contained in:
Leszek Swirski 2023-01-17 11:25:23 +01:00 committed by V8 LUCI CQ
parent 04f19e973e
commit 503b56efdf
2 changed files with 30 additions and 1 deletions

View File

@ -4008,11 +4008,13 @@ bool MaglevGraphBuilder::TryBuildFastInstanceOf(
ValueNode* callable_node;
if (callable_node_if_not_constant) {
// Check that {callable_node_if_not_constant} is actually {callable}.
AddNewNode<CheckValue>({callable_node_if_not_constant}, callable);
BuildCheckValue(callable_node_if_not_constant, callable);
callable_node = callable_node_if_not_constant;
} else {
callable_node = GetConstant(callable);
}
BuildCheckMaps(callable_node,
base::VectorOf(access_info.lookup_start_object_maps()));
// Call @@hasInstance
CallArguments args(ConvertReceiverMode::kNotNullOrUndefined,

View File

@ -0,0 +1,27 @@
// Copyright 2023 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: --maglev --allow-natives-syntax
function func() {}
function foo(x) {
return x instanceof func;
}
%PrepareFunctionForOptimization(foo);
foo();
foo();
%OptimizeMaglevOnNextCall(foo);
foo();
let custom_has_instance_runs = 0;
Object.defineProperty(func, Symbol.hasInstance, {
value: function() {
custom_has_instance_runs++;
return true;
}
});
assertTrue(foo());
assertEquals(custom_has_instance_runs, 1);