diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 7ff3c6a..17cbc94 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -21,6 +21,8 @@ #define DEBUG_VERBOSE 0 +// GCOVR_EXCL_START + __attribute__((always_inline)) inline void *safe_malloc(size_t s) { if (void *p = malloc(s)) { return p; @@ -441,6 +443,8 @@ Key toKeyAfter(Arena &arena, int n) { // ==================== BEGIN IMPLEMENTATION ==================== +// GCOVR_EXCL_STOP + struct Entry { int64_t pointVersion; int64_t rangeVersion; @@ -663,7 +667,7 @@ Node *&getChildExists(Node *self, uint8_t index) { auto *self256 = static_cast(self); return self256->children[index]; } - __builtin_unreachable(); + __builtin_unreachable(); // GCOVR_EXCL_LINE } int getChildGeq(Node *self, int child) { @@ -769,7 +773,7 @@ int getChildLeq(Node *self, int child) { } else if (self->type == Type::Node48) { auto *self48 = static_cast(self); // TODO the plain loop is faster? -#if 0 && (defined(HAS_AVX) || defined(HAS_ARM_NEON)) +#if defined(HAS_AVX) || defined(HAS_ARM_NEON) int i = child; if (i < 0) { return -1; @@ -802,7 +806,7 @@ int getChildLeq(Node *self, int child) { } else { auto *self256 = static_cast(self); // TODO: The plain loop is faster? -#if 0 && defined(__clang__) +#if defined(__clang__) int i = child; constexpr int kUnrollCount = 8; // Must be a power of two and <= 8 for (; (i & (kUnrollCount - 1)) != 0; --i) { @@ -853,7 +857,7 @@ Node *&getOrCreateChild(Node *&self, uint8_t index) { } if (self->numChildren == 4) { auto *newSelf = new (safe_malloc(sizeof(Node16))) Node16; - memcpy((void*)newSelf, self, offsetof(Node, type)); + memcpy((void *)newSelf, self, offsetof(Node, type)); memcpy(newSelf->index, self4->index, 4); memcpy(newSelf->children, self4->children, 4 * sizeof(void *)); free(std::exchange(self, newSelf)); @@ -1072,10 +1076,7 @@ std::string_view getSearchPath(Arena &arena, Node *n) { result.push_back(n->parentsIndex); } std::reverse(result.begin(), result.end()); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wreturn-stack-address" return std::string_view((const char *)&result[0], result.size()); // NOLINT -#pragma GCC diagnostic pop } void printLogical(std::string &result, Node *node) { @@ -1262,61 +1263,6 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl { int64_t oldestVersion; }; -void checkParentPointers(Node *node, bool &success) { - for (int i = getChildGeq(node, 0); i >= 0; i = getChildGeq(node, i + 1)) { - auto *child = getChild(node, i); - if (child->parent != node) { - Arena arena; - fprintf(stderr, "%s child %d has parent pointer %p. Expected %p\n", - printable(getSearchPath(arena, node)).c_str(), i, - (void *)child->parent, (void *)node); - success = false; - } - checkParentPointers(child, success); - } -} - -int64_t checkMaxVersion(Node *node, bool &success) { - int64_t expected = - node->entryPresent - ? std::max(node->entry.pointVersion, node->entry.rangeVersion) - : std::numeric_limits::lowest(); - for (int i = getChildGeq(node, 0); i >= 0; i = getChildGeq(node, i + 1)) { - auto *child = getChild(node, i); - expected = std::max(expected, checkMaxVersion(child, success)); - } - if (node->maxVersion != expected) { - Arena arena; - fprintf(stderr, "%s has max version %d. Expected %d\n", - printable(getSearchPath(arena, node)).c_str(), - int(node->maxVersion), int(expected)); - success = false; - } - return expected; -} - -bool checkCorrectness(Node *node, ReferenceImpl &refImpl) { - bool success = true; - - checkParentPointers(node, success); - - std::string logicalMap; - std::string referenceLogicalMap; - printLogical(logicalMap, node); - refImpl.printLogical(referenceLogicalMap); - if (logicalMap != referenceLogicalMap) { - fprintf(stderr, - "Logical map not equal to reference logical map.\n\nActual:\n" - "%s\nExpected:\n%s\n", - logicalMap.c_str(), referenceLogicalMap.c_str()); - success = false; - } - - return success; -} - -// ==================== END IMPLEMENTATION ==================== - void ConflictSet::check(const ReadRange *reads, Result *results, int count) const { return impl->check(reads, results, count); @@ -1380,8 +1326,66 @@ __attribute__((__visibility__("default"))) void ConflictSet_destroy(void *cs) { } } +// ==================== END IMPLEMENTATION ==================== + +// GCOVR_EXCL_START + +void checkParentPointers(Node *node, bool &success) { + for (int i = getChildGeq(node, 0); i >= 0; i = getChildGeq(node, i + 1)) { + auto *child = getChildExists(node, i); + if (child->parent != node) { + Arena arena; + fprintf(stderr, "%s child %d has parent pointer %p. Expected %p\n", + printable(getSearchPath(arena, node)).c_str(), i, + (void *)child->parent, (void *)node); + success = false; + } + checkParentPointers(child, success); + } +} + +int64_t checkMaxVersion(Node *node, bool &success) { + int64_t expected = + node->entryPresent + ? std::max(node->entry.pointVersion, node->entry.rangeVersion) + : std::numeric_limits::lowest(); + for (int i = getChildGeq(node, 0); i >= 0; i = getChildGeq(node, i + 1)) { + auto *child = getChildExists(node, i); + expected = std::max(expected, checkMaxVersion(child, success)); + } + if (node->maxVersion != expected) { + Arena arena; + fprintf(stderr, "%s has max version %d. Expected %d\n", + printable(getSearchPath(arena, node)).c_str(), + int(node->maxVersion), int(expected)); + success = false; + } + return expected; +} + +bool checkCorrectness(Node *node, ReferenceImpl &refImpl) { + bool success = true; + + checkParentPointers(node, success); + + std::string logicalMap; + std::string referenceLogicalMap; + printLogical(logicalMap, node); + refImpl.printLogical(referenceLogicalMap); + if (logicalMap != referenceLogicalMap) { + fprintf(stderr, + "Logical map not equal to reference logical map.\n\nActual:\n" + "%s\nExpected:\n%s\n", + logicalMap.c_str(), referenceLogicalMap.c_str()); + success = false; + } + + return success; +} namespace std { -void __throw_length_error(const char *) { __builtin_unreachable(); } +void __throw_length_error(const char *) { + __builtin_unreachable(); +} } // namespace std #ifdef ENABLE_MAIN @@ -1493,4 +1497,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { } return 0; } -#endif \ No newline at end of file +#endif + +// GCOVR_EXCL_STOP \ No newline at end of file