Commit fa103efb authored by Jakob Linke's avatar Jakob Linke Committed by V8 LUCI CQ

[maglev] Handle cleared `handler.data1` values

.. in TryBuildMonomorphicLoadFromLoadHandler. If data1 is cleared,
emit an unconditional eager deopt.

Note all early-return paths must happen before any code is emitted.

Bug: v8:7700
Change-Id: I00d5ff258cc88a0cb2423267b362c05540d09839
Fixed: chromium:1359714
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3898691Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Jakob Linke <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83211}
parent e6a08cd9
...@@ -1063,25 +1063,41 @@ bool MaglevGraphBuilder::TryBuildMonomorphicLoadFromLoadHandler( ...@@ -1063,25 +1063,41 @@ bool MaglevGraphBuilder::TryBuildMonomorphicLoadFromLoadHandler(
const compiler::MapRef& map, LoadHandler handler) { const compiler::MapRef& map, LoadHandler handler) {
Object maybe_smi_handler = handler.smi_handler(local_isolate_); Object maybe_smi_handler = handler.smi_handler(local_isolate_);
if (!maybe_smi_handler.IsSmi()) return false; if (!maybe_smi_handler.IsSmi()) return false;
int smi_handler = Smi::cast(maybe_smi_handler).value();
const int smi_handler = Smi::ToInt(maybe_smi_handler);
LoadHandler::Kind kind = LoadHandler::KindBits::decode(smi_handler); LoadHandler::Kind kind = LoadHandler::KindBits::decode(smi_handler);
bool do_access_check_on_lookup_start_object =
LoadHandler::DoAccessCheckOnLookupStartObjectBits::decode(smi_handler);
bool lookup_on_lookup_start_object =
LoadHandler::LookupOnLookupStartObjectBits::decode(smi_handler);
if (lookup_on_lookup_start_object) return false;
if (kind != LoadHandler::Kind::kConstantFromPrototype && if (kind != LoadHandler::Kind::kConstantFromPrototype &&
kind != LoadHandler::Kind::kAccessorFromPrototype) kind != LoadHandler::Kind::kAccessorFromPrototype) {
return false;
}
if (LoadHandler::LookupOnLookupStartObjectBits::decode(smi_handler)) {
return false;
}
// This fiddly early return is necessary because we can't return `false` any
// more once we've started emitting code.
if (!map.IsStringMap() &&
LoadHandler::DoAccessCheckOnLookupStartObjectBits::decode(smi_handler)) {
return false; return false;
}
MaybeObject maybe_data1 = handler.data1(local_isolate_);
if (maybe_data1.IsCleared()) {
EmitUnconditionalDeopt(
DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess);
return true;
}
const Object data1 = maybe_data1.GetHeapObjectOrSmi();
if (map.IsStringMap()) { if (map.IsStringMap()) {
// Check for string maps before checking if we need to do an access check. // Check for string maps before checking if we need to do an access check.
// Primitive strings always get the prototype from the native context // Primitive strings always get the prototype from the native context
// they're operated on, so they don't need the access check. // they're operated on, so they don't need the access check.
BuildCheckString(lookup_start_object); BuildCheckString(lookup_start_object);
} else if (do_access_check_on_lookup_start_object) {
return false;
} else { } else {
DCHECK(!LoadHandler::DoAccessCheckOnLookupStartObjectBits::decode(
smi_handler));
BuildMapCheck(lookup_start_object, map); BuildMapCheck(lookup_start_object, map);
} }
...@@ -1110,21 +1126,19 @@ bool MaglevGraphBuilder::TryBuildMonomorphicLoadFromLoadHandler( ...@@ -1110,21 +1126,19 @@ bool MaglevGraphBuilder::TryBuildMonomorphicLoadFromLoadHandler(
switch (kind) { switch (kind) {
case LoadHandler::Kind::kConstantFromPrototype: { case LoadHandler::Kind::kConstantFromPrototype: {
MaybeObject value = handler.data1(local_isolate_); if (data1.IsSmi()) {
if (value.IsSmi()) { // Functionally, the else branch does the same - but we avoid the
SetAccumulator(GetSmiConstant(value.ToSmi().value())); // broker overhead by dispatching here.
SetAccumulator(GetSmiConstant(Smi::ToInt(data1)));
} else { } else {
SetAccumulator(GetConstant(MakeRefAssumeMemoryFence( SetAccumulator(GetConstant(MakeRefAssumeMemoryFence(
broker(), broker(), broker()->CanonicalPersistentHandle(data1))));
broker()->CanonicalPersistentHandle(value.GetHeapObject()))));
} }
break; break;
} }
case LoadHandler::Kind::kAccessorFromPrototype: { case LoadHandler::Kind::kAccessorFromPrototype: {
MaybeObject getter = handler.data1(local_isolate_);
compiler::ObjectRef getter_ref = MakeRefAssumeMemoryFence( compiler::ObjectRef getter_ref = MakeRefAssumeMemoryFence(
broker(), broker(), broker()->CanonicalPersistentHandle(data1));
broker()->CanonicalPersistentHandle(getter.GetHeapObject()));
Call* call = CreateNewNode<Call>(Call::kFixedInputCount + 1, Call* call = CreateNewNode<Call>(Call::kFixedInputCount + 1,
ConvertReceiverMode::kNotNullOrUndefined, ConvertReceiverMode::kNotNullOrUndefined,
......
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