Commit b0230ead authored by Frank Emrich's avatar Frank Emrich Committed by Commit Bot

[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: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72954}
parent 2a8514b6
...@@ -1248,8 +1248,78 @@ void SmallOrderedNameDictionary::SmallOrderedNameDictionaryVerify( ...@@ -1248,8 +1248,78 @@ void SmallOrderedNameDictionary::SmallOrderedNameDictionaryVerify(
} }
void SwissNameDictionary::SwissNameDictionaryVerify(Isolate* isolate) { void SwissNameDictionary::SwissNameDictionaryVerify(Isolate* isolate) {
// TODO(v8:11388) Here to satisfy compiler, implemented in follow-up CL. this->SwissNameDictionaryVerify(isolate, false);
UNREACHABLE(); }
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) { void JSRegExp::JSRegExpVerify(Isolate* isolate) {
......
...@@ -940,9 +940,72 @@ void OrderedNameDictionary::OrderedNameDictionaryPrint(std::ostream& os) { ...@@ -940,9 +940,72 @@ void OrderedNameDictionary::OrderedNameDictionaryPrint(std::ostream& os) {
PrintDictionaryContentsFull(os, *this); 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) { void SwissNameDictionary::SwissNameDictionaryPrint(std::ostream& os) {
// Here to satisfy compiler, implemented in follow-up CL. this->PrintHeader(os, "SwissNameDictionary");
UNREACHABLE(); 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 void PropertyArray::PropertyArrayPrint(std::ostream& os) { // NOLINT
......
...@@ -206,6 +206,9 @@ class SwissNameDictionary : public HeapObject { ...@@ -206,6 +206,9 @@ class SwissNameDictionary : public HeapObject {
inline static constexpr Offset CtrlTableStartOffset(int capacity); inline static constexpr Offset CtrlTableStartOffset(int capacity);
inline static constexpr Offset PropertyDetailsTableStartOffset(int capacity); inline static constexpr Offset PropertyDetailsTableStartOffset(int capacity);
#if VERIFY_HEAP
void SwissNameDictionaryVerify(Isolate* isolate, bool slow_checks);
#endif
DECL_VERIFIER(SwissNameDictionary) DECL_VERIFIER(SwissNameDictionary)
DECL_PRINTER(SwissNameDictionary) DECL_PRINTER(SwissNameDictionary)
DECL_CAST(SwissNameDictionary) DECL_CAST(SwissNameDictionary)
......
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