Commit 4153feb2 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Make PropertyAccessInfo carry unrecorded dependencies

Instead of recording dependencies during ComputePropertyAccessInfo(s),
store off-the-record dependencies in the resulting PropertyAccessInfo(s)
and record them when the PropertyAccessInfo(s) are consumed. This will
enable us to do the ComputePropertyAccessInfo(s) during serialization.

Bug: v8:7790
Change-Id: I2a3918eb3bc2c795061ca7969c0053b68a53aea7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1581610
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61051}
parent e4669a9c
This diff is collapsed.
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <iosfwd> #include <iosfwd>
#include "src/compiler/compilation-dependencies.h"
#include "src/compiler/types.h" #include "src/compiler/types.h"
#include "src/feedback-vector.h" #include "src/feedback-vector.h"
#include "src/field-index.h" #include "src/field-index.h"
...@@ -24,7 +25,6 @@ class Factory; ...@@ -24,7 +25,6 @@ class Factory;
namespace compiler { namespace compiler {
// Forward declarations. // Forward declarations.
class CompilationDependencies;
class ElementAccessFeedback; class ElementAccessFeedback;
class Type; class Type;
class TypeCache; class TypeCache;
...@@ -79,6 +79,8 @@ class PropertyAccessInfo final { ...@@ -79,6 +79,8 @@ class PropertyAccessInfo final {
MaybeHandle<JSObject> holder); MaybeHandle<JSObject> holder);
static PropertyAccessInfo DataField( static PropertyAccessInfo DataField(
PropertyConstness constness, MapHandles const& receiver_maps, PropertyConstness constness, MapHandles const& receiver_maps,
std::vector<CompilationDependencies::Dependency const*>&&
unrecorded_dependencies,
FieldIndex field_index, MachineRepresentation field_representation, FieldIndex field_index, MachineRepresentation field_representation,
Type field_type, MaybeHandle<Map> field_map = MaybeHandle<Map>(), Type field_type, MaybeHandle<Map> field_map = MaybeHandle<Map>(),
MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(), MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(),
...@@ -95,6 +97,8 @@ class PropertyAccessInfo final { ...@@ -95,6 +97,8 @@ class PropertyAccessInfo final {
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;
void RecordDependencies(CompilationDependencies* dependencies);
bool IsInvalid() const { return kind() == kInvalid; } bool IsInvalid() const { return kind() == kInvalid; }
bool IsNotFound() const { return kind() == kNotFound; } bool IsNotFound() const { return kind() == kNotFound; }
bool IsDataConstant() const { return kind() == kDataConstant; } bool IsDataConstant() const { return kind() == kDataConstant; }
...@@ -109,7 +113,12 @@ class PropertyAccessInfo final { ...@@ -109,7 +113,12 @@ class PropertyAccessInfo final {
bool HasTransitionMap() const { return !transition_map().is_null(); } bool HasTransitionMap() const { return !transition_map().is_null(); }
Kind kind() const { return kind_; } Kind kind() const { return kind_; }
MaybeHandle<JSObject> holder() const { return holder_; } MaybeHandle<JSObject> holder() const {
// This CHECK tries to protect against using the access info without
// recording its dependencies first.
CHECK(unrecorded_dependencies_.empty());
return holder_;
}
MaybeHandle<Map> transition_map() const { return transition_map_; } MaybeHandle<Map> transition_map() const { return transition_map_; }
Handle<Object> constant() const { return constant_; } Handle<Object> constant() const { return constant_; }
FieldIndex field_index() const { return field_index_; } FieldIndex field_index() const { return field_index_; }
...@@ -126,14 +135,17 @@ class PropertyAccessInfo final { ...@@ -126,14 +135,17 @@ class PropertyAccessInfo final {
MapHandles const& receiver_maps); MapHandles const& receiver_maps);
PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder, PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
Handle<Object> constant, MapHandles const& receiver_maps); Handle<Object> constant, MapHandles const& receiver_maps);
PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder, PropertyAccessInfo(
MaybeHandle<Map> transition_map, FieldIndex field_index, Kind kind, MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map,
MachineRepresentation field_representation, FieldIndex field_index, MachineRepresentation field_representation,
Type field_type, MaybeHandle<Map> field_map, Type field_type, MaybeHandle<Map> field_map,
MapHandles const& receiver_maps); MapHandles const& receiver_maps,
std::vector<CompilationDependencies::Dependency const*>&& dependencies);
Kind kind_; Kind kind_;
MapHandles receiver_maps_; MapHandles receiver_maps_;
std::vector<CompilationDependencies::Dependency const*>
unrecorded_dependencies_;
Handle<Object> constant_; Handle<Object> constant_;
MaybeHandle<Map> transition_map_; MaybeHandle<Map> transition_map_;
MaybeHandle<JSObject> holder_; MaybeHandle<JSObject> holder_;
...@@ -159,19 +171,26 @@ class AccessInfoFactory final { ...@@ -159,19 +171,26 @@ class AccessInfoFactory final {
PropertyAccessInfo ComputePropertyAccessInfo(Handle<Map> map, PropertyAccessInfo ComputePropertyAccessInfo(Handle<Map> map,
Handle<Name> name, Handle<Name> name,
AccessMode access_mode) const; AccessMode access_mode) const;
PropertyAccessInfo ComputePropertyAccessInfo(MapHandles const& maps,
Handle<Name> name, // Convenience wrapper around {ComputePropertyAccessInfo} for multiple maps.
AccessMode access_mode) const;
void ComputePropertyAccessInfos( void ComputePropertyAccessInfos(
MapHandles const& maps, Handle<Name> name, AccessMode access_mode, MapHandles const& maps, Handle<Name> name, AccessMode access_mode,
ZoneVector<PropertyAccessInfo>* access_infos) const; ZoneVector<PropertyAccessInfo>* access_infos) const;
// Merge as many of the given {infos} as possible. Return false iff // Merge as many of the given {infos} as possible and record any dependencies.
// any of them was invalid. // Return false iff any of them was invalid, in which case no dependencies are
// recorded.
// TODO(neis): Make access_mode part of access info?
bool FinalizePropertyAccessInfos( bool FinalizePropertyAccessInfos(
ZoneVector<PropertyAccessInfo> infos, AccessMode access_mode, ZoneVector<PropertyAccessInfo> infos, AccessMode access_mode,
ZoneVector<PropertyAccessInfo>* result) const; ZoneVector<PropertyAccessInfo>* result) const;
// Merge the given {infos} to a single one and record any dependencies. If the
// merge is not possible, the result has kind {kInvalid} and no dependencies
// are recorded.
PropertyAccessInfo FinalizePropertyAccessInfosAsOne(
ZoneVector<PropertyAccessInfo> infos, AccessMode access_mode) const;
private: private:
bool ConsolidateElementLoad(ElementAccessFeedback const& processed, bool ConsolidateElementLoad(ElementAccessFeedback const& processed,
ElementAccessInfo* access_info) const; ElementAccessInfo* access_info) const;
...@@ -188,6 +207,10 @@ class AccessInfoFactory final { ...@@ -188,6 +207,10 @@ class AccessInfoFactory final {
Handle<Map> receiver_map, Handle<Name> name, Handle<Map> map, Handle<Map> receiver_map, Handle<Name> name, Handle<Map> map,
MaybeHandle<JSObject> holder, int number, AccessMode access_mode) const; MaybeHandle<JSObject> holder, int number, AccessMode access_mode) const;
void MergePropertyAccessInfos(ZoneVector<PropertyAccessInfo> infos,
AccessMode access_mode,
ZoneVector<PropertyAccessInfo>* result) const;
CompilationDependencies* dependencies() const { return dependencies_; } CompilationDependencies* dependencies() const { return dependencies_; }
JSHeapBroker* broker() const { return broker_; } JSHeapBroker* broker() const { return broker_; }
Isolate* isolate() const { return broker()->isolate(); } Isolate* isolate() const { return broker()->isolate(); }
......
This diff is collapsed.
...@@ -107,16 +107,28 @@ class V8_EXPORT_PRIVATE CompilationDependencies : public ZoneObject { ...@@ -107,16 +107,28 @@ class V8_EXPORT_PRIVATE CompilationDependencies : public ZoneObject {
SlackTrackingPrediction DependOnInitialMapInstanceSizePrediction( SlackTrackingPrediction DependOnInitialMapInstanceSizePrediction(
const JSFunctionRef& function); const JSFunctionRef& function);
// The methods below allow for gathering dependencies without actually
// recording them. They can be recorded at a later time (or they can be
// ignored). For example,
// DependOnTransition(map);
// is equivalent to:
// RecordDependency(TransitionDependencyOffTheRecord(map));
class Dependency;
void RecordDependency(Dependency const* dependency);
Dependency const* TransitionDependencyOffTheRecord(
const MapRef& target_map) const;
Dependency const* FieldRepresentationDependencyOffTheRecord(
const MapRef& map, int descriptor) const;
Dependency const* FieldTypeDependencyOffTheRecord(const MapRef& map,
int descriptor) const;
// Exposed only for testing purposes. // Exposed only for testing purposes.
bool AreValid() const; bool AreValid() const;
// Exposed only because C++.
class Dependency;
private: private:
Zone* const zone_; Zone* const zone_;
JSHeapBroker* const broker_; JSHeapBroker* const broker_;
ZoneForwardList<Dependency*> dependencies_; ZoneForwardList<Dependency const*> dependencies_;
}; };
} // namespace compiler } // namespace compiler
......
...@@ -6887,11 +6887,17 @@ Reduction JSCallReducer::ReduceRegExpPrototypeTest(Node* node) { ...@@ -6887,11 +6887,17 @@ Reduction JSCallReducer::ReduceRegExpPrototypeTest(Node* node) {
} }
// Compute property access info for "exec" on {resolution}. // Compute property access info for "exec" on {resolution}.
AccessInfoFactory access_info_factory(broker(), dependencies(), PropertyAccessInfo ai_exec;
graph()->zone()); {
PropertyAccessInfo ai_exec = access_info_factory.ComputePropertyAccessInfo( ZoneVector<PropertyAccessInfo> access_infos(graph()->zone());
MapHandles(regexp_maps.begin(), regexp_maps.end()), AccessInfoFactory access_info_factory(broker(), dependencies(),
factory()->exec_string(), AccessMode::kLoad); 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);
}
if (ai_exec.IsInvalid()) return NoChange(); if (ai_exec.IsInvalid()) return NoChange();
// If "exec" has been modified on {regexp}, we can't do anything. // If "exec" has been modified on {regexp}, we can't do anything.
......
...@@ -406,6 +406,7 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) { ...@@ -406,6 +406,7 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) {
access_info_factory.ComputePropertyAccessInfo( access_info_factory.ComputePropertyAccessInfo(
receiver_map, factory()->has_instance_symbol(), AccessMode::kLoad); receiver_map, factory()->has_instance_symbol(), AccessMode::kLoad);
if (access_info.IsInvalid()) return NoChange(); if (access_info.IsInvalid()) return NoChange();
access_info.RecordDependencies(dependencies());
PropertyAccessBuilder access_builder(jsgraph(), broker(), dependencies()); PropertyAccessBuilder access_builder(jsgraph(), broker(), dependencies());
...@@ -725,12 +726,17 @@ Reduction JSNativeContextSpecialization::ReduceJSResolvePromise(Node* node) { ...@@ -725,12 +726,17 @@ Reduction JSNativeContextSpecialization::ReduceJSResolvePromise(Node* node) {
} }
// Compute property access info for "then" on {resolution}. // Compute property access info for "then" on {resolution}.
AccessInfoFactory access_info_factory(broker(), dependencies(), PropertyAccessInfo access_info;
graph()->zone()); {
PropertyAccessInfo access_info = ZoneVector<PropertyAccessInfo> access_infos(graph()->zone());
access_info_factory.ComputePropertyAccessInfo( AccessInfoFactory access_info_factory(broker(), dependencies(),
MapHandles(resolution_maps.begin(), resolution_maps.end()), graph()->zone());
factory()->then_string(), AccessMode::kLoad); access_info_factory.ComputePropertyAccessInfos(
MapHandles(resolution_maps.begin(), resolution_maps.end()),
factory()->then_string(), AccessMode::kLoad, &access_infos);
access_info = access_info_factory.FinalizePropertyAccessInfosAsOne(
access_infos, AccessMode::kLoad);
}
if (access_info.IsInvalid()) return NoChange(); if (access_info.IsInvalid()) return NoChange();
// We can further optimize the case where {resolution} // We can further optimize the case where {resolution}
...@@ -2459,6 +2465,7 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral( ...@@ -2459,6 +2465,7 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral(
access_info_factory.ComputePropertyAccessInfo( access_info_factory.ComputePropertyAccessInfo(
receiver_map, cached_name.object(), AccessMode::kStoreInLiteral); receiver_map, cached_name.object(), AccessMode::kStoreInLiteral);
if (access_info.IsInvalid()) return NoChange(); if (access_info.IsInvalid()) return NoChange();
access_info.RecordDependencies(dependencies());
Node* receiver = NodeProperties::GetValueInput(node, 0); Node* receiver = NodeProperties::GetValueInput(node, 0);
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
......
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