Commit ff74066b authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Introduce NamedAccessFeedback

Brokerize parts of named property access.

Bug: v8:7790
Change-Id: I465bced5f266969040d1e966946a162b0a850c5b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1596734Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61414}
parent e5a5f5ae
This diff is collapsed.
......@@ -29,22 +29,21 @@ class ElementAccessFeedback;
class Type;
class TypeCache;
// Whether we are loading a property or storing to a property.
// For a store during literal creation, do not walk up the prototype chain.
enum class AccessMode { kLoad, kStore, kStoreInLiteral, kHas };
std::ostream& operator<<(std::ostream&, AccessMode);
// This class encapsulates all information required to access a certain element.
class ElementAccessInfo final {
public:
ElementAccessInfo();
ElementAccessInfo(MapHandles const& receiver_maps,
ElementsKind elements_kind);
ElementAccessInfo(ZoneVector<Handle<Map>>&& receiver_maps,
ElementsKind elements_kind, Zone* zone);
ElementsKind elements_kind() const { return elements_kind_; }
MapHandles const& receiver_maps() const { return receiver_maps_; }
MapHandles const& transition_sources() const { return transition_sources_; }
ZoneVector<Handle<Map>> const& receiver_maps() const {
return receiver_maps_;
}
ZoneVector<Handle<Map>> const& transition_sources() const {
return transition_sources_;
}
void AddTransitionSource(Handle<Map> map) {
CHECK_EQ(receiver_maps_.size(), 1);
......@@ -53,8 +52,8 @@ class ElementAccessInfo final {
private:
ElementsKind elements_kind_;
MapHandles receiver_maps_;
MapHandles transition_sources_;
ZoneVector<Handle<Map>> receiver_maps_;
ZoneVector<Handle<Map>> transition_sources_;
};
// This class encapsulates all information required to access a certain
......@@ -71,31 +70,31 @@ class PropertyAccessInfo final {
kStringLength
};
static PropertyAccessInfo NotFound(MapHandles const& receiver_maps,
static PropertyAccessInfo NotFound(Zone* zone, Handle<Map> receiver_map,
MaybeHandle<JSObject> holder);
static PropertyAccessInfo DataField(
MapHandles const& receiver_maps,
std::vector<CompilationDependencies::Dependency const*>&&
Zone* zone, Handle<Map> receiver_map,
ZoneVector<CompilationDependencies::Dependency const*>&&
unrecorded_dependencies,
FieldIndex field_index, MachineRepresentation field_representation,
Type field_type, MaybeHandle<Map> field_map = MaybeHandle<Map>(),
MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(),
MaybeHandle<Map> transition_map = MaybeHandle<Map>());
static PropertyAccessInfo DataConstant(
MapHandles const& receiver_maps,
std::vector<CompilationDependencies::Dependency const*>&&
Zone* zone, Handle<Map> receiver_map,
ZoneVector<CompilationDependencies::Dependency const*>&&
unrecorded_dependencies,
FieldIndex field_index, MachineRepresentation field_representation,
Type field_type, MaybeHandle<Map> field_map,
MaybeHandle<JSObject> holder);
static PropertyAccessInfo AccessorConstant(MapHandles const& receiver_maps,
static PropertyAccessInfo AccessorConstant(Zone* zone,
Handle<Map> receiver_map,
Handle<Object> constant,
MaybeHandle<JSObject> holder);
static PropertyAccessInfo ModuleExport(MapHandles const& receiver_maps,
static PropertyAccessInfo ModuleExport(Zone* zone, Handle<Map> receiver_map,
Handle<Cell> cell);
static PropertyAccessInfo StringLength(MapHandles const& receiver_maps);
PropertyAccessInfo();
static PropertyAccessInfo StringLength(Zone* zone, Handle<Map> receiver_map);
static PropertyAccessInfo Invalid(Zone* zone);
bool Merge(PropertyAccessInfo const* that, AccessMode access_mode,
Zone* zone) V8_WARN_UNUSED_RESULT;
......@@ -127,24 +126,28 @@ class PropertyAccessInfo final {
return field_representation_;
}
MaybeHandle<Map> field_map() const { return field_map_; }
MapHandles const& receiver_maps() const { return receiver_maps_; }
ZoneVector<Handle<Map>> const& receiver_maps() const {
return receiver_maps_;
}
Handle<Cell> export_cell() const;
private:
PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
MapHandles const& receiver_maps);
PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
Handle<Object> constant, MapHandles const& receiver_maps);
explicit PropertyAccessInfo(Zone* zone);
PropertyAccessInfo(Zone* zone, Kind kind, MaybeHandle<JSObject> holder,
ZoneVector<Handle<Map>>&& receiver_maps);
PropertyAccessInfo(Zone* zone, Kind kind, MaybeHandle<JSObject> holder,
Handle<Object> constant,
ZoneVector<Handle<Map>>&& receiver_maps);
PropertyAccessInfo(
Kind kind, MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map,
FieldIndex field_index, MachineRepresentation field_representation,
Type field_type, MaybeHandle<Map> field_map,
MapHandles const& receiver_maps,
std::vector<CompilationDependencies::Dependency const*>&& dependencies);
ZoneVector<Handle<Map>>&& receiver_maps,
ZoneVector<CompilationDependencies::Dependency const*>&& dependencies);
Kind kind_;
MapHandles receiver_maps_;
std::vector<CompilationDependencies::Dependency const*>
ZoneVector<Handle<Map>> receiver_maps_;
ZoneVector<CompilationDependencies::Dependency const*>
unrecorded_dependencies_;
Handle<Object> constant_;
MaybeHandle<Map> transition_map_;
......@@ -162,8 +165,8 @@ class AccessInfoFactory final {
AccessInfoFactory(JSHeapBroker* broker, CompilationDependencies* dependencies,
Zone* zone);
bool ComputeElementAccessInfo(Handle<Map> map, AccessMode access_mode,
ElementAccessInfo* access_info) const;
base::Optional<ElementAccessInfo> ComputeElementAccessInfo(
Handle<Map> map, AccessMode access_mode) const;
bool ComputeElementAccessInfos(
FeedbackNexus nexus, MapHandles const& maps, AccessMode access_mode,
ZoneVector<ElementAccessInfo>* access_infos) const;
......@@ -192,8 +195,8 @@ class AccessInfoFactory final {
ZoneVector<PropertyAccessInfo> infos, AccessMode access_mode) const;
private:
bool ConsolidateElementLoad(ElementAccessFeedback const& processed,
ElementAccessInfo* access_info) const;
base::Optional<ElementAccessInfo> ConsolidateElementLoad(
ElementAccessFeedback const& processed) const;
PropertyAccessInfo LookupSpecialFieldAccessor(Handle<Map> map,
Handle<Name> name) const;
PropertyAccessInfo LookupTransition(Handle<Map> map, Handle<Name> name,
......
......@@ -599,7 +599,7 @@ void CompilationDependencies::DependOnStablePrototypeChains(
}
}
template void CompilationDependencies::DependOnStablePrototypeChains(
MapHandles const& receiver_maps, WhereToStart start,
ZoneVector<Handle<Map>> const& receiver_maps, WhereToStart start,
base::Optional<JSObjectRef> last_prototype);
template void CompilationDependencies::DependOnStablePrototypeChains(
ZoneHandleSet<Map> const& receiver_maps, WhereToStart start,
......
......@@ -6749,17 +6749,15 @@ Reduction JSCallReducer::ReduceRegExpPrototypeTest(Node* node) {
MapHandles const& regexp_maps = inference.GetMaps();
// Compute property access info for "exec" on {resolution}.
PropertyAccessInfo ai_exec;
{
ZoneVector<PropertyAccessInfo> access_infos(graph()->zone());
AccessInfoFactory access_info_factory(broker(), dependencies(),
graph()->zone());
access_info_factory.ComputePropertyAccessInfos(
MapHandles(regexp_maps.begin(), regexp_maps.end()),
factory()->exec_string(), AccessMode::kLoad, &access_infos);
ai_exec = access_info_factory.FinalizePropertyAccessInfosAsOne(
access_infos, AccessMode::kLoad);
}
ZoneVector<PropertyAccessInfo> access_infos(graph()->zone());
AccessInfoFactory access_info_factory(broker(), dependencies(),
graph()->zone());
access_info_factory.ComputePropertyAccessInfos(
MapHandles(regexp_maps.begin(), regexp_maps.end()),
factory()->exec_string(), AccessMode::kLoad, &access_infos);
PropertyAccessInfo ai_exec =
access_info_factory.FinalizePropertyAccessInfosAsOne(access_infos,
AccessMode::kLoad);
if (ai_exec.IsInvalid()) return inference.NoChange();
// If "exec" has been modified on {regexp}, we can't do anything.
......
......@@ -13,6 +13,7 @@
#include "src/bootstrapper.h"
#include "src/boxed-float.h"
#include "src/code-factory.h"
#include "src/compiler/access-info.h"
#include "src/compiler/graph-reducer.h"
#include "src/compiler/per-isolate-compiler-cache.h"
#include "src/objects-inl.h"
......@@ -3256,6 +3257,9 @@ bool CanInlineElementAccess(MapRef const& map) {
return false;
}
InsufficientFeedback::InsufficientFeedback()
: ProcessedFeedback(kInsufficient) {}
GlobalAccessFeedback::GlobalAccessFeedback(PropertyCellRef cell)
: ProcessedFeedback(kGlobalAccess),
cell_or_context_(cell),
......@@ -3336,6 +3340,14 @@ ElementAccessFeedback::MapIterator ElementAccessFeedback::all_maps(
return MapIterator(*this, broker);
}
NamedAccessFeedback::NamedAccessFeedback(
NameRef const& name, ZoneVector<PropertyAccessInfo> const& access_infos)
: ProcessedFeedback(kNamedAccess),
name_(name),
access_infos_(access_infos) {
CHECK(!access_infos.empty());
}
FeedbackSource::FeedbackSource(FeedbackNexus const& nexus)
: vector(nexus.vector_handle()), slot(nexus.slot()) {}
......@@ -3377,6 +3389,8 @@ GlobalAccessFeedback const* JSHeapBroker::GetGlobalAccessFeedback(
ElementAccessFeedback const* JSHeapBroker::ProcessFeedbackMapsForElementAccess(
MapHandles const& maps) {
DCHECK(!maps.empty());
// Collect possible transition targets.
MapHandles possible_transition_targets;
possible_transition_targets.reserve(maps.size());
......@@ -3388,8 +3402,6 @@ ElementAccessFeedback const* JSHeapBroker::ProcessFeedbackMapsForElementAccess(
}
}
if (maps.empty()) return nullptr;
ElementAccessFeedback* result = new (zone()) ElementAccessFeedback(zone());
// Separate the actual receiver maps and the possible transition sources.
......
......@@ -37,6 +37,10 @@ class VectorSlotPair;
namespace compiler {
// Whether we are loading a property or storing to a property.
// For a store during literal creation, do not walk up the prototype chain.
enum class AccessMode { kLoad, kStore, kStoreInLiteral, kHas };
enum class OddballType : uint8_t {
kNone, // Not an Oddball.
kBoolean, // True or False.
......@@ -97,6 +101,7 @@ class CompilationDependencies;
class JSHeapBroker;
class ObjectData;
class PerIsolateCompilerCache;
class PropertyAccessInfo;
#define FORWARD_DECL(Name) class Name##Ref;
HEAP_BROKER_OBJECT_LIST(FORWARD_DECL)
#undef FORWARD_DECL
......@@ -704,7 +709,7 @@ class InternalizedStringRef : public StringRef {
class ProcessedFeedback : public ZoneObject {
public:
enum Kind { kElementAccess, kGlobalAccess };
enum Kind { kInsufficient, kGlobalAccess, kNamedAccess, kElementAccess };
Kind kind() const { return kind_; }
protected:
......@@ -714,6 +719,11 @@ class ProcessedFeedback : public ZoneObject {
Kind const kind_;
};
class InsufficientFeedback final : public ProcessedFeedback {
public:
InsufficientFeedback();
};
class GlobalAccessFeedback : public ProcessedFeedback {
public:
explicit GlobalAccessFeedback(PropertyCellRef cell);
......@@ -765,6 +775,21 @@ class ElementAccessFeedback : public ProcessedFeedback {
MapIterator all_maps(JSHeapBroker* broker) const;
};
class NamedAccessFeedback : public ProcessedFeedback {
public:
NamedAccessFeedback(NameRef const& name,
ZoneVector<PropertyAccessInfo> const& access_infos);
NameRef const& name() const { return name_; }
ZoneVector<PropertyAccessInfo> const& access_infos() const {
return access_infos_;
}
private:
NameRef const name_;
ZoneVector<PropertyAccessInfo> const access_infos_;
};
struct FeedbackSource {
FeedbackSource(Handle<FeedbackVector> vector_, FeedbackSlot slot_)
: vector(vector_), slot(slot_) {}
......
......@@ -107,10 +107,15 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
FeedbackNexus const& nexus,
NameRef const& name,
AccessMode access_mode);
Reduction ReduceNamedAccess(Node* node, Node* value,
NamedAccessFeedback const& processed,
AccessMode access_mode, Node* key = nullptr);
// TODO(neis): This second version of ReduceNamedAccess is here only
// temporarily while keyed access is not fully brokerized yet.
Reduction ReduceNamedAccess(Node* node, Node* value,
MapHandles const& receiver_maps,
NameRef const& name, AccessMode access_mode,
Node* key = nullptr);
Node* key);
Reduction ReduceGlobalAccess(Node* node, Node* receiver, Node* value,
NameRef const& name, AccessMode access_mode,
Node* key = nullptr);
......@@ -214,7 +219,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(MapHandles const& receiver_maps);
bool CanTreatHoleAsUndefined(ZoneVector<Handle<Map>> const& receiver_maps);
// Extract receiver maps from {nexus} and filter based on {receiver} if
// possible.
......
......@@ -1248,8 +1248,8 @@ struct SerializationPhase {
void Run(PipelineData* data, Zone* temp_zone) {
SerializerForBackgroundCompilation serializer(
data->broker(), temp_zone, data->info()->closure(),
data->info()->is_source_positions_enabled());
data->broker(), data->dependencies(), temp_zone,
data->info()->closure(), data->info()->is_source_positions_enabled());
serializer.Run();
}
};
......
......@@ -32,7 +32,8 @@ SimplifiedOperatorBuilder* PropertyAccessBuilder::simplified() const {
return jsgraph()->simplified();
}
bool HasOnlyStringMaps(JSHeapBroker* broker, MapHandles const& maps) {
bool HasOnlyStringMaps(JSHeapBroker* broker,
ZoneVector<Handle<Map>> const& maps) {
for (auto map : maps) {
MapRef map_ref(broker, map);
if (!map_ref.IsStringMap()) return false;
......@@ -42,7 +43,8 @@ bool HasOnlyStringMaps(JSHeapBroker* broker, MapHandles const& maps) {
namespace {
bool HasOnlyNumberMaps(JSHeapBroker* broker, MapHandles const& maps) {
bool HasOnlyNumberMaps(JSHeapBroker* broker,
ZoneVector<Handle<Map>> const& maps) {
for (auto map : maps) {
MapRef map_ref(broker, map);
if (map_ref.instance_type() != HEAP_NUMBER_TYPE) return false;
......@@ -52,10 +54,9 @@ bool HasOnlyNumberMaps(JSHeapBroker* broker, MapHandles const& maps) {
} // namespace
bool PropertyAccessBuilder::TryBuildStringCheck(JSHeapBroker* broker,
MapHandles const& maps,
Node** receiver, Node** effect,
Node* control) {
bool PropertyAccessBuilder::TryBuildStringCheck(
JSHeapBroker* broker, ZoneVector<Handle<Map>> const& maps, Node** receiver,
Node** effect, Node* control) {
if (HasOnlyStringMaps(broker, maps)) {
// Monormorphic string access (ignoring the fact that there are multiple
// String maps).
......@@ -67,10 +68,9 @@ bool PropertyAccessBuilder::TryBuildStringCheck(JSHeapBroker* broker,
return false;
}
bool PropertyAccessBuilder::TryBuildNumberCheck(JSHeapBroker* broker,
MapHandles const& maps,
Node** receiver, Node** effect,
Node* control) {
bool PropertyAccessBuilder::TryBuildNumberCheck(
JSHeapBroker* broker, ZoneVector<Handle<Map>> const& maps, Node** receiver,
Node** effect, Node* control) {
if (HasOnlyNumberMaps(broker, maps)) {
// Monomorphic number access (we also deal with Smis here).
*receiver = *effect =
......@@ -143,9 +143,9 @@ Node* PropertyAccessBuilder::BuildCheckHeapObject(Node* receiver, Node** effect,
return receiver;
}
void PropertyAccessBuilder::BuildCheckMaps(Node* receiver, Node** effect,
Node* control,
MapHandles const& receiver_maps) {
void PropertyAccessBuilder::BuildCheckMaps(
Node* receiver, Node** effect, Node* control,
ZoneVector<Handle<Map>> const& receiver_maps) {
HeapObjectMatcher m(receiver);
if (m.HasValue()) {
MapRef receiver_map = m.Ref(broker()).map();
......
......@@ -33,15 +33,17 @@ class PropertyAccessBuilder {
// Builds the appropriate string check if the maps are only string
// maps.
bool TryBuildStringCheck(JSHeapBroker* broker, MapHandles const& maps,
Node** receiver, Node** effect, Node* control);
bool TryBuildStringCheck(JSHeapBroker* broker,
ZoneVector<Handle<Map>> const& maps, Node** receiver,
Node** effect, Node* control);
// Builds a number check if all maps are number maps.
bool TryBuildNumberCheck(JSHeapBroker* broker, MapHandles const& maps,
Node** receiver, Node** effect, Node* control);
bool TryBuildNumberCheck(JSHeapBroker* broker,
ZoneVector<Handle<Map>> const& maps, Node** receiver,
Node** effect, Node* control);
Node* BuildCheckHeapObject(Node* receiver, Node** effect, Node* control);
void BuildCheckMaps(Node* receiver, Node** effect, Node* control,
std::vector<Handle<Map>> const& receiver_maps);
ZoneVector<Handle<Map>> const& receiver_maps);
Node* BuildCheckValue(Node* receiver, Node** effect, Node* control,
Handle<HeapObject> value);
......@@ -72,7 +74,8 @@ class PropertyAccessBuilder {
CompilationDependencies* dependencies_;
};
bool HasOnlyStringMaps(JSHeapBroker* broker, MapHandles const& maps);
bool HasOnlyStringMaps(JSHeapBroker* broker,
ZoneVector<Handle<Map>> const& maps);
} // namespace compiler
} // namespace internal
......
......@@ -247,9 +247,10 @@ int SerializerForBackgroundCompilation::Environment::RegisterToLocalIndex(
}
SerializerForBackgroundCompilation::SerializerForBackgroundCompilation(
JSHeapBroker* broker, Zone* zone, Handle<JSFunction> closure,
bool collect_source_positions)
JSHeapBroker* broker, CompilationDependencies* dependencies, Zone* zone,
Handle<JSFunction> closure, bool collect_source_positions)
: broker_(broker),
dependencies_(dependencies),
zone_(zone),
collect_source_positions_(collect_source_positions),
environment_(new (zone) Environment(zone, {closure, broker_->isolate()})),
......@@ -258,10 +259,11 @@ SerializerForBackgroundCompilation::SerializerForBackgroundCompilation(
}
SerializerForBackgroundCompilation::SerializerForBackgroundCompilation(
JSHeapBroker* broker, Zone* zone, CompilationSubject function,
base::Optional<Hints> new_target, const HintsVector& arguments,
bool collect_source_positions)
JSHeapBroker* broker, CompilationDependencies* dependencies, Zone* zone,
CompilationSubject function, base::Optional<Hints> new_target,
const HintsVector& arguments, bool collect_source_positions)
: broker_(broker),
dependencies_(dependencies),
zone_(zone),
collect_source_positions_(collect_source_positions),
environment_(new (zone) Environment(zone, broker_->isolate(), function,
......@@ -580,7 +582,7 @@ Hints SerializerForBackgroundCompilation::RunChildSerializer(
<< *environment());
SerializerForBackgroundCompilation child_serializer(
broker(), zone(), function, new_target, arguments,
broker(), dependencies(), zone(), function, new_target, arguments,
collect_source_positions());
return child_serializer.Run();
}
......@@ -790,32 +792,12 @@ MapHandles GetRelevantReceiverMaps(Isolate* isolate, MapContainer const& maps) {
}
} // namespace
// Note: We never use the same feedback slot for multiple access modes.
void SerializerForBackgroundCompilation::ProcessFeedbackForKeyedPropertyAccess(
FeedbackSlot slot, AccessMode mode) {
if (slot.IsInvalid()) return;
if (environment()->function().feedback_vector.is_null()) return;
FeedbackNexus nexus(environment()->function().feedback_vector, slot);
FeedbackSource source(nexus);
if (broker()->HasFeedback(source)) return;
if (nexus.GetKeyType() == PROPERTY) {
CHECK_NE(mode, AccessMode::kStoreInLiteral);
return; // TODO(neis): Support named access.
}
DCHECK_EQ(nexus.GetKeyType(), ELEMENT);
CHECK(nexus.GetName().is_null());
MapHandles maps;
nexus.ExtractMaps(&maps);
ElementAccessFeedback const* processed =
broker()->ProcessFeedbackMapsForElementAccess(
GetRelevantReceiverMaps(broker()->isolate(), maps));
broker()->SetFeedback(source, processed);
if (processed == nullptr) return;
for (ElementAccessFeedback::MapIterator it = processed->all_maps(broker());
ElementAccessFeedback const*
SerializerForBackgroundCompilation::ProcessFeedbackMapsForElementAccess(
const MapHandles& maps, AccessMode mode) {
ElementAccessFeedback const* result =
broker()->ProcessFeedbackMapsForElementAccess(maps);
for (ElementAccessFeedback::MapIterator it = result->all_maps(broker());
!it.done(); it.advance()) {
switch (mode) {
case AccessMode::kHas:
......@@ -830,6 +812,41 @@ void SerializerForBackgroundCompilation::ProcessFeedbackForKeyedPropertyAccess(
break;
}
}
return result;
}
// Note: We never use the same feedback slot for multiple access modes.
void SerializerForBackgroundCompilation::ProcessFeedbackForKeyedPropertyAccess(
FeedbackSlot slot, AccessMode mode) {
if (slot.IsInvalid()) return;
if (environment()->function().feedback_vector.is_null()) return;
FeedbackNexus nexus(environment()->function().feedback_vector, slot);
FeedbackSource source(nexus);
if (broker()->HasFeedback(source)) return;
ProcessedFeedback const* processed = nullptr;
if (nexus.ic_state() == UNINITIALIZED) {
processed = new (broker()->zone()) InsufficientFeedback();
} else {
if (nexus.GetKeyType() == PROPERTY) {
CHECK_NE(mode, AccessMode::kStoreInLiteral);
// TODO(neis): Support named access.
} else {
DCHECK_EQ(nexus.GetKeyType(), ELEMENT);
DCHECK(nexus.GetName().is_null());
MapHandles maps;
if (nexus.ExtractMaps(&maps) != 0) {
maps = GetRelevantReceiverMaps(broker()->isolate(), maps);
if (maps.empty()) {
processed = new (broker()->zone()) InsufficientFeedback();
} else {
processed = ProcessFeedbackMapsForElementAccess(maps, mode);
}
}
}
}
broker()->SetFeedback(source, processed);
}
void SerializerForBackgroundCompilation::ProcessKeyedPropertyAccess(
......@@ -878,7 +895,7 @@ void SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess(
// Note: We never use the same feedback slot for multiple names.
void SerializerForBackgroundCompilation::ProcessFeedbackForNamedPropertyAccess(
FeedbackSlot slot, NameRef const& name) {
FeedbackSlot slot, NameRef const& name, AccessMode mode) {
if (slot.IsInvalid()) return;
if (environment()->function().feedback_vector.is_null()) return;
......@@ -886,15 +903,31 @@ void SerializerForBackgroundCompilation::ProcessFeedbackForNamedPropertyAccess(
FeedbackSource source(nexus);
if (broker()->HasFeedback(source)) return;
MapHandles maps;
nexus.ExtractMaps(&maps);
for (Handle<Map> map : GetRelevantReceiverMaps(broker()->isolate(), maps)) {
ProcessMapForNamedPropertyAccess(MapRef(broker(), map), name);
ProcessedFeedback const* processed = nullptr;
if (nexus.ic_state() == UNINITIALIZED) {
processed = new (broker()->zone()) InsufficientFeedback();
} else {
MapHandles maps;
if (nexus.ExtractMaps(&maps) != 0) {
ZoneVector<PropertyAccessInfo> access_infos(broker()->zone());
for (Handle<Map> map :
GetRelevantReceiverMaps(broker()->isolate(), maps)) {
MapRef map_ref(broker(), map);
ProcessMapForNamedPropertyAccess(map_ref, name);
AccessInfoFactory access_info_factory(broker(), dependencies(),
broker()->zone());
access_infos.push_back(access_info_factory.ComputePropertyAccessInfo(
map, name.object(), mode));
}
if (access_infos.empty()) {
processed = new (broker()->zone()) InsufficientFeedback();
} else {
processed =
new (broker()->zone()) NamedAccessFeedback(name, access_infos);
}
}
}
// NamedProperty support is still WIP. For now we don't have any actual data
// to store, so use nullptr to at least record that we processed the feedback.
broker()->SetFeedback(source, nullptr);
broker()->SetFeedback(source, processed);
}
void SerializerForBackgroundCompilation::VisitLdaKeyedProperty(
......@@ -909,7 +942,7 @@ void SerializerForBackgroundCompilation::VisitLdaKeyedProperty(
void SerializerForBackgroundCompilation::ProcessNamedPropertyAccess(
Hints const& receiver, NameRef const& name, FeedbackSlot slot,
AccessMode mode) {
if (!slot.IsInvalid()) ProcessFeedbackForNamedPropertyAccess(slot, name);
ProcessFeedbackForNamedPropertyAccess(slot, name, mode);
for (Handle<Map> map :
GetRelevantReceiverMaps(broker()->isolate(), receiver.maps())) {
......@@ -956,6 +989,11 @@ void SerializerForBackgroundCompilation::VisitStaNamedProperty(
ProcessNamedPropertyAccess(iterator, AccessMode::kStore);
}
void SerializerForBackgroundCompilation::VisitStaNamedOwnProperty(
BytecodeArrayIterator* iterator) {
ProcessNamedPropertyAccess(iterator, AccessMode::kStoreInLiteral);
}
void SerializerForBackgroundCompilation::VisitTestIn(
BytecodeArrayIterator* iterator) {
Hints const& receiver = environment()->accumulator_hints();
......
......@@ -189,6 +189,7 @@ namespace compiler {
V(StaGlobal) \
V(StaInArrayLiteral) \
V(StaKeyedProperty) \
V(StaNamedOwnProperty) \
V(StaNamedProperty) \
V(Star) \
V(TestIn) \
......@@ -270,16 +271,18 @@ using HintsVector = ZoneVector<Hints>;
// optimizations in the compiler, is copied to the heap broker.
class SerializerForBackgroundCompilation {
public:
SerializerForBackgroundCompilation(JSHeapBroker* broker, Zone* zone,
Handle<JSFunction> closure,
SerializerForBackgroundCompilation(JSHeapBroker* broker,
CompilationDependencies* dependencies,
Zone* zone, Handle<JSFunction> closure,
bool collect_source_positions);
Hints Run(); // NOTE: Returns empty for an already-serialized function.
class Environment;
private:
SerializerForBackgroundCompilation(JSHeapBroker* broker, Zone* zone,
CompilationSubject function,
SerializerForBackgroundCompilation(JSHeapBroker* broker,
CompilationDependencies* dependencies,
Zone* zone, CompilationSubject function,
base::Optional<Hints> new_target,
const HintsVector& arguments,
bool collect_source_positions);
......@@ -311,8 +314,11 @@ class SerializerForBackgroundCompilation {
GlobalAccessFeedback const* ProcessFeedbackForGlobalAccess(FeedbackSlot slot);
void ProcessFeedbackForKeyedPropertyAccess(FeedbackSlot slot,
AccessMode mode);
ElementAccessFeedback const* ProcessFeedbackMapsForElementAccess(
const MapHandles& maps, AccessMode mode);
void ProcessFeedbackForNamedPropertyAccess(FeedbackSlot slot,
NameRef const& name);
NameRef const& name,
AccessMode mode);
void ProcessMapForNamedPropertyAccess(MapRef const& map, NameRef const& name);
Hints RunChildSerializer(CompilationSubject function,
......@@ -320,6 +326,7 @@ class SerializerForBackgroundCompilation {
const HintsVector& arguments, bool with_spread);
JSHeapBroker* broker() const { return broker_; }
CompilationDependencies* dependencies() const { return dependencies_; }
Zone* zone() const { return zone_; }
// The following flag is initialized from OptimizedCompilationInfo's
// {is_source_positions_enabled}.
......@@ -327,6 +334,7 @@ class SerializerForBackgroundCompilation {
Environment* environment() const { return environment_; }
JSHeapBroker* const broker_;
CompilationDependencies* const dependencies_;
Zone* const zone_;
bool const collect_source_positions_;
Environment* const environment_;
......
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