Skip to content

Commit e5227a3

Browse files
committed
Templatize Relative*Pointer on offset type.
We usually want to use 32-bit offsets, since we use them to reference other objects within the same small-code-model image. However, for data structures that are both compiler-generated and runtime-allocated, we may want to save the relocation in compile time, but need a full-width offset to be able to relatively reference things from the heap. NFC yet.
1 parent 0159627 commit e5227a3

File tree

1 file changed

+23
-17
lines changed

1 file changed

+23
-17
lines changed

include/swift/Basic/RelativePointer.h

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ namespace swift {
2626
/// A relative reference to an object stored in memory. The reference may be
2727
/// direct or indirect, and uses the low bit of the (assumed at least
2828
/// 2-byte-aligned) pointer to differentiate.
29-
template<typename ValueTy, bool Nullable = false>
29+
template<typename ValueTy, bool Nullable = false, typename Offset = int32_t>
3030
class RelativeIndirectablePointer {
3131
private:
3232
/// The relative offset of the pointer's memory from the `this` pointer.
3333
/// If the low bit is clear, this is a direct reference; otherwise, it is
3434
/// an indirect reference.
35-
int32_t RelativeOffset;
35+
Offset RelativeOffset;
3636

3737
/// RelativePointers should appear in statically-generated metadata. They
3838
/// shouldn't be constructed or copied.
@@ -44,6 +44,10 @@ class RelativeIndirectablePointer {
4444
RelativeIndirectablePointer &operator=(const RelativeIndirectablePointer &)
4545
= delete;
4646

47+
static_assert(std::is_integral<Offset>::value &&
48+
std::is_signed<Offset>::value,
49+
"offset type should be signed integer");
50+
4751
public:
4852
const ValueTy *get() const & {
4953
// Check for null.
@@ -79,11 +83,11 @@ class RelativeIndirectablePointer {
7983
/// A relative reference to a function, intended to reference private metadata
8084
/// functions for the current executable or dynamic library image from
8185
/// position-independent constant data.
82-
template<typename T, bool Nullable>
86+
template<typename T, bool Nullable, typename Offset>
8387
class RelativeDirectPointerImpl {
8488
private:
8589
/// The relative offset of the function's entry point from *this.
86-
int32_t RelativeOffset;
90+
Offset RelativeOffset;
8791

8892
/// RelativePointers should appear in statically-generated metadata. They
8993
/// shouldn't be constructed or copied.
@@ -117,11 +121,11 @@ class RelativeDirectPointerImpl {
117121
};
118122

119123
/// A direct relative reference to an object.
120-
template<typename T, bool Nullable = true>
124+
template<typename T, bool Nullable = true, typename Offset = int32_t>
121125
class RelativeDirectPointer :
122-
private RelativeDirectPointerImpl<T, Nullable>
126+
private RelativeDirectPointerImpl<T, Nullable, Offset>
123127
{
124-
using super = RelativeDirectPointerImpl<T, Nullable>;
128+
using super = RelativeDirectPointerImpl<T, Nullable, Offset>;
125129
public:
126130
using super::get;
127131

@@ -142,11 +146,11 @@ class RelativeDirectPointer :
142146

143147
/// A specialization of RelativeDirectPointer for function pointers,
144148
/// allowing for calls.
145-
template<typename RetTy, typename...ArgTy, bool Nullable>
146-
class RelativeDirectPointer<RetTy (ArgTy...), Nullable> :
147-
private RelativeDirectPointerImpl<RetTy (ArgTy...), Nullable>
149+
template<typename RetTy, typename...ArgTy, bool Nullable, typename Offset>
150+
class RelativeDirectPointer<RetTy (ArgTy...), Nullable, Offset> :
151+
private RelativeDirectPointerImpl<RetTy (ArgTy...), Nullable, Offset>
148152
{
149-
using super = RelativeDirectPointerImpl<RetTy (ArgTy...), Nullable>;
153+
using super = RelativeDirectPointerImpl<RetTy (ArgTy...), Nullable, Offset>;
150154
public:
151155
using super::get;
152156

@@ -163,9 +167,9 @@ class RelativeDirectPointer<RetTy (ArgTy...), Nullable> :
163167

164168
/// A direct relative reference to an aligned object, with an additional
165169
/// tiny integer value crammed into its low bits.
166-
template<typename PointeeTy, typename IntTy>
170+
template<typename PointeeTy, typename IntTy, typename Offset = int32_t>
167171
class RelativeDirectPointerIntPair {
168-
int32_t RelativeOffsetPlusInt;
172+
Offset RelativeOffsetPlusInt;
169173

170174
/// RelativePointers should appear in statically-generated metadata. They
171175
/// shouldn't be constructed or copied.
@@ -177,18 +181,20 @@ class RelativeDirectPointerIntPair {
177181
RelativeDirectPointerIntPair &operator=(const RelativeDirectPointerIntPair&)
178182
= delete;
179183

180-
static int32_t getMask() {
181-
static_assert(alignof(PointeeTy) >= alignof(int32_t),
182-
"pointee alignment must be at least 32 bit");
184+
static Offset getMask() {
185+
static_assert(alignof(PointeeTy) >= alignof(Offset),
186+
"pointee alignment must be at least as strict as offset type");
183187

184-
return alignof(int32_t) - 1;
188+
return alignof(Offset) - 1;
185189
}
186190

187191
public:
188192
using ValueTy = PointeeTy;
189193
using PointerTy = PointeeTy*;
190194

191195
PointerTy getPointer() const & {
196+
197+
192198
// The value is addressed relative to `this`.
193199
auto base = reinterpret_cast<intptr_t>(this);
194200
intptr_t absolute = base + (RelativeOffsetPlusInt & ~getMask());

0 commit comments

Comments
 (0)