Commit 37c861a7 authored by Jaroslav Sevcik's avatar Jaroslav Sevcik Committed by Commit Bot

[turbofan] Fix receiver != holder case for constant loads.

Bug: chromium:945187
Change-Id: If6f36a4767ffda5f23873c79775116514dd0a2b6
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1539582
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60464}
parent 04088798
...@@ -197,17 +197,28 @@ Node* PropertyAccessBuilder::ResolveHolder( ...@@ -197,17 +197,28 @@ Node* PropertyAccessBuilder::ResolveHolder(
Node* PropertyAccessBuilder::TryBuildLoadConstantDataField( Node* PropertyAccessBuilder::TryBuildLoadConstantDataField(
Handle<Name> name, PropertyAccessInfo const& access_info, Node* receiver) { Handle<Name> name, PropertyAccessInfo const& access_info, Node* receiver) {
// Optimize immutable property loads. // Optimize immutable property loads.
// First, determine if we have a constant holder to load from.
Handle<JSObject> holder;
// If {access_info} has a holder, just use it.
if (!access_info.holder().ToHandle(&holder)) {
// Otherwise, try to match the {receiver} as a constant.
HeapObjectMatcher m(receiver); HeapObjectMatcher m(receiver);
if (m.HasValue() && m.Value()->IsJSObject()) { if (!m.HasValue() || !m.Value()->IsJSObject()) return nullptr;
// Make sure the actual map of the receiver is among the maps in
// {access_info}. // Let us make sure the actual map of the constant receiver is among
// the maps in {access_info}.
Handle<Map> receiver_map = handle(m.Value()->map(), isolate()); Handle<Map> receiver_map = handle(m.Value()->map(), isolate());
if (std::find_if(access_info.receiver_maps().begin(), if (std::find_if(access_info.receiver_maps().begin(),
access_info.receiver_maps().end(), [&](Handle<Map> map) { access_info.receiver_maps().end(), [&](Handle<Map> map) {
return map.address() == receiver_map.address(); return map.address() == receiver_map.address();
}) == access_info.receiver_maps().end()) { }) == access_info.receiver_maps().end()) {
// The map of the receiver is not in the feedback, let us bail out.
return nullptr; return nullptr;
} }
holder = Handle<JSObject>::cast(m.Value());
}
// TODO(ishell): Use something simpler like // TODO(ishell): Use something simpler like
// //
// Handle<Object> value = // Handle<Object> value =
...@@ -218,11 +229,10 @@ Node* PropertyAccessBuilder::TryBuildLoadConstantDataField( ...@@ -218,11 +229,10 @@ Node* PropertyAccessBuilder::TryBuildLoadConstantDataField(
// TODO(turbofan): Given that we already have the field_index here, we // TODO(turbofan): Given that we already have the field_index here, we
// might be smarter in the future and not rely on the LookupIterator. // might be smarter in the future and not rely on the LookupIterator.
LookupIterator it(isolate(), m.Value(), name, LookupIterator it(isolate(), holder, name,
LookupIterator::OWN_SKIP_INTERCEPTOR); LookupIterator::OWN_SKIP_INTERCEPTOR);
if (it.state() == LookupIterator::DATA) { if (it.state() == LookupIterator::DATA) {
bool is_readonly_non_configurable = bool is_readonly_non_configurable = it.IsReadOnly() && !it.IsConfigurable();
it.IsReadOnly() && !it.IsConfigurable();
if (is_readonly_non_configurable || if (is_readonly_non_configurable ||
(FLAG_track_constant_fields && access_info.IsDataConstantField())) { (FLAG_track_constant_fields && access_info.IsDataConstantField())) {
Node* value = jsgraph()->Constant(JSReceiver::GetDataProperty(&it)); Node* value = jsgraph()->Constant(JSReceiver::GetDataProperty(&it));
...@@ -243,7 +253,6 @@ Node* PropertyAccessBuilder::TryBuildLoadConstantDataField( ...@@ -243,7 +253,6 @@ Node* PropertyAccessBuilder::TryBuildLoadConstantDataField(
return value; return value;
} }
} }
}
return nullptr; return nullptr;
} }
...@@ -251,7 +260,6 @@ Node* PropertyAccessBuilder::BuildLoadDataField( ...@@ -251,7 +260,6 @@ Node* PropertyAccessBuilder::BuildLoadDataField(
Handle<Name> name, PropertyAccessInfo const& access_info, Node* receiver, Handle<Name> name, PropertyAccessInfo const& access_info, Node* receiver,
Node** effect, Node** control) { Node** effect, Node** control) {
DCHECK(access_info.IsDataField() || access_info.IsDataConstantField()); DCHECK(access_info.IsDataField() || access_info.IsDataConstantField());
receiver = ResolveHolder(access_info, receiver);
if (Node* value = if (Node* value =
TryBuildLoadConstantDataField(name, access_info, receiver)) { TryBuildLoadConstantDataField(name, access_info, receiver)) {
return value; return value;
...@@ -261,7 +269,7 @@ Node* PropertyAccessBuilder::BuildLoadDataField( ...@@ -261,7 +269,7 @@ Node* PropertyAccessBuilder::BuildLoadDataField(
Type const field_type = access_info.field_type(); Type const field_type = access_info.field_type();
MachineRepresentation const field_representation = MachineRepresentation const field_representation =
access_info.field_representation(); access_info.field_representation();
Node* storage = receiver; Node* storage = ResolveHolder(access_info, receiver);
if (!field_index.is_inobject()) { if (!field_index.is_inobject()) {
storage = *effect = graph()->NewNode( storage = *effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForJSObjectPropertiesOrHash()), simplified()->LoadField(AccessBuilder::ForJSObjectPropertiesOrHash()),
......
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