Skip to content

Commit c712938

Browse files
authored
Merge pull request #27414 from brentdax/identify-yourself
[NFC] Explicitly control alignment of Identifiers
2 parents 0c8dd88 + dee631b commit c712938

File tree

3 files changed

+45
-25
lines changed

3 files changed

+45
-25
lines changed

include/swift/AST/Identifier.h

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,26 @@ class Identifier {
5656

5757
const char *Pointer;
5858

59+
public:
60+
enum : size_t {
61+
NumLowBitsAvailable = 2,
62+
RequiredAlignment = 1 << NumLowBitsAvailable,
63+
SpareBitMask = ((intptr_t)1 << NumLowBitsAvailable) - 1
64+
};
65+
66+
private:
5967
/// Constructor, only accessible by ASTContext, which handles the uniquing.
60-
explicit Identifier(const char *Ptr) : Pointer(Ptr) {}
68+
explicit Identifier(const char *Ptr) : Pointer(Ptr) {
69+
assert(((uintptr_t)Ptr & SpareBitMask) == 0
70+
&& "Identifier pointer does not use any spare bits");
71+
}
72+
73+
/// A type with the alignment expected of a valid \c Identifier::Pointer .
74+
struct alignas(uint32_t) Aligner {};
75+
76+
static_assert(alignof(Aligner) >= RequiredAlignment,
77+
"Identifier table will provide enough spare bits");
78+
6179
public:
6280
explicit Identifier() : Pointer(nullptr) {}
6381

@@ -153,12 +171,15 @@ class Identifier {
153171
bool operator<(Identifier RHS) const { return Pointer < RHS.Pointer; }
154172

155173
static Identifier getEmptyKey() {
156-
return Identifier((const char*)
157-
llvm::DenseMapInfo<const void*>::getEmptyKey());
174+
uintptr_t Val = static_cast<uintptr_t>(-1);
175+
Val <<= NumLowBitsAvailable;
176+
return Identifier((const char*)Val);
158177
}
178+
159179
static Identifier getTombstoneKey() {
160-
return Identifier((const char*)
161-
llvm::DenseMapInfo<const void*>::getTombstoneKey());
180+
uintptr_t Val = static_cast<uintptr_t>(-2);
181+
Val <<= NumLowBitsAvailable;
182+
return Identifier((const char*)Val);
162183
}
163184

164185
private:
@@ -202,7 +223,7 @@ namespace llvm {
202223
static inline swift::Identifier getFromVoidPointer(void *P) {
203224
return swift::Identifier::getFromOpaquePointer(P);
204225
}
205-
enum { NumLowBitsAvailable = 2 };
226+
enum { NumLowBitsAvailable = swift::Identifier::NumLowBitsAvailable };
206227
};
207228

208229
} // end namespace llvm
@@ -221,15 +242,15 @@ class DeclBaseName {
221242
};
222243

223244
private:
224-
/// In a special DeclName represenenting a subscript, this opaque pointer
245+
/// In a special DeclName representing a subscript, this opaque pointer
225246
/// is used as the data of the base name identifier.
226247
/// This is an implementation detail that should never leak outside of
227248
/// DeclName.
228-
static void *SubscriptIdentifierData;
249+
static const Identifier::Aligner SubscriptIdentifierData;
229250
/// As above, for special constructor DeclNames.
230-
static void *ConstructorIdentifierData;
251+
static const Identifier::Aligner ConstructorIdentifierData;
231252
/// As above, for special destructor DeclNames.
232-
static void *DestructorIdentifierData;
253+
static const Identifier::Aligner DestructorIdentifierData;
233254

234255
Identifier Ident;
235256

@@ -239,23 +260,23 @@ class DeclBaseName {
239260
DeclBaseName(Identifier I) : Ident(I) {}
240261

241262
static DeclBaseName createSubscript() {
242-
return DeclBaseName(Identifier((const char *)SubscriptIdentifierData));
263+
return DeclBaseName(Identifier((const char *)&SubscriptIdentifierData));
243264
}
244265

245266
static DeclBaseName createConstructor() {
246-
return DeclBaseName(Identifier((const char *)ConstructorIdentifierData));
267+
return DeclBaseName(Identifier((const char *)&ConstructorIdentifierData));
247268
}
248269

249270
static DeclBaseName createDestructor() {
250-
return DeclBaseName(Identifier((const char *)DestructorIdentifierData));
271+
return DeclBaseName(Identifier((const char *)&DestructorIdentifierData));
251272
}
252273

253274
Kind getKind() const {
254-
if (Ident.get() == SubscriptIdentifierData) {
275+
if (Ident.get() == (const char *)&SubscriptIdentifierData) {
255276
return Kind::Subscript;
256-
} else if (Ident.get() == ConstructorIdentifierData) {
277+
} else if (Ident.get() == (const char *)&ConstructorIdentifierData) {
257278
return Kind::Constructor;
258-
} else if (Ident.get() == DestructorIdentifierData) {
279+
} else if (Ident.get() == (const char *)&DestructorIdentifierData) {
259280
return Kind::Destructor;
260281
} else {
261282
return Kind::Normal;
@@ -720,7 +741,7 @@ namespace llvm {
720741
static inline swift::DeclName getFromVoidPointer(void *ptr) {
721742
return swift::DeclName::getFromOpaqueValue(ptr);
722743
}
723-
enum { NumLowBitsAvailable = 0 };
744+
enum { NumLowBitsAvailable = PointerLikeTypeTraits<swift::DeclBaseName>::NumLowBitsAvailable - 2 };
724745
};
725746

726747
// DeclNames hash just like pointers.

lib/AST/ASTContext.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ struct ASTContext::Implementation {
165165

166166
// FIXME: This is a StringMap rather than a StringSet because StringSet
167167
// doesn't allow passing in a pre-existing allocator.
168-
llvm::StringMap<char, llvm::BumpPtrAllocator&> IdentifierTable;
168+
llvm::StringMap<Identifier::Aligner, llvm::BumpPtrAllocator&>
169+
IdentifierTable;
169170

170171
/// The declaration of Swift.AssignmentPrecedence.
171172
PrecedenceGroupDecl *AssignmentPrecedence = nullptr;
@@ -642,7 +643,8 @@ Identifier ASTContext::getIdentifier(StringRef Str) const {
642643
if (Str.data() == nullptr)
643644
return Identifier(nullptr);
644645

645-
auto I = getImpl().IdentifierTable.insert(std::make_pair(Str, char())).first;
646+
auto pair = std::make_pair(Str, Identifier::Aligner());
647+
auto I = getImpl().IdentifierTable.insert(pair).first;
646648
return Identifier(I->getKeyData());
647649
}
648650

lib/AST/Identifier.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,9 @@
2121
#include "clang/Basic/CharInfo.h"
2222
using namespace swift;
2323

24-
void *DeclBaseName::SubscriptIdentifierData =
25-
&DeclBaseName::SubscriptIdentifierData;
26-
void *DeclBaseName::ConstructorIdentifierData =
27-
&DeclBaseName::ConstructorIdentifierData;
28-
void *DeclBaseName::DestructorIdentifierData =
29-
&DeclBaseName::DestructorIdentifierData;
24+
constexpr const Identifier::Aligner DeclBaseName::SubscriptIdentifierData{};
25+
constexpr const Identifier::Aligner DeclBaseName::ConstructorIdentifierData{};
26+
constexpr const Identifier::Aligner DeclBaseName::DestructorIdentifierData{};
3027

3128
raw_ostream &llvm::operator<<(raw_ostream &OS, Identifier I) {
3229
if (I.get() == nullptr)

0 commit comments

Comments
 (0)