diff --git a/CMakeLists.txt b/CMakeLists.txt index 543601d..610a399 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,8 +102,6 @@ option(DISABLE_TSAN "Disable TSAN" OFF) # https://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.clientreq include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/valgrind) -add_compile_options($<$:-Wno-invalid-offsetof>) - if(APPLE) add_link_options(-Wl,-dead_strip) else() diff --git a/ConflictSet.cpp b/ConflictSet.cpp index e14af86..0e9b68a 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -281,7 +281,6 @@ private: struct Node { - /* begin section that's copied to the next node */ union { Entry entry; /* Set to the forwarding point for this node if releaseDeferred is set */ @@ -292,7 +291,6 @@ struct Node { int16_t numChildren; bool entryPresent; uint8_t parentsIndex; - /* end section that's copied to the next node */ /* If set, this node has been replaced and the next node in the forwarding * chain is `forwardTo`*/ @@ -322,10 +320,6 @@ Type TaggedNodePointer::getType() { return Type(p & uintptr_t(7)); } -constexpr int kNodeCopyBegin = offsetof(Node, entry); -constexpr int kNodeCopySize = - offsetof(Node, parentsIndex) + sizeof(Node::parentsIndex) - kNodeCopyBegin; - // copyChildrenAndKeyFrom is responsible for copying all // public members of Node, copying the partial key, logically copying the // children (converting representation if necessary), and updating all the @@ -431,27 +425,35 @@ struct Node256 : Node { size_t size() const { return sizeof(Node256) + getCapacity(); } }; +template +void copyCommon(To &to, const From &from) + requires(std::is_base_of_v && std::is_base_of_v) +{ + memcpy(&to.entry, &from.entry, sizeof(from.entry)); + to.parent = from.parent; + to.partialKeyLen = from.partialKeyLen; + to.numChildren = from.numChildren; + to.entryPresent = from.entryPresent; + to.parentsIndex = from.parentsIndex; +} + inline void Node0::copyChildrenAndKeyFrom(const Node0 &other) { - memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin, - kNodeCopySize); + copyCommon(*this, other); memcpy(partialKey(), &other + 1, partialKeyLen); } inline void Node0::copyChildrenAndKeyFrom(const Node3 &other) { - memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin, - kNodeCopySize); + copyCommon(*this, other); memcpy(partialKey(), &other + 1, partialKeyLen); } inline void Node3::copyChildrenAndKeyFrom(const Node0 &other) { - memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin, - kNodeCopySize); + copyCommon(*this, other); memcpy(partialKey(), &other + 1, partialKeyLen); } inline void Node3::copyChildrenAndKeyFrom(const Node3 &other) { - memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin, - kNodeCopySize); + copyCommon(*this, other); memcpy(index, other.index, kMaxNodes); memcpy(children, other.children, kMaxNodes * sizeof(children[0])); // NOLINT memcpy(childMaxVersion, other.childMaxVersion, @@ -464,8 +466,7 @@ inline void Node3::copyChildrenAndKeyFrom(const Node3 &other) { } inline void Node3::copyChildrenAndKeyFrom(const Node16 &other) { - memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin, - kNodeCopySize); + copyCommon(*this, other); memcpy(index, other.index, kMaxNodes); memcpy(children, other.children, kMaxNodes * sizeof(children[0])); // NOLINT memcpy(childMaxVersion, other.childMaxVersion, @@ -478,8 +479,7 @@ inline void Node3::copyChildrenAndKeyFrom(const Node16 &other) { } inline void Node16::copyChildrenAndKeyFrom(const Node3 &other) { - memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin, - kNodeCopySize); + copyCommon(*this, other); memcpy(index, other.index, Node3::kMaxNodes); memcpy(children, other.children, Node3::kMaxNodes * sizeof(children[0])); // NOLINT @@ -494,8 +494,7 @@ inline void Node16::copyChildrenAndKeyFrom(const Node3 &other) { } inline void Node16::copyChildrenAndKeyFrom(const Node16 &other) { - memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin, - kNodeCopySize); + copyCommon(*this, other); memcpy(index, other.index, sizeof(index)); for (int i = 0; i < numChildren; ++i) { children[i] = other.children[i]; @@ -507,8 +506,7 @@ inline void Node16::copyChildrenAndKeyFrom(const Node16 &other) { } inline void Node16::copyChildrenAndKeyFrom(const Node48 &other) { - memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin, - kNodeCopySize); + copyCommon(*this, other); int i = 0; other.bitSet.forEachSet([&](int c) { // Suppress a false positive -Waggressive-loop-optimizations warning @@ -525,8 +523,7 @@ inline void Node16::copyChildrenAndKeyFrom(const Node48 &other) { } inline void Node48::copyChildrenAndKeyFrom(const Node16 &other) { - memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin, - kNodeCopySize); + copyCommon(*this, other); assert(numChildren == Node16::kMaxNodes); memset(index, -1, sizeof(index)); memset(children, 0, sizeof(children)); @@ -552,8 +549,7 @@ inline void Node48::copyChildrenAndKeyFrom(const Node16 &other) { } inline void Node48::copyChildrenAndKeyFrom(const Node48 &other) { - memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin, - kNodeCopySize); + copyCommon(*this, other); bitSet = other.bitSet; memcpy(index, other.index, sizeof(index)); memset(children, 0, sizeof(children)); @@ -573,8 +569,7 @@ inline void Node48::copyChildrenAndKeyFrom(const Node48 &other) { } inline void Node48::copyChildrenAndKeyFrom(const Node256 &other) { - memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin, - kNodeCopySize); + copyCommon(*this, other); memset(index, -1, sizeof(index)); memset(children, 0, sizeof(children)); const auto z = InternalVersionT::zero; @@ -601,8 +596,7 @@ inline void Node48::copyChildrenAndKeyFrom(const Node256 &other) { } inline void Node256::copyChildrenAndKeyFrom(const Node48 &other) { - memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin, - kNodeCopySize); + copyCommon(*this, other); bitSet = other.bitSet; memset(children, 0, sizeof(children)); const auto z = InternalVersionT::zero; @@ -624,8 +618,7 @@ inline void Node256::copyChildrenAndKeyFrom(const Node48 &other) { } inline void Node256::copyChildrenAndKeyFrom(const Node256 &other) { - memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin, - kNodeCopySize); + copyCommon(*this, other); memset(children, 0, sizeof(children)); const auto z = InternalVersionT::zero; for (auto &v : childMaxVersion) {