Commit 03f4c091 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

Snapshot: support rehashing of standalone descriptors.

This is necessary in order to support class literals boilerplates which will
contain descriptor arrays not attached to maps.

This CL introduces Heap::descriptor_array_map() which will be used only for
descriptor arrays templates created as a part of class literal boilerplate.

We don't use the new map for all descriptors for now because in order to handle
chicken-egg problem in deserializer which can be solved in a clean and readable
way only if introduce a DESCRIPTOR_ARRAY_TYPE instance type which we can't
currently do because the InstanceType enum is already "full".

Bug: v8:5799
Change-Id: I732d236b0dda2c436ab3ce3ac5967f6c66162df3
Reviewed-on: https://chromium-review.googlesource.com/758360
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49271}
parent 52b0b901
......@@ -101,6 +101,7 @@ using v8::MemoryPressureLevel;
V(Map, debug_evaluate_context_map, DebugEvaluateContextMap) \
V(Map, script_context_table_map, ScriptContextTableMap) \
/* Maps */ \
V(Map, descriptor_array_map, DescriptorArrayMap) \
V(Map, fixed_double_array_map, FixedDoubleArrayMap) \
V(Map, mutable_heap_number_map, MutableHeapNumberMap) \
V(Map, ordered_hash_table_map, OrderedHashTableMap) \
......
......@@ -112,6 +112,10 @@ bool Heap::CreateInitialMaps() {
fixed_cow_array_map()->set_elements_kind(HOLEY_ELEMENTS);
DCHECK_NE(fixed_array_map(), fixed_cow_array_map());
ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel,
descriptor_array)
descriptor_array_map()->set_elements_kind(PACKED_ELEMENTS);
ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, undefined);
ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, null);
ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, the_hole);
......@@ -169,10 +173,13 @@ bool Heap::CreateInitialMaps() {
// Allocate the empty descriptor array.
{
STATIC_ASSERT(DescriptorArray::kFirstIndex != 0);
AllocationResult allocation =
AllocateUninitializedFixedArray(DescriptorArray::kFirstIndex, TENURED);
if (!allocation.To(&obj)) return false;
}
// TODO(ishell): set map to |descriptor_array_map| once we can use it for all
// descriptor arrays.
set_empty_descriptor_array(DescriptorArray::cast(obj));
DescriptorArray::cast(obj)->set(DescriptorArray::kDescriptorLengthIndex,
Smi::kZero);
......@@ -183,6 +190,7 @@ bool Heap::CreateInitialMaps() {
FinalizePartialMap(this, meta_map());
FinalizePartialMap(this, fixed_array_map());
FinalizePartialMap(this, fixed_cow_array_map());
FinalizePartialMap(this, descriptor_array_map());
FinalizePartialMap(this, undefined_map());
undefined_map()->set_is_undetectable();
FinalizePartialMap(this, null_map());
......
......@@ -81,6 +81,7 @@ TYPE_CHECKER(CallHandlerInfo, TUPLE3_TYPE)
TYPE_CHECKER(Cell, CELL_TYPE)
TYPE_CHECKER(ConstantElementsPair, TUPLE2_TYPE)
TYPE_CHECKER(CoverageInfo, FIXED_ARRAY_TYPE)
TYPE_CHECKER(FeedbackVector, FEEDBACK_VECTOR_TYPE)
TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
TYPE_CHECKER(Foreign, FOREIGN_TYPE)
TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
......@@ -318,6 +319,14 @@ bool HeapObject::IsPromiseCapability() const { return IsTuple3(); }
bool HeapObject::IsDescriptorArray() const { return IsFixedArray(); }
// TODO(ishell): remove once we use |descriptor_array_map| for all
// DescriptorArray objects.
bool HeapObject::IsDescriptorArrayTemplate() const {
// We can't use descriptor_array_map() here because during deserialization
// we may call this function before the descriptor_array_map is deserialized.
return map() == GetHeap()->root(Heap::kDescriptorArrayMapRootIndex);
}
bool HeapObject::IsPropertyDescriptorObject() const { return IsFixedArray(); }
bool HeapObject::IsEnumCache() const { return IsTuple2(); }
......@@ -330,10 +339,6 @@ bool HeapObject::IsRegExpMatchInfo() const { return IsFixedArray(); }
bool Object::IsLayoutDescriptor() const { return IsSmi() || IsByteArray(); }
bool HeapObject::IsFeedbackVector() const {
return map() == GetHeap()->feedback_vector_map();
}
bool HeapObject::IsFeedbackMetadata() const { return IsFixedArray(); }
bool HeapObject::IsDeoptimizationData() const {
......@@ -1960,6 +1965,11 @@ AllocationAlignment HeapObject::RequiredAlignment() const {
bool HeapObject::NeedsRehashing() const {
switch (map()->instance_type()) {
case FIXED_ARRAY_TYPE:
if (IsDescriptorArrayTemplate()) {
return DescriptorArray::cast(this)->number_of_descriptors() > 1;
}
return false;
case TRANSITION_ARRAY_TYPE:
return TransitionArray::cast(this)->number_of_entries() > 1;
case HASH_TABLE_TYPE:
......@@ -2044,17 +2054,15 @@ Object** FixedArray::RawFieldOfElementAt(int index) {
ACCESSORS(EnumCache, keys, FixedArray, kKeysOffset)
ACCESSORS(EnumCache, indices, FixedArray, kIndicesOffset)
int DescriptorArray::number_of_descriptors() {
int DescriptorArray::number_of_descriptors() const {
return Smi::ToInt(get(kDescriptorLengthIndex));
}
int DescriptorArray::number_of_descriptors_storage() {
int DescriptorArray::number_of_descriptors_storage() const {
return (length() - kFirstIndex) / kEntrySize;
}
int DescriptorArray::NumberOfSlackDescriptors() {
int DescriptorArray::NumberOfSlackDescriptors() const {
return number_of_descriptors_storage() - number_of_descriptors();
}
......@@ -2063,8 +2071,7 @@ void DescriptorArray::SetNumberOfDescriptors(int number_of_descriptors) {
set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors));
}
inline int DescriptorArray::number_of_entries() {
inline int DescriptorArray::number_of_entries() const {
return number_of_descriptors();
}
......
......@@ -3635,6 +3635,8 @@ bool HeapObject::CanBeRehashed() const {
switch (map()->instance_type()) {
case HASH_TABLE_TYPE:
return IsNameDictionary() || IsGlobalDictionary() || IsNumberDictionary();
case FIXED_ARRAY_TYPE:
return IsDescriptorArrayTemplate();
case TRANSITION_ARRAY_TYPE:
return true;
case SMALL_ORDERED_HASH_MAP_TYPE:
......@@ -3665,6 +3667,12 @@ void HeapObject::RehashBasedOnMap() {
UNREACHABLE();
}
break;
case FIXED_ARRAY_TYPE:
if (IsDescriptorArrayTemplate()) {
DCHECK_LE(1, DescriptorArray::cast(this)->number_of_descriptors());
DescriptorArray::cast(this)->Sort();
}
break;
case TRANSITION_ARRAY_TYPE:
TransitionArray::cast(this)->Sort();
break;
......@@ -10340,7 +10348,8 @@ Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate,
// Allocate the array of keys.
Handle<FixedArray> result =
factory->NewFixedArray(LengthFor(size), pretenure);
// TODO(ishell): set map to |descriptor_array_map| once we can use it for all
// descriptor arrays.
result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors));
result->set(kEnumCacheIndex, isolate->heap()->empty_enum_cache());
return Handle<DescriptorArray>::cast(result);
......
......@@ -1721,6 +1721,8 @@ class HeapObject: public Object {
HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
#undef IS_TYPE_FUNCTION_DECL
inline bool IsDescriptorArrayTemplate() const;
#define IS_TYPE_FUNCTION_DECL(Type, Value) \
INLINE(bool Is##Type(Isolate* isolate) const);
ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
......
......@@ -46,12 +46,12 @@ class EnumCache : public Tuple2 {
class DescriptorArray : public FixedArray {
public:
// Returns the number of descriptors in the array.
inline int number_of_descriptors();
inline int number_of_descriptors_storage();
inline int NumberOfSlackDescriptors();
inline int number_of_descriptors() const;
inline int number_of_descriptors_storage() const;
inline int NumberOfSlackDescriptors() const;
inline void SetNumberOfDescriptors(int number_of_descriptors);
inline int number_of_entries();
inline int number_of_entries() const;
inline EnumCache* GetEnumCache();
......
......@@ -250,28 +250,29 @@ KNOWN_MAPS = {
0x03ce1: (173, "FeedbackVectorMap"),
0x03d31: (171, "DebugEvaluateContextMap"),
0x03d81: (171, "ScriptContextTableMap"),
0x03dd1: (192, "ExternalMap"),
0x03e21: (106, "NativeSourceStringMap"),
0x03e71: (165, "Tuple2Map"),
0x03ec1: (153, "InterceptorInfoMap"),
0x03f11: (150, "AccessorInfoMap"),
0x03f61: (151, "AccessorPairMap"),
0x03fb1: (152, "AccessCheckInfoMap"),
0x04001: (154, "FunctionTemplateInfoMap"),
0x04051: (155, "ObjectTemplateInfoMap"),
0x040a1: (156, "AllocationSiteMap"),
0x040f1: (157, "AllocationMementoMap"),
0x04141: (159, "AliasedArgumentsEntryMap"),
0x04191: (160, "PromiseResolveThenableJobInfoMap"),
0x041e1: (161, "PromiseReactionJobInfoMap"),
0x04231: (162, "DebugInfoMap"),
0x04281: (163, "StackFrameInfoMap"),
0x042d1: (164, "PrototypeInfoMap"),
0x04321: (166, "Tuple3Map"),
0x04371: (167, "ContextExtensionMap"),
0x043c1: (168, "ModuleMap"),
0x04411: (169, "ModuleInfoEntryMap"),
0x04461: (170, "AsyncGeneratorRequestMap"),
0x03dd1: (171, "DescriptorArrayMap"),
0x03e21: (192, "ExternalMap"),
0x03e71: (106, "NativeSourceStringMap"),
0x03ec1: (165, "Tuple2Map"),
0x03f11: (153, "InterceptorInfoMap"),
0x03f61: (150, "AccessorInfoMap"),
0x03fb1: (151, "AccessorPairMap"),
0x04001: (152, "AccessCheckInfoMap"),
0x04051: (154, "FunctionTemplateInfoMap"),
0x040a1: (155, "ObjectTemplateInfoMap"),
0x040f1: (156, "AllocationSiteMap"),
0x04141: (157, "AllocationMementoMap"),
0x04191: (159, "AliasedArgumentsEntryMap"),
0x041e1: (160, "PromiseResolveThenableJobInfoMap"),
0x04231: (161, "PromiseReactionJobInfoMap"),
0x04281: (162, "DebugInfoMap"),
0x042d1: (163, "StackFrameInfoMap"),
0x04321: (164, "PrototypeInfoMap"),
0x04371: (166, "Tuple3Map"),
0x043c1: (167, "ContextExtensionMap"),
0x04411: (168, "ModuleMap"),
0x04461: (169, "ModuleInfoEntryMap"),
0x044b1: (170, "AsyncGeneratorRequestMap"),
}
# List of known V8 objects.
......
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