Add some GCOVR annotations
This commit is contained in:
132
ConflictSet.cpp
132
ConflictSet.cpp
@@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
#define DEBUG_VERBOSE 0
|
#define DEBUG_VERBOSE 0
|
||||||
|
|
||||||
|
// GCOVR_EXCL_START
|
||||||
|
|
||||||
__attribute__((always_inline)) inline void *safe_malloc(size_t s) {
|
__attribute__((always_inline)) inline void *safe_malloc(size_t s) {
|
||||||
if (void *p = malloc(s)) {
|
if (void *p = malloc(s)) {
|
||||||
return p;
|
return p;
|
||||||
@@ -441,6 +443,8 @@ Key toKeyAfter(Arena &arena, int n) {
|
|||||||
|
|
||||||
// ==================== BEGIN IMPLEMENTATION ====================
|
// ==================== BEGIN IMPLEMENTATION ====================
|
||||||
|
|
||||||
|
// GCOVR_EXCL_STOP
|
||||||
|
|
||||||
struct Entry {
|
struct Entry {
|
||||||
int64_t pointVersion;
|
int64_t pointVersion;
|
||||||
int64_t rangeVersion;
|
int64_t rangeVersion;
|
||||||
@@ -663,7 +667,7 @@ Node *&getChildExists(Node *self, uint8_t index) {
|
|||||||
auto *self256 = static_cast<Node256 *>(self);
|
auto *self256 = static_cast<Node256 *>(self);
|
||||||
return self256->children[index];
|
return self256->children[index];
|
||||||
}
|
}
|
||||||
__builtin_unreachable();
|
__builtin_unreachable(); // GCOVR_EXCL_LINE
|
||||||
}
|
}
|
||||||
|
|
||||||
int getChildGeq(Node *self, int child) {
|
int getChildGeq(Node *self, int child) {
|
||||||
@@ -769,7 +773,7 @@ int getChildLeq(Node *self, int child) {
|
|||||||
} else if (self->type == Type::Node48) {
|
} else if (self->type == Type::Node48) {
|
||||||
auto *self48 = static_cast<Node48 *>(self);
|
auto *self48 = static_cast<Node48 *>(self);
|
||||||
// TODO the plain loop is faster?
|
// 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;
|
int i = child;
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -802,7 +806,7 @@ int getChildLeq(Node *self, int child) {
|
|||||||
} else {
|
} else {
|
||||||
auto *self256 = static_cast<Node256 *>(self);
|
auto *self256 = static_cast<Node256 *>(self);
|
||||||
// TODO: The plain loop is faster?
|
// TODO: The plain loop is faster?
|
||||||
#if 0 && defined(__clang__)
|
#if defined(__clang__)
|
||||||
int i = child;
|
int i = child;
|
||||||
constexpr int kUnrollCount = 8; // Must be a power of two and <= 8
|
constexpr int kUnrollCount = 8; // Must be a power of two and <= 8
|
||||||
for (; (i & (kUnrollCount - 1)) != 0; --i) {
|
for (; (i & (kUnrollCount - 1)) != 0; --i) {
|
||||||
@@ -853,7 +857,7 @@ Node *&getOrCreateChild(Node *&self, uint8_t index) {
|
|||||||
}
|
}
|
||||||
if (self->numChildren == 4) {
|
if (self->numChildren == 4) {
|
||||||
auto *newSelf = new (safe_malloc(sizeof(Node16))) Node16;
|
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->index, self4->index, 4);
|
||||||
memcpy(newSelf->children, self4->children, 4 * sizeof(void *));
|
memcpy(newSelf->children, self4->children, 4 * sizeof(void *));
|
||||||
free(std::exchange(self, newSelf));
|
free(std::exchange(self, newSelf));
|
||||||
@@ -1072,10 +1076,7 @@ std::string_view getSearchPath(Arena &arena, Node *n) {
|
|||||||
result.push_back(n->parentsIndex);
|
result.push_back(n->parentsIndex);
|
||||||
}
|
}
|
||||||
std::reverse(result.begin(), result.end());
|
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
|
return std::string_view((const char *)&result[0], result.size()); // NOLINT
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void printLogical(std::string &result, Node *node) {
|
void printLogical(std::string &result, Node *node) {
|
||||||
@@ -1262,61 +1263,6 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
|||||||
int64_t oldestVersion;
|
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<int64_t>::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,
|
void ConflictSet::check(const ReadRange *reads, Result *results,
|
||||||
int count) const {
|
int count) const {
|
||||||
return impl->check(reads, results, count);
|
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<int64_t>::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 {
|
namespace std {
|
||||||
void __throw_length_error(const char *) { __builtin_unreachable(); }
|
void __throw_length_error(const char *) {
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
|
||||||
#ifdef ENABLE_MAIN
|
#ifdef ENABLE_MAIN
|
||||||
@@ -1494,3 +1498,5 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// GCOVR_EXCL_STOP
|
Reference in New Issue
Block a user