Reland: Introduce HASH_TABLE_TYPE instance type.

This is so that we can distinguish hash tables by instance type. We can
then introduce maps for each kind of hash tables to further distinguish.

R=mstarzinger@chromium.org

Bug: v8:6593
Change-Id: Ice9e6bb7b85d825207ac489b6930ac9020d60db8
Reviewed-on: https://chromium-review.googlesource.com/582814
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46861}
This commit is contained in:
Yang Guo 2017-07-25 09:59:54 +02:00 committed by Commit Bot
parent 072d0e3eb6
commit 89ef9556d7
17 changed files with 64 additions and 46 deletions

View File

@ -1336,7 +1336,7 @@ Node* CodeStubAssembler::LoadFixedTypedArrayElementAsTagged(
Node* CodeStubAssembler::LoadAndUntagToWord32FixedArrayElement(
Node* object, Node* index_node, int additional_offset,
ParameterMode parameter_mode) {
CSA_SLOW_ASSERT(this, IsFixedArray(object));
CSA_SLOW_ASSERT(this, Word32Or(IsFixedArray(object), IsHashTable(object)));
CSA_SLOW_ASSERT(this, MatchesParameterMode(index_node, parameter_mode));
int32_t header_size =
FixedArray::kHeaderSize + additional_offset - kHeapObjectTag;
@ -1526,8 +1526,9 @@ Node* CodeStubAssembler::StoreFixedArrayElement(Node* object, Node* index_node,
WriteBarrierMode barrier_mode,
int additional_offset,
ParameterMode parameter_mode) {
CSA_SLOW_ASSERT(this,
Word32Or(IsFixedArray(object), IsPropertyArray(object)));
CSA_SLOW_ASSERT(
this, Word32Or(IsHashTable(object),
Word32Or(IsFixedArray(object), IsPropertyArray(object))));
CSA_SLOW_ASSERT(this, MatchesParameterMode(index_node, parameter_mode));
DCHECK(barrier_mode == SKIP_WRITE_BARRIER ||
barrier_mode == UPDATE_WRITE_BARRIER);
@ -3498,7 +3499,7 @@ Node* CodeStubAssembler::IsFixedArrayWithKind(Node* object, ElementsKind kind) {
return IsFixedDoubleArray(object);
} else {
DCHECK(IsSmiOrObjectElementsKind(kind));
return IsFixedArray(object);
return Word32Or(IsFixedArray(object), IsHashTable(object));
}
}
@ -3581,7 +3582,7 @@ Node* CodeStubAssembler::IsFixedDoubleArray(Node* object) {
}
Node* CodeStubAssembler::IsHashTable(Node* object) {
return WordEqual(LoadMap(object), LoadRoot(Heap::kHashTableMapRootIndex));
return HasInstanceType(object, HASH_TABLE_TYPE);
}
Node* CodeStubAssembler::IsDictionary(Node* object) {

View File

@ -294,6 +294,7 @@ Type::bitset BitsetType::Lub(i::Map* map) {
case FUNCTION_TEMPLATE_INFO_TYPE:
case ACCESSOR_PAIR_TYPE:
case FIXED_ARRAY_TYPE:
case HASH_TABLE_TYPE:
case FIXED_DOUBLE_ARRAY_TYPE:
case BYTE_ARRAY_TYPE:
case BYTECODE_ARRAY_TYPE:
@ -335,7 +336,6 @@ Type::bitset BitsetType::Lub(i::Map* map) {
case TUPLE3_TYPE:
case CONTEXT_EXTENSION_TYPE:
case ASYNC_GENERATOR_REQUEST_TYPE:
case PADDING_TYPE_0:
UNREACHABLE();
}
UNREACHABLE();

View File

@ -3781,6 +3781,7 @@ Handle<Object> TranslatedState::MaterializeCapturedObjectAt(
object->set_extension(*extension);
return object;
}
case HASH_TABLE_TYPE:
case FIXED_ARRAY_TYPE: {
Handle<Object> lengthObject = materializer.FieldAt(value_index);
int32_t array_length = 0;
@ -3935,7 +3936,6 @@ Handle<Object> TranslatedState::MaterializeCapturedObjectAt(
case TUPLE2_TYPE:
case TUPLE3_TYPE:
case ASYNC_GENERATOR_REQUEST_TYPE:
case PADDING_TYPE_0:
case WASM_MODULE_TYPE:
case WASM_INSTANCE_TYPE:
case WASM_MEMORY_TYPE:

View File

@ -2581,9 +2581,9 @@ bool Heap::CreateInitialMaps() {
roots_[entry.index] = map;
}
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, hash_table)
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, ordered_hash_table)
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, unseeded_number_dictionary)
ALLOCATE_VARSIZE_MAP(HASH_TABLE_TYPE, hash_table)
ALLOCATE_VARSIZE_MAP(HASH_TABLE_TYPE, ordered_hash_table)
ALLOCATE_VARSIZE_MAP(HASH_TABLE_TYPE, unseeded_number_dictionary)
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, function_context)
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, catch_context)

View File

@ -328,7 +328,8 @@ void ObjectStatsCollector::CollectGlobalStatistics() {
}
static bool CanRecordFixedArray(Heap* heap, FixedArrayBase* array) {
return array->map()->instance_type() == FIXED_ARRAY_TYPE &&
return (array->map()->instance_type() == FIXED_ARRAY_TYPE ||
array->map()->instance_type() == HASH_TABLE_TYPE) &&
array->map() != heap->fixed_double_array_map() &&
array != heap->empty_fixed_array() &&
array != heap->empty_byte_array() &&

View File

@ -71,13 +71,14 @@ class ObjectStats {
size_histogram_[FIRST_FIXED_ARRAY_SUB_TYPE + array_sub_type]
[HistogramIndexFromSize(size)]++;
if (over_allocated > 0) {
InstanceType type =
array->IsHashTable() ? HASH_TABLE_TYPE : FIXED_ARRAY_TYPE;
over_allocated_[FIRST_FIXED_ARRAY_SUB_TYPE + array_sub_type] +=
over_allocated;
over_allocated_histogram_[FIRST_FIXED_ARRAY_SUB_TYPE + array_sub_type]
[HistogramIndexFromSize(over_allocated)]++;
over_allocated_[InstanceType::FIXED_ARRAY_TYPE] += over_allocated;
over_allocated_histogram_[InstanceType::FIXED_ARRAY_TYPE]
[HistogramIndexFromSize(over_allocated)]++;
over_allocated_[type] += over_allocated;
over_allocated_histogram_[type][HistogramIndexFromSize(over_allocated)]++;
}
return true;
}

View File

@ -584,6 +584,7 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3) {
}
switch (type) {
case HASH_TABLE_TYPE:
case FIXED_ARRAY_TYPE:
return Op::template apply<FixedArray::BodyDescriptor>(p1, p2, p3);
case FIXED_DOUBLE_ARRAY_TYPE:

View File

@ -72,6 +72,7 @@ void HeapObject::HeapObjectVerify() {
case MUTABLE_HEAP_NUMBER_TYPE:
HeapNumber::cast(this)->HeapNumberVerify();
break;
case HASH_TABLE_TYPE:
case FIXED_ARRAY_TYPE:
FixedArray::cast(this)->FixedArrayVerify();
break;

View File

@ -80,6 +80,7 @@ TYPE_CHECKER(CoverageInfo, FIXED_ARRAY_TYPE)
TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
TYPE_CHECKER(Foreign, FOREIGN_TYPE)
TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
TYPE_CHECKER(HashTable, HASH_TABLE_TYPE)
TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
TYPE_CHECKER(JSArrayBuffer, JS_ARRAY_BUFFER_TYPE)
TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
@ -135,6 +136,7 @@ bool HeapObject::IsFixedArrayBase() const {
bool HeapObject::IsFixedArray() const {
InstanceType instance_type = map()->instance_type();
return instance_type == FIXED_ARRAY_TYPE ||
instance_type == HASH_TABLE_TYPE ||
instance_type == TRANSITION_ARRAY_TYPE;
}
@ -419,10 +421,6 @@ inline bool Is<JSArray>(Object* obj) {
return obj->IsJSArray();
}
bool HeapObject::IsHashTable() const {
return map() == GetHeap()->hash_table_map();
}
bool HeapObject::IsWeakHashTable() const { return IsHashTable(); }
bool HeapObject::IsDictionary() const {
@ -3204,7 +3202,7 @@ int HeapObject::SizeFromMap(Map* map) const {
if (instance_size != kVariableSizeSentinel) return instance_size;
// Only inline the most frequent cases.
InstanceType instance_type = map->instance_type();
if (instance_type == FIXED_ARRAY_TYPE ||
if (instance_type == FIXED_ARRAY_TYPE || instance_type == HASH_TABLE_TYPE ||
instance_type == TRANSITION_ARRAY_TYPE) {
return FixedArray::SizeFor(
reinterpret_cast<const FixedArray*>(this)->synchronized_length());

View File

@ -79,6 +79,7 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
case FIXED_DOUBLE_ARRAY_TYPE:
FixedDoubleArray::cast(this)->FixedDoubleArrayPrint(os);
break;
case HASH_TABLE_TYPE:
case FIXED_ARRAY_TYPE:
FixedArray::cast(this)->FixedArrayPrint(os);
break;
@ -643,7 +644,7 @@ void AliasedArgumentsEntry::AliasedArgumentsEntryPrint(
void FixedArray::FixedArrayPrint(std::ostream& os) { // NOLINT
HeapObject::PrintHeader(os, "FixedArray");
HeapObject::PrintHeader(os, IsHashTable() ? "HashTable" : "FixedArray");
os << "\n - map = " << Brief(map());
os << "\n - length: " << length();
PrintFixedArrayElements(os, this);

View File

@ -2984,6 +2984,7 @@ VisitorId Map::GetVisitorId(Map* map) {
case FREE_SPACE_TYPE:
return kVisitFreeSpace;
case HASH_TABLE_TYPE:
case FIXED_ARRAY_TYPE:
return kVisitFixedArray;
@ -3274,6 +3275,9 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) { // NOLINT
os << "<Map(" << ElementsKindToString(Map::cast(this)->elements_kind())
<< ")>";
break;
case HASH_TABLE_TYPE:
os << "<HashTable[" << FixedArray::cast(this)->length() << "]>";
break;
case FIXED_ARRAY_TYPE:
os << "<FixedArray[" << FixedArray::cast(this)->length() << "]>";
break;
@ -12800,6 +12804,7 @@ bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
case FIXED_DOUBLE_ARRAY_TYPE:
case FOREIGN_TYPE:
case FREE_SPACE_TYPE:
case HASH_TABLE_TYPE:
case HEAP_NUMBER_TYPE:
case JS_BOUND_FUNCTION_TYPE:
case JS_GLOBAL_OBJECT_TYPE:

View File

@ -365,10 +365,10 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
V(MODULE_TYPE) \
V(MODULE_INFO_ENTRY_TYPE) \
V(ASYNC_GENERATOR_REQUEST_TYPE) \
V(PADDING_TYPE_0) \
V(FIXED_ARRAY_TYPE) \
V(PROPERTY_ARRAY_TYPE) \
V(HASH_TABLE_TYPE) \
V(TRANSITION_ARRAY_TYPE) \
V(PROPERTY_ARRAY_TYPE) \
V(SHARED_FUNCTION_INFO_TYPE) \
V(CELL_TYPE) \
V(WEAK_CELL_TYPE) \
@ -712,10 +712,10 @@ enum InstanceType : uint8_t {
MODULE_TYPE,
MODULE_INFO_ENTRY_TYPE,
ASYNC_GENERATOR_REQUEST_TYPE,
PADDING_TYPE_0,
FIXED_ARRAY_TYPE,
PROPERTY_ARRAY_TYPE,
HASH_TABLE_TYPE,
TRANSITION_ARRAY_TYPE,
PROPERTY_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
CELL_TYPE,
WEAK_CELL_TYPE,

View File

@ -163,6 +163,11 @@ void PartialSerializer::SerializeEmbedderFields() {
void PartialSerializer::CheckRehashability(HeapObject* table) {
DCHECK(table->IsHashTable());
if (!can_be_rehashed_) return;
if (table->IsUnseededNumberDictionary()) return;
if (table->IsOrderedHashMap() &&
OrderedHashMap::cast(table)->NumberOfElements() == 0) {
return;
}
// We can only correctly rehash if the global dictionary is the only hash
// table that we deserialize.
if (table == rehashable_global_dictionary_) return;

View File

@ -187,6 +187,8 @@ void StartupSerializer::CheckRehashability(HeapObject* table) {
if (!can_be_rehashed_) return;
// We can only correctly rehash if the four hash tables below are the only
// ones that we deserialize.
if (table->IsUnseededNumberDictionary()) return;
if (table == isolate_->heap()->empty_ordered_hash_table()) return;
if (table == isolate_->heap()->empty_slow_element_dictionary()) return;
if (table == isolate_->heap()->empty_property_dictionary()) return;
if (table == isolate_->heap()->weak_object_to_code_table()) return;

View File

@ -79,6 +79,7 @@ TEST(HeapMaps) {
CheckMap(heap->meta_map(), MAP_TYPE, Map::kSize);
CheckMap(heap->heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize);
CheckMap(heap->fixed_array_map(), FIXED_ARRAY_TYPE, kVariableSizeSentinel);
CheckMap(heap->hash_table_map(), HASH_TABLE_TYPE, kVariableSizeSentinel);
CheckMap(heap->string_map(), STRING_TYPE, kVariableSizeSentinel);
}

View File

@ -1679,6 +1679,7 @@ class V8Heap(object):
"MAP_TYPE": Map,
"ODDBALL_TYPE": Oddball,
"FIXED_ARRAY_TYPE": FixedArray,
"HASH_TABLE_TYPE": FixedArray,
"JS_FUNCTION_TYPE": JSFunction,
"SHARED_FUNCTION_INFO_TYPE": SharedFunctionInfo,
"SCRIPT_TYPE": Script,

View File

@ -71,10 +71,10 @@ INSTANCE_TYPES = {
167: "MODULE_TYPE",
168: "MODULE_INFO_ENTRY_TYPE",
169: "ASYNC_GENERATOR_REQUEST_TYPE",
170: "PADDING_TYPE_0",
171: "FIXED_ARRAY_TYPE",
172: "PROPERTY_ARRAY_TYPE",
173: "TRANSITION_ARRAY_TYPE",
170: "FIXED_ARRAY_TYPE",
171: "HASH_TABLE_TYPE",
172: "TRANSITION_ARRAY_TYPE",
173: "PROPERTY_ARRAY_TYPE",
174: "SHARED_FUNCTION_INFO_TYPE",
175: "CELL_TYPE",
176: "WEAK_CELL_TYPE",
@ -162,7 +162,7 @@ KNOWN_MAPS = {
0x02201: (137, "FreeSpaceMap"),
0x02259: (131, "MetaMap"),
0x022b1: (130, "NullMap"),
0x02309: (171, "FixedArrayMap"),
0x02309: (170, "FixedArrayMap"),
0x02361: (8, "OneByteInternalizedStringMap"),
0x023b9: (148, "OnePointerFillerMap"),
0x02411: (148, "TwoPointerFillerMap"),
@ -172,44 +172,44 @@ KNOWN_MAPS = {
0x02571: (130, "TheHoleMap"),
0x025c9: (130, "BooleanMap"),
0x02621: (135, "ByteArrayMap"),
0x02679: (171, "FixedCOWArrayMap"),
0x02679: (170, "FixedCOWArrayMap"),
0x026d1: (171, "HashTableMap"),
0x02729: (128, "SymbolMap"),
0x02781: (72, "OneByteStringMap"),
0x027d9: (171, "ScopeInfoMap"),
0x027d9: (170, "ScopeInfoMap"),
0x02831: (174, "SharedFunctionInfoMap"),
0x02889: (132, "CodeMap"),
0x028e1: (171, "FunctionContextMap"),
0x028e1: (170, "FunctionContextMap"),
0x02939: (175, "CellMap"),
0x02991: (176, "WeakCellMap"),
0x029e9: (177, "GlobalPropertyCellMap"),
0x02a41: (134, "ForeignMap"),
0x02a99: (173, "TransitionArrayMap"),
0x02a99: (172, "TransitionArrayMap"),
0x02af1: (130, "ArgumentsMarkerMap"),
0x02b49: (130, "ExceptionMap"),
0x02ba1: (130, "TerminationExceptionMap"),
0x02bf9: (130, "OptimizedOutMap"),
0x02c51: (130, "StaleRegisterMap"),
0x02ca9: (171, "NativeContextMap"),
0x02d01: (171, "ModuleContextMap"),
0x02d59: (171, "EvalContextMap"),
0x02db1: (171, "ScriptContextMap"),
0x02e09: (171, "BlockContextMap"),
0x02e61: (171, "CatchContextMap"),
0x02eb9: (171, "WithContextMap"),
0x02ca9: (170, "NativeContextMap"),
0x02d01: (170, "ModuleContextMap"),
0x02d59: (170, "EvalContextMap"),
0x02db1: (170, "ScriptContextMap"),
0x02e09: (170, "BlockContextMap"),
0x02e61: (170, "CatchContextMap"),
0x02eb9: (170, "WithContextMap"),
0x02f11: (147, "FixedDoubleArrayMap"),
0x02f69: (133, "MutableHeapNumberMap"),
0x02fc1: (171, "OrderedHashTableMap"),
0x03019: (171, "SloppyArgumentsElementsMap"),
0x03019: (170, "SloppyArgumentsElementsMap"),
0x03071: (178, "SmallOrderedHashMapMap"),
0x030c9: (179, "SmallOrderedHashSetMap"),
0x03121: (185, "JSMessageObjectMap"),
0x03179: (136, "BytecodeArrayMap"),
0x031d1: (171, "ModuleInfoMap"),
0x031d1: (170, "ModuleInfoMap"),
0x03229: (175, "NoClosuresCellMap"),
0x03281: (175, "OneClosureCellMap"),
0x032d9: (175, "ManyClosuresCellMap"),
0x03331: (172, "PropertyArrayMap"),
0x03331: (173, "PropertyArrayMap"),
0x03389: (64, "StringMap"),
0x033e1: (73, "ConsOneByteStringMap"),
0x03439: (65, "ConsStringMap"),
@ -240,9 +240,9 @@ KNOWN_MAPS = {
0x03cd1: (145, "FixedFloat64ArrayMap"),
0x03d29: (146, "FixedUint8ClampedArrayMap"),
0x03d81: (157, "ScriptMap"),
0x03dd9: (171, "FeedbackVectorMap"),
0x03e31: (171, "DebugEvaluateContextMap"),
0x03e89: (171, "ScriptContextTableMap"),
0x03dd9: (170, "FeedbackVectorMap"),
0x03e31: (170, "DebugEvaluateContextMap"),
0x03e89: (170, "ScriptContextTableMap"),
0x03ee1: (171, "UnseededNumberDictionaryMap"),
0x03f39: (188, "ExternalMap"),
0x03f91: (106, "NativeSourceStringMap"),