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,51 +197,60 @@ Node* PropertyAccessBuilder::ResolveHolder( ...@@ -197,51 +197,60 @@ 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.
HeapObjectMatcher m(receiver);
if (m.HasValue() && m.Value()->IsJSObject()) { // First, determine if we have a constant holder to load from.
// Make sure the actual map of the receiver is among the maps in Handle<JSObject> holder;
// {access_info}. // 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);
if (!m.HasValue() || !m.Value()->IsJSObject()) return nullptr;
// 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;
} }
// TODO(ishell): Use something simpler like holder = Handle<JSObject>::cast(m.Value());
// }
// Handle<Object> value =
// JSObject::FastPropertyAt(Handle<JSObject>::cast(m.Value()), // TODO(ishell): Use something simpler like
// Representation::Tagged(), field_index); //
// // Handle<Object> value =
// here, once we have the immutable bit in the access_info. // JSObject::FastPropertyAt(Handle<JSObject>::cast(m.Value()),
// Representation::Tagged(), field_index);
//
// here, once we have the immutable bit in the access_info.
// 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)); if (!is_readonly_non_configurable) {
if (!is_readonly_non_configurable) { // It's necessary to add dependency on the map that introduced
// It's necessary to add dependency on the map that introduced // the field.
// the field. DCHECK(access_info.IsDataConstantField());
DCHECK(access_info.IsDataConstantField()); DCHECK(!it.is_dictionary_holder());
DCHECK(!it.is_dictionary_holder()); MapRef map(broker(),
MapRef map(broker(), handle(it.GetHolder<HeapObject>()->map(), isolate()));
handle(it.GetHolder<HeapObject>()->map(), isolate())); map.SerializeOwnDescriptors(); // TODO(neis): Remove later.
map.SerializeOwnDescriptors(); // TODO(neis): Remove later. if (dependencies()->DependOnFieldConstness(
if (dependencies()->DependOnFieldConstness( map, it.GetFieldDescriptorIndex()) !=
map, it.GetFieldDescriptorIndex()) != PropertyConstness::kConst) {
PropertyConstness::kConst) { return nullptr;
return nullptr;
}
} }
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