14
14
#define LLVM_EXECUTIONENGINE_ORC_SHARED_EXECUTORADDRESS_H
15
15
16
16
#include " llvm/ADT/DenseMapInfo.h"
17
+ #include " llvm/ADT/identity.h"
17
18
#include " llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
18
19
#include " llvm/Support/FormatVariadic.h"
19
20
#include " llvm/Support/raw_ostream.h"
@@ -29,34 +30,76 @@ using ExecutorAddrDiff = uint64_t;
29
30
// / Represents an address in the executor process.
30
31
class ExecutorAddr {
31
32
public:
33
+ // / A wrap/unwrap function that leaves pointers unmodified.
34
+ template <typename T> using rawPtr = llvm::identity<T>;
35
+
36
+ // / Default wrap function to use on this host.
37
+ template <typename T> using defaultWrap = rawPtr<T>;
38
+
39
+ // / Default unwrap function to use on this host.
40
+ template <typename T> using defaultUnwrap = rawPtr<T>;
41
+
42
+ // / Merges a tag into the raw address value:
43
+ // / P' = P | (TagValue << TagOffset).
44
+ class Tag {
45
+ public:
46
+ constexpr Tag (uintptr_t TagValue, uintptr_t TagOffset)
47
+ : TagMask(TagValue << TagOffset) {}
48
+
49
+ template <typename T> constexpr T *operator ()(T *P) {
50
+ return reinterpret_cast <T*>(reinterpret_cast <uintptr_t >(P) | TagMask);
51
+ }
52
+
53
+ private:
54
+ uintptr_t TagMask;
55
+ };
56
+
57
+ // / Strips a tag of the given length from the given offset within the pointer:
58
+ // / P' = P & ~(((1 << TagLen) -1) << TagOffset)
59
+ class Untag {
60
+ public:
61
+ constexpr Untag (uintptr_t TagLen, uintptr_t TagOffset)
62
+ : UntagMask(~(((1 << TagLen) - 1) << TagOffset)) {}
63
+
64
+ template <typename T> constexpr T *operator ()(T *P) {
65
+ return reinterpret_cast <T *>(reinterpret_cast <uintptr_t >(P) & UntagMask);
66
+ }
67
+
68
+ private:
69
+ uintptr_t UntagMask;
70
+ };
71
+
32
72
ExecutorAddr () = default ;
33
73
34
74
// / Create an ExecutorAddr from the given value.
35
75
explicit constexpr ExecutorAddr (uint64_t Addr) : Addr(Addr) {}
36
76
37
77
// / Create an ExecutorAddr from the given pointer.
38
78
// / Warning: This should only be used when JITing in-process.
39
- template <typename T> static ExecutorAddr fromPtr (T *Value) {
79
+ template <typename T, typename UnwrapFn = defaultUnwrap<T *>>
80
+ static ExecutorAddr fromPtr (T *Ptr, UnwrapFn &&Unwrap = UnwrapFn()) {
40
81
return ExecutorAddr (
41
- static_cast <uint64_t >(reinterpret_cast <uintptr_t >(Value )));
82
+ static_cast <uint64_t >(reinterpret_cast <uintptr_t >(Unwrap (Ptr) )));
42
83
}
43
84
44
85
// / Cast this ExecutorAddr to a pointer of the given type.
45
86
// / Warning: This should only be used when JITing in-process.
46
- template <typename T>
47
- std::enable_if_t <std::is_pointer<T>::value, T> toPtr () const {
87
+ template <typename T, typename WrapFn = defaultWrap<T>>
88
+ std::enable_if_t <std::is_pointer<T>::value, T>
89
+ toPtr (WrapFn &&Wrap = WrapFn()) const {
48
90
uintptr_t IntPtr = static_cast <uintptr_t >(Addr);
49
91
assert (IntPtr == Addr && " ExecutorAddr value out of range for uintptr_t" );
50
- return reinterpret_cast <T>(IntPtr);
92
+ return Wrap ( reinterpret_cast <T>(IntPtr) );
51
93
}
52
94
53
95
// / Cast this ExecutorAddr to a pointer of the given function type.
54
96
// / Warning: This should only be used when JITing in-process.
55
- template <typename T>
56
- std::enable_if_t <std::is_function<T>::value, T *> toPtr () const {
97
+ template <typename T, typename WrapFn = defaultWrap<T *>>
98
+ std::enable_if_t <std::is_function<T>::value, T *>
99
+ toPtr (WrapFn &&Wrap = WrapFn()) const {
57
100
uintptr_t IntPtr = static_cast <uintptr_t >(Addr);
58
101
assert (IntPtr == Addr && " ExecutorAddr value out of range for uintptr_t" );
59
- return reinterpret_cast <T *>(IntPtr);
102
+ return Wrap ( reinterpret_cast <T *>(IntPtr) );
60
103
}
61
104
62
105
uint64_t getValue () const { return Addr; }
0 commit comments