Commit eea2cc65 authored by Jakob Gruber's avatar Jakob Gruber Committed by V8 LUCI CQ

[compiler] Refactor PropertyAccessInfo to contain refs

.. instead of handles and update all uses. Likewise with
ElementAccessInfo. Essentially, this creates the needed refs up-front
and removes useless MakeRef calls from PAI users.

Bug: v8:7790, v8:11671
Change-Id: I175e77dcca27760101606587de615e3497e68c68
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3030701
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75805}
parent d430856d
...@@ -82,8 +82,8 @@ std::ostream& operator<<(std::ostream& os, AccessMode access_mode) { ...@@ -82,8 +82,8 @@ std::ostream& operator<<(std::ostream& os, AccessMode access_mode) {
} }
ElementAccessInfo::ElementAccessInfo( ElementAccessInfo::ElementAccessInfo(
ZoneVector<Handle<Map>>&& lookup_start_object_maps, ZoneVector<MapRef>&& lookup_start_object_maps, ElementsKind elements_kind,
ElementsKind elements_kind, Zone* zone) Zone* zone)
: elements_kind_(elements_kind), : elements_kind_(elements_kind),
lookup_start_object_maps_(lookup_start_object_maps), lookup_start_object_maps_(lookup_start_object_maps),
transition_sources_(zone) { transition_sources_(zone) {
...@@ -96,22 +96,21 @@ PropertyAccessInfo PropertyAccessInfo::Invalid(Zone* zone) { ...@@ -96,22 +96,21 @@ PropertyAccessInfo PropertyAccessInfo::Invalid(Zone* zone) {
} }
// static // static
PropertyAccessInfo PropertyAccessInfo::NotFound(Zone* zone, PropertyAccessInfo PropertyAccessInfo::NotFound(
Handle<Map> receiver_map, Zone* zone, MapRef receiver_map, base::Optional<JSObjectRef> holder) {
MaybeHandle<JSObject> holder) {
return PropertyAccessInfo(zone, kNotFound, holder, {{receiver_map}, zone}); return PropertyAccessInfo(zone, kNotFound, holder, {{receiver_map}, zone});
} }
// static // static
PropertyAccessInfo PropertyAccessInfo::DataField( PropertyAccessInfo PropertyAccessInfo::DataField(
Zone* zone, Handle<Map> receiver_map, Zone* zone, MapRef receiver_map,
ZoneVector<CompilationDependency const*>&& dependencies, ZoneVector<CompilationDependency const*>&& dependencies,
FieldIndex field_index, Representation field_representation, FieldIndex field_index, Representation field_representation,
Type field_type, Handle<Map> field_owner_map, MaybeHandle<Map> field_map, Type field_type, MapRef field_owner_map, base::Optional<MapRef> field_map,
MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map) { base::Optional<JSObjectRef> holder, base::Optional<MapRef> transition_map) {
DCHECK_IMPLIES( DCHECK_IMPLIES(field_representation.IsDouble(),
field_representation.IsDouble(), HasFieldRepresentationDependenciesOnMap(
HasFieldRepresentationDependenciesOnMap(dependencies, field_owner_map)); dependencies, field_owner_map.object()));
return PropertyAccessInfo(kDataField, holder, transition_map, field_index, return PropertyAccessInfo(kDataField, holder, transition_map, field_index,
field_representation, field_type, field_owner_map, field_representation, field_type, field_owner_map,
field_map, {{receiver_map}, zone}, field_map, {{receiver_map}, zone},
...@@ -120,11 +119,11 @@ PropertyAccessInfo PropertyAccessInfo::DataField( ...@@ -120,11 +119,11 @@ PropertyAccessInfo PropertyAccessInfo::DataField(
// static // static
PropertyAccessInfo PropertyAccessInfo::FastDataConstant( PropertyAccessInfo PropertyAccessInfo::FastDataConstant(
Zone* zone, Handle<Map> receiver_map, Zone* zone, MapRef receiver_map,
ZoneVector<CompilationDependency const*>&& dependencies, ZoneVector<CompilationDependency const*>&& dependencies,
FieldIndex field_index, Representation field_representation, FieldIndex field_index, Representation field_representation,
Type field_type, Handle<Map> field_owner_map, MaybeHandle<Map> field_map, Type field_type, MapRef field_owner_map, base::Optional<MapRef> field_map,
MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map) { base::Optional<JSObjectRef> holder, base::Optional<MapRef> transition_map) {
return PropertyAccessInfo(kFastDataConstant, holder, transition_map, return PropertyAccessInfo(kFastDataConstant, holder, transition_map,
field_index, field_representation, field_type, field_index, field_representation, field_type,
field_owner_map, field_map, {{receiver_map}, zone}, field_owner_map, field_map, {{receiver_map}, zone},
...@@ -133,39 +132,38 @@ PropertyAccessInfo PropertyAccessInfo::FastDataConstant( ...@@ -133,39 +132,38 @@ PropertyAccessInfo PropertyAccessInfo::FastDataConstant(
// static // static
PropertyAccessInfo PropertyAccessInfo::FastAccessorConstant( PropertyAccessInfo PropertyAccessInfo::FastAccessorConstant(
Zone* zone, Handle<Map> receiver_map, Handle<Object> constant, Zone* zone, MapRef receiver_map, base::Optional<ObjectRef> constant,
MaybeHandle<JSObject> holder) { base::Optional<JSObjectRef> holder) {
return PropertyAccessInfo(zone, kFastAccessorConstant, holder, constant, return PropertyAccessInfo(zone, kFastAccessorConstant, holder, constant, {},
MaybeHandle<Name>(), {{receiver_map}, zone}); {{receiver_map}, zone});
} }
// static // static
PropertyAccessInfo PropertyAccessInfo::ModuleExport(Zone* zone, PropertyAccessInfo PropertyAccessInfo::ModuleExport(Zone* zone,
Handle<Map> receiver_map, MapRef receiver_map,
Handle<Cell> cell) { CellRef cell) {
return PropertyAccessInfo(zone, kModuleExport, MaybeHandle<JSObject>(), cell, return PropertyAccessInfo(zone, kModuleExport, {}, cell, {},
MaybeHandle<Name>{}, {{receiver_map}, zone}); {{receiver_map}, zone});
} }
// static // static
PropertyAccessInfo PropertyAccessInfo::StringLength(Zone* zone, PropertyAccessInfo PropertyAccessInfo::StringLength(Zone* zone,
Handle<Map> receiver_map) { MapRef receiver_map) {
return PropertyAccessInfo(zone, kStringLength, MaybeHandle<JSObject>(), return PropertyAccessInfo(zone, kStringLength, {}, {{receiver_map}, zone});
{{receiver_map}, zone});
} }
// static // static
PropertyAccessInfo PropertyAccessInfo::DictionaryProtoDataConstant( PropertyAccessInfo PropertyAccessInfo::DictionaryProtoDataConstant(
Zone* zone, Handle<Map> receiver_map, Handle<JSObject> holder, Zone* zone, MapRef receiver_map, JSObjectRef holder,
InternalIndex dictionary_index, Handle<Name> name) { InternalIndex dictionary_index, NameRef name) {
return PropertyAccessInfo(zone, kDictionaryProtoDataConstant, holder, return PropertyAccessInfo(zone, kDictionaryProtoDataConstant, holder,
{{receiver_map}, zone}, dictionary_index, name); {{receiver_map}, zone}, dictionary_index, name);
} }
// static // static
PropertyAccessInfo PropertyAccessInfo::DictionaryProtoAccessorConstant( PropertyAccessInfo PropertyAccessInfo::DictionaryProtoAccessorConstant(
Zone* zone, Handle<Map> receiver_map, MaybeHandle<JSObject> holder, Zone* zone, MapRef receiver_map, base::Optional<JSObjectRef> holder,
Handle<Object> constant, Handle<Name> property_name) { ObjectRef constant, NameRef property_name) {
return PropertyAccessInfo(zone, kDictionaryProtoAccessorConstant, holder, return PropertyAccessInfo(zone, kDictionaryProtoAccessorConstant, holder,
constant, property_name, {{receiver_map}, zone}); constant, property_name, {{receiver_map}, zone});
} }
...@@ -193,8 +191,8 @@ PropertyAccessInfo::PropertyAccessInfo(Zone* zone) ...@@ -193,8 +191,8 @@ PropertyAccessInfo::PropertyAccessInfo(Zone* zone)
dictionary_index_(InternalIndex::NotFound()) {} dictionary_index_(InternalIndex::NotFound()) {}
PropertyAccessInfo::PropertyAccessInfo( PropertyAccessInfo::PropertyAccessInfo(
Zone* zone, Kind kind, MaybeHandle<JSObject> holder, Zone* zone, Kind kind, base::Optional<JSObjectRef> holder,
ZoneVector<Handle<Map>>&& lookup_start_object_maps) ZoneVector<MapRef>&& lookup_start_object_maps)
: kind_(kind), : kind_(kind),
lookup_start_object_maps_(lookup_start_object_maps), lookup_start_object_maps_(lookup_start_object_maps),
holder_(holder), holder_(holder),
...@@ -204,9 +202,9 @@ PropertyAccessInfo::PropertyAccessInfo( ...@@ -204,9 +202,9 @@ PropertyAccessInfo::PropertyAccessInfo(
dictionary_index_(InternalIndex::NotFound()) {} dictionary_index_(InternalIndex::NotFound()) {}
PropertyAccessInfo::PropertyAccessInfo( PropertyAccessInfo::PropertyAccessInfo(
Zone* zone, Kind kind, MaybeHandle<JSObject> holder, Zone* zone, Kind kind, base::Optional<JSObjectRef> holder,
Handle<Object> constant, MaybeHandle<Name> property_name, base::Optional<ObjectRef> constant, base::Optional<NameRef> name,
ZoneVector<Handle<Map>>&& lookup_start_object_maps) ZoneVector<MapRef>&& lookup_start_object_maps)
: kind_(kind), : kind_(kind),
lookup_start_object_maps_(lookup_start_object_maps), lookup_start_object_maps_(lookup_start_object_maps),
constant_(constant), constant_(constant),
...@@ -215,15 +213,16 @@ PropertyAccessInfo::PropertyAccessInfo( ...@@ -215,15 +213,16 @@ PropertyAccessInfo::PropertyAccessInfo(
field_representation_(Representation::None()), field_representation_(Representation::None()),
field_type_(Type::Any()), field_type_(Type::Any()),
dictionary_index_(InternalIndex::NotFound()), dictionary_index_(InternalIndex::NotFound()),
name_(property_name) { name_(name) {
DCHECK_IMPLIES(kind == kDictionaryProtoAccessorConstant, DCHECK_IMPLIES(kind == kDictionaryProtoAccessorConstant, name.has_value());
!property_name.is_null());
} }
PropertyAccessInfo::PropertyAccessInfo( PropertyAccessInfo::PropertyAccessInfo(
Kind kind, MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map, Kind kind, base::Optional<JSObjectRef> holder,
FieldIndex field_index, Representation field_representation, base::Optional<MapRef> transition_map, FieldIndex field_index,
Type field_type, Handle<Map> field_owner_map, MaybeHandle<Map> field_map, Representation field_representation, Type field_type,
ZoneVector<Handle<Map>>&& lookup_start_object_maps, MapRef field_owner_map, base::Optional<MapRef> field_map,
ZoneVector<MapRef>&& lookup_start_object_maps,
ZoneVector<CompilationDependency const*>&& unrecorded_dependencies) ZoneVector<CompilationDependency const*>&& unrecorded_dependencies)
: kind_(kind), : kind_(kind),
lookup_start_object_maps_(lookup_start_object_maps), lookup_start_object_maps_(lookup_start_object_maps),
...@@ -236,14 +235,14 @@ PropertyAccessInfo::PropertyAccessInfo( ...@@ -236,14 +235,14 @@ PropertyAccessInfo::PropertyAccessInfo(
field_owner_map_(field_owner_map), field_owner_map_(field_owner_map),
field_map_(field_map), field_map_(field_map),
dictionary_index_(InternalIndex::NotFound()) { dictionary_index_(InternalIndex::NotFound()) {
DCHECK_IMPLIES(!transition_map.is_null(), DCHECK_IMPLIES(transition_map.has_value(),
field_owner_map.address() == transition_map.address()); field_owner_map.equals(transition_map.value()));
} }
PropertyAccessInfo::PropertyAccessInfo( PropertyAccessInfo::PropertyAccessInfo(
Zone* zone, Kind kind, MaybeHandle<JSObject> holder, Zone* zone, Kind kind, base::Optional<JSObjectRef> holder,
ZoneVector<Handle<Map>>&& lookup_start_object_maps, ZoneVector<MapRef>&& lookup_start_object_maps,
InternalIndex dictionary_index, Handle<Name> name) InternalIndex dictionary_index, NameRef name)
: kind_(kind), : kind_(kind),
lookup_start_object_maps_(lookup_start_object_maps), lookup_start_object_maps_(lookup_start_object_maps),
holder_(holder), holder_(holder),
...@@ -262,10 +261,21 @@ MinimorphicLoadPropertyAccessInfo::MinimorphicLoadPropertyAccessInfo( ...@@ -262,10 +261,21 @@ MinimorphicLoadPropertyAccessInfo::MinimorphicLoadPropertyAccessInfo(
field_representation_(field_representation), field_representation_(field_representation),
field_type_(field_type) {} field_type_(field_type) {}
namespace {
template <class RefT>
bool OptionalRefEquals(base::Optional<RefT> lhs, base::Optional<RefT> rhs) {
if (!lhs.has_value()) return !rhs.has_value();
if (!rhs.has_value()) return false;
return lhs->equals(rhs.value());
}
} // namespace
bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that, bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that,
AccessMode access_mode, Zone* zone) { AccessMode access_mode, Zone* zone) {
if (this->kind_ != that->kind_) return false; if (this->kind_ != that->kind_) return false;
if (this->holder_.address() != that->holder_.address()) return false; if (!OptionalRefEquals(holder_, that->holder_)) return false;
switch (this->kind_) { switch (this->kind_) {
case kInvalid: case kInvalid:
...@@ -290,8 +300,8 @@ bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that, ...@@ -290,8 +300,8 @@ bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that,
} }
this->field_representation_ = Representation::Tagged(); this->field_representation_ = Representation::Tagged();
} }
if (this->field_map_.address() != that->field_map_.address()) { if (!OptionalRefEquals(field_map_, that->field_map_)) {
this->field_map_ = MaybeHandle<Map>(); field_map_ = {};
} }
break; break;
} }
...@@ -301,11 +311,10 @@ bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that, ...@@ -301,11 +311,10 @@ bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that,
// must match exactly, otherwise we cannot merge the stores. We // must match exactly, otherwise we cannot merge the stores. We
// also need to make sure that in case of transitioning stores, // also need to make sure that in case of transitioning stores,
// the transition targets match. // the transition targets match.
if (this->field_map_.address() != that->field_map_.address() || if (!OptionalRefEquals(field_map_, that->field_map_) ||
!this->field_representation_.Equals( !this->field_representation_.Equals(
that->field_representation_) || that->field_representation_) ||
this->transition_map_.address() != !OptionalRefEquals(transition_map_, that->transition_map_)) {
that->transition_map_.address()) {
return false; return false;
} }
break; break;
...@@ -329,7 +338,7 @@ bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that, ...@@ -329,7 +338,7 @@ bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that,
case kDictionaryProtoAccessorConstant: case kDictionaryProtoAccessorConstant:
case kFastAccessorConstant: { case kFastAccessorConstant: {
// Check if we actually access the same constant. // Check if we actually access the same constant.
if (this->constant_.address() == that->constant_.address()) { if (OptionalRefEquals(constant_, that->constant_)) {
DCHECK(this->unrecorded_dependencies_.empty()); DCHECK(this->unrecorded_dependencies_.empty());
DCHECK(that->unrecorded_dependencies_.empty()); DCHECK(that->unrecorded_dependencies_.empty());
this->lookup_start_object_maps_.insert( this->lookup_start_object_maps_.insert(
...@@ -369,10 +378,8 @@ bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that, ...@@ -369,10 +378,8 @@ bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that,
} }
ConstFieldInfo PropertyAccessInfo::GetConstFieldInfo() const { ConstFieldInfo PropertyAccessInfo::GetConstFieldInfo() const {
if (IsFastDataConstant()) { return IsFastDataConstant() ? ConstFieldInfo(field_owner_map_->object())
return ConstFieldInfo(field_owner_map_.ToHandleChecked()); : ConstFieldInfo::None();
}
return ConstFieldInfo::None();
} }
AccessInfoFactory::AccessInfoFactory(JSHeapBroker* broker, AccessInfoFactory::AccessInfoFactory(JSHeapBroker* broker,
...@@ -390,7 +397,7 @@ base::Optional<ElementAccessInfo> AccessInfoFactory::ComputeElementAccessInfo( ...@@ -390,7 +397,7 @@ base::Optional<ElementAccessInfo> AccessInfoFactory::ComputeElementAccessInfo(
if (!map_ref.has_value()) return {}; if (!map_ref.has_value()) return {};
if (!CanInlineElementAccess(*map_ref)) return base::nullopt; if (!CanInlineElementAccess(*map_ref)) return base::nullopt;
ElementsKind const elements_kind = map_ref->elements_kind(); ElementsKind const elements_kind = map_ref->elements_kind();
return ElementAccessInfo({{map}, zone()}, elements_kind, zone()); return ElementAccessInfo({{map_ref.value()}, zone()}, elements_kind, zone());
} }
bool AccessInfoFactory::ComputeElementAccessInfos( bool AccessInfoFactory::ComputeElementAccessInfos(
...@@ -418,7 +425,9 @@ bool AccessInfoFactory::ComputeElementAccessInfos( ...@@ -418,7 +425,9 @@ bool AccessInfoFactory::ComputeElementAccessInfos(
if (!access_info.has_value()) return false; if (!access_info.has_value()) return false;
for (size_t i = 1; i < group.size(); ++i) { for (size_t i = 1; i < group.size(); ++i) {
access_info->AddTransitionSource(group[i]); base::Optional<MapRef> map_ref = TryMakeRef(broker(), group[i]);
if (!map_ref.has_value()) continue;
access_info->AddTransitionSource(map_ref.value());
} }
access_infos->push_back(*access_info); access_infos->push_back(*access_info);
} }
...@@ -511,17 +520,33 @@ PropertyAccessInfo AccessInfoFactory::ComputeDataFieldAccessInfo( ...@@ -511,17 +520,33 @@ PropertyAccessInfo AccessInfoFactory::ComputeDataFieldAccessInfo(
// TODO(v8:11670): Make FindFieldOwner and friends robust wrt concurrency. // TODO(v8:11670): Make FindFieldOwner and friends robust wrt concurrency.
Handle<Map> field_owner_map = broker()->CanonicalPersistentHandle( Handle<Map> field_owner_map = broker()->CanonicalPersistentHandle(
map->FindFieldOwner(isolate(), descriptor)); map->FindFieldOwner(isolate(), descriptor));
base::Optional<MapRef> field_owner_map_ref =
TryMakeRef(broker(), field_owner_map);
if (!field_owner_map_ref.has_value()) return Invalid();
base::Optional<MapRef> field_map_ref;
if (!field_map.is_null()) {
field_map_ref = TryMakeRef(broker(), field_map.ToHandleChecked());
}
base::Optional<MapRef> receiver_map_ref = TryMakeRef(broker(), receiver_map);
if (!receiver_map_ref.has_value()) return Invalid();
base::Optional<JSObjectRef> holder_ref;
if (!holder.is_null()) {
holder_ref = TryMakeRef(broker(), holder.ToHandleChecked());
}
switch (constness) { switch (constness) {
case PropertyConstness::kMutable: case PropertyConstness::kMutable:
return PropertyAccessInfo::DataField( return PropertyAccessInfo::DataField(
zone(), receiver_map, std::move(unrecorded_dependencies), field_index, zone(), receiver_map_ref.value(), std::move(unrecorded_dependencies),
details_representation, field_type, field_owner_map, field_map, field_index, details_representation, field_type,
holder); field_owner_map_ref.value(), field_map_ref, holder_ref, {});
case PropertyConstness::kConst: case PropertyConstness::kConst:
return PropertyAccessInfo::FastDataConstant( return PropertyAccessInfo::FastDataConstant(
zone(), receiver_map, std::move(unrecorded_dependencies), field_index, zone(), receiver_map_ref.value(), std::move(unrecorded_dependencies),
details_representation, field_type, field_owner_map, field_map, field_index, details_representation, field_type,
holder); field_owner_map_ref.value(), field_map_ref, holder_ref, {});
} }
UNREACHABLE(); UNREACHABLE();
} }
...@@ -534,6 +559,11 @@ PropertyAccessInfo AccessorAccessInfoHelper( ...@@ -534,6 +559,11 @@ PropertyAccessInfo AccessorAccessInfoHelper(
const AccessInfoFactory* ai_factory, Handle<Map> receiver_map, const AccessInfoFactory* ai_factory, Handle<Map> receiver_map,
Handle<Name> name, Handle<Map> map, MaybeHandle<JSObject> holder, Handle<Name> name, Handle<Map> map, MaybeHandle<JSObject> holder,
AccessMode access_mode, AccessorsObjectGetter get_accessors) { AccessMode access_mode, AccessorsObjectGetter get_accessors) {
base::Optional<MapRef> receiver_map_ref = TryMakeRef(broker, receiver_map);
if (!receiver_map_ref.has_value()) {
return PropertyAccessInfo::Invalid(zone);
}
if (map->instance_type() == JS_MODULE_NAMESPACE_TYPE) { if (map->instance_type() == JS_MODULE_NAMESPACE_TYPE) {
DCHECK(map->is_prototype_map()); DCHECK(map->is_prototype_map());
Handle<PrototypeInfo> proto_info = broker->CanonicalPersistentHandle( Handle<PrototypeInfo> proto_info = broker->CanonicalPersistentHandle(
...@@ -548,15 +578,25 @@ PropertyAccessInfo AccessorAccessInfoHelper( ...@@ -548,15 +578,25 @@ PropertyAccessInfo AccessorAccessInfoHelper(
// This module has not been fully initialized yet. // This module has not been fully initialized yet.
return PropertyAccessInfo::Invalid(zone); return PropertyAccessInfo::Invalid(zone);
} }
return PropertyAccessInfo::ModuleExport(zone, receiver_map, cell); base::Optional<CellRef> cell_ref = TryMakeRef(broker, cell);
if (!cell_ref.has_value()) {
return PropertyAccessInfo::Invalid(zone);
}
return PropertyAccessInfo::ModuleExport(zone, receiver_map_ref.value(),
cell_ref.value());
} }
if (access_mode == AccessMode::kHas) { if (access_mode == AccessMode::kHas) {
// kHas is not supported for dictionary mode objects. // kHas is not supported for dictionary mode objects.
DCHECK(!map->is_dictionary_map()); DCHECK(!map->is_dictionary_map());
base::Optional<JSObjectRef> holder_ref;
if (!holder.is_null()) {
holder_ref = TryMakeRef(broker, holder.ToHandleChecked());
}
// HasProperty checks don't call getter/setters, existence is sufficient. // HasProperty checks don't call getter/setters, existence is sufficient.
return PropertyAccessInfo::FastAccessorConstant(zone, receiver_map, return PropertyAccessInfo::FastAccessorConstant(
Handle<Object>(), holder); zone, receiver_map_ref.value(), {}, holder_ref);
} }
Handle<Object> maybe_accessors = get_accessors(); Handle<Object> maybe_accessors = get_accessors();
if (!maybe_accessors->IsAccessorPair()) { if (!maybe_accessors->IsAccessorPair()) {
...@@ -567,8 +607,8 @@ PropertyAccessInfo AccessorAccessInfoHelper( ...@@ -567,8 +607,8 @@ PropertyAccessInfo AccessorAccessInfoHelper(
access_mode == AccessMode::kLoad ? accessors->getter() access_mode == AccessMode::kLoad ? accessors->getter()
: accessors->setter()); : accessors->setter());
ObjectData* data = broker->TryGetOrCreateData(accessor); base::Optional<ObjectRef> accessor_ref = TryMakeRef(broker, accessor);
if (data == nullptr) return PropertyAccessInfo::Invalid(zone); if (!accessor_ref.has_value()) return PropertyAccessInfo::Invalid(zone);
if (!accessor->IsJSFunction()) { if (!accessor->IsJSFunction()) {
CallOptimization optimization(broker->local_isolate_or_isolate(), accessor); CallOptimization optimization(broker->local_isolate_or_isolate(), accessor);
...@@ -600,12 +640,21 @@ PropertyAccessInfo AccessorAccessInfoHelper( ...@@ -600,12 +640,21 @@ PropertyAccessInfo AccessorAccessInfoHelper(
if (!access_info.IsInvalid()) return access_info; if (!access_info.IsInvalid()) return access_info;
} }
} }
base::Optional<JSObjectRef> holder_ref;
if (!holder.is_null()) {
holder_ref = TryMakeRef(broker, holder.ToHandleChecked());
}
if (map->is_dictionary_map()) { if (map->is_dictionary_map()) {
base::Optional<NameRef> name_ref = TryMakeRef(broker, name);
if (!name_ref.has_value()) return PropertyAccessInfo::Invalid(zone);
return PropertyAccessInfo::DictionaryProtoAccessorConstant( return PropertyAccessInfo::DictionaryProtoAccessorConstant(
zone, receiver_map, holder, accessor, name); zone, receiver_map_ref.value(), holder_ref, accessor_ref.value(),
name_ref.value());
} else { } else {
return PropertyAccessInfo::FastAccessorConstant(zone, receiver_map, return PropertyAccessInfo::FastAccessorConstant(
accessor, holder); zone, receiver_map_ref.value(), accessor_ref.value(), holder_ref);
} }
} }
...@@ -643,8 +692,16 @@ PropertyAccessInfo AccessInfoFactory::ComputeDictionaryProtoAccessInfo( ...@@ -643,8 +692,16 @@ PropertyAccessInfo AccessInfoFactory::ComputeDictionaryProtoAccessInfo(
} }
if (details.kind() == PropertyKind::kData) { if (details.kind() == PropertyKind::kData) {
base::Optional<MapRef> receiver_map_ref =
TryMakeRef(broker(), receiver_map);
if (!receiver_map_ref.has_value()) return Invalid();
base::Optional<JSObjectRef> holder_ref = TryMakeRef(broker(), holder);
if (!holder_ref.has_value()) return Invalid();
base::Optional<NameRef> name_ref = TryMakeRef(broker(), name);
if (!name_ref.has_value()) return Invalid();
return PropertyAccessInfo::DictionaryProtoDataConstant( return PropertyAccessInfo::DictionaryProtoDataConstant(
zone(), receiver_map, holder, dictionary_index, name); zone(), receiver_map_ref.value(), holder_ref.value(), dictionary_index,
name_ref.value());
} }
auto get_accessors = [&]() { auto get_accessors = [&]() {
...@@ -899,10 +956,20 @@ PropertyAccessInfo AccessInfoFactory::ComputePropertyAccessInfo( ...@@ -899,10 +956,20 @@ PropertyAccessInfo AccessInfoFactory::ComputePropertyAccessInfo(
if (access_mode == AccessMode::kStore) { if (access_mode == AccessMode::kStore) {
return LookupTransition(receiver_map, name, holder); return LookupTransition(receiver_map, name, holder);
} }
base::Optional<MapRef> receiver_map_ref =
TryMakeRef(broker(), receiver_map);
if (!receiver_map_ref.has_value()) return Invalid();
base::Optional<JSObjectRef> holder_ref;
if (!holder.is_null()) {
holder_ref = TryMakeRef(broker(), holder.ToHandleChecked());
}
// The property was not found (access returns undefined or throws // The property was not found (access returns undefined or throws
// depending on the language mode of the load operation. // depending on the language mode of the load operation.
// Implemented according to ES6 section 9.1.8 [[Get]] (P, Receiver) // Implemented according to ES6 section 9.1.8 [[Get]] (P, Receiver)
return PropertyAccessInfo::NotFound(zone(), receiver_map, holder); return PropertyAccessInfo::NotFound(zone(), receiver_map_ref.value(),
holder_ref);
} else { } else {
return Invalid(); return Invalid();
} }
...@@ -1014,7 +1081,7 @@ Maybe<ElementsKind> GeneralizeElementsKind(ElementsKind this_kind, ...@@ -1014,7 +1081,7 @@ Maybe<ElementsKind> GeneralizeElementsKind(ElementsKind this_kind,
base::Optional<ElementAccessInfo> AccessInfoFactory::ConsolidateElementLoad( base::Optional<ElementAccessInfo> AccessInfoFactory::ConsolidateElementLoad(
ElementAccessFeedback const& feedback) const { ElementAccessFeedback const& feedback) const {
if (feedback.transition_groups().empty()) return base::nullopt; if (feedback.transition_groups().empty()) return {};
DCHECK(!feedback.transition_groups().front().empty()); DCHECK(!feedback.transition_groups().front().empty());
Handle<Map> first_map = feedback.transition_groups().front().front(); Handle<Map> first_map = feedback.transition_groups().front().front();
...@@ -1023,20 +1090,20 @@ base::Optional<ElementAccessInfo> AccessInfoFactory::ConsolidateElementLoad( ...@@ -1023,20 +1090,20 @@ base::Optional<ElementAccessInfo> AccessInfoFactory::ConsolidateElementLoad(
InstanceType instance_type = first_map_ref->instance_type(); InstanceType instance_type = first_map_ref->instance_type();
ElementsKind elements_kind = first_map_ref->elements_kind(); ElementsKind elements_kind = first_map_ref->elements_kind();
ZoneVector<Handle<Map>> maps(zone()); ZoneVector<MapRef> maps(zone());
for (auto const& group : feedback.transition_groups()) { for (auto const& group : feedback.transition_groups()) {
for (Handle<Map> map_handle : group) { for (Handle<Map> map_handle : group) {
base::Optional<MapRef> map = TryMakeRef(broker(), map_handle); base::Optional<MapRef> map = TryMakeRef(broker(), map_handle);
if (!map.has_value()) return {}; if (!map.has_value()) return {};
if (map->instance_type() != instance_type || if (map->instance_type() != instance_type ||
!CanInlineElementAccess(*map)) { !CanInlineElementAccess(*map)) {
return base::nullopt; return {};
} }
if (!GeneralizeElementsKind(elements_kind, map->elements_kind()) if (!GeneralizeElementsKind(elements_kind, map->elements_kind())
.To(&elements_kind)) { .To(&elements_kind)) {
return base::nullopt; return {};
} }
maps.push_back(map->object()); maps.push_back(map.value());
} }
} }
...@@ -1048,7 +1115,9 @@ PropertyAccessInfo AccessInfoFactory::LookupSpecialFieldAccessor( ...@@ -1048,7 +1115,9 @@ PropertyAccessInfo AccessInfoFactory::LookupSpecialFieldAccessor(
// Check for String::length field accessor. // Check for String::length field accessor.
if (map->IsStringMap()) { if (map->IsStringMap()) {
if (Name::Equals(isolate(), name, isolate()->factory()->length_string())) { if (Name::Equals(isolate(), name, isolate()->factory()->length_string())) {
return PropertyAccessInfo::StringLength(zone(), map); base::Optional<MapRef> map_ref = TryMakeRef(broker(), map);
if (!map_ref.has_value()) return Invalid();
return PropertyAccessInfo::StringLength(zone(), map_ref.value());
} }
return Invalid(); return Invalid();
} }
...@@ -1075,9 +1144,12 @@ PropertyAccessInfo AccessInfoFactory::LookupSpecialFieldAccessor( ...@@ -1075,9 +1144,12 @@ PropertyAccessInfo AccessInfoFactory::LookupSpecialFieldAccessor(
field_type = type_cache_->kJSArrayLengthType; field_type = type_cache_->kJSArrayLengthType;
} }
} }
base::Optional<MapRef> map_ref = TryMakeRef(broker(), map);
if (!map_ref.has_value()) return Invalid();
// Special fields are always mutable. // Special fields are always mutable.
return PropertyAccessInfo::DataField(zone(), map, {{}, zone()}, field_index, return PropertyAccessInfo::DataField(
field_representation, field_type, map); zone(), map_ref.value(), {{}, zone()}, field_index,
field_representation, field_type, map_ref.value(), {}, {}, {});
} }
return Invalid(); return Invalid();
} }
...@@ -1176,20 +1248,35 @@ PropertyAccessInfo AccessInfoFactory::LookupTransition( ...@@ -1176,20 +1248,35 @@ PropertyAccessInfo AccessInfoFactory::LookupTransition(
transition_map_ref->SerializeBackPointer( transition_map_ref->SerializeBackPointer(
NotConcurrentInliningTag{broker()}); // For BuildPropertyStore. NotConcurrentInliningTag{broker()}); // For BuildPropertyStore.
} }
base::Optional<MapRef> field_map_ref;
if (!field_map.is_null()) {
field_map_ref = TryMakeRef(broker(), field_map.ToHandleChecked());
}
base::Optional<MapRef> map_ref = TryMakeRef(broker(), map);
if (!map_ref.has_value()) return Invalid();
base::Optional<JSObjectRef> holder_ref;
if (!holder.is_null()) {
holder_ref = TryMakeRef(broker(), holder.ToHandleChecked());
}
// Transitioning stores *may* store to const fields. The resulting // Transitioning stores *may* store to const fields. The resulting
// DataConstant access infos can be distinguished from later, i.e. redundant, // DataConstant access infos can be distinguished from later, i.e. redundant,
// stores to the same constant field by the presence of a transition map. // stores to the same constant field by the presence of a transition map.
switch (dependencies()->DependOnFieldConstness(*transition_map_ref, number)) { switch (dependencies()->DependOnFieldConstness(*transition_map_ref, number)) {
case PropertyConstness::kMutable: case PropertyConstness::kMutable:
return PropertyAccessInfo::DataField( return PropertyAccessInfo::DataField(
zone(), map, std::move(unrecorded_dependencies), field_index, zone(), map_ref.value(), std::move(unrecorded_dependencies),
details_representation, field_type, transition_map, field_map, holder, field_index, details_representation, field_type,
transition_map); transition_map_ref.value(), field_map_ref, holder_ref,
transition_map_ref.value());
case PropertyConstness::kConst: case PropertyConstness::kConst:
return PropertyAccessInfo::FastDataConstant( return PropertyAccessInfo::FastDataConstant(
zone(), map, std::move(unrecorded_dependencies), field_index, zone(), map_ref.value(), std::move(unrecorded_dependencies),
details_representation, field_type, transition_map, field_map, holder, field_index, details_representation, field_type,
transition_map); transition_map_ref.value(), field_map_ref, holder_ref,
transition_map_ref.value());
} }
UNREACHABLE(); UNREACHABLE();
} }
......
...@@ -37,26 +37,26 @@ std::ostream& operator<<(std::ostream&, AccessMode); ...@@ -37,26 +37,26 @@ std::ostream& operator<<(std::ostream&, AccessMode);
// This class encapsulates all information required to access a certain element. // This class encapsulates all information required to access a certain element.
class ElementAccessInfo final { class ElementAccessInfo final {
public: public:
ElementAccessInfo(ZoneVector<Handle<Map>>&& lookup_start_object_maps, ElementAccessInfo(ZoneVector<MapRef>&& lookup_start_object_maps,
ElementsKind elements_kind, Zone* zone); ElementsKind elements_kind, Zone* zone);
ElementsKind elements_kind() const { return elements_kind_; } ElementsKind elements_kind() const { return elements_kind_; }
ZoneVector<Handle<Map>> const& lookup_start_object_maps() const { ZoneVector<MapRef> const& lookup_start_object_maps() const {
return lookup_start_object_maps_; return lookup_start_object_maps_;
} }
ZoneVector<Handle<Map>> const& transition_sources() const { ZoneVector<MapRef> const& transition_sources() const {
return transition_sources_; return transition_sources_;
} }
void AddTransitionSource(Handle<Map> map) { void AddTransitionSource(MapRef map) {
CHECK_EQ(lookup_start_object_maps_.size(), 1); CHECK_EQ(lookup_start_object_maps_.size(), 1);
transition_sources_.push_back(map); transition_sources_.push_back(map);
} }
private: private:
ElementsKind elements_kind_; ElementsKind elements_kind_;
ZoneVector<Handle<Map>> lookup_start_object_maps_; ZoneVector<MapRef> lookup_start_object_maps_;
ZoneVector<Handle<Map>> transition_sources_; ZoneVector<MapRef> transition_sources_;
}; };
// This class encapsulates all information required to access a certain // This class encapsulates all information required to access a certain
...@@ -75,37 +75,35 @@ class PropertyAccessInfo final { ...@@ -75,37 +75,35 @@ class PropertyAccessInfo final {
kStringLength kStringLength
}; };
static PropertyAccessInfo NotFound(Zone* zone, Handle<Map> receiver_map, static PropertyAccessInfo NotFound(Zone* zone, MapRef receiver_map,
MaybeHandle<JSObject> holder); base::Optional<JSObjectRef> holder);
static PropertyAccessInfo DataField( static PropertyAccessInfo DataField(
Zone* zone, Handle<Map> receiver_map, Zone* zone, MapRef receiver_map,
ZoneVector<CompilationDependency const*>&& unrecorded_dependencies, ZoneVector<CompilationDependency const*>&& unrecorded_dependencies,
FieldIndex field_index, Representation field_representation, FieldIndex field_index, Representation field_representation,
Type field_type, Handle<Map> field_owner_map, Type field_type, MapRef field_owner_map, base::Optional<MapRef> field_map,
MaybeHandle<Map> field_map = MaybeHandle<Map>(), base::Optional<JSObjectRef> holder,
MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(), base::Optional<MapRef> transition_map);
MaybeHandle<Map> transition_map = MaybeHandle<Map>());
static PropertyAccessInfo FastDataConstant( static PropertyAccessInfo FastDataConstant(
Zone* zone, Handle<Map> receiver_map, Zone* zone, MapRef receiver_map,
ZoneVector<CompilationDependency const*>&& unrecorded_dependencies, ZoneVector<CompilationDependency const*>&& unrecorded_dependencies,
FieldIndex field_index, Representation field_representation, FieldIndex field_index, Representation field_representation,
Type field_type, Handle<Map> field_owner_map, MaybeHandle<Map> field_map, Type field_type, MapRef field_owner_map, base::Optional<MapRef> field_map,
MaybeHandle<JSObject> holder, base::Optional<JSObjectRef> holder,
MaybeHandle<Map> transition_map = MaybeHandle<Map>()); base::Optional<MapRef> transition_map);
static PropertyAccessInfo FastAccessorConstant(Zone* zone, static PropertyAccessInfo FastAccessorConstant(
Handle<Map> receiver_map, Zone* zone, MapRef receiver_map, base::Optional<ObjectRef> constant,
Handle<Object> constant, base::Optional<JSObjectRef> holder);
MaybeHandle<JSObject> holder); static PropertyAccessInfo ModuleExport(Zone* zone, MapRef receiver_map,
static PropertyAccessInfo ModuleExport(Zone* zone, Handle<Map> receiver_map, CellRef cell);
Handle<Cell> cell); static PropertyAccessInfo StringLength(Zone* zone, MapRef receiver_map);
static PropertyAccessInfo StringLength(Zone* zone, Handle<Map> receiver_map);
static PropertyAccessInfo Invalid(Zone* zone); static PropertyAccessInfo Invalid(Zone* zone);
static PropertyAccessInfo DictionaryProtoDataConstant( static PropertyAccessInfo DictionaryProtoDataConstant(
Zone* zone, Handle<Map> receiver_map, Handle<JSObject> holder, Zone* zone, MapRef receiver_map, JSObjectRef holder,
InternalIndex dict_index, Handle<Name> name); InternalIndex dict_index, NameRef name);
static PropertyAccessInfo DictionaryProtoAccessorConstant( static PropertyAccessInfo DictionaryProtoAccessorConstant(
Zone* zone, Handle<Map> receiver_map, MaybeHandle<JSObject> holder, Zone* zone, MapRef receiver_map, base::Optional<JSObjectRef> holder,
Handle<Object> constant, Handle<Name> name); ObjectRef constant, NameRef name);
bool Merge(PropertyAccessInfo const* that, AccessMode access_mode, bool Merge(PropertyAccessInfo const* that, AccessMode access_mode,
Zone* zone) V8_WARN_UNUSED_RESULT; Zone* zone) V8_WARN_UNUSED_RESULT;
...@@ -128,7 +126,7 @@ class PropertyAccessInfo final { ...@@ -128,7 +126,7 @@ class PropertyAccessInfo final {
return kind() == kDictionaryProtoAccessorConstant; return kind() == kDictionaryProtoAccessorConstant;
} }
bool HasTransitionMap() const { return !transition_map().is_null(); } bool HasTransitionMap() const { return transition_map().has_value(); }
bool HasDictionaryHolder() const { bool HasDictionaryHolder() const {
return kind_ == kDictionaryProtoDataConstant || return kind_ == kDictionaryProtoDataConstant ||
kind_ == kDictionaryProtoAccessorConstant; kind_ == kDictionaryProtoAccessorConstant;
...@@ -136,17 +134,17 @@ class PropertyAccessInfo final { ...@@ -136,17 +134,17 @@ class PropertyAccessInfo final {
ConstFieldInfo GetConstFieldInfo() const; ConstFieldInfo GetConstFieldInfo() const;
Kind kind() const { return kind_; } Kind kind() const { return kind_; }
MaybeHandle<JSObject> holder() const { base::Optional<JSObjectRef> holder() const {
// TODO(neis): There was a CHECK here that tries to protect against // TODO(neis): There was a CHECK here that tries to protect against
// using the access info without recording its dependencies first. // using the access info without recording its dependencies first.
// Find a more suitable place for it. // Find a more suitable place for it.
return holder_; return holder_;
} }
MaybeHandle<Map> transition_map() const { base::Optional<MapRef> transition_map() const {
DCHECK(!HasDictionaryHolder()); DCHECK(!HasDictionaryHolder());
return transition_map_; return transition_map_;
} }
Handle<Object> constant() const { return constant_; } base::Optional<ObjectRef> constant() const { return constant_; }
FieldIndex field_index() const { FieldIndex field_index() const {
DCHECK(!HasDictionaryHolder()); DCHECK(!HasDictionaryHolder());
return field_index_; return field_index_;
...@@ -160,11 +158,11 @@ class PropertyAccessInfo final { ...@@ -160,11 +158,11 @@ class PropertyAccessInfo final {
DCHECK(!HasDictionaryHolder()); DCHECK(!HasDictionaryHolder());
return field_representation_; return field_representation_;
} }
MaybeHandle<Map> field_map() const { base::Optional<MapRef> field_map() const {
DCHECK(!HasDictionaryHolder()); DCHECK(!HasDictionaryHolder());
return field_map_; return field_map_;
} }
ZoneVector<Handle<Map>> const& lookup_start_object_maps() const { ZoneVector<MapRef> const& lookup_start_object_maps() const {
return lookup_start_object_maps_; return lookup_start_object_maps_;
} }
...@@ -173,46 +171,48 @@ class PropertyAccessInfo final { ...@@ -173,46 +171,48 @@ class PropertyAccessInfo final {
return dictionary_index_; return dictionary_index_;
} }
Handle<Name> name() const { NameRef name() const {
DCHECK(HasDictionaryHolder()); DCHECK(HasDictionaryHolder());
return name_.ToHandleChecked(); return name_.value();
} }
private: private:
explicit PropertyAccessInfo(Zone* zone); explicit PropertyAccessInfo(Zone* zone);
PropertyAccessInfo(Zone* zone, Kind kind, MaybeHandle<JSObject> holder, PropertyAccessInfo(Zone* zone, Kind kind, base::Optional<JSObjectRef> holder,
ZoneVector<Handle<Map>>&& lookup_start_object_maps); ZoneVector<MapRef>&& lookup_start_object_maps);
PropertyAccessInfo(Zone* zone, Kind kind, MaybeHandle<JSObject> holder, PropertyAccessInfo(Zone* zone, Kind kind, base::Optional<JSObjectRef> holder,
Handle<Object> constant, MaybeHandle<Name> name, base::Optional<ObjectRef> constant,
ZoneVector<Handle<Map>>&& lookup_start_object_maps); base::Optional<NameRef> name,
PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder, ZoneVector<MapRef>&& lookup_start_object_maps);
MaybeHandle<Map> transition_map, FieldIndex field_index, PropertyAccessInfo(Kind kind, base::Optional<JSObjectRef> holder,
base::Optional<MapRef> transition_map,
FieldIndex field_index,
Representation field_representation, Type field_type, Representation field_representation, Type field_type,
Handle<Map> field_owner_map, MaybeHandle<Map> field_map, MapRef field_owner_map, base::Optional<MapRef> field_map,
ZoneVector<Handle<Map>>&& lookup_start_object_maps, ZoneVector<MapRef>&& lookup_start_object_maps,
ZoneVector<CompilationDependency const*>&& dependencies); ZoneVector<CompilationDependency const*>&& dependencies);
PropertyAccessInfo(Zone* zone, Kind kind, MaybeHandle<JSObject> holder, PropertyAccessInfo(Zone* zone, Kind kind, base::Optional<JSObjectRef> holder,
ZoneVector<Handle<Map>>&& lookup_start_object_maps, ZoneVector<MapRef>&& lookup_start_object_maps,
InternalIndex dictionary_index, Handle<Name> name); InternalIndex dictionary_index, NameRef name);
// Members used for fast and dictionary mode holders: // Members used for fast and dictionary mode holders:
Kind kind_; Kind kind_;
ZoneVector<Handle<Map>> lookup_start_object_maps_; ZoneVector<MapRef> lookup_start_object_maps_;
Handle<Object> constant_; base::Optional<ObjectRef> constant_;
MaybeHandle<JSObject> holder_; base::Optional<JSObjectRef> holder_;
// Members only used for fast mode holders: // Members only used for fast mode holders:
ZoneVector<CompilationDependency const*> unrecorded_dependencies_; ZoneVector<CompilationDependency const*> unrecorded_dependencies_;
MaybeHandle<Map> transition_map_; base::Optional<MapRef> transition_map_;
FieldIndex field_index_; FieldIndex field_index_;
Representation field_representation_; Representation field_representation_;
Type field_type_; Type field_type_;
MaybeHandle<Map> field_owner_map_; base::Optional<MapRef> field_owner_map_;
MaybeHandle<Map> field_map_; base::Optional<MapRef> field_map_;
// Members only used for dictionary mode holders: // Members only used for dictionary mode holders:
InternalIndex dictionary_index_; InternalIndex dictionary_index_;
MaybeHandle<Name> name_; base::Optional<NameRef> name_;
}; };
// This class encapsulates information required to generate load properties // This class encapsulates information required to generate load properties
......
...@@ -881,12 +881,10 @@ void DependOnStablePrototypeChain(CompilationDependencies* deps, MapRef map, ...@@ -881,12 +881,10 @@ void DependOnStablePrototypeChain(CompilationDependencies* deps, MapRef map,
} }
} // namespace } // namespace
template <class MapContainer>
void CompilationDependencies::DependOnStablePrototypeChains( void CompilationDependencies::DependOnStablePrototypeChains(
MapContainer const& receiver_maps, WhereToStart start, ZoneVector<MapRef> const& receiver_maps, WhereToStart start,
base::Optional<JSObjectRef> last_prototype) { base::Optional<JSObjectRef> last_prototype) {
for (auto map : receiver_maps) { for (MapRef receiver_map : receiver_maps) {
MapRef receiver_map = MakeRef(broker_, map);
if (start == kStartAtReceiver) DependOnStableMap(receiver_map); if (start == kStartAtReceiver) DependOnStableMap(receiver_map);
if (receiver_map.IsPrimitiveMap()) { if (receiver_map.IsPrimitiveMap()) {
// Perform the implicit ToObject for primitives here. // Perform the implicit ToObject for primitives here.
...@@ -900,12 +898,6 @@ void CompilationDependencies::DependOnStablePrototypeChains( ...@@ -900,12 +898,6 @@ void CompilationDependencies::DependOnStablePrototypeChains(
DependOnStablePrototypeChain(this, receiver_map, last_prototype); DependOnStablePrototypeChain(this, receiver_map, last_prototype);
} }
} }
template void CompilationDependencies::DependOnStablePrototypeChains(
ZoneVector<Handle<Map>> const& receiver_maps, WhereToStart start,
base::Optional<JSObjectRef> last_prototype);
template void CompilationDependencies::DependOnStablePrototypeChains(
ZoneHandleSet<Map> const& receiver_maps, WhereToStart start,
base::Optional<JSObjectRef> last_prototype);
void CompilationDependencies::DependOnElementsKinds( void CompilationDependencies::DependOnElementsKinds(
const AllocationSiteRef& site) { const AllocationSiteRef& site) {
......
...@@ -116,9 +116,8 @@ class V8_EXPORT_PRIVATE CompilationDependencies : public ZoneObject { ...@@ -116,9 +116,8 @@ class V8_EXPORT_PRIVATE CompilationDependencies : public ZoneObject {
// For each given map, depend on the stability of (the maps of) all prototypes // For each given map, depend on the stability of (the maps of) all prototypes
// up to (and including) the {last_prototype}. // up to (and including) the {last_prototype}.
template <class MapContainer>
void DependOnStablePrototypeChains( void DependOnStablePrototypeChains(
MapContainer const& receiver_maps, WhereToStart start, ZoneVector<MapRef> const& receiver_maps, WhereToStart start,
base::Optional<JSObjectRef> last_prototype = base::Optional<JSObjectRef> last_prototype =
base::Optional<JSObjectRef>()); base::Optional<JSObjectRef>());
......
...@@ -8002,14 +8002,12 @@ Reduction JSCallReducer::ReduceRegExpPrototypeTest(Node* node) { ...@@ -8002,14 +8002,12 @@ Reduction JSCallReducer::ReduceRegExpPrototypeTest(Node* node) {
// If "exec" has been modified on {regexp}, we can't do anything. // If "exec" has been modified on {regexp}, we can't do anything.
if (ai_exec.IsFastDataConstant()) { if (ai_exec.IsFastDataConstant()) {
Handle<JSObject> holder; base::Optional<JSObjectRef> holder = ai_exec.holder();
// Do not reduce if the exec method is not on the prototype chain. // Do not reduce if the exec method is not on the prototype chain.
if (!ai_exec.holder().ToHandle(&holder)) return inference.NoChange(); if (!holder.has_value()) return inference.NoChange();
JSObjectRef holder_ref = MakeRef(broker(), holder);
// Bail out if the exec method is not the original one. // Bail out if the exec method is not the original one.
base::Optional<ObjectRef> constant = holder_ref.GetOwnFastDataProperty( base::Optional<ObjectRef> constant = holder->GetOwnFastDataProperty(
ai_exec.field_representation(), ai_exec.field_index(), dependencies()); ai_exec.field_representation(), ai_exec.field_index(), dependencies());
if (!constant.has_value() || if (!constant.has_value() ||
!constant->equals(native_context().regexp_exec_function())) { !constant->equals(native_context().regexp_exec_function())) {
...@@ -8018,8 +8016,7 @@ Reduction JSCallReducer::ReduceRegExpPrototypeTest(Node* node) { ...@@ -8018,8 +8016,7 @@ Reduction JSCallReducer::ReduceRegExpPrototypeTest(Node* node) {
// Add proper dependencies on the {regexp}s [[Prototype]]s. // Add proper dependencies on the {regexp}s [[Prototype]]s.
dependencies()->DependOnStablePrototypeChains( dependencies()->DependOnStablePrototypeChains(
ai_exec.lookup_start_object_maps(), kStartAtPrototype, ai_exec.lookup_start_object_maps(), kStartAtPrototype, holder.value());
MakeRef(broker(), holder));
} else { } else {
// TODO(v8:11457) Support dictionary mode protoypes here. // TODO(v8:11457) Support dictionary mode protoypes here.
return inference.NoChange(); return inference.NoChange();
......
...@@ -35,19 +35,16 @@ namespace compiler { ...@@ -35,19 +35,16 @@ namespace compiler {
namespace { namespace {
bool HasNumberMaps(JSHeapBroker* broker, ZoneVector<Handle<Map>> const& maps) { bool HasNumberMaps(JSHeapBroker* broker, ZoneVector<MapRef> const& maps) {
for (auto map : maps) { for (MapRef map : maps) {
MapRef map_ref = MakeRef(broker, map); if (map.IsHeapNumberMap()) return true;
if (map_ref.IsHeapNumberMap()) return true;
} }
return false; return false;
} }
bool HasOnlyJSArrayMaps(JSHeapBroker* broker, bool HasOnlyJSArrayMaps(JSHeapBroker* broker, ZoneVector<MapRef> const& maps) {
ZoneVector<Handle<Map>> const& maps) { for (MapRef map : maps) {
for (auto map : maps) { if (!map.IsJSArrayMap()) return false;
MapRef map_ref = MakeRef(broker, map);
if (!map_ref.IsJSArrayMap()) return false;
} }
return true; return true;
} }
...@@ -427,8 +424,9 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) { ...@@ -427,8 +424,9 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) {
} }
// TODO(v8:11457) Support dictionary mode holders here. // TODO(v8:11457) Support dictionary mode holders here.
if (access_info.IsInvalid() || access_info.HasDictionaryHolder()) if (access_info.IsInvalid() || access_info.HasDictionaryHolder()) {
return NoChange(); return NoChange();
}
access_info.RecordDependencies(dependencies()); access_info.RecordDependencies(dependencies());
PropertyAccessBuilder access_builder(jsgraph(), broker(), dependencies()); PropertyAccessBuilder access_builder(jsgraph(), broker(), dependencies());
...@@ -456,10 +454,9 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) { ...@@ -456,10 +454,9 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) {
} }
if (access_info.IsFastDataConstant()) { if (access_info.IsFastDataConstant()) {
Handle<JSObject> holder; base::Optional<JSObjectRef> holder = access_info.holder();
bool found_on_proto = access_info.holder().ToHandle(&holder); bool found_on_proto = holder.has_value();
JSObjectRef holder_ref = JSObjectRef holder_ref = found_on_proto ? holder.value() : receiver_ref;
found_on_proto ? MakeRef(broker(), holder) : receiver_ref;
base::Optional<ObjectRef> constant = holder_ref.GetOwnFastDataProperty( base::Optional<ObjectRef> constant = holder_ref.GetOwnFastDataProperty(
access_info.field_representation(), access_info.field_index(), access_info.field_representation(), access_info.field_index(),
dependencies()); dependencies());
...@@ -470,7 +467,7 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) { ...@@ -470,7 +467,7 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) {
if (found_on_proto) { if (found_on_proto) {
dependencies()->DependOnStablePrototypeChains( dependencies()->DependOnStablePrototypeChains(
access_info.lookup_start_object_maps(), kStartAtPrototype, access_info.lookup_start_object_maps(), kStartAtPrototype,
MakeRef(broker(), holder)); holder.value());
} }
// Check that {constructor} is actually {receiver}. // Check that {constructor} is actually {receiver}.
...@@ -532,6 +529,8 @@ JSNativeContextSpecialization::InferHasInPrototypeChain( ...@@ -532,6 +529,8 @@ JSNativeContextSpecialization::InferHasInPrototypeChain(
broker(), receiver, effect, &receiver_maps); broker(), receiver, effect, &receiver_maps);
if (result == NodeProperties::kNoMaps) return kMayBeInPrototypeChain; if (result == NodeProperties::kNoMaps) return kMayBeInPrototypeChain;
ZoneVector<MapRef> receiver_map_refs(zone());
// Try to determine either that all of the {receiver_maps} have the given // Try to determine either that all of the {receiver_maps} have the given
// {prototype} in their chain, or that none do. If we can't tell, return // {prototype} in their chain, or that none do. If we can't tell, return
// kMayBeInPrototypeChain. // kMayBeInPrototypeChain.
...@@ -539,6 +538,7 @@ JSNativeContextSpecialization::InferHasInPrototypeChain( ...@@ -539,6 +538,7 @@ JSNativeContextSpecialization::InferHasInPrototypeChain(
bool none = true; bool none = true;
for (size_t i = 0; i < receiver_maps.size(); ++i) { for (size_t i = 0; i < receiver_maps.size(); ++i) {
MapRef map = MakeRef(broker(), receiver_maps[i]); MapRef map = MakeRef(broker(), receiver_maps[i]);
receiver_map_refs.push_back(map);
if (result == NodeProperties::kUnreliableMaps && !map.is_stable()) { if (result == NodeProperties::kUnreliableMaps && !map.is_stable()) {
return kMayBeInPrototypeChain; return kMayBeInPrototypeChain;
} }
...@@ -584,7 +584,7 @@ JSNativeContextSpecialization::InferHasInPrototypeChain( ...@@ -584,7 +584,7 @@ JSNativeContextSpecialization::InferHasInPrototypeChain(
WhereToStart start = result == NodeProperties::kUnreliableMaps WhereToStart start = result == NodeProperties::kUnreliableMaps
? kStartAtReceiver ? kStartAtReceiver
: kStartAtPrototype; : kStartAtPrototype;
dependencies()->DependOnStablePrototypeChains(receiver_maps, start, dependencies()->DependOnStablePrototypeChains(receiver_map_refs, start,
last_prototype); last_prototype);
} }
...@@ -1135,9 +1135,9 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess( ...@@ -1135,9 +1135,9 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
STATIC_ASSERT(JSLoadNamedFromSuperNode::ReceiverIndex() == 0); STATIC_ASSERT(JSLoadNamedFromSuperNode::ReceiverIndex() == 0);
Node* context = NodeProperties::GetContextInput(node); Node* context = NodeProperties::GetContextInput(node);
Node* frame_state = NodeProperties::GetFrameStateInput(node); FrameState frame_state{NodeProperties::GetFrameStateInput(node)};
Node* effect = NodeProperties::GetEffectInput(node); Effect effect{NodeProperties::GetEffectInput(node)};
Node* control = NodeProperties::GetControlInput(node); Control control{NodeProperties::GetControlInput(node)};
// receiver = the object we pass to the accessor (if any) as the "this" value. // receiver = the object we pass to the accessor (if any) as the "this" value.
Node* receiver = NodeProperties::GetValueInput(node, 0); Node* receiver = NodeProperties::GetValueInput(node, 0);
...@@ -1250,12 +1250,10 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess( ...@@ -1250,12 +1250,10 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
Node* if_true = graph()->NewNode(common()->IfTrue(), branch); Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
Node* etrue = effect; Node* etrue = effect;
Node* if_false = graph()->NewNode(common()->IfFalse(), branch); Control if_false{graph()->NewNode(common()->IfFalse(), branch)};
Node* efalse = effect; Effect efalse = effect;
{
access_builder.BuildCheckMaps(receiver, &efalse, if_false, access_builder.BuildCheckMaps(receiver, &efalse, if_false,
access_info.lookup_start_object_maps()); access_info.lookup_start_object_maps());
}
control = graph()->NewNode(common()->Merge(2), if_true, if_false); control = graph()->NewNode(common()->Merge(2), if_true, if_false);
effect = effect =
...@@ -1323,11 +1321,11 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess( ...@@ -1323,11 +1321,11 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
Node* this_value = value; Node* this_value = value;
Node* this_lookup_start_object = lookup_start_object; Node* this_lookup_start_object = lookup_start_object;
Node* this_receiver = receiver; Node* this_receiver = receiver;
Node* this_effect = effect; Effect this_effect = effect;
Node* this_control = fallthrough_control; Control this_control{fallthrough_control};
// Perform map check on {lookup_start_object}. // Perform map check on {lookup_start_object}.
ZoneVector<Handle<Map>> const& lookup_start_object_maps = ZoneVector<MapRef> const& lookup_start_object_maps =
access_info.lookup_start_object_maps(); access_info.lookup_start_object_maps();
{ {
// Whether to insert a dedicated MapGuard node into the // Whether to insert a dedicated MapGuard node into the
...@@ -1349,8 +1347,8 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess( ...@@ -1349,8 +1347,8 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
} else { } else {
// Explicitly branch on the {lookup_start_object_maps}. // Explicitly branch on the {lookup_start_object_maps}.
ZoneHandleSet<Map> maps; ZoneHandleSet<Map> maps;
for (Handle<Map> map : lookup_start_object_maps) { for (MapRef map : lookup_start_object_maps) {
maps.insert(map, graph()->zone()); maps.insert(map.object(), graph()->zone());
} }
Node* check = this_effect = Node* check = this_effect =
graph()->NewNode(simplified()->CompareMaps(maps), graph()->NewNode(simplified()->CompareMaps(maps),
...@@ -1381,8 +1379,8 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess( ...@@ -1381,8 +1379,8 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
// Introduce a MapGuard to learn from this on the effect chain. // Introduce a MapGuard to learn from this on the effect chain.
if (insert_map_guard) { if (insert_map_guard) {
ZoneHandleSet<Map> maps; ZoneHandleSet<Map> maps;
for (auto lookup_start_object_map : lookup_start_object_maps) { for (MapRef map : lookup_start_object_maps) {
maps.insert(lookup_start_object_map, graph()->zone()); maps.insert(map.object(), graph()->zone());
} }
this_effect = this_effect =
graph()->NewNode(simplified()->MapGuard(maps), graph()->NewNode(simplified()->MapGuard(maps),
...@@ -1709,10 +1707,10 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess( ...@@ -1709,10 +1707,10 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
JSHasPropertyNode::ObjectIndex() == 0); JSHasPropertyNode::ObjectIndex() == 0);
Node* receiver = NodeProperties::GetValueInput(node, 0); Node* receiver = NodeProperties::GetValueInput(node, 0);
Node* effect = NodeProperties::GetEffectInput(node); FrameState frame_state{
Node* control = NodeProperties::GetControlInput(node); NodeProperties::FindFrameStateBefore(node, jsgraph()->Dead())};
Node* frame_state = Effect effect{NodeProperties::GetEffectInput(node)};
NodeProperties::FindFrameStateBefore(node, jsgraph()->Dead()); Control control{NodeProperties::GetControlInput(node)};
// TODO(neis): It's odd that we do optimizations below that don't really care // TODO(neis): It's odd that we do optimizations below that don't really care
// about the feedback, but we don't do them when the feedback is megamorphic. // about the feedback, but we don't do them when the feedback is megamorphic.
...@@ -1753,8 +1751,7 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess( ...@@ -1753,8 +1751,7 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
// the zone allocation of this vector. // the zone allocation of this vector.
ZoneVector<MapRef> prototype_maps(zone()); ZoneVector<MapRef> prototype_maps(zone());
for (ElementAccessInfo const& access_info : access_infos) { for (ElementAccessInfo const& access_info : access_infos) {
for (Handle<Map> map : access_info.lookup_start_object_maps()) { for (MapRef receiver_map : access_info.lookup_start_object_maps()) {
MapRef receiver_map = MakeRef(broker(), map);
// If the {receiver_map} has a prototype and its elements backing // If the {receiver_map} has a prototype and its elements backing
// store is either holey, or we have a potentially growing store, // store is either holey, or we have a potentially growing store,
// then we need to check that all prototypes have stable maps with // then we need to check that all prototypes have stable maps with
...@@ -1797,11 +1794,9 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess( ...@@ -1797,11 +1794,9 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
ElementAccessInfo access_info = access_infos.front(); ElementAccessInfo access_info = access_infos.front();
// Perform possible elements kind transitions. // Perform possible elements kind transitions.
MapRef transition_target = MapRef transition_target = access_info.lookup_start_object_maps().front();
MakeRef(broker(), access_info.lookup_start_object_maps().front()); for (MapRef transition_source : access_info.transition_sources()) {
for (auto source : access_info.transition_sources()) {
DCHECK_EQ(access_info.lookup_start_object_maps().size(), 1); DCHECK_EQ(access_info.lookup_start_object_maps().size(), 1);
MapRef transition_source = MakeRef(broker(), source);
effect = graph()->NewNode( effect = graph()->NewNode(
simplified()->TransitionElementsKind(ElementsTransition( simplified()->TransitionElementsKind(ElementsTransition(
IsSimpleMapChangeTransition(transition_source.elements_kind(), IsSimpleMapChangeTransition(transition_source.elements_kind(),
...@@ -1845,14 +1840,12 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess( ...@@ -1845,14 +1840,12 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
Node* this_receiver = receiver; Node* this_receiver = receiver;
Node* this_value = value; Node* this_value = value;
Node* this_index = index; Node* this_index = index;
Node* this_effect = effect; Effect this_effect = effect;
Node* this_control = fallthrough_control; Control this_control{fallthrough_control};
// Perform possible elements kind transitions. // Perform possible elements kind transitions.
MapRef transition_target = MapRef transition_target = access_info.lookup_start_object_maps().front();
MakeRef(broker(), access_info.lookup_start_object_maps().front()); for (MapRef transition_source : access_info.transition_sources()) {
for (auto source : access_info.transition_sources()) {
MapRef transition_source = MakeRef(broker(), source);
DCHECK_EQ(access_info.lookup_start_object_maps().size(), 1); DCHECK_EQ(access_info.lookup_start_object_maps().size(), 1);
this_effect = graph()->NewNode( this_effect = graph()->NewNode(
simplified()->TransitionElementsKind(ElementsTransition( simplified()->TransitionElementsKind(ElementsTransition(
...@@ -1865,7 +1858,7 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess( ...@@ -1865,7 +1858,7 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
} }
// Perform map check(s) on {receiver}. // Perform map check(s) on {receiver}.
ZoneVector<Handle<Map>> const& receiver_maps = ZoneVector<MapRef> const& receiver_maps =
access_info.lookup_start_object_maps(); access_info.lookup_start_object_maps();
if (j == access_infos.size() - 1) { if (j == access_infos.size() - 1) {
// Last map check on the fallthrough control path, do a // Last map check on the fallthrough control path, do a
...@@ -1876,8 +1869,8 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess( ...@@ -1876,8 +1869,8 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
} else { } else {
// Explicitly branch on the {receiver_maps}. // Explicitly branch on the {receiver_maps}.
ZoneHandleSet<Map> maps; ZoneHandleSet<Map> maps;
for (Handle<Map> map : receiver_maps) { for (MapRef map : receiver_maps) {
maps.insert(map, graph()->zone()); maps.insert(map.object(), graph()->zone());
} }
Node* check = this_effect = Node* check = this_effect =
graph()->NewNode(simplified()->CompareMaps(maps), receiver, graph()->NewNode(simplified()->CompareMaps(maps), receiver,
...@@ -2217,14 +2210,13 @@ Node* JSNativeContextSpecialization::InlinePropertyGetterCall( ...@@ -2217,14 +2210,13 @@ Node* JSNativeContextSpecialization::InlinePropertyGetterCall(
Node* receiver, ConvertReceiverMode receiver_mode, Node* context, Node* receiver, ConvertReceiverMode receiver_mode, Node* context,
Node* frame_state, Node** effect, Node** control, Node* frame_state, Node** effect, Node** control,
ZoneVector<Node*>* if_exceptions, PropertyAccessInfo const& access_info) { ZoneVector<Node*>* if_exceptions, PropertyAccessInfo const& access_info) {
ObjectRef constant = MakeRef(broker(), access_info.constant()); ObjectRef constant = access_info.constant().value();
if (access_info.IsDictionaryProtoAccessorConstant()) { if (access_info.IsDictionaryProtoAccessorConstant()) {
// For fast mode holders we recorded dependencies in BuildPropertyLoad. // For fast mode holders we recorded dependencies in BuildPropertyLoad.
for (const Handle<Map> map : access_info.lookup_start_object_maps()) { for (const MapRef map : access_info.lookup_start_object_maps()) {
dependencies()->DependOnConstantInDictionaryPrototypeChain( dependencies()->DependOnConstantInDictionaryPrototypeChain(
MakeRef(broker(), map), MakeRef(broker(), access_info.name()), map, access_info.name(), constant, PropertyKind::kAccessor);
constant, PropertyKind::kAccessor);
} }
} }
...@@ -2239,10 +2231,9 @@ Node* JSNativeContextSpecialization::InlinePropertyGetterCall( ...@@ -2239,10 +2231,9 @@ Node* JSNativeContextSpecialization::InlinePropertyGetterCall(
receiver_mode), receiver_mode),
target, receiver, feedback, context, frame_state, *effect, *control); target, receiver, feedback, context, frame_state, *effect, *control);
} else { } else {
Node* holder = access_info.holder().is_null() Node* holder = access_info.holder().has_value()
? receiver ? jsgraph()->Constant(access_info.holder().value())
: jsgraph()->Constant(MakeRef( : receiver;
broker(), access_info.holder().ToHandleChecked()));
value = InlineApiCall(receiver, holder, frame_state, nullptr, effect, value = InlineApiCall(receiver, holder, frame_state, nullptr, effect,
control, constant.AsFunctionTemplateInfo()); control, constant.AsFunctionTemplateInfo());
} }
...@@ -2262,7 +2253,7 @@ void JSNativeContextSpecialization::InlinePropertySetterCall( ...@@ -2262,7 +2253,7 @@ void JSNativeContextSpecialization::InlinePropertySetterCall(
Node* receiver, Node* value, Node* context, Node* frame_state, Node* receiver, Node* value, Node* context, Node* frame_state,
Node** effect, Node** control, ZoneVector<Node*>* if_exceptions, Node** effect, Node** control, ZoneVector<Node*>* if_exceptions,
PropertyAccessInfo const& access_info) { PropertyAccessInfo const& access_info) {
ObjectRef constant = MakeRef(broker(), access_info.constant()); ObjectRef constant = access_info.constant().value();
Node* target = jsgraph()->Constant(constant); Node* target = jsgraph()->Constant(constant);
// Introduce the call to the setter function. // Introduce the call to the setter function.
if (constant.IsJSFunction()) { if (constant.IsJSFunction()) {
...@@ -2274,10 +2265,9 @@ void JSNativeContextSpecialization::InlinePropertySetterCall( ...@@ -2274,10 +2265,9 @@ void JSNativeContextSpecialization::InlinePropertySetterCall(
target, receiver, value, feedback, context, frame_state, *effect, target, receiver, value, feedback, context, frame_state, *effect,
*control); *control);
} else { } else {
Node* holder = access_info.holder().is_null() Node* holder = access_info.holder().has_value()
? receiver ? jsgraph()->Constant(access_info.holder().value())
: jsgraph()->Constant(MakeRef( : receiver;
broker(), access_info.holder().ToHandleChecked()));
InlineApiCall(receiver, holder, frame_state, value, effect, control, InlineApiCall(receiver, holder, frame_state, value, effect, control,
constant.AsFunctionTemplateInfo()); constant.AsFunctionTemplateInfo());
} }
...@@ -2351,12 +2341,11 @@ JSNativeContextSpecialization::BuildPropertyLoad( ...@@ -2351,12 +2341,11 @@ JSNativeContextSpecialization::BuildPropertyLoad(
Node* effect, Node* control, NameRef const& name, Node* effect, Node* control, NameRef const& name,
ZoneVector<Node*>* if_exceptions, PropertyAccessInfo const& access_info) { ZoneVector<Node*>* if_exceptions, PropertyAccessInfo const& access_info) {
// Determine actual holder and perform prototype chain checks. // Determine actual holder and perform prototype chain checks.
Handle<JSObject> holder; base::Optional<JSObjectRef> holder = access_info.holder();
if (access_info.holder().ToHandle(&holder) && if (holder.has_value() && !access_info.HasDictionaryHolder()) {
!access_info.HasDictionaryHolder()) {
dependencies()->DependOnStablePrototypeChains( dependencies()->DependOnStablePrototypeChains(
access_info.lookup_start_object_maps(), kStartAtPrototype, access_info.lookup_start_object_maps(), kStartAtPrototype,
MakeRef(broker(), holder)); holder.value());
} }
// Generate the actual property access. // Generate the actual property access.
...@@ -2373,8 +2362,7 @@ JSNativeContextSpecialization::BuildPropertyLoad( ...@@ -2373,8 +2362,7 @@ JSNativeContextSpecialization::BuildPropertyLoad(
InlinePropertyGetterCall(receiver, receiver_mode, context, frame_state, InlinePropertyGetterCall(receiver, receiver_mode, context, frame_state,
&effect, &control, if_exceptions, access_info); &effect, &control, if_exceptions, access_info);
} else if (access_info.IsModuleExport()) { } else if (access_info.IsModuleExport()) {
Node* cell = Node* cell = jsgraph()->Constant(access_info.constant().value().AsCell());
jsgraph()->Constant(MakeRef(broker(), access_info.constant()).AsCell());
value = effect = value = effect =
graph()->NewNode(simplified()->LoadField(AccessBuilder::ForCellValue()), graph()->NewNode(simplified()->LoadField(AccessBuilder::ForCellValue()),
cell, effect, control); cell, effect, control);
...@@ -2406,11 +2394,11 @@ JSNativeContextSpecialization::BuildPropertyTest( ...@@ -2406,11 +2394,11 @@ JSNativeContextSpecialization::BuildPropertyTest(
DCHECK(!access_info.HasDictionaryHolder()); DCHECK(!access_info.HasDictionaryHolder());
// Determine actual holder and perform prototype chain checks. // Determine actual holder and perform prototype chain checks.
Handle<JSObject> holder; base::Optional<JSObjectRef> holder = access_info.holder();
if (access_info.holder().ToHandle(&holder)) { if (holder.has_value()) {
dependencies()->DependOnStablePrototypeChains( dependencies()->DependOnStablePrototypeChains(
access_info.lookup_start_object_maps(), kStartAtPrototype, access_info.lookup_start_object_maps(), kStartAtPrototype,
MakeRef(broker(), holder)); holder.value());
} }
Node* value = access_info.IsNotFound() ? jsgraph()->FalseConstant() Node* value = access_info.IsNotFound() ? jsgraph()->FalseConstant()
...@@ -2448,13 +2436,13 @@ JSNativeContextSpecialization::BuildPropertyStore( ...@@ -2448,13 +2436,13 @@ JSNativeContextSpecialization::BuildPropertyStore(
Node* control, NameRef const& name, ZoneVector<Node*>* if_exceptions, Node* control, NameRef const& name, ZoneVector<Node*>* if_exceptions,
PropertyAccessInfo const& access_info, AccessMode access_mode) { PropertyAccessInfo const& access_info, AccessMode access_mode) {
// Determine actual holder and perform prototype chain checks. // Determine actual holder and perform prototype chain checks.
Handle<JSObject> holder;
PropertyAccessBuilder access_builder(jsgraph(), broker(), dependencies()); PropertyAccessBuilder access_builder(jsgraph(), broker(), dependencies());
if (access_info.holder().ToHandle(&holder)) { base::Optional<JSObjectRef> holder = access_info.holder();
if (holder.has_value()) {
DCHECK_NE(AccessMode::kStoreInLiteral, access_mode); DCHECK_NE(AccessMode::kStoreInLiteral, access_mode);
dependencies()->DependOnStablePrototypeChains( dependencies()->DependOnStablePrototypeChains(
access_info.lookup_start_object_maps(), kStartAtPrototype, access_info.lookup_start_object_maps(), kStartAtPrototype,
MakeRef(broker(), holder)); holder.value());
} }
DCHECK(!access_info.IsNotFound()); DCHECK(!access_info.IsNotFound());
...@@ -2575,12 +2563,13 @@ JSNativeContextSpecialization::BuildPropertyStore( ...@@ -2575,12 +2563,13 @@ JSNativeContextSpecialization::BuildPropertyStore(
} else if (field_representation == } else if (field_representation ==
MachineRepresentation::kTaggedPointer) { MachineRepresentation::kTaggedPointer) {
Handle<Map> field_map; base::Optional<MapRef> field_map = access_info.field_map();
if (access_info.field_map().ToHandle(&field_map)) { if (field_map.has_value()) {
// Emit a map check for the value. // Emit a map check for the value.
effect = graph()->NewNode( effect =
simplified()->CheckMaps(CheckMapsFlag::kNone, graph()->NewNode(simplified()->CheckMaps(
ZoneHandleSet<Map>(field_map)), CheckMapsFlag::kNone,
ZoneHandleSet<Map>(field_map->object())),
value, effect, control); value, effect, control);
} else { } else {
// Ensure that {value} is a HeapObject. // Ensure that {value} is a HeapObject.
...@@ -2607,11 +2596,11 @@ JSNativeContextSpecialization::BuildPropertyStore( ...@@ -2607,11 +2596,11 @@ JSNativeContextSpecialization::BuildPropertyStore(
UNREACHABLE(); UNREACHABLE();
} }
// Check if we need to perform a transitioning store. // Check if we need to perform a transitioning store.
Handle<Map> transition_map; base::Optional<MapRef> transition_map = access_info.transition_map();
if (access_info.transition_map().ToHandle(&transition_map)) { if (transition_map.has_value()) {
// Check if we need to grow the properties backing store // Check if we need to grow the properties backing store
// with this transitioning store. // with this transitioning store.
MapRef transition_map_ref = MakeRef(broker(), transition_map); MapRef transition_map_ref = transition_map.value();
MapRef original_map = transition_map_ref.GetBackPointer().AsMap(); MapRef original_map = transition_map_ref.GetBackPointer().AsMap();
if (original_map.UnusedPropertyFields() == 0) { if (original_map.UnusedPropertyFields() == 0) {
DCHECK(!field_index.is_inobject()); DCHECK(!field_index.is_inobject());
...@@ -2713,7 +2702,7 @@ JSNativeContextSpecialization::BuildElementAccess( ...@@ -2713,7 +2702,7 @@ JSNativeContextSpecialization::BuildElementAccess(
// TODO(bmeurer): We currently specialize based on elements kind. We should // TODO(bmeurer): We currently specialize based on elements kind. We should
// also be able to properly support strings and other JSObjects here. // also be able to properly support strings and other JSObjects here.
ElementsKind elements_kind = access_info.elements_kind(); ElementsKind elements_kind = access_info.elements_kind();
ZoneVector<Handle<Map>> const& receiver_maps = ZoneVector<MapRef> const& receiver_maps =
access_info.lookup_start_object_maps(); access_info.lookup_start_object_maps();
if (IsTypedArrayElementsKind(elements_kind)) { if (IsTypedArrayElementsKind(elements_kind)) {
...@@ -3455,12 +3444,11 @@ Node* JSNativeContextSpecialization::BuildCheckEqualsName(NameRef const& name, ...@@ -3455,12 +3444,11 @@ Node* JSNativeContextSpecialization::BuildCheckEqualsName(NameRef const& name,
} }
bool JSNativeContextSpecialization::CanTreatHoleAsUndefined( bool JSNativeContextSpecialization::CanTreatHoleAsUndefined(
ZoneVector<Handle<Map>> const& receiver_maps) { ZoneVector<MapRef> const& receiver_maps) {
// Check if all {receiver_maps} have one of the initial Array.prototype // Check if all {receiver_maps} have one of the initial Array.prototype
// or Object.prototype objects as their prototype (in any of the current // or Object.prototype objects as their prototype (in any of the current
// native contexts, as the global Array protector works isolate-wide). // native contexts, as the global Array protector works isolate-wide).
for (Handle<Map> map : receiver_maps) { for (MapRef receiver_map : receiver_maps) {
MapRef receiver_map = MakeRef(broker(), map);
ObjectRef receiver_prototype = receiver_map.prototype().value(); ObjectRef receiver_prototype = receiver_map.prototype().value();
if (!receiver_prototype.IsJSObject() || if (!receiver_prototype.IsJSObject() ||
!broker()->IsArrayOrObjectPrototype(receiver_prototype.AsJSObject())) { !broker()->IsArrayOrObjectPrototype(receiver_prototype.AsJSObject())) {
......
...@@ -210,7 +210,7 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final ...@@ -210,7 +210,7 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
// Checks if we can turn the hole into undefined when loading an element // Checks if we can turn the hole into undefined when loading an element
// from an object with one of the {receiver_maps}; sets up appropriate // from an object with one of the {receiver_maps}; sets up appropriate
// code dependencies and might use the array protector cell. // code dependencies and might use the array protector cell.
bool CanTreatHoleAsUndefined(ZoneVector<Handle<Map>> const& receiver_maps); bool CanTreatHoleAsUndefined(ZoneVector<MapRef> const& receiver_maps);
void RemoveImpossibleMaps(Node* object, ZoneVector<Handle<Map>>* maps) const; void RemoveImpossibleMaps(Node* object, ZoneVector<Handle<Map>>* maps) const;
......
...@@ -34,31 +34,28 @@ SimplifiedOperatorBuilder* PropertyAccessBuilder::simplified() const { ...@@ -34,31 +34,28 @@ SimplifiedOperatorBuilder* PropertyAccessBuilder::simplified() const {
return jsgraph()->simplified(); return jsgraph()->simplified();
} }
bool HasOnlyStringMaps(JSHeapBroker* broker, bool HasOnlyStringMaps(JSHeapBroker* broker, ZoneVector<MapRef> const& maps) {
ZoneVector<Handle<Map>> const& maps) { for (MapRef map : maps) {
for (auto map : maps) { if (!map.IsStringMap()) return false;
MapRef map_ref = MakeRef(broker, map);
if (!map_ref.IsStringMap()) return false;
} }
return true; return true;
} }
namespace { namespace {
bool HasOnlyNumberMaps(JSHeapBroker* broker, bool HasOnlyNumberMaps(JSHeapBroker* broker, ZoneVector<MapRef> const& maps) {
ZoneVector<Handle<Map>> const& maps) { for (MapRef map : maps) {
for (auto map : maps) { if (map.instance_type() != HEAP_NUMBER_TYPE) return false;
MapRef map_ref = MakeRef(broker, map);
if (map_ref.instance_type() != HEAP_NUMBER_TYPE) return false;
} }
return true; return true;
} }
} // namespace } // namespace
bool PropertyAccessBuilder::TryBuildStringCheck( bool PropertyAccessBuilder::TryBuildStringCheck(JSHeapBroker* broker,
JSHeapBroker* broker, ZoneVector<Handle<Map>> const& maps, Node** receiver, ZoneVector<MapRef> const& maps,
Node** effect, Node* control) { Node** receiver, Effect* effect,
Control control) {
if (HasOnlyStringMaps(broker, maps)) { if (HasOnlyStringMaps(broker, maps)) {
// Monormorphic string access (ignoring the fact that there are multiple // Monormorphic string access (ignoring the fact that there are multiple
// String maps). // String maps).
...@@ -70,9 +67,10 @@ bool PropertyAccessBuilder::TryBuildStringCheck( ...@@ -70,9 +67,10 @@ bool PropertyAccessBuilder::TryBuildStringCheck(
return false; return false;
} }
bool PropertyAccessBuilder::TryBuildNumberCheck( bool PropertyAccessBuilder::TryBuildNumberCheck(JSHeapBroker* broker,
JSHeapBroker* broker, ZoneVector<Handle<Map>> const& maps, Node** receiver, ZoneVector<MapRef> const& maps,
Node** effect, Node* control) { Node** receiver, Effect* effect,
Control control) {
if (HasOnlyNumberMaps(broker, maps)) { if (HasOnlyNumberMaps(broker, maps)) {
// Monomorphic number access (we also deal with Smis here). // Monomorphic number access (we also deal with Smis here).
*receiver = *effect = *receiver = *effect =
...@@ -83,15 +81,15 @@ bool PropertyAccessBuilder::TryBuildNumberCheck( ...@@ -83,15 +81,15 @@ bool PropertyAccessBuilder::TryBuildNumberCheck(
return false; return false;
} }
void PropertyAccessBuilder::BuildCheckMaps( void PropertyAccessBuilder::BuildCheckMaps(Node* object, Effect* effect,
Node* object, Node** effect, Node* control, Control control,
ZoneVector<Handle<Map>> const& maps) { ZoneVector<MapRef> const& maps) {
HeapObjectMatcher m(object); HeapObjectMatcher m(object);
if (m.HasResolvedValue()) { if (m.HasResolvedValue()) {
MapRef object_map = m.Ref(broker()).map(); MapRef object_map = m.Ref(broker()).map();
if (object_map.is_stable()) { if (object_map.is_stable()) {
for (Handle<Map> map : maps) { for (MapRef map : maps) {
if (MakeRef(broker(), map).equals(object_map)) { if (map.equals(object_map)) {
dependencies()->DependOnStableMap(object_map); dependencies()->DependOnStableMap(object_map);
return; return;
} }
...@@ -100,10 +98,9 @@ void PropertyAccessBuilder::BuildCheckMaps( ...@@ -100,10 +98,9 @@ void PropertyAccessBuilder::BuildCheckMaps(
} }
ZoneHandleSet<Map> map_set; ZoneHandleSet<Map> map_set;
CheckMapsFlags flags = CheckMapsFlag::kNone; CheckMapsFlags flags = CheckMapsFlag::kNone;
for (Handle<Map> map : maps) { for (MapRef map : maps) {
MapRef object_map = MakeRef(broker(), map); map_set.insert(map.object(), graph()->zone());
map_set.insert(object_map.object(), graph()->zone()); if (map.is_migration_target()) {
if (object_map.is_migration_target()) {
flags |= CheckMapsFlag::kTryMigrateInstance; flags |= CheckMapsFlag::kTryMigrateInstance;
} }
} }
...@@ -127,9 +124,9 @@ Node* PropertyAccessBuilder::BuildCheckValue(Node* receiver, Effect* effect, ...@@ -127,9 +124,9 @@ Node* PropertyAccessBuilder::BuildCheckValue(Node* receiver, Effect* effect,
Node* PropertyAccessBuilder::ResolveHolder( Node* PropertyAccessBuilder::ResolveHolder(
PropertyAccessInfo const& access_info, Node* lookup_start_object) { PropertyAccessInfo const& access_info, Node* lookup_start_object) {
Handle<JSObject> holder; base::Optional<JSObjectRef> holder = access_info.holder();
if (access_info.holder().ToHandle(&holder)) { if (holder.has_value()) {
return jsgraph()->Constant(MakeRef(broker(), holder)); return jsgraph()->Constant(holder.value());
} }
return lookup_start_object; return lookup_start_object;
} }
...@@ -155,29 +152,27 @@ base::Optional<Node*> PropertyAccessBuilder::FoldLoadDictPrototypeConstant( ...@@ -155,29 +152,27 @@ base::Optional<Node*> PropertyAccessBuilder::FoldLoadDictPrototypeConstant(
DCHECK(V8_DICT_PROPERTY_CONST_TRACKING_BOOL); DCHECK(V8_DICT_PROPERTY_CONST_TRACKING_BOOL);
DCHECK(access_info.IsDictionaryProtoDataConstant()); DCHECK(access_info.IsDictionaryProtoDataConstant());
JSObjectRef holder =
MakeRef(broker(), access_info.holder().ToHandleChecked());
InternalIndex index = access_info.dictionary_index(); InternalIndex index = access_info.dictionary_index();
base::Optional<ObjectRef> value = base::Optional<ObjectRef> value =
holder.GetOwnDictionaryProperty(index, dependencies()); access_info.holder()->GetOwnDictionaryProperty(index, dependencies());
if (!value) return {}; if (!value) return {};
for (Handle<Map> map : access_info.lookup_start_object_maps()) { for (MapRef map : access_info.lookup_start_object_maps()) {
Handle<Map> map_handle = map.object();
// Non-JSReceivers that passed AccessInfoFactory::ComputePropertyAccessInfo // Non-JSReceivers that passed AccessInfoFactory::ComputePropertyAccessInfo
// must have different lookup start map. // must have different lookup start map.
if (!map->IsJSReceiverMap()) { if (!map_handle->IsJSReceiverMap()) {
// Perform the implicit ToObject for primitives here. // Perform the implicit ToObject for primitives here.
// Implemented according to ES6 section 7.3.2 GetV (V, P). // Implemented according to ES6 section 7.3.2 GetV (V, P).
JSFunction constructor = JSFunction constructor =
Map::GetConstructorFunction( Map::GetConstructorFunction(
*map, *broker()->target_native_context().object()) *map_handle, *broker()->target_native_context().object())
.value(); .value();
map = MakeRef(broker(), constructor.initial_map()).object(); map = MakeRef(broker(), constructor.initial_map());
DCHECK(map->IsJSObjectMap()); DCHECK(map.object()->IsJSObjectMap());
} }
dependencies()->DependOnConstantInDictionaryPrototypeChain( dependencies()->DependOnConstantInDictionaryPrototypeChain(
MakeRef(broker(), map), MakeRef(broker(), access_info.name()), map, access_info.name(), value.value(), PropertyKind::kData);
value.value(), PropertyKind::kData);
} }
return jsgraph()->Constant(value.value()); return jsgraph()->Constant(value.value());
...@@ -189,9 +184,10 @@ Node* PropertyAccessBuilder::TryFoldLoadConstantDataField( ...@@ -189,9 +184,10 @@ Node* PropertyAccessBuilder::TryFoldLoadConstantDataField(
if (!access_info.IsFastDataConstant()) return nullptr; if (!access_info.IsFastDataConstant()) return nullptr;
// First, determine if we have a constant holder to load from. // First, determine if we have a constant holder to load from.
Handle<JSObject> holder; base::Optional<JSObjectRef> holder = access_info.holder();
// If {access_info} has a holder, just use it. // If {access_info} has a holder, just use it.
if (!access_info.holder().ToHandle(&holder)) { if (!holder.has_value()) {
// Otherwise, try to match the {lookup_start_object} as a constant. // Otherwise, try to match the {lookup_start_object} as a constant.
HeapObjectMatcher m(lookup_start_object); HeapObjectMatcher m(lookup_start_object);
if (!m.HasResolvedValue() || !m.Ref(broker()).IsJSObject()) return nullptr; if (!m.HasResolvedValue() || !m.Ref(broker()).IsJSObject()) return nullptr;
...@@ -199,26 +195,22 @@ Node* PropertyAccessBuilder::TryFoldLoadConstantDataField( ...@@ -199,26 +195,22 @@ Node* PropertyAccessBuilder::TryFoldLoadConstantDataField(
// Let us make sure the actual map of the constant lookup_start_object is // Let us make sure the actual map of the constant lookup_start_object is
// among the maps in {access_info}. // among the maps in {access_info}.
MapRef lookup_start_object_map = m.Ref(broker()).map(); MapRef lookup_start_object_map = m.Ref(broker()).map();
if (std::find_if( if (std::find_if(access_info.lookup_start_object_maps().begin(),
access_info.lookup_start_object_maps().begin(), access_info.lookup_start_object_maps().end(),
access_info.lookup_start_object_maps().end(), [&](Handle<Map> map) { [&](MapRef map) {
return MakeRef(broker(), map).equals(lookup_start_object_map); return map.equals(lookup_start_object_map);
}) == access_info.lookup_start_object_maps().end()) { }) == access_info.lookup_start_object_maps().end()) {
// The map of the lookup_start_object is not in the feedback, let us bail // The map of the lookup_start_object is not in the feedback, let us bail
// out. // out.
return nullptr; return nullptr;
} }
holder = m.Ref(broker()).AsJSObject().object(); holder = m.Ref(broker()).AsJSObject();
} }
JSObjectRef holder_ref = MakeRef(broker(), holder); base::Optional<ObjectRef> value =
base::Optional<ObjectRef> value = holder_ref.GetOwnFastDataProperty( holder->GetOwnFastDataProperty(access_info.field_representation(),
access_info.field_representation(), access_info.field_index(), access_info.field_index(), dependencies());
dependencies()); return value.has_value() ? jsgraph()->Constant(*value) : nullptr;
if (!value.has_value()) {
return nullptr;
}
return jsgraph()->Constant(*value);
} }
Node* PropertyAccessBuilder::BuildLoadDataField(NameRef const& name, Node* PropertyAccessBuilder::BuildLoadDataField(NameRef const& name,
...@@ -333,12 +325,11 @@ Node* PropertyAccessBuilder::BuildLoadDataField( ...@@ -333,12 +325,11 @@ Node* PropertyAccessBuilder::BuildLoadDataField(
field_representation == MachineRepresentation::kCompressedPointer) { field_representation == MachineRepresentation::kCompressedPointer) {
// Remember the map of the field value, if its map is stable. This is // Remember the map of the field value, if its map is stable. This is
// used by the LoadElimination to eliminate map checks on the result. // used by the LoadElimination to eliminate map checks on the result.
Handle<Map> field_map; base::Optional<MapRef> field_map = access_info.field_map();
if (access_info.field_map().ToHandle(&field_map)) { if (field_map.has_value()) {
MapRef field_map_ref = MakeRef(broker(), field_map); if (field_map->is_stable()) {
if (field_map_ref.is_stable()) { dependencies()->DependOnStableMap(field_map.value());
dependencies()->DependOnStableMap(field_map_ref); field_access.map = field_map->object();
field_access.map = field_map;
} }
} }
} }
......
...@@ -36,25 +36,15 @@ class PropertyAccessBuilder { ...@@ -36,25 +36,15 @@ class PropertyAccessBuilder {
// Builds the appropriate string check if the maps are only string // Builds the appropriate string check if the maps are only string
// maps. // maps.
bool TryBuildStringCheck(JSHeapBroker* broker, bool TryBuildStringCheck(JSHeapBroker* broker, ZoneVector<MapRef> const& maps,
ZoneVector<Handle<Map>> const& maps, Node** receiver, Node** receiver, Effect* effect, Control control);
Node** effect, Node* control);
// Builds a number check if all maps are number maps. // Builds a number check if all maps are number maps.
bool TryBuildNumberCheck(JSHeapBroker* broker, bool TryBuildNumberCheck(JSHeapBroker* broker, ZoneVector<MapRef> const& maps,
ZoneVector<Handle<Map>> const& maps, Node** receiver, Node** receiver, Effect* effect, Control control);
Node** effect, Node* control);
// TODO(jgruber): Remove the untyped version once all uses are
// updated.
void BuildCheckMaps(Node* object, Node** effect, Node* control,
ZoneVector<Handle<Map>> const& maps);
void BuildCheckMaps(Node* object, Effect* effect, Control control, void BuildCheckMaps(Node* object, Effect* effect, Control control,
ZoneVector<Handle<Map>> const& maps) { ZoneVector<MapRef> const& maps);
Node* e = *effect;
Node* c = control;
BuildCheckMaps(object, &e, c, maps);
*effect = e;
}
Node* BuildCheckValue(Node* receiver, Effect* effect, Control control, Node* BuildCheckValue(Node* receiver, Effect* effect, Control control,
Handle<HeapObject> value); Handle<HeapObject> value);
...@@ -106,8 +96,7 @@ class PropertyAccessBuilder { ...@@ -106,8 +96,7 @@ class PropertyAccessBuilder {
CompilationDependencies* dependencies_; CompilationDependencies* dependencies_;
}; };
bool HasOnlyStringMaps(JSHeapBroker* broker, bool HasOnlyStringMaps(JSHeapBroker* broker, ZoneVector<MapRef> const& maps);
ZoneVector<Handle<Map>> const& maps);
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
......
...@@ -2613,11 +2613,10 @@ PropertyAccessInfo SerializerForBackgroundCompilation::ProcessMapForRegExpTest( ...@@ -2613,11 +2613,10 @@ PropertyAccessInfo SerializerForBackgroundCompilation::ProcessMapForRegExpTest(
AccessMode::kLoad, dependencies(), AccessMode::kLoad, dependencies(),
SerializationPolicy::kSerializeIfNeeded); SerializationPolicy::kSerializeIfNeeded);
Handle<JSObject> holder; base::Optional<JSObjectRef> holder = ai_exec.holder();
if (ai_exec.IsFastDataConstant() && ai_exec.holder().ToHandle(&holder)) { if (ai_exec.IsFastDataConstant() && holder.has_value()) {
// The property is on the prototype chain. // The property is on the prototype chain.
JSObjectRef holder_ref = MakeRef(broker(), holder); holder->GetOwnFastDataProperty(ai_exec.field_representation(),
holder_ref.GetOwnFastDataProperty(ai_exec.field_representation(),
ai_exec.field_index(), nullptr, ai_exec.field_index(), nullptr,
SerializationPolicy::kSerializeIfNeeded); SerializationPolicy::kSerializeIfNeeded);
} }
...@@ -2632,12 +2631,11 @@ void SerializerForBackgroundCompilation::ProcessHintsForRegExpTest( ...@@ -2632,12 +2631,11 @@ void SerializerForBackgroundCompilation::ProcessHintsForRegExpTest(
Handle<Map> regexp_map(regexp->map(), broker()->isolate()); Handle<Map> regexp_map(regexp->map(), broker()->isolate());
PropertyAccessInfo ai_exec = PropertyAccessInfo ai_exec =
ProcessMapForRegExpTest(MakeRef(broker(), regexp_map)); ProcessMapForRegExpTest(MakeRef(broker(), regexp_map));
Handle<JSObject> holder; base::Optional<JSObjectRef> holder = ai_exec.holder();
if (ai_exec.IsFastDataConstant() && !ai_exec.holder().ToHandle(&holder)) { if (ai_exec.IsFastDataConstant() && holder.has_value()) {
// The property is on the object itself. // The property is on the object itself.
JSObjectRef holder_ref = MakeRef(broker(), regexp); holder->GetOwnFastDataProperty(ai_exec.field_representation(),
holder_ref.GetOwnFastDataProperty( ai_exec.field_index(), nullptr,
ai_exec.field_representation(), ai_exec.field_index(), nullptr,
SerializationPolicy::kSerializeIfNeeded); SerializationPolicy::kSerializeIfNeeded);
} }
} }
...@@ -2927,12 +2925,12 @@ void SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess( ...@@ -2927,12 +2925,12 @@ void SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess(
// For JSNativeContextSpecialization::InlinePropertySetterCall // For JSNativeContextSpecialization::InlinePropertySetterCall
// and InlinePropertyGetterCall. // and InlinePropertyGetterCall.
base::Optional<ObjectRef> constant = access_info.constant();
if ((access_info.IsFastAccessorConstant() || if ((access_info.IsFastAccessorConstant() ||
access_info.IsDictionaryProtoAccessorConstant()) && access_info.IsDictionaryProtoAccessorConstant()) &&
!access_info.constant().is_null()) { constant.has_value()) {
if (access_info.constant()->IsJSFunction()) { if (constant->IsJSFunction()) {
JSFunctionRef function = JSFunctionRef function = constant->AsJSFunction();
MakeRef(broker(), Handle<JSFunction>::cast(access_info.constant()));
if (receiver_map.has_value()) { if (receiver_map.has_value()) {
// For JSCallReducer and JSInlining(Heuristic). // For JSCallReducer and JSInlining(Heuristic).
...@@ -2957,16 +2955,10 @@ void SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess( ...@@ -2957,16 +2955,10 @@ void SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess(
} }
} }
} }
} else if (access_info.constant()->IsJSBoundFunction()) {
// For JSCallReducer::ReduceJSCall.
MakeRef(broker(), Handle<JSBoundFunction>::cast(access_info.constant()));
} else {
MakeRef(broker(), FunctionTemplateInfo::cast(*access_info.constant()));
} }
} else if (access_info.IsModuleExport()) { } else if (access_info.IsModuleExport()) {
// For JSNativeContextSpecialization::BuildPropertyLoad // For JSNativeContextSpecialization::BuildPropertyLoad
DCHECK(!access_info.constant().is_null()); DCHECK(access_info.constant()->IsCell());
MakeRef(broker(), Handle<Cell>::cast(access_info.constant()));
} }
switch (access_mode) { switch (access_mode) {
...@@ -2975,11 +2967,8 @@ void SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess( ...@@ -2975,11 +2967,8 @@ void SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess(
// PropertyAccessBuilder::BuildLoadDictPrototypeConstant // PropertyAccessBuilder::BuildLoadDictPrototypeConstant
if (access_info.IsFastDataConstant() || if (access_info.IsFastDataConstant() ||
access_info.IsDictionaryProtoDataConstant()) { access_info.IsDictionaryProtoDataConstant()) {
base::Optional<JSObjectRef> holder; base::Optional<JSObjectRef> holder = access_info.holder();
Handle<JSObject> prototype; if (!holder.has_value()) {
if (access_info.holder().ToHandle(&prototype)) {
holder = MakeRef(broker(), prototype);
} else {
CHECK_IMPLIES(concrete_receiver.has_value(), CHECK_IMPLIES(concrete_receiver.has_value(),
concrete_receiver->map().equals(*receiver_map)); concrete_receiver->map().equals(*receiver_map));
holder = concrete_receiver; holder = concrete_receiver;
...@@ -3004,12 +2993,12 @@ void SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess( ...@@ -3004,12 +2993,12 @@ void SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess(
case AccessMode::kStoreInLiteral: case AccessMode::kStoreInLiteral:
// For MapInference (StoreField case). // For MapInference (StoreField case).
if (access_info.IsDataField() || access_info.IsFastDataConstant()) { if (access_info.IsDataField() || access_info.IsFastDataConstant()) {
Handle<Map> transition_map; base::Optional<MapRef> transition_map = access_info.transition_map();
if (access_info.transition_map().ToHandle(&transition_map)) { if (transition_map.has_value()) {
MapRef map_ref = MakeRef(broker(), transition_map);
TRACE_BROKER(broker(), "Propagating transition map " TRACE_BROKER(broker(), "Propagating transition map "
<< map_ref << " to receiver hints."); << transition_map.value()
receiver->AddMap(transition_map, zone(), broker_, false); << " to receiver hints.");
receiver->AddMap(transition_map->object(), zone(), broker_, false);
} }
} }
break; break;
...@@ -3323,10 +3312,10 @@ void SerializerForBackgroundCompilation::ProcessConstantForInstanceOf( ...@@ -3323,10 +3312,10 @@ void SerializerForBackgroundCompilation::ProcessConstantForInstanceOf(
ProcessConstantForOrdinaryHasInstance(constructor_heap_object, ProcessConstantForOrdinaryHasInstance(constructor_heap_object,
walk_prototypes); walk_prototypes);
} else if (access_info.IsFastDataConstant()) { } else if (access_info.IsFastDataConstant()) {
Handle<JSObject> holder; base::Optional<JSObjectRef> holder = access_info.holder();
bool found_on_proto = access_info.holder().ToHandle(&holder); bool found_on_proto = holder.has_value();
JSObjectRef holder_ref = JSObjectRef holder_ref =
found_on_proto ? MakeRef(broker(), holder) : constructor.AsJSObject(); found_on_proto ? holder.value() : constructor.AsJSObject();
base::Optional<ObjectRef> constant = holder_ref.GetOwnFastDataProperty( base::Optional<ObjectRef> constant = holder_ref.GetOwnFastDataProperty(
access_info.field_representation(), access_info.field_index(), nullptr, access_info.field_representation(), access_info.field_index(), nullptr,
SerializationPolicy::kSerializeIfNeeded); SerializationPolicy::kSerializeIfNeeded);
......
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