Commit 27900f17 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[compiler] Fix use of HeapObjectMatcher

In a few places we incorrectly assumed to know the instance type of the
heap object. In particular, in JSCallReducer::ReduceDataViewAccess,
doing map inference on the receiver and determining that all maps are
JSDataView maps does not guarantee that the receiver is a JSDataView
constant because we might deopt before getting to the data view
operation.

Bug: chromium:1146652
Change-Id: I1611308c3ebe0d33fa6b0cf0938d777b4e6449ff
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2524440
Auto-Submit: Georg Neis <neis@chromium.org>
Commit-Queue: Maya Lekova <mslekova@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71034}
parent 6925c86b
...@@ -2726,7 +2726,7 @@ Reduction JSCallReducer::ReduceFunctionPrototypeCall(Node* node) { ...@@ -2726,7 +2726,7 @@ Reduction JSCallReducer::ReduceFunctionPrototypeCall(Node* node) {
// to ensure any exception is thrown in the correct context. // to ensure any exception is thrown in the correct context.
Node* context; Node* context;
HeapObjectMatcher m(target); HeapObjectMatcher m(target);
if (m.HasResolvedValue()) { if (m.HasResolvedValue() && m.Ref(broker()).IsJSFunction()) {
JSFunctionRef function = m.Ref(broker()).AsJSFunction(); JSFunctionRef function = m.Ref(broker()).AsJSFunction();
if (should_disallow_heap_access() && !function.serialized()) { if (should_disallow_heap_access() && !function.serialized()) {
TRACE_BROKER_MISSING(broker(), "Serialize call on function " << function); TRACE_BROKER_MISSING(broker(), "Serialize call on function " << function);
...@@ -7346,7 +7346,7 @@ Reduction JSCallReducer::ReduceDataViewAccess(Node* node, DataViewAccess access, ...@@ -7346,7 +7346,7 @@ Reduction JSCallReducer::ReduceDataViewAccess(Node* node, DataViewAccess access,
// Check that the {offset} is within range for the {receiver}. // Check that the {offset} is within range for the {receiver}.
HeapObjectMatcher m(receiver); HeapObjectMatcher m(receiver);
if (m.HasResolvedValue()) { if (m.HasResolvedValue() && m.Ref(broker()).IsJSDataView()) {
// We only deal with DataViews here whose [[ByteLength]] is at least // We only deal with DataViews here whose [[ByteLength]] is at least
// {element_size}, as for all other DataViews it'll be out-of-bounds. // {element_size}, as for all other DataViews it'll be out-of-bounds.
JSDataViewRef dataview = m.Ref(broker()).AsJSDataView(); JSDataViewRef dataview = m.Ref(broker()).AsJSDataView();
......
...@@ -353,7 +353,9 @@ Reduction JSNativeContextSpecialization::ReduceJSGetSuperConstructor( ...@@ -353,7 +353,9 @@ Reduction JSNativeContextSpecialization::ReduceJSGetSuperConstructor(
// Check if the input is a known JSFunction. // Check if the input is a known JSFunction.
HeapObjectMatcher m(constructor); HeapObjectMatcher m(constructor);
if (!m.HasResolvedValue()) return NoChange(); if (!m.HasResolvedValue() || !m.Ref(broker()).IsJSFunction()) {
return NoChange();
}
JSFunctionRef function = m.Ref(broker()).AsJSFunction(); JSFunctionRef function = m.Ref(broker()).AsJSFunction();
MapRef function_map = function.map(); MapRef function_map = function.map();
if (should_disallow_heap_access() && !function_map.serialized_prototype()) { if (should_disallow_heap_access() && !function_map.serialized_prototype()) {
......
...@@ -44,7 +44,6 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) { ...@@ -44,7 +44,6 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
DisallowHeapAccess no_heap_access; DisallowHeapAccess no_heap_access;
switch (node->opcode()) { switch (node->opcode()) {
case IrOpcode::kBooleanNot: { case IrOpcode::kBooleanNot: {
// TODO(neis): Provide HeapObjectRefMatcher?
HeapObjectMatcher m(node->InputAt(0)); HeapObjectMatcher m(node->InputAt(0));
if (m.Is(factory()->true_value())) return ReplaceBoolean(false); if (m.Is(factory()->true_value())) return ReplaceBoolean(false);
if (m.Is(factory()->false_value())) return ReplaceBoolean(true); if (m.Is(factory()->false_value())) return ReplaceBoolean(true);
......
// 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
function IsDataView(obj) {
return obj.getFloat64;
}
%NeverOptimizeFunction(IsDataView);
function bar(obj) {
if (IsDataView(obj)) obj.getFloat64(0);
}
%PrepareFunctionForOptimization(bar);
bar(new DataView(new ArrayBuffer(42)));
const proxy = new Proxy({}, {});
function foo() { bar(proxy) }
%PrepareFunctionForOptimization(foo);
foo();
%OptimizeFunctionOnNextCall(foo);
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