Commit 64b0c307 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Fix descriptor array serialization.

This did unnecessarily much work, part of it even didn't make sense
due to my misunderstanding of the different ownership notions.

Bug: v8:7790
Change-Id: I8f630b544d2fa9d583ceb7e496e88b9a655385a7
Reviewed-on: https://chromium-review.googlesource.com/1236955Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56135}
parent d6f6ab11
...@@ -405,7 +405,7 @@ bool AccessInfoFactory::ComputePropertyAccessInfo( ...@@ -405,7 +405,7 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
// about the contents now. // about the contents now.
} else if (descriptors_field_type->IsClass()) { } else if (descriptors_field_type->IsClass()) {
MapRef map_ref(js_heap_broker(), map); MapRef map_ref(js_heap_broker(), map);
map_ref.SerializeDescriptors(); // TODO(neis): Remove later. map_ref.SerializeOwnDescriptors(); // TODO(neis): Remove later.
dependencies()->DependOnFieldType(map_ref, number); dependencies()->DependOnFieldType(map_ref, number);
// Remember the field map, and try to infer a useful type. // Remember the field map, and try to infer a useful type.
Handle<Map> map(descriptors_field_type->AsClass(), isolate()); Handle<Map> map(descriptors_field_type->AsClass(), isolate());
...@@ -710,7 +710,8 @@ bool AccessInfoFactory::LookupTransition(Handle<Map> map, Handle<Name> name, ...@@ -710,7 +710,8 @@ bool AccessInfoFactory::LookupTransition(Handle<Map> map, Handle<Name> name,
return false; return false;
} else if (descriptors_field_type->IsClass()) { } else if (descriptors_field_type->IsClass()) {
MapRef transition_map_ref(js_heap_broker(), transition_map); MapRef transition_map_ref(js_heap_broker(), transition_map);
transition_map_ref.SerializeDescriptors(); // TODO(neis): Remove later. transition_map_ref
.SerializeOwnDescriptors(); // TODO(neis): Remove later.
dependencies()->DependOnFieldType(transition_map_ref, number); dependencies()->DependOnFieldType(transition_map_ref, number);
// Remember the field map, and try to infer a useful type. // Remember the field map, and try to infer a useful type.
Handle<Map> map(descriptors_field_type->AsClass(), isolate()); Handle<Map> map(descriptors_field_type->AsClass(), isolate());
......
...@@ -558,11 +558,12 @@ class MapData : public HeapObjectData { ...@@ -558,11 +558,12 @@ class MapData : public HeapObjectData {
return elements_kind_generalizations_; return elements_kind_generalizations_;
} }
// Serialize the descriptor array and, recursively, that of any field owner. // Serialize the own part of the descriptor array and, recursively, that of
void SerializeDescriptors(); // any field owner.
const ZoneVector<PropertyDescriptor>& descriptors() const { void SerializeOwnDescriptors();
CHECK(serialized_descriptors_); DescriptorArrayData* instance_descriptors() const {
return descriptors_; CHECK(serialized_own_descriptors_);
return instance_descriptors_;
} }
void SerializeConstructorOrBackpointer(); void SerializeConstructorOrBackpointer();
...@@ -591,8 +592,8 @@ class MapData : public HeapObjectData { ...@@ -591,8 +592,8 @@ class MapData : public HeapObjectData {
bool serialized_elements_kind_generalizations_ = false; bool serialized_elements_kind_generalizations_ = false;
ZoneVector<MapData*> elements_kind_generalizations_; ZoneVector<MapData*> elements_kind_generalizations_;
bool serialized_descriptors_ = false; bool serialized_own_descriptors_ = false;
ZoneVector<PropertyDescriptor> descriptors_; DescriptorArrayData* instance_descriptors_ = nullptr;
bool serialized_constructor_or_backpointer_ = false; bool serialized_constructor_or_backpointer_ = false;
ObjectData* constructor_or_backpointer_ = nullptr; ObjectData* constructor_or_backpointer_ = nullptr;
...@@ -664,8 +665,7 @@ MapData::MapData(JSHeapBroker* broker, ObjectData** storage, Handle<Map> object) ...@@ -664,8 +665,7 @@ MapData::MapData(JSHeapBroker* broker, ObjectData** storage, Handle<Map> object)
: 0), : 0),
in_object_properties_( in_object_properties_(
object->IsJSObjectMap() ? object->GetInObjectProperties() : 0), object->IsJSObjectMap() ? object->GetInObjectProperties() : 0),
elements_kind_generalizations_(broker->zone()), elements_kind_generalizations_(broker->zone()) {}
descriptors_(broker->zone()) {}
JSFunctionData::JSFunctionData(JSHeapBroker* broker, ObjectData** storage, JSFunctionData::JSFunctionData(JSHeapBroker* broker, ObjectData** storage,
Handle<JSFunction> object) Handle<JSFunction> object)
...@@ -734,6 +734,18 @@ void MapData::SerializeElementsKindGeneralizations() { ...@@ -734,6 +734,18 @@ void MapData::SerializeElementsKindGeneralizations() {
} }
} }
class DescriptorArrayData : public HeapObjectData {
public:
DescriptorArrayData(JSHeapBroker* broker, ObjectData** storage,
Handle<DescriptorArray> object)
: HeapObjectData(broker, storage, object), contents_(broker->zone()) {}
ZoneVector<PropertyDescriptor>& contents() { return contents_; }
private:
ZoneVector<PropertyDescriptor> contents_;
};
class FeedbackVectorData : public HeapObjectData { class FeedbackVectorData : public HeapObjectData {
public: public:
const ZoneVector<ObjectData*>& feedback() { return feedback_; } const ZoneVector<ObjectData*>& feedback() { return feedback_; }
...@@ -1112,21 +1124,31 @@ void MapData::SerializePrototype() { ...@@ -1112,21 +1124,31 @@ void MapData::SerializePrototype() {
prototype_ = broker()->GetOrCreateData(map->prototype()); prototype_ = broker()->GetOrCreateData(map->prototype());
} }
void MapData::SerializeDescriptors() { void MapData::SerializeOwnDescriptors() {
if (serialized_descriptors_) return; if (serialized_own_descriptors_) return;
serialized_descriptors_ = true; serialized_own_descriptors_ = true;
TraceScope tracer(this, "MapData::SerializeDescriptors"); TraceScope tracer(this, "MapData::SerializeOwnDescriptors");
Handle<Map> map = Handle<Map>::cast(object()); Handle<Map> map = Handle<Map>::cast(object());
DCHECK_NULL(instance_descriptors_);
instance_descriptors_ = broker()
->GetOrCreateData(map->instance_descriptors())
->AsDescriptorArray();
int const number_of_own = map->NumberOfOwnDescriptors();
ZoneVector<PropertyDescriptor>& contents = instance_descriptors_->contents();
int const current_size = static_cast<int>(contents.size());
if (number_of_own <= current_size) return;
Isolate* const isolate = broker()->isolate(); Isolate* const isolate = broker()->isolate();
Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate); auto descriptors =
// We copy all descriptors (not only the own) in order to support Handle<DescriptorArray>::cast(instance_descriptors_->object());
// FindFieldOwner, which is used by the FieldType compilation dependency. CHECK_EQ(*descriptors, map->instance_descriptors());
int const number_of_descriptors = descriptors->number_of_descriptors(); contents.reserve(number_of_own);
DCHECK(descriptors_.empty());
descriptors_.reserve(number_of_descriptors); // Copy the new descriptors.
for (int i = current_size; i < number_of_own; ++i) {
for (int i = 0; i < number_of_descriptors; ++i) {
PropertyDescriptor d; PropertyDescriptor d;
d.key = broker()->GetOrCreateData(descriptors->GetKey(i))->AsName(); d.key = broker()->GetOrCreateData(descriptors->GetKey(i))->AsName();
d.details = descriptors->GetDetails(i); d.details = descriptors->GetDetails(i);
...@@ -1137,11 +1159,25 @@ void MapData::SerializeDescriptors() { ...@@ -1137,11 +1159,25 @@ void MapData::SerializeDescriptors() {
d.field_type = broker()->GetOrCreateData(descriptors->GetFieldType(i)); d.field_type = broker()->GetOrCreateData(descriptors->GetFieldType(i));
d.is_unboxed_double_field = map->IsUnboxedDoubleField(d.field_index); d.is_unboxed_double_field = map->IsUnboxedDoubleField(d.field_index);
// Recurse. // Recurse.
d.field_owner->SerializeDescriptors();
} }
descriptors_.push_back(d); contents.push_back(d);
}
CHECK_EQ(number_of_own, contents.size());
// Recurse on the new owner maps.
for (int i = current_size; i < number_of_own; ++i) {
const PropertyDescriptor& d = contents[i];
if (d.details.location() == kField) {
CHECK_LE(
Handle<Map>::cast(d.field_owner->object())->NumberOfOwnDescriptors(),
number_of_own);
d.field_owner->SerializeOwnDescriptors();
}
} }
broker()->Trace("Copied %zu descriptors.\n", descriptors_.size());
broker()->Trace("Copied %zu descriptors into %p (%zu total).\n",
number_of_own - current_size, instance_descriptors_,
number_of_own);
} }
void JSObjectData::SerializeRecursive(int depth) { void JSObjectData::SerializeRecursive(int depth) {
...@@ -1236,9 +1272,9 @@ void JSObjectData::SerializeRecursive(int depth) { ...@@ -1236,9 +1272,9 @@ void JSObjectData::SerializeRecursive(int depth) {
inobject_fields_.push_back(JSObjectField{value_data}); inobject_fields_.push_back(JSObjectField{value_data});
} }
} }
broker()->Trace("Copied %zu fields.\n", inobject_fields_.size()); broker()->Trace("Copied %zu in-object fields.\n", inobject_fields_.size());
map()->SerializeDescriptors(); map()->SerializeOwnDescriptors();
if (IsJSArray()) AsJSArray()->Serialize(); if (IsJSArray()) AsJSArray()->Serialize();
} }
...@@ -1648,7 +1684,8 @@ FieldIndex MapRef::GetFieldIndexFor(int descriptor_index) const { ...@@ -1648,7 +1684,8 @@ FieldIndex MapRef::GetFieldIndexFor(int descriptor_index) const {
AllowHandleDereference allow_handle_dereference; AllowHandleDereference allow_handle_dereference;
return FieldIndex::ForDescriptor(*object<Map>(), descriptor_index); return FieldIndex::ForDescriptor(*object<Map>(), descriptor_index);
} }
return data()->AsMap()->descriptors().at(descriptor_index).field_index; DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
return descriptors->contents().at(descriptor_index).field_index;
} }
int MapRef::GetInObjectPropertyOffset(int i) const { int MapRef::GetInObjectPropertyOffset(int i) const {
...@@ -1664,7 +1701,8 @@ PropertyDetails MapRef::GetPropertyDetails(int descriptor_index) const { ...@@ -1664,7 +1701,8 @@ PropertyDetails MapRef::GetPropertyDetails(int descriptor_index) const {
AllowHandleDereference allow_handle_dereference; AllowHandleDereference allow_handle_dereference;
return object<Map>()->instance_descriptors()->GetDetails(descriptor_index); return object<Map>()->instance_descriptors()->GetDetails(descriptor_index);
} }
return data()->AsMap()->descriptors().at(descriptor_index).details; DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
return descriptors->contents().at(descriptor_index).details;
} }
NameRef MapRef::GetPropertyKey(int descriptor_index) const { NameRef MapRef::GetPropertyKey(int descriptor_index) const {
...@@ -1676,7 +1714,8 @@ NameRef MapRef::GetPropertyKey(int descriptor_index) const { ...@@ -1676,7 +1714,8 @@ NameRef MapRef::GetPropertyKey(int descriptor_index) const {
handle(object<Map>()->instance_descriptors()->GetKey(descriptor_index), handle(object<Map>()->instance_descriptors()->GetKey(descriptor_index),
broker()->isolate())); broker()->isolate()));
} }
return NameRef(data()->AsMap()->descriptors().at(descriptor_index).key); DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
return NameRef(descriptors->contents().at(descriptor_index).key);
} }
bool MapRef::IsFixedCowArrayMap() const { bool MapRef::IsFixedCowArrayMap() const {
...@@ -1694,8 +1733,8 @@ MapRef MapRef::FindFieldOwner(int descriptor_index) const { ...@@ -1694,8 +1733,8 @@ MapRef MapRef::FindFieldOwner(int descriptor_index) const {
broker()->isolate()); broker()->isolate());
return MapRef(broker(), owner); return MapRef(broker(), owner);
} }
return MapRef( DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
data()->AsMap()->descriptors().at(descriptor_index).field_owner); return MapRef(descriptors->contents().at(descriptor_index).field_owner);
} }
ObjectRef MapRef::GetFieldType(int descriptor_index) const { ObjectRef MapRef::GetFieldType(int descriptor_index) const {
...@@ -1707,8 +1746,8 @@ ObjectRef MapRef::GetFieldType(int descriptor_index) const { ...@@ -1707,8 +1746,8 @@ ObjectRef MapRef::GetFieldType(int descriptor_index) const {
broker()->isolate()); broker()->isolate());
return ObjectRef(broker(), field_type); return ObjectRef(broker(), field_type);
} }
return ObjectRef( DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
data()->AsMap()->descriptors().at(descriptor_index).field_type); return ObjectRef(descriptors->contents().at(descriptor_index).field_type);
} }
bool MapRef::IsUnboxedDoubleField(int descriptor_index) const { bool MapRef::IsUnboxedDoubleField(int descriptor_index) const {
...@@ -1717,11 +1756,8 @@ bool MapRef::IsUnboxedDoubleField(int descriptor_index) const { ...@@ -1717,11 +1756,8 @@ bool MapRef::IsUnboxedDoubleField(int descriptor_index) const {
return object<Map>()->IsUnboxedDoubleField( return object<Map>()->IsUnboxedDoubleField(
FieldIndex::ForDescriptor(*object<Map>(), descriptor_index)); FieldIndex::ForDescriptor(*object<Map>(), descriptor_index));
} }
return data() DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
->AsMap() return descriptors->contents().at(descriptor_index).is_unboxed_double_field;
->descriptors()
.at(descriptor_index)
.is_unboxed_double_field;
} }
uint16_t StringRef::GetFirstChar() { uint16_t StringRef::GetFirstChar() {
...@@ -2184,10 +2220,10 @@ void JSObjectRef::SerializeObjectCreateMap() { ...@@ -2184,10 +2220,10 @@ void JSObjectRef::SerializeObjectCreateMap() {
data()->AsJSObject()->SerializeObjectCreateMap(); data()->AsJSObject()->SerializeObjectCreateMap();
} }
void MapRef::SerializeDescriptors() { void MapRef::SerializeOwnDescriptors() {
if (broker()->mode() == JSHeapBroker::kDisabled) return; if (broker()->mode() == JSHeapBroker::kDisabled) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsMap()->SerializeDescriptors(); data()->AsMap()->SerializeOwnDescriptors();
} }
void ModuleRef::Serialize() { void ModuleRef::Serialize() {
......
...@@ -50,6 +50,7 @@ enum class OddballType : uint8_t { ...@@ -50,6 +50,7 @@ enum class OddballType : uint8_t {
V(AllocationSite) \ V(AllocationSite) \
V(Cell) \ V(Cell) \
V(Code) \ V(Code) \
V(DescriptorArray) \
V(FeedbackVector) \ V(FeedbackVector) \
V(FixedArrayBase) \ V(FixedArrayBase) \
V(HeapNumber) \ V(HeapNumber) \
...@@ -284,6 +285,11 @@ class ScriptContextTableRef : public HeapObjectRef { ...@@ -284,6 +285,11 @@ class ScriptContextTableRef : public HeapObjectRef {
base::Optional<LookupResult> lookup(const NameRef& name) const; base::Optional<LookupResult> lookup(const NameRef& name) const;
}; };
class DescriptorArrayRef : public HeapObjectRef {
public:
using HeapObjectRef::HeapObjectRef;
};
class FeedbackVectorRef : public HeapObjectRef { class FeedbackVectorRef : public HeapObjectRef {
public: public:
using HeapObjectRef::HeapObjectRef; using HeapObjectRef::HeapObjectRef;
...@@ -345,7 +351,7 @@ class MapRef : public HeapObjectRef { ...@@ -345,7 +351,7 @@ class MapRef : public HeapObjectRef {
base::Optional<MapRef> AsElementsKind(ElementsKind kind) const; base::Optional<MapRef> AsElementsKind(ElementsKind kind) const;
// Concerning the underlying instance_descriptors: // Concerning the underlying instance_descriptors:
void SerializeDescriptors(); void SerializeOwnDescriptors();
MapRef FindFieldOwner(int descriptor_index) const; MapRef FindFieldOwner(int descriptor_index) const;
PropertyDetails GetPropertyDetails(int descriptor_index) const; PropertyDetails GetPropertyDetails(int descriptor_index) const;
NameRef GetPropertyKey(int descriptor_index) const; NameRef GetPropertyKey(int descriptor_index) const;
......
...@@ -209,7 +209,7 @@ Node* PropertyAccessBuilder::TryBuildLoadConstantDataField( ...@@ -209,7 +209,7 @@ Node* PropertyAccessBuilder::TryBuildLoadConstantDataField(
DCHECK(!it.is_dictionary_holder()); DCHECK(!it.is_dictionary_holder());
MapRef map(js_heap_broker(), MapRef map(js_heap_broker(),
handle(it.GetHolder<HeapObject>()->map(), isolate())); handle(it.GetHolder<HeapObject>()->map(), isolate()));
map.SerializeDescriptors(); // TODO(neis): Remove later. map.SerializeOwnDescriptors(); // TODO(neis): Remove later.
dependencies()->DependOnFieldType(map, it.GetFieldDescriptorIndex()); dependencies()->DependOnFieldType(map, it.GetFieldDescriptorIndex());
} }
return value; return value;
......
...@@ -657,7 +657,7 @@ static void TestGeneralizeField(int detach_property_at_index, ...@@ -657,7 +657,7 @@ static void TestGeneralizeField(int detach_property_at_index,
JSHeapBroker broker(isolate, &zone); JSHeapBroker broker(isolate, &zone);
CompilationDependencies dependencies(isolate, &zone); CompilationDependencies dependencies(isolate, &zone);
MapRef map_ref(&broker, map); MapRef map_ref(&broker, map);
map_ref.SerializeDescriptors(); map_ref.SerializeOwnDescriptors();
dependencies.DependOnFieldType(map_ref, property_index); dependencies.DependOnFieldType(map_ref, property_index);
Handle<Map> field_owner(map->FindFieldOwner(isolate, property_index), Handle<Map> field_owner(map->FindFieldOwner(isolate, property_index),
...@@ -1031,7 +1031,7 @@ static void TestReconfigureDataFieldAttribute_GeneralizeField( ...@@ -1031,7 +1031,7 @@ static void TestReconfigureDataFieldAttribute_GeneralizeField(
JSHeapBroker broker(isolate, &zone); JSHeapBroker broker(isolate, &zone);
CompilationDependencies dependencies(isolate, &zone); CompilationDependencies dependencies(isolate, &zone);
MapRef map_ref(&broker, map); MapRef map_ref(&broker, map);
map_ref.SerializeDescriptors(); map_ref.SerializeOwnDescriptors();
dependencies.DependOnFieldType(map_ref, kSplitProp); dependencies.DependOnFieldType(map_ref, kSplitProp);
// Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which
...@@ -1117,7 +1117,7 @@ static void TestReconfigureDataFieldAttribute_GeneralizeFieldTrivial( ...@@ -1117,7 +1117,7 @@ static void TestReconfigureDataFieldAttribute_GeneralizeFieldTrivial(
JSHeapBroker broker(isolate, &zone); JSHeapBroker broker(isolate, &zone);
CompilationDependencies dependencies(isolate, &zone); CompilationDependencies dependencies(isolate, &zone);
MapRef map_ref(&broker, map); MapRef map_ref(&broker, map);
map_ref.SerializeDescriptors(); map_ref.SerializeOwnDescriptors();
dependencies.DependOnFieldType(map_ref, kSplitProp); dependencies.DependOnFieldType(map_ref, kSplitProp);
// Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which
...@@ -1800,7 +1800,7 @@ static void TestReconfigureElementsKind_GeneralizeField( ...@@ -1800,7 +1800,7 @@ static void TestReconfigureElementsKind_GeneralizeField(
JSHeapBroker broker(isolate, &zone); JSHeapBroker broker(isolate, &zone);
CompilationDependencies dependencies(isolate, &zone); CompilationDependencies dependencies(isolate, &zone);
MapRef map_ref(&broker, map); MapRef map_ref(&broker, map);
map_ref.SerializeDescriptors(); map_ref.SerializeOwnDescriptors();
dependencies.DependOnFieldType(map_ref, kDiffProp); dependencies.DependOnFieldType(map_ref, kDiffProp);
// Reconfigure elements kinds of |map2|, which should generalize // Reconfigure elements kinds of |map2|, which should generalize
...@@ -1897,7 +1897,7 @@ static void TestReconfigureElementsKind_GeneralizeFieldTrivial( ...@@ -1897,7 +1897,7 @@ static void TestReconfigureElementsKind_GeneralizeFieldTrivial(
JSHeapBroker broker(isolate, &zone); JSHeapBroker broker(isolate, &zone);
CompilationDependencies dependencies(isolate, &zone); CompilationDependencies dependencies(isolate, &zone);
MapRef map_ref(&broker, map); MapRef map_ref(&broker, map);
map_ref.SerializeDescriptors(); map_ref.SerializeOwnDescriptors();
dependencies.DependOnFieldType(map_ref, kDiffProp); dependencies.DependOnFieldType(map_ref, kDiffProp);
// Reconfigure elements kinds of |map2|, which should generalize // Reconfigure elements kinds of |map2|, which should generalize
......
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