Update some of the invariant checks to account for leaves
Some checks failed
Tests / 64 bit versions total: 8331, passed: 8331
Tests / Debug total: 8329, passed: 8329
Tests / SIMD fallback total: 8331, passed: 8331
weaselab/conflict-set/pipeline/head There was a failure building this commit

This commit is contained in:
2024-11-22 18:39:45 -08:00
parent 235938b5aa
commit 55e23bafba

View File

@@ -269,14 +269,22 @@ struct TaggedNodePointer {
TaggedNodePointer(const TaggedNodePointer &) = default; TaggedNodePointer(const TaggedNodePointer &) = default;
TaggedNodePointer &operator=(const TaggedNodePointer &) = default; TaggedNodePointer &operator=(const TaggedNodePointer &) = default;
/*implicit*/ TaggedNodePointer(Node *n); /*implicit*/ TaggedNodePointer(Node *n);
// Leaf constructor
TaggedNodePointer(InternalVersionT rangeVersion, struct Node *parent);
void prefetch() { void prefetch() {
// __builtin_prefetch is ok even if argument isn't addressable // __builtin_prefetch is ok even if argument isn't addressable
__builtin_prefetch((void *)withoutType()); __builtin_prefetch((void *)withoutType());
} }
bool isLeaf() { return getType() > Type_Node256; } bool isLeaf() { return (p & uintptr_t(15)) > Type_Node256; }
InternalVersionT rangeVersion() {
assert(isLeaf());
return InternalVersionT(p >> 32);
}
private: private:
TaggedNodePointer(struct Node *p, Type t) : p((uintptr_t)p) { TaggedNodePointer(struct Node *p, Type t) : p((uintptr_t)p) {
@@ -323,6 +331,12 @@ private:
TaggedNodePointer::TaggedNodePointer(Node *n) TaggedNodePointer::TaggedNodePointer(Node *n)
: TaggedNodePointer(n, n->getType()) {} : TaggedNodePointer(n, n->getType()) {}
TaggedNodePointer::TaggedNodePointer(InternalVersionT rangeVersion, Node *n) {
p = rangeVersion.toInt64();
p <<= 32;
p |= n->getType();
}
Type TaggedNodePointer::getType() { Type TaggedNodePointer::getType() {
assert(p != 0); assert(p != 0);
prefetch(); prefetch();
@@ -6096,18 +6110,27 @@ void checkVersionsGeqOldestExtant(Node *n,
[[maybe_unused]] auto *self = static_cast<Node3 *>(n); [[maybe_unused]] auto *self = static_cast<Node3 *>(n);
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
assert(self->childMaxVersion[i] >= oldestExtantVersion); assert(self->childMaxVersion[i] >= oldestExtantVersion);
if (i < self->numChildren && self->children[i].isLeaf()) {
assert(self->children[i].rangeVersion() >= oldestExtantVersion);
}
} }
} break; } break;
case Type_Node16: { case Type_Node16: {
[[maybe_unused]] auto *self = static_cast<Node16 *>(n); [[maybe_unused]] auto *self = static_cast<Node16 *>(n);
for (int i = 0; i < 16; ++i) { for (int i = 0; i < 16; ++i) {
assert(self->childMaxVersion[i] >= oldestExtantVersion); assert(self->childMaxVersion[i] >= oldestExtantVersion);
if (i < self->numChildren && self->children[i].isLeaf()) {
assert(self->children[i].rangeVersion() >= oldestExtantVersion);
}
} }
} break; } break;
case Type_Node48: { case Type_Node48: {
auto *self = static_cast<Node48 *>(n); auto *self = static_cast<Node48 *>(n);
for (int i = 0; i < 48; ++i) { for (int i = 0; i < 48; ++i) {
assert(self->childMaxVersion[i] >= oldestExtantVersion); assert(self->childMaxVersion[i] >= oldestExtantVersion);
if (i < self->numChildren && self->children[i].isLeaf()) {
assert(self->children[i].rangeVersion() >= oldestExtantVersion);
}
} }
for ([[maybe_unused]] auto m : self->maxOfMax) { for ([[maybe_unused]] auto m : self->maxOfMax) {
assert(m >= oldestExtantVersion); assert(m >= oldestExtantVersion);
@@ -6117,11 +6140,18 @@ void checkVersionsGeqOldestExtant(Node *n,
auto *self = static_cast<Node256 *>(n); auto *self = static_cast<Node256 *>(n);
for (int i = 0; i < 256; ++i) { for (int i = 0; i < 256; ++i) {
assert(self->childMaxVersion[i] >= oldestExtantVersion); assert(self->childMaxVersion[i] >= oldestExtantVersion);
if (self->children[i].isLeaf()) {
assert(self->children[i].rangeVersion() >= oldestExtantVersion);
}
} }
for ([[maybe_unused]] auto m : self->maxOfMax) { for ([[maybe_unused]] auto m : self->maxOfMax) {
assert(m >= oldestExtantVersion); assert(m >= oldestExtantVersion);
} }
} break; } break;
case Type_Leaf3:
case Type_Leaf16:
case Type_Leaf48:
case Type_Leaf256:
default: default:
abort(); abort();
} }
@@ -6180,9 +6210,10 @@ checkMaxVersion(Node *root, Node *node, InternalVersionT oldestVersion,
return total; return total;
} }
[[maybe_unused]] void checkMemoryBoundInvariants(Node *node, bool &success) { [[maybe_unused]] void checkMemoryBoundInvariants(TaggedNodePointer node,
bool &success) {
int minNumChildren; int minNumChildren;
switch (node->getType()) { switch (node.getType()) {
case Type_Node0: case Type_Node0:
minNumChildren = kMinChildrenNode0; minNumChildren = kMinChildrenNode0;
break; break;
@@ -6198,6 +6229,11 @@ checkMaxVersion(Node *root, Node *node, InternalVersionT oldestVersion,
case Type_Node256: case Type_Node256:
minNumChildren = kMinChildrenNode256; minNumChildren = kMinChildrenNode256;
break; break;
case Type_Leaf3:
case Type_Leaf16:
case Type_Leaf48:
case Type_Leaf256:
return;
default: default:
abort(); abort();
} }
@@ -6219,8 +6255,9 @@ checkMaxVersion(Node *root, Node *node, InternalVersionT oldestVersion,
success = false; success = false;
} }
for (auto child = getChildGeq(node, 0); child != nullptr; // Safety: if node were a leaf we would have returned by now
child = getChildGeq(node, child->parentsIndex + 1)) { for (auto child = getChildGeq(node.asNodeUnsafe(), 0); child != nullptr;
child = getChildGeq(node.asNodeUnsafe(), child->parentsIndex + 1)) {
checkMemoryBoundInvariants(child, success); checkMemoryBoundInvariants(child, success);
} }
} }