Skip to content

Commit

Permalink
tptr: add pointer tagging templates (#7067)
Browse files Browse the repository at this point in the history
  • Loading branch information
JakobR committed Dec 19, 2023
1 parent fcc7b25 commit 4c9f705
Showing 1 changed file with 20 additions and 1 deletion.
21 changes: 20 additions & 1 deletion src/util/tptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Revision History:

#include <cstdint>
#include "util/machine.h"
#include "util/debug.h"

#define TAG_SHIFT PTR_ALIGNMENT
#define ALIGNMENT_VALUE (1 << PTR_ALIGNMENT)
Expand All @@ -42,4 +43,22 @@ Revision History:

#define UNBOXINT(PTR) static_cast<int>(reinterpret_cast<uintptr_t>(PTR) >> PTR_ALIGNMENT)


template <typename U, typename T>
U unbox(T* ptr) {
return static_cast<U>(reinterpret_cast<std::uintptr_t>(ptr) >> PTR_ALIGNMENT);
}

template <typename T>
unsigned get_tag(T* ptr) {
return reinterpret_cast<std::uintptr_t>(ptr) & TAG_MASK;
}

template <typename T, typename U>
T* box(U val, std::uintptr_t tag = 0) {
static_assert( sizeof(T*) >= sizeof(U) + PTR_ALIGNMENT );
SASSERT_EQ(tag & PTR_MASK, 0);
T* ptr = reinterpret_cast<T*>((static_cast<std::uintptr_t>(val) << PTR_ALIGNMENT) | tag);
SASSERT_EQ(val, unbox<U>(ptr)); // roundtrip of conversion integer -> pointer -> integer is not actually guaranteed by the C++ standard (but seems fine in practice, as indicated by previous usage of BOXINT/UNBOXINT)
SASSERT_EQ(tag, get_tag(ptr));
return ptr;
}

0 comments on commit 4c9f705

Please sign in to comment.