Commit 69a7e86a authored by Maya Lekova's avatar Maya Lekova Committed by Commit Bot

[turbofan] Fully brokerize ReducePropertyAccess

Bug: v8:7790
Change-Id: I6f493d994f49d84020966322d60061567b54c854
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1760808
Commit-Queue: Maya Lekova <mslekova@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63265}
parent d3e6e046
...@@ -592,6 +592,7 @@ class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef { ...@@ -592,6 +592,7 @@ class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef {
bool supports_fast_array_iteration() const; bool supports_fast_array_iteration() const;
bool supports_fast_array_resize() const; bool supports_fast_array_resize() const;
bool IsMapOfCurrentGlobalProxy() const; bool IsMapOfCurrentGlobalProxy() const;
bool is_abandoned_prototype_map() const;
OddballType oddball_type() const; OddballType oddball_type() const;
...@@ -624,6 +625,9 @@ class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef { ...@@ -624,6 +625,9 @@ class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef {
bool IsUnboxedDoubleField(int descriptor_index) const; bool IsUnboxedDoubleField(int descriptor_index) const;
ObjectRef GetStrongValue(int descriptor_number) const; ObjectRef GetStrongValue(int descriptor_number) const;
void SerializeRootMap();
base::Optional<MapRef> FindRootMap() const;
// Available after calling JSFunctionRef::Serialize on a function that has // Available after calling JSFunctionRef::Serialize on a function that has
// this map as initial map. // this map as initial map.
ObjectRef GetConstructor() const; ObjectRef GetConstructor() const;
......
...@@ -974,6 +974,9 @@ class MapData : public HeapObjectData { ...@@ -974,6 +974,9 @@ class MapData : public HeapObjectData {
bool IsMapOfCurrentGlobalProxy() const { bool IsMapOfCurrentGlobalProxy() const {
return is_map_of_current_global_proxy_; return is_map_of_current_global_proxy_;
} }
bool is_abandoned_prototype_map() const {
return is_abandoned_prototype_map_;
}
// Extra information. // Extra information.
...@@ -992,6 +995,9 @@ class MapData : public HeapObjectData { ...@@ -992,6 +995,9 @@ class MapData : public HeapObjectData {
return instance_descriptors_; return instance_descriptors_;
} }
void SerializeRootMap(JSHeapBroker* broker);
MapData* FindRootMap() const;
void SerializeConstructor(JSHeapBroker* broker); void SerializeConstructor(JSHeapBroker* broker);
ObjectData* GetConstructor() const { ObjectData* GetConstructor() const {
CHECK(serialized_constructor_); CHECK(serialized_constructor_);
...@@ -1031,6 +1037,7 @@ class MapData : public HeapObjectData { ...@@ -1031,6 +1037,7 @@ class MapData : public HeapObjectData {
bool const supports_fast_array_iteration_; bool const supports_fast_array_iteration_;
bool const supports_fast_array_resize_; bool const supports_fast_array_resize_;
bool const is_map_of_current_global_proxy_; bool const is_map_of_current_global_proxy_;
bool const is_abandoned_prototype_map_;
bool serialized_elements_kind_generalizations_ = false; bool serialized_elements_kind_generalizations_ = false;
ZoneVector<MapData*> elements_kind_generalizations_; ZoneVector<MapData*> elements_kind_generalizations_;
...@@ -1047,6 +1054,9 @@ class MapData : public HeapObjectData { ...@@ -1047,6 +1054,9 @@ class MapData : public HeapObjectData {
bool serialized_prototype_ = false; bool serialized_prototype_ = false;
ObjectData* prototype_ = nullptr; ObjectData* prototype_ = nullptr;
bool serialized_root_map_ = false;
MapData* root_map_ = nullptr;
bool serialized_for_element_load_ = false; bool serialized_for_element_load_ = false;
bool serialized_for_element_store_ = false; bool serialized_for_element_store_ = false;
...@@ -1155,6 +1165,7 @@ MapData::MapData(JSHeapBroker* broker, ObjectData** storage, Handle<Map> object) ...@@ -1155,6 +1165,7 @@ MapData::MapData(JSHeapBroker* broker, ObjectData** storage, Handle<Map> object)
SupportsFastArrayResize(broker->isolate(), object)), SupportsFastArrayResize(broker->isolate(), object)),
is_map_of_current_global_proxy_( is_map_of_current_global_proxy_(
object->IsMapOfGlobalProxy(broker->isolate()->native_context())), object->IsMapOfGlobalProxy(broker->isolate()->native_context())),
is_abandoned_prototype_map_(object->is_abandoned_prototype_map()),
elements_kind_generalizations_(broker->zone()) {} elements_kind_generalizations_(broker->zone()) {}
JSFunctionData::JSFunctionData(JSHeapBroker* broker, ObjectData** storage, JSFunctionData::JSFunctionData(JSHeapBroker* broker, ObjectData** storage,
...@@ -2009,6 +2020,19 @@ void MapData::SerializeOwnDescriptor(JSHeapBroker* broker, ...@@ -2009,6 +2020,19 @@ void MapData::SerializeOwnDescriptor(JSHeapBroker* broker,
<< contents.size() << " total)"); << contents.size() << " total)");
} }
void MapData::SerializeRootMap(JSHeapBroker* broker) {
if (serialized_root_map_) return;
serialized_root_map_ = true;
TraceScope tracer(broker, this, "MapData::SerializeRootMap");
Handle<Map> map = Handle<Map>::cast(object());
DCHECK_NULL(root_map_);
root_map_ =
broker->GetOrCreateData(map->FindRootMap(broker->isolate()))->AsMap();
}
MapData* MapData::FindRootMap() const { return root_map_; }
void JSObjectData::SerializeRecursiveAsBoilerplate(JSHeapBroker* broker, void JSObjectData::SerializeRecursiveAsBoilerplate(JSHeapBroker* broker,
int depth) { int depth) {
if (serialized_as_boilerplate_) return; if (serialized_as_boilerplate_) return;
...@@ -3091,6 +3115,7 @@ BIMODAL_ACCESSOR(Map, HeapObject, prototype) ...@@ -3091,6 +3115,7 @@ BIMODAL_ACCESSOR(Map, HeapObject, prototype)
BIMODAL_ACCESSOR_C(Map, InstanceType, instance_type) BIMODAL_ACCESSOR_C(Map, InstanceType, instance_type)
BIMODAL_ACCESSOR(Map, Object, GetConstructor) BIMODAL_ACCESSOR(Map, Object, GetConstructor)
BIMODAL_ACCESSOR(Map, HeapObject, GetBackPointer) BIMODAL_ACCESSOR(Map, HeapObject, GetBackPointer)
BIMODAL_ACCESSOR_C(Map, bool, is_abandoned_prototype_map)
#define DEF_NATIVE_CONTEXT_ACCESSOR(type, name) \ #define DEF_NATIVE_CONTEXT_ACCESSOR(type, name) \
BIMODAL_ACCESSOR(NativeContext, type, name) BIMODAL_ACCESSOR(NativeContext, type, name)
...@@ -3228,6 +3253,26 @@ ObjectRef MapRef::GetStrongValue(int descriptor_index) const { ...@@ -3228,6 +3253,26 @@ ObjectRef MapRef::GetStrongValue(int descriptor_index) const {
return ObjectRef(broker(), data()->AsMap()->GetStrongValue(descriptor_index)); return ObjectRef(broker(), data()->AsMap()->GetStrongValue(descriptor_index));
} }
void MapRef::SerializeRootMap() {
if (broker()->mode() == JSHeapBroker::kDisabled) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsMap()->SerializeRootMap(broker());
}
base::Optional<MapRef> MapRef::FindRootMap() const {
if (broker()->mode() == JSHeapBroker::kDisabled) {
AllowHandleDereference allow_handle_dereference;
return MapRef(broker(), handle(object()->FindRootMap(broker()->isolate()),
broker()->isolate()));
}
MapData* map_data = data()->AsMap()->FindRootMap();
if (map_data) {
return MapRef(broker(), map_data);
}
TRACE_BROKER_MISSING(broker(), "root map for object " << object());
return base::nullopt;
}
void* JSTypedArrayRef::external_pointer() const { void* JSTypedArrayRef::external_pointer() const {
if (broker()->mode() == JSHeapBroker::kDisabled) { if (broker()->mode() == JSHeapBroker::kDisabled) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereference allow_handle_dereference;
...@@ -4401,7 +4446,10 @@ ElementAccessFeedback const& JSHeapBroker::ProcessFeedbackMapsForElementAccess( ...@@ -4401,7 +4446,10 @@ ElementAccessFeedback const& JSHeapBroker::ProcessFeedbackMapsForElementAccess(
MapHandles possible_transition_targets; MapHandles possible_transition_targets;
possible_transition_targets.reserve(maps.size()); possible_transition_targets.reserve(maps.size());
for (Handle<Map> map : maps) { for (Handle<Map> map : maps) {
if (CanInlineElementAccess(MapRef(this, map)) && MapRef map_ref(this, map);
map_ref.SerializeRootMap();
if (CanInlineElementAccess(map_ref) &&
IsFastElementsKind(map->elements_kind()) && IsFastElementsKind(map->elements_kind()) &&
GetInitialFastElementsKind() != map->elements_kind()) { GetInitialFastElementsKind() != map->elements_kind()) {
possible_transition_targets.push_back(map); possible_transition_targets.push_back(map);
......
...@@ -1481,18 +1481,16 @@ base::Optional<JSTypedArrayRef> GetTypedArrayConstant(JSHeapBroker* broker, ...@@ -1481,18 +1481,16 @@ base::Optional<JSTypedArrayRef> GetTypedArrayConstant(JSHeapBroker* broker,
void JSNativeContextSpecialization::RemoveImpossibleReceiverMaps( void JSNativeContextSpecialization::RemoveImpossibleReceiverMaps(
Node* receiver, ZoneVector<Handle<Map>>* receiver_maps) const { Node* receiver, ZoneVector<Handle<Map>>* receiver_maps) const {
// TODO(neis): Decide what to do about this for concurrent inlining. base::Optional<MapRef> root_map = InferReceiverRootMap(receiver);
AllowHandleAllocation allow_handle_allocation; if (root_map.has_value()) {
AllowHandleDereference allow_handle_dereference;
Handle<Map> root_map;
if (InferReceiverRootMap(receiver).ToHandle(&root_map)) {
DCHECK(!root_map->is_abandoned_prototype_map()); DCHECK(!root_map->is_abandoned_prototype_map());
Isolate* isolate = this->isolate();
receiver_maps->erase( receiver_maps->erase(
std::remove_if(receiver_maps->begin(), receiver_maps->end(), std::remove_if(receiver_maps->begin(), receiver_maps->end(),
[root_map, isolate](Handle<Map> map) { [root_map, this](Handle<Map> map) {
return map->is_abandoned_prototype_map() || MapRef map_ref(broker(), map);
map->FindRootMap(isolate) != *root_map; return map_ref.is_abandoned_prototype_map() ||
(map_ref.FindRootMap().has_value() &&
!map_ref.FindRootMap()->equals(*root_map));
}), }),
receiver_maps->end()); receiver_maps->end());
} }
...@@ -1826,6 +1824,8 @@ Reduction JSNativeContextSpecialization::ReduceElementLoadFromHeapConstant( ...@@ -1826,6 +1824,8 @@ Reduction JSNativeContextSpecialization::ReduceElementLoadFromHeapConstant(
Reduction JSNativeContextSpecialization::ReducePropertyAccess( Reduction JSNativeContextSpecialization::ReducePropertyAccess(
Node* node, Node* key, base::Optional<NameRef> static_name, Node* value, Node* node, Node* key, base::Optional<NameRef> static_name, Node* value,
FeedbackSource const& source, AccessMode access_mode) { FeedbackSource const& source, AccessMode access_mode) {
DisallowHeapAccessIf disallow_heap_access(FLAG_concurrent_inlining);
DCHECK_EQ(key == nullptr, static_name.has_value()); DCHECK_EQ(key == nullptr, static_name.has_value());
DCHECK(node->opcode() == IrOpcode::kJSLoadProperty || DCHECK(node->opcode() == IrOpcode::kJSLoadProperty ||
node->opcode() == IrOpcode::kJSStoreProperty || node->opcode() == IrOpcode::kJSStoreProperty ||
...@@ -3230,21 +3230,24 @@ bool JSNativeContextSpecialization::InferReceiverMaps( ...@@ -3230,21 +3230,24 @@ bool JSNativeContextSpecialization::InferReceiverMaps(
return false; return false;
} }
MaybeHandle<Map> JSNativeContextSpecialization::InferReceiverRootMap( base::Optional<MapRef> JSNativeContextSpecialization::InferReceiverRootMap(
Node* receiver) const { Node* receiver) const {
HeapObjectMatcher m(receiver); HeapObjectMatcher m(receiver);
if (m.HasValue()) { if (m.HasValue()) {
return handle(m.Value()->map().FindRootMap(isolate()), isolate()); MapRef map = m.Ref(broker()).map();
return map.FindRootMap();
} else if (m.IsJSCreate()) { } else if (m.IsJSCreate()) {
base::Optional<MapRef> initial_map = base::Optional<MapRef> initial_map =
NodeProperties::GetJSCreateMap(broker(), receiver); NodeProperties::GetJSCreateMap(broker(), receiver);
if (initial_map.has_value()) { if (initial_map.has_value()) {
DCHECK_EQ(*initial_map->object(), if (!initial_map->FindRootMap().has_value()) {
initial_map->object()->FindRootMap(isolate())); return base::nullopt;
return initial_map->object(); }
DCHECK(initial_map->equals(*initial_map->FindRootMap()));
return *initial_map;
} }
} }
return MaybeHandle<Map>(); return base::nullopt;
} }
Graph* JSNativeContextSpecialization::graph() const { Graph* JSNativeContextSpecialization::graph() const {
......
...@@ -231,7 +231,7 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final ...@@ -231,7 +231,7 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
// Try to infer a root map for the {receiver} independent of the current // Try to infer a root map for the {receiver} independent of the current
// program location. // program location.
MaybeHandle<Map> InferReceiverRootMap(Node* receiver) const; base::Optional<MapRef> InferReceiverRootMap(Node* receiver) const;
// Checks if we know at compile time that the {receiver} either definitely // Checks if we know at compile time that the {receiver} either definitely
// has the {prototype} in it's prototype chain, or the {receiver} definitely // has the {prototype} in it's prototype chain, or the {receiver} definitely
......
...@@ -424,7 +424,7 @@ class SerializerForBackgroundCompilation { ...@@ -424,7 +424,7 @@ class SerializerForBackgroundCompilation {
bool honor_bailout_on_uninitialized); bool honor_bailout_on_uninitialized);
PropertyAccessInfo ProcessMapForNamedPropertyAccess( PropertyAccessInfo ProcessMapForNamedPropertyAccess(
MapRef const& receiver_map, NameRef const& name, AccessMode access_mode, MapRef receiver_map, NameRef const& name, AccessMode access_mode,
base::Optional<JSObjectRef> receiver, Hints* new_accumulator_hints); base::Optional<JSObjectRef> receiver, Hints* new_accumulator_hints);
void ProcessCreateContext(interpreter::BytecodeArrayIterator* iterator, void ProcessCreateContext(interpreter::BytecodeArrayIterator* iterator,
...@@ -2245,8 +2245,11 @@ void SerializerForBackgroundCompilation::ProcessUnaryOrBinaryOperation( ...@@ -2245,8 +2245,11 @@ void SerializerForBackgroundCompilation::ProcessUnaryOrBinaryOperation(
PropertyAccessInfo PropertyAccessInfo
SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess( SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess(
MapRef const& receiver_map, NameRef const& name, AccessMode access_mode, MapRef receiver_map, NameRef const& name, AccessMode access_mode,
base::Optional<JSObjectRef> receiver, Hints* new_accumulator_hints) { base::Optional<JSObjectRef> receiver, Hints* new_accumulator_hints) {
// For JSNativeContextSpecialization::InferReceiverRootMap
receiver_map.SerializeRootMap();
// For JSNativeContextSpecialization::ReduceNamedAccess. // For JSNativeContextSpecialization::ReduceNamedAccess.
if (receiver_map.IsMapOfCurrentGlobalProxy()) { if (receiver_map.IsMapOfCurrentGlobalProxy()) {
broker()->native_context().global_proxy_object().GetPropertyCell( broker()->native_context().global_proxy_object().GetPropertyCell(
...@@ -2391,16 +2394,16 @@ void SerializerForBackgroundCompilation::ProcessNamedAccess( ...@@ -2391,16 +2394,16 @@ void SerializerForBackgroundCompilation::ProcessNamedAccess(
Hints receiver, NamedAccessFeedback const& feedback, AccessMode access_mode, Hints receiver, NamedAccessFeedback const& feedback, AccessMode access_mode,
Hints* new_accumulator_hints) { Hints* new_accumulator_hints) {
for (Handle<Map> map : feedback.AsNamedAccess().maps()) { for (Handle<Map> map : feedback.AsNamedAccess().maps()) {
ProcessMapForNamedPropertyAccess(MapRef(broker(), map), feedback.name(), MapRef map_ref(broker(), map);
access_mode, base::nullopt, ProcessMapForNamedPropertyAccess(map_ref, feedback.name(), access_mode,
new_accumulator_hints); base::nullopt, new_accumulator_hints);
} }
for (Handle<Map> map : for (Handle<Map> map :
GetRelevantReceiverMaps(broker()->isolate(), receiver.maps())) { GetRelevantReceiverMaps(broker()->isolate(), receiver.maps())) {
ProcessMapForNamedPropertyAccess(MapRef(broker(), map), feedback.name(), MapRef map_ref(broker(), map);
access_mode, base::nullopt, ProcessMapForNamedPropertyAccess(map_ref, feedback.name(), access_mode,
new_accumulator_hints); base::nullopt, new_accumulator_hints);
} }
JSGlobalProxyRef global_proxy = JSGlobalProxyRef global_proxy =
...@@ -2408,9 +2411,10 @@ void SerializerForBackgroundCompilation::ProcessNamedAccess( ...@@ -2408,9 +2411,10 @@ void SerializerForBackgroundCompilation::ProcessNamedAccess(
for (Handle<Object> hint : receiver.constants()) { for (Handle<Object> hint : receiver.constants()) {
ObjectRef object(broker(), hint); ObjectRef object(broker(), hint);
if (access_mode == AccessMode::kLoad && object.IsJSObject()) { if (access_mode == AccessMode::kLoad && object.IsJSObject()) {
ProcessMapForNamedPropertyAccess( MapRef map_ref = object.AsJSObject().map();
object.AsJSObject().map(), feedback.name(), access_mode, ProcessMapForNamedPropertyAccess(map_ref, feedback.name(), access_mode,
object.AsJSObject(), new_accumulator_hints); object.AsJSObject(),
new_accumulator_hints);
} }
// For JSNativeContextSpecialization::ReduceNamedAccessFromNexus. // For JSNativeContextSpecialization::ReduceNamedAccessFromNexus.
// TODO(neis): This should be done even if megamorphic. // TODO(neis): This should be done even if megamorphic.
...@@ -2451,6 +2455,11 @@ void SerializerForBackgroundCompilation::ProcessElementAccess( ...@@ -2451,6 +2455,11 @@ void SerializerForBackgroundCompilation::ProcessElementAccess(
for (Handle<Object> hint : receiver.constants()) { for (Handle<Object> hint : receiver.constants()) {
ObjectRef receiver_ref(broker(), hint); ObjectRef receiver_ref(broker(), hint);
// For JSNativeContextSpecialization::InferReceiverRootMap
if (receiver_ref.IsHeapObject()) {
receiver_ref.AsHeapObject().map().SerializeRootMap();
}
// For JSNativeContextSpecialization::ReduceElementAccess. // For JSNativeContextSpecialization::ReduceElementAccess.
if (receiver_ref.IsJSTypedArray()) { if (receiver_ref.IsJSTypedArray()) {
receiver_ref.AsJSTypedArray().Serialize(); receiver_ref.AsJSTypedArray().Serialize();
...@@ -2476,6 +2485,12 @@ void SerializerForBackgroundCompilation::ProcessElementAccess( ...@@ -2476,6 +2485,12 @@ void SerializerForBackgroundCompilation::ProcessElementAccess(
} }
} }
} }
// For JSNativeContextSpecialization::InferReceiverRootMap
for (Handle<Map> map : receiver.maps()) {
MapRef map_ref(broker(), map);
map_ref.SerializeRootMap();
}
} }
void SerializerForBackgroundCompilation::VisitLdaNamedProperty( void SerializerForBackgroundCompilation::VisitLdaNamedProperty(
......
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