[dict-proto] C++ implementation of SwissNameDictionary, pt. 5
This CL is part of a series that adds the C++ implementation of SwissNameDictionary, a deterministic property backing store based on Swiss Tables. This CL adds printing and verification functions. Bug: v8:11388 Change-Id: I6af8672f19589f5693ebafbcafb8d59b26749eef Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2704669 Commit-Queue: Frank Emrich <emrich@google.com> Reviewed-by: Igor Sheludko <ishell@chromium.org> Reviewed-by: Marja Hölttä <marja@chromium.org> Cr-Commit-Position: refs/heads/master@{#72954}
This commit is contained in:
parent
2a8514b65a
commit
b0230ead9d
@ -1248,8 +1248,78 @@ void SmallOrderedNameDictionary::SmallOrderedNameDictionaryVerify(
|
||||
}
|
||||
|
||||
void SwissNameDictionary::SwissNameDictionaryVerify(Isolate* isolate) {
|
||||
// TODO(v8:11388) Here to satisfy compiler, implemented in follow-up CL.
|
||||
UNREACHABLE();
|
||||
this->SwissNameDictionaryVerify(isolate, false);
|
||||
}
|
||||
|
||||
void SwissNameDictionary::SwissNameDictionaryVerify(Isolate* isolate,
|
||||
bool slow_checks) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
|
||||
CHECK(IsValidCapacity(Capacity()));
|
||||
|
||||
meta_table().ByteArrayVerify(isolate);
|
||||
|
||||
int seen_deleted = 0;
|
||||
int seen_present = 0;
|
||||
|
||||
for (int i = 0; i < Capacity(); i++) {
|
||||
ctrl_t ctrl = GetCtrl(i);
|
||||
|
||||
if (IsFull(ctrl) || slow_checks) {
|
||||
Object key = KeyAt(i);
|
||||
Object value = ValueAtRaw(i);
|
||||
|
||||
if (IsFull(ctrl)) {
|
||||
++seen_present;
|
||||
|
||||
Name name = Name::cast(key);
|
||||
if (slow_checks) {
|
||||
CHECK_EQ(swiss_table::H2(name.hash()), ctrl);
|
||||
}
|
||||
|
||||
CHECK(!key.IsTheHole());
|
||||
CHECK(!value.IsTheHole());
|
||||
name.NameVerify(isolate);
|
||||
value.ObjectVerify(isolate);
|
||||
} else if (IsDeleted(ctrl)) {
|
||||
++seen_deleted;
|
||||
CHECK(key.IsTheHole());
|
||||
CHECK(value.IsTheHole());
|
||||
} else if (IsEmpty(ctrl)) {
|
||||
CHECK(key.IsTheHole());
|
||||
CHECK(value.IsTheHole());
|
||||
} else {
|
||||
// Something unexpected. Note that we don't use kSentinel at the moment.
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_EQ(seen_present, NumberOfElements());
|
||||
if (slow_checks) {
|
||||
CHECK_EQ(seen_deleted, NumberOfDeletedElements());
|
||||
|
||||
// Verify copy of first group at end (= after Capacity() slots) of control
|
||||
// table.
|
||||
for (int i = 0; i < std::min(static_cast<int>(Group::kWidth), Capacity());
|
||||
++i) {
|
||||
CHECK_EQ(CtrlTable()[i], CtrlTable()[Capacity() + i]);
|
||||
}
|
||||
// If 2 * capacity is smaller than the capacity plus group width, the slots
|
||||
// after that must be empty.
|
||||
for (int i = 2 * Capacity(); i < Capacity() + kGroupWidth; ++i) {
|
||||
CHECK_EQ(Ctrl::kEmpty, CtrlTable()[i]);
|
||||
}
|
||||
|
||||
for (int enum_index = 0; enum_index < UsedCapacity(); ++enum_index) {
|
||||
int entry = EntryForEnumerationIndex(enum_index);
|
||||
CHECK_LT(entry, Capacity());
|
||||
ctrl_t ctrl = GetCtrl(entry);
|
||||
|
||||
// Enum table must not point to empty slots.
|
||||
CHECK(IsFull(ctrl) || IsDeleted(ctrl));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JSRegExp::JSRegExpVerify(Isolate* isolate) {
|
||||
|
@ -940,9 +940,72 @@ void OrderedNameDictionary::OrderedNameDictionaryPrint(std::ostream& os) {
|
||||
PrintDictionaryContentsFull(os, *this);
|
||||
}
|
||||
|
||||
void print_hex_byte(std::ostream& os, int value) {
|
||||
os << "0x" << std::setfill('0') << std::setw(2) << std::right << std::hex
|
||||
<< (value & 0xff) << std::setfill(' ');
|
||||
}
|
||||
|
||||
void SwissNameDictionary::SwissNameDictionaryPrint(std::ostream& os) {
|
||||
// Here to satisfy compiler, implemented in follow-up CL.
|
||||
UNREACHABLE();
|
||||
this->PrintHeader(os, "SwissNameDictionary");
|
||||
os << "\n - meta table ByteArray: "
|
||||
<< reinterpret_cast<void*>(this->meta_table().ptr());
|
||||
os << "\n - capacity: " << this->Capacity();
|
||||
os << "\n - elements: " << this->NumberOfElements();
|
||||
os << "\n - deleted: " << this->NumberOfDeletedElements();
|
||||
|
||||
std::ios_base::fmtflags sav_flags = os.flags();
|
||||
os << "\n - ctrl table (omitting buckets where key is hole value): {";
|
||||
for (int i = 0; i < this->Capacity() + kGroupWidth; i++) {
|
||||
ctrl_t ctrl = CtrlTable()[i];
|
||||
|
||||
if (ctrl == Ctrl::kEmpty) continue;
|
||||
|
||||
os << "\n " << std::setw(12) << std::dec << i << ": ";
|
||||
switch (ctrl) {
|
||||
case Ctrl::kEmpty:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
case Ctrl::kDeleted:
|
||||
print_hex_byte(os, ctrl);
|
||||
os << " (= kDeleted)";
|
||||
break;
|
||||
case Ctrl::kSentinel:
|
||||
print_hex_byte(os, ctrl);
|
||||
os << " (= kSentinel)";
|
||||
break;
|
||||
default:
|
||||
print_hex_byte(os, ctrl);
|
||||
os << " (= H2 of a key)";
|
||||
break;
|
||||
}
|
||||
}
|
||||
os << "\n }";
|
||||
|
||||
os << "\n - enumeration table: {";
|
||||
for (int enum_index = 0; enum_index < this->UsedCapacity(); enum_index++) {
|
||||
int entry = EntryForEnumerationIndex(enum_index);
|
||||
os << "\n " << std::setw(12) << std::dec << enum_index << ": " << entry;
|
||||
}
|
||||
os << "\n }";
|
||||
|
||||
os << "\n - data table (omitting slots where key is the hole): {";
|
||||
for (int bucket = 0; bucket < this->Capacity(); ++bucket) {
|
||||
Object k;
|
||||
if (!this->ToKey(this->GetReadOnlyRoots(), bucket, &k)) continue;
|
||||
|
||||
Object value = this->ValueAtRaw(bucket);
|
||||
PropertyDetails details = this->DetailsAt(bucket);
|
||||
os << "\n " << std::setw(12) << std::dec << bucket << ": ";
|
||||
if (k.IsString()) {
|
||||
String::cast(k).PrintUC16(os);
|
||||
} else {
|
||||
os << Brief(k);
|
||||
}
|
||||
os << " -> " << Brief(value);
|
||||
details.PrintAsSlowTo(os, false);
|
||||
}
|
||||
os << "\n }\n";
|
||||
os.flags(sav_flags);
|
||||
}
|
||||
|
||||
void PropertyArray::PropertyArrayPrint(std::ostream& os) { // NOLINT
|
||||
|
@ -206,6 +206,9 @@ class SwissNameDictionary : public HeapObject {
|
||||
inline static constexpr Offset CtrlTableStartOffset(int capacity);
|
||||
inline static constexpr Offset PropertyDetailsTableStartOffset(int capacity);
|
||||
|
||||
#if VERIFY_HEAP
|
||||
void SwissNameDictionaryVerify(Isolate* isolate, bool slow_checks);
|
||||
#endif
|
||||
DECL_VERIFIER(SwissNameDictionary)
|
||||
DECL_PRINTER(SwissNameDictionary)
|
||||
DECL_CAST(SwissNameDictionary)
|
||||
|
Loading…
Reference in New Issue
Block a user