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
This diff is collapsed.
......@@ -37,26 +37,26 @@ std::ostream& operator<<(std::ostream&, AccessMode);
// This class encapsulates all information required to access a certain element.
class ElementAccessInfo final {
public:
ElementAccessInfo(ZoneVector<Handle<Map>>&& lookup_start_object_maps,
ElementAccessInfo(ZoneVector<MapRef>&& lookup_start_object_maps,
ElementsKind elements_kind, Zone* zone);
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_;
}
ZoneVector<Handle<Map>> const& transition_sources() const {
ZoneVector<MapRef> const& transition_sources() const {
return transition_sources_;
}
void AddTransitionSource(Handle<Map> map) {
void AddTransitionSource(MapRef map) {
CHECK_EQ(lookup_start_object_maps_.size(), 1);
transition_sources_.push_back(map);
}
private:
ElementsKind elements_kind_;
ZoneVector<Handle<Map>> lookup_start_object_maps_;
ZoneVector<Handle<Map>> transition_sources_;
ZoneVector<MapRef> lookup_start_object_maps_;
ZoneVector<MapRef> transition_sources_;
};
// This class encapsulates all information required to access a certain
......@@ -75,37 +75,35 @@ class PropertyAccessInfo final {
kStringLength
};
static PropertyAccessInfo NotFound(Zone* zone, Handle<Map> receiver_map,
MaybeHandle<JSObject> holder);
static PropertyAccessInfo NotFound(Zone* zone, MapRef receiver_map,
base::Optional<JSObjectRef> holder);
static PropertyAccessInfo DataField(
Zone* zone, Handle<Map> receiver_map,
Zone* zone, MapRef receiver_map,
ZoneVector<CompilationDependency const*>&& unrecorded_dependencies,
FieldIndex field_index, Representation field_representation,
Type field_type, Handle<Map> field_owner_map,
MaybeHandle<Map> field_map = MaybeHandle<Map>(),
MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(),
MaybeHandle<Map> transition_map = MaybeHandle<Map>());
Type field_type, MapRef field_owner_map, base::Optional<MapRef> field_map,
base::Optional<JSObjectRef> holder,
base::Optional<MapRef> transition_map);
static PropertyAccessInfo FastDataConstant(
Zone* zone, Handle<Map> receiver_map,
Zone* zone, MapRef receiver_map,
ZoneVector<CompilationDependency const*>&& unrecorded_dependencies,
FieldIndex field_index, Representation field_representation,
Type field_type, Handle<Map> field_owner_map, MaybeHandle<Map> field_map,
MaybeHandle<JSObject> holder,
MaybeHandle<Map> transition_map = MaybeHandle<Map>());
static PropertyAccessInfo FastAccessorConstant(Zone* zone,
Handle<Map> receiver_map,
Handle<Object> constant,
MaybeHandle<JSObject> holder);
static PropertyAccessInfo ModuleExport(Zone* zone, Handle<Map> receiver_map,
Handle<Cell> cell);
static PropertyAccessInfo StringLength(Zone* zone, Handle<Map> receiver_map);
Type field_type, MapRef field_owner_map, base::Optional<MapRef> field_map,
base::Optional<JSObjectRef> holder,
base::Optional<MapRef> transition_map);
static PropertyAccessInfo FastAccessorConstant(
Zone* zone, MapRef receiver_map, base::Optional<ObjectRef> constant,
base::Optional<JSObjectRef> holder);
static PropertyAccessInfo ModuleExport(Zone* zone, MapRef receiver_map,
CellRef cell);
static PropertyAccessInfo StringLength(Zone* zone, MapRef receiver_map);
static PropertyAccessInfo Invalid(Zone* zone);
static PropertyAccessInfo DictionaryProtoDataConstant(
Zone* zone, Handle<Map> receiver_map, Handle<JSObject> holder,
InternalIndex dict_index, Handle<Name> name);
Zone* zone, MapRef receiver_map, JSObjectRef holder,
InternalIndex dict_index, NameRef name);
static PropertyAccessInfo DictionaryProtoAccessorConstant(
Zone* zone, Handle<Map> receiver_map, MaybeHandle<JSObject> holder,
Handle<Object> constant, Handle<Name> name);
Zone* zone, MapRef receiver_map, base::Optional<JSObjectRef> holder,
ObjectRef constant, NameRef name);
bool Merge(PropertyAccessInfo const* that, AccessMode access_mode,
Zone* zone) V8_WARN_UNUSED_RESULT;
......@@ -128,7 +126,7 @@ class PropertyAccessInfo final {
return kind() == kDictionaryProtoAccessorConstant;
}
bool HasTransitionMap() const { return !transition_map().is_null(); }
bool HasTransitionMap() const { return transition_map().has_value(); }
bool HasDictionaryHolder() const {
return kind_ == kDictionaryProtoDataConstant ||
kind_ == kDictionaryProtoAccessorConstant;
......@@ -136,17 +134,17 @@ class PropertyAccessInfo final {
ConstFieldInfo GetConstFieldInfo() const;
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
// using the access info without recording its dependencies first.
// Find a more suitable place for it.
return holder_;
}
MaybeHandle<Map> transition_map() const {
base::Optional<MapRef> transition_map() const {
DCHECK(!HasDictionaryHolder());
return transition_map_;
}
Handle<Object> constant() const { return constant_; }
base::Optional<ObjectRef> constant() const { return constant_; }
FieldIndex field_index() const {
DCHECK(!HasDictionaryHolder());
return field_index_;
......@@ -160,11 +158,11 @@ class PropertyAccessInfo final {
DCHECK(!HasDictionaryHolder());
return field_representation_;
}
MaybeHandle<Map> field_map() const {
base::Optional<MapRef> field_map() const {
DCHECK(!HasDictionaryHolder());
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_;
}
......@@ -173,46 +171,48 @@ class PropertyAccessInfo final {
return dictionary_index_;
}
Handle<Name> name() const {
NameRef name() const {
DCHECK(HasDictionaryHolder());
return name_.ToHandleChecked();
return name_.value();
}
private:
explicit PropertyAccessInfo(Zone* zone);
PropertyAccessInfo(Zone* zone, Kind kind, MaybeHandle<JSObject> holder,
ZoneVector<Handle<Map>>&& lookup_start_object_maps);
PropertyAccessInfo(Zone* zone, Kind kind, MaybeHandle<JSObject> holder,
Handle<Object> constant, MaybeHandle<Name> name,
ZoneVector<Handle<Map>>&& lookup_start_object_maps);
PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
MaybeHandle<Map> transition_map, FieldIndex field_index,
PropertyAccessInfo(Zone* zone, Kind kind, base::Optional<JSObjectRef> holder,
ZoneVector<MapRef>&& lookup_start_object_maps);
PropertyAccessInfo(Zone* zone, Kind kind, base::Optional<JSObjectRef> holder,
base::Optional<ObjectRef> constant,
base::Optional<NameRef> name,
ZoneVector<MapRef>&& lookup_start_object_maps);
PropertyAccessInfo(Kind kind, base::Optional<JSObjectRef> holder,
base::Optional<MapRef> transition_map,
FieldIndex field_index,
Representation field_representation, Type field_type,
Handle<Map> field_owner_map, MaybeHandle<Map> field_map,
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*>&& dependencies);
PropertyAccessInfo(Zone* zone, Kind kind, MaybeHandle<JSObject> holder,
ZoneVector<Handle<Map>>&& lookup_start_object_maps,
InternalIndex dictionary_index, Handle<Name> name);
PropertyAccessInfo(Zone* zone, Kind kind, base::Optional<JSObjectRef> holder,
ZoneVector<MapRef>&& lookup_start_object_maps,
InternalIndex dictionary_index, NameRef name);
// Members used for fast and dictionary mode holders:
Kind kind_;
ZoneVector<Handle<Map>> lookup_start_object_maps_;
Handle<Object> constant_;
MaybeHandle<JSObject> holder_;
ZoneVector<MapRef> lookup_start_object_maps_;
base::Optional<ObjectRef> constant_;
base::Optional<JSObjectRef> holder_;
// Members only used for fast mode holders:
ZoneVector<CompilationDependency const*> unrecorded_dependencies_;
MaybeHandle<Map> transition_map_;
base::Optional<MapRef> transition_map_;
FieldIndex field_index_;
Representation field_representation_;
Type field_type_;
MaybeHandle<Map> field_owner_map_;
MaybeHandle<Map> field_map_;
base::Optional<MapRef> field_owner_map_;
base::Optional<MapRef> field_map_;
// Members only used for dictionary mode holders:
InternalIndex dictionary_index_;
MaybeHandle<Name> name_;
base::Optional<NameRef> name_;
};
// This class encapsulates information required to generate load properties
......
......@@ -881,12 +881,10 @@ void DependOnStablePrototypeChain(CompilationDependencies* deps, MapRef map,
}
} // namespace
template <class MapContainer>
void CompilationDependencies::DependOnStablePrototypeChains(
MapContainer const& receiver_maps, WhereToStart start,
ZoneVector<MapRef> const& receiver_maps, WhereToStart start,
base::Optional<JSObjectRef> last_prototype) {
for (auto map : receiver_maps) {
MapRef receiver_map = MakeRef(broker_, map);
for (MapRef receiver_map : receiver_maps) {
if (start == kStartAtReceiver) DependOnStableMap(receiver_map);
if (receiver_map.IsPrimitiveMap()) {
// Perform the implicit ToObject for primitives here.
......@@ -900,12 +898,6 @@ void CompilationDependencies::DependOnStablePrototypeChains(
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(
const AllocationSiteRef& site) {
......
......@@ -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
// up to (and including) the {last_prototype}.
template <class MapContainer>
void DependOnStablePrototypeChains(
MapContainer const& receiver_maps, WhereToStart start,
ZoneVector<MapRef> const& receiver_maps, WhereToStart start,
base::Optional<JSObjectRef> last_prototype =
base::Optional<JSObjectRef>());
......
......@@ -8002,14 +8002,12 @@ Reduction JSCallReducer::ReduceRegExpPrototypeTest(Node* node) {
// If "exec" has been modified on {regexp}, we can't do anything.
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.
if (!ai_exec.holder().ToHandle(&holder)) return inference.NoChange();
JSObjectRef holder_ref = MakeRef(broker(), holder);
if (!holder.has_value()) return inference.NoChange();
// 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());
if (!constant.has_value() ||
!constant->equals(native_context().regexp_exec_function())) {
......@@ -8018,8 +8016,7 @@ Reduction JSCallReducer::ReduceRegExpPrototypeTest(Node* node) {
// Add proper dependencies on the {regexp}s [[Prototype]]s.
dependencies()->DependOnStablePrototypeChains(
ai_exec.lookup_start_object_maps(), kStartAtPrototype,
MakeRef(broker(), holder));
ai_exec.lookup_start_object_maps(), kStartAtPrototype, holder.value());
} else {
// TODO(v8:11457) Support dictionary mode protoypes here.
return inference.NoChange();
......
......@@ -210,7 +210,7 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
// 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
// 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;
......
......@@ -34,31 +34,28 @@ SimplifiedOperatorBuilder* PropertyAccessBuilder::simplified() const {
return jsgraph()->simplified();
}
bool HasOnlyStringMaps(JSHeapBroker* broker,
ZoneVector<Handle<Map>> const& maps) {
for (auto map : maps) {
MapRef map_ref = MakeRef(broker, map);
if (!map_ref.IsStringMap()) return false;
bool HasOnlyStringMaps(JSHeapBroker* broker, ZoneVector<MapRef> const& maps) {
for (MapRef map : maps) {
if (!map.IsStringMap()) return false;
}
return true;
}
namespace {
bool HasOnlyNumberMaps(JSHeapBroker* broker,
ZoneVector<Handle<Map>> const& maps) {
for (auto map : maps) {
MapRef map_ref = MakeRef(broker, map);
if (map_ref.instance_type() != HEAP_NUMBER_TYPE) return false;
bool HasOnlyNumberMaps(JSHeapBroker* broker, ZoneVector<MapRef> const& maps) {
for (MapRef map : maps) {
if (map.instance_type() != HEAP_NUMBER_TYPE) return false;
}
return true;
}
} // namespace
bool PropertyAccessBuilder::TryBuildStringCheck(
JSHeapBroker* broker, ZoneVector<Handle<Map>> const& maps, Node** receiver,
Node** effect, Node* control) {
bool PropertyAccessBuilder::TryBuildStringCheck(JSHeapBroker* broker,
ZoneVector<MapRef> const& maps,
Node** receiver, Effect* effect,
Control control) {
if (HasOnlyStringMaps(broker, maps)) {
// Monormorphic string access (ignoring the fact that there are multiple
// String maps).
......@@ -70,9 +67,10 @@ bool PropertyAccessBuilder::TryBuildStringCheck(
return false;
}
bool PropertyAccessBuilder::TryBuildNumberCheck(
JSHeapBroker* broker, ZoneVector<Handle<Map>> const& maps, Node** receiver,
Node** effect, Node* control) {
bool PropertyAccessBuilder::TryBuildNumberCheck(JSHeapBroker* broker,
ZoneVector<MapRef> const& maps,
Node** receiver, Effect* effect,
Control control) {
if (HasOnlyNumberMaps(broker, maps)) {
// Monomorphic number access (we also deal with Smis here).
*receiver = *effect =
......@@ -83,15 +81,15 @@ bool PropertyAccessBuilder::TryBuildNumberCheck(
return false;
}
void PropertyAccessBuilder::BuildCheckMaps(
Node* object, Node** effect, Node* control,
ZoneVector<Handle<Map>> const& maps) {
void PropertyAccessBuilder::BuildCheckMaps(Node* object, Effect* effect,
Control control,
ZoneVector<MapRef> const& maps) {
HeapObjectMatcher m(object);
if (m.HasResolvedValue()) {
MapRef object_map = m.Ref(broker()).map();
if (object_map.is_stable()) {
for (Handle<Map> map : maps) {
if (MakeRef(broker(), map).equals(object_map)) {
for (MapRef map : maps) {
if (map.equals(object_map)) {
dependencies()->DependOnStableMap(object_map);
return;
}
......@@ -100,10 +98,9 @@ void PropertyAccessBuilder::BuildCheckMaps(
}
ZoneHandleSet<Map> map_set;
CheckMapsFlags flags = CheckMapsFlag::kNone;
for (Handle<Map> map : maps) {
MapRef object_map = MakeRef(broker(), map);
map_set.insert(object_map.object(), graph()->zone());
if (object_map.is_migration_target()) {
for (MapRef map : maps) {
map_set.insert(map.object(), graph()->zone());
if (map.is_migration_target()) {
flags |= CheckMapsFlag::kTryMigrateInstance;
}
}
......@@ -127,9 +124,9 @@ Node* PropertyAccessBuilder::BuildCheckValue(Node* receiver, Effect* effect,
Node* PropertyAccessBuilder::ResolveHolder(
PropertyAccessInfo const& access_info, Node* lookup_start_object) {
Handle<JSObject> holder;
if (access_info.holder().ToHandle(&holder)) {
return jsgraph()->Constant(MakeRef(broker(), holder));
base::Optional<JSObjectRef> holder = access_info.holder();
if (holder.has_value()) {
return jsgraph()->Constant(holder.value());
}
return lookup_start_object;
}
......@@ -155,29 +152,27 @@ base::Optional<Node*> PropertyAccessBuilder::FoldLoadDictPrototypeConstant(
DCHECK(V8_DICT_PROPERTY_CONST_TRACKING_BOOL);
DCHECK(access_info.IsDictionaryProtoDataConstant());
JSObjectRef holder =
MakeRef(broker(), access_info.holder().ToHandleChecked());
InternalIndex index = access_info.dictionary_index();
base::Optional<ObjectRef> value =
holder.GetOwnDictionaryProperty(index, dependencies());
access_info.holder()->GetOwnDictionaryProperty(index, dependencies());
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
// must have different lookup start map.
if (!map->IsJSReceiverMap()) {
if (!map_handle->IsJSReceiverMap()) {
// Perform the implicit ToObject for primitives here.
// Implemented according to ES6 section 7.3.2 GetV (V, P).
JSFunction constructor =
Map::GetConstructorFunction(
*map, *broker()->target_native_context().object())
*map_handle, *broker()->target_native_context().object())
.value();
map = MakeRef(broker(), constructor.initial_map()).object();
DCHECK(map->IsJSObjectMap());
map = MakeRef(broker(), constructor.initial_map());
DCHECK(map.object()->IsJSObjectMap());
}
dependencies()->DependOnConstantInDictionaryPrototypeChain(
MakeRef(broker(), map), MakeRef(broker(), access_info.name()),
value.value(), PropertyKind::kData);
map, access_info.name(), value.value(), PropertyKind::kData);
}
return jsgraph()->Constant(value.value());
......@@ -189,9 +184,10 @@ Node* PropertyAccessBuilder::TryFoldLoadConstantDataField(
if (!access_info.IsFastDataConstant()) return nullptr;
// 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.holder().ToHandle(&holder)) {
if (!holder.has_value()) {
// Otherwise, try to match the {lookup_start_object} as a constant.
HeapObjectMatcher m(lookup_start_object);
if (!m.HasResolvedValue() || !m.Ref(broker()).IsJSObject()) return nullptr;
......@@ -199,26 +195,22 @@ Node* PropertyAccessBuilder::TryFoldLoadConstantDataField(
// Let us make sure the actual map of the constant lookup_start_object is
// among the maps in {access_info}.
MapRef lookup_start_object_map = m.Ref(broker()).map();
if (std::find_if(
access_info.lookup_start_object_maps().begin(),
access_info.lookup_start_object_maps().end(), [&](Handle<Map> map) {
return MakeRef(broker(), map).equals(lookup_start_object_map);
}) == access_info.lookup_start_object_maps().end()) {
if (std::find_if(access_info.lookup_start_object_maps().begin(),
access_info.lookup_start_object_maps().end(),
[&](MapRef map) {
return map.equals(lookup_start_object_map);
}) == access_info.lookup_start_object_maps().end()) {
// The map of the lookup_start_object is not in the feedback, let us bail
// out.
return nullptr;
}
holder = m.Ref(broker()).AsJSObject().object();
holder = m.Ref(broker()).AsJSObject();
}
JSObjectRef holder_ref = MakeRef(broker(), holder);
base::Optional<ObjectRef> value = holder_ref.GetOwnFastDataProperty(
access_info.field_representation(), access_info.field_index(),
dependencies());
if (!value.has_value()) {
return nullptr;
}
return jsgraph()->Constant(*value);
base::Optional<ObjectRef> value =
holder->GetOwnFastDataProperty(access_info.field_representation(),
access_info.field_index(), dependencies());
return value.has_value() ? jsgraph()->Constant(*value) : nullptr;
}
Node* PropertyAccessBuilder::BuildLoadDataField(NameRef const& name,
......@@ -333,12 +325,11 @@ Node* PropertyAccessBuilder::BuildLoadDataField(
field_representation == MachineRepresentation::kCompressedPointer) {
// 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.
Handle<Map> field_map;
if (access_info.field_map().ToHandle(&field_map)) {
MapRef field_map_ref = MakeRef(broker(), field_map);
if (field_map_ref.is_stable()) {
dependencies()->DependOnStableMap(field_map_ref);
field_access.map = field_map;
base::Optional<MapRef> field_map = access_info.field_map();
if (field_map.has_value()) {
if (field_map->is_stable()) {
dependencies()->DependOnStableMap(field_map.value());
field_access.map = field_map->object();
}
}
}
......
......@@ -36,25 +36,15 @@ class PropertyAccessBuilder {
// Builds the appropriate string check if the maps are only string
// maps.
bool TryBuildStringCheck(JSHeapBroker* broker,
ZoneVector<Handle<Map>> const& maps, Node** receiver,
Node** effect, Node* control);
bool TryBuildStringCheck(JSHeapBroker* broker, ZoneVector<MapRef> const& maps,
Node** receiver, Effect* effect, Control control);
// Builds a number check if all maps are number maps.
bool TryBuildNumberCheck(JSHeapBroker* broker,
ZoneVector<Handle<Map>> const& maps, Node** receiver,
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);
bool TryBuildNumberCheck(JSHeapBroker* broker, ZoneVector<MapRef> const& maps,
Node** receiver, Effect* effect, Control control);
void BuildCheckMaps(Node* object, Effect* effect, Control control,
ZoneVector<Handle<Map>> const& maps) {
Node* e = *effect;
Node* c = control;
BuildCheckMaps(object, &e, c, maps);
*effect = e;
}
ZoneVector<MapRef> const& maps);
Node* BuildCheckValue(Node* receiver, Effect* effect, Control control,
Handle<HeapObject> value);
......@@ -106,8 +96,7 @@ class PropertyAccessBuilder {
CompilationDependencies* dependencies_;
};
bool HasOnlyStringMaps(JSHeapBroker* broker,
ZoneVector<Handle<Map>> const& maps);
bool HasOnlyStringMaps(JSHeapBroker* broker, ZoneVector<MapRef> const& maps);
} // namespace compiler
} // namespace internal
......
......@@ -2613,13 +2613,12 @@ PropertyAccessInfo SerializerForBackgroundCompilation::ProcessMapForRegExpTest(
AccessMode::kLoad, dependencies(),
SerializationPolicy::kSerializeIfNeeded);
Handle<JSObject> holder;
if (ai_exec.IsFastDataConstant() && ai_exec.holder().ToHandle(&holder)) {
base::Optional<JSObjectRef> holder = ai_exec.holder();
if (ai_exec.IsFastDataConstant() && holder.has_value()) {
// The property is on the prototype chain.
JSObjectRef holder_ref = MakeRef(broker(), holder);
holder_ref.GetOwnFastDataProperty(ai_exec.field_representation(),
ai_exec.field_index(), nullptr,
SerializationPolicy::kSerializeIfNeeded);
holder->GetOwnFastDataProperty(ai_exec.field_representation(),
ai_exec.field_index(), nullptr,
SerializationPolicy::kSerializeIfNeeded);
}
return ai_exec;
}
......@@ -2632,13 +2631,12 @@ void SerializerForBackgroundCompilation::ProcessHintsForRegExpTest(
Handle<Map> regexp_map(regexp->map(), broker()->isolate());
PropertyAccessInfo ai_exec =
ProcessMapForRegExpTest(MakeRef(broker(), regexp_map));
Handle<JSObject> holder;
if (ai_exec.IsFastDataConstant() && !ai_exec.holder().ToHandle(&holder)) {
base::Optional<JSObjectRef> holder = ai_exec.holder();
if (ai_exec.IsFastDataConstant() && holder.has_value()) {
// The property is on the object itself.
JSObjectRef holder_ref = MakeRef(broker(), regexp);
holder_ref.GetOwnFastDataProperty(
ai_exec.field_representation(), ai_exec.field_index(), nullptr,
SerializationPolicy::kSerializeIfNeeded);
holder->GetOwnFastDataProperty(ai_exec.field_representation(),
ai_exec.field_index(), nullptr,
SerializationPolicy::kSerializeIfNeeded);
}
}
......@@ -2927,12 +2925,12 @@ void SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess(
// For JSNativeContextSpecialization::InlinePropertySetterCall
// and InlinePropertyGetterCall.
base::Optional<ObjectRef> constant = access_info.constant();
if ((access_info.IsFastAccessorConstant() ||
access_info.IsDictionaryProtoAccessorConstant()) &&
!access_info.constant().is_null()) {
if (access_info.constant()->IsJSFunction()) {
JSFunctionRef function =
MakeRef(broker(), Handle<JSFunction>::cast(access_info.constant()));
constant.has_value()) {
if (constant->IsJSFunction()) {
JSFunctionRef function = constant->AsJSFunction();
if (receiver_map.has_value()) {
// For JSCallReducer and JSInlining(Heuristic).
......@@ -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()) {
// For JSNativeContextSpecialization::BuildPropertyLoad
DCHECK(!access_info.constant().is_null());
MakeRef(broker(), Handle<Cell>::cast(access_info.constant()));
DCHECK(access_info.constant()->IsCell());
}
switch (access_mode) {
......@@ -2975,11 +2967,8 @@ void SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess(
// PropertyAccessBuilder::BuildLoadDictPrototypeConstant
if (access_info.IsFastDataConstant() ||
access_info.IsDictionaryProtoDataConstant()) {
base::Optional<JSObjectRef> holder;
Handle<JSObject> prototype;
if (access_info.holder().ToHandle(&prototype)) {
holder = MakeRef(broker(), prototype);
} else {
base::Optional<JSObjectRef> holder = access_info.holder();
if (!holder.has_value()) {
CHECK_IMPLIES(concrete_receiver.has_value(),
concrete_receiver->map().equals(*receiver_map));
holder = concrete_receiver;
......@@ -3004,12 +2993,12 @@ void SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess(
case AccessMode::kStoreInLiteral:
// For MapInference (StoreField case).
if (access_info.IsDataField() || access_info.IsFastDataConstant()) {
Handle<Map> transition_map;
if (access_info.transition_map().ToHandle(&transition_map)) {
MapRef map_ref = MakeRef(broker(), transition_map);
base::Optional<MapRef> transition_map = access_info.transition_map();
if (transition_map.has_value()) {
TRACE_BROKER(broker(), "Propagating transition map "
<< map_ref << " to receiver hints.");
receiver->AddMap(transition_map, zone(), broker_, false);
<< transition_map.value()
<< " to receiver hints.");
receiver->AddMap(transition_map->object(), zone(), broker_, false);
}
}
break;
......@@ -3323,10 +3312,10 @@ void SerializerForBackgroundCompilation::ProcessConstantForInstanceOf(
ProcessConstantForOrdinaryHasInstance(constructor_heap_object,
walk_prototypes);
} else if (access_info.IsFastDataConstant()) {
Handle<JSObject> holder;
bool found_on_proto = access_info.holder().ToHandle(&holder);
base::Optional<JSObjectRef> holder = access_info.holder();
bool found_on_proto = holder.has_value();
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(
access_info.field_representation(), access_info.field_index(), nullptr,
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