Skip to content

Commit a68fcb1

Browse files
committed
[prespecialized metadata] Add token for caching.
Emit a once token when adding canonical prespecialized metadata records to a nominal type descriptor and add the token itself as a trailing object to the type descriptor. The new token will, in subsequent commits, enable the canonical prespecialized metadata records attached to the type descriptor to be added to the metadata cache exactly once.
1 parent a69502e commit a68fcb1

File tree

13 files changed

+164
-9
lines changed

13 files changed

+164
-9
lines changed

docs/ABI/Mangling.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ Globals
175175

176176
global ::= global 'MJ' // noncanonical specialized generic type metadata instantiation cache associated with global
177177
global ::= global 'MN' // noncanonical specialized generic type metadata for global
178+
global ::= global 'Mz' // canonical specialized generic type metadata caching token
178179

179180
#if SWIFT_RUNTIME_VERSION >= 5.4
180181
global ::= context (decl-name '_')+ 'WZ' // global variable one-time initialization function

include/swift/ABI/Metadata.h

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "llvm/ADT/ArrayRef.h"
3131
#include "swift/Strings.h"
3232
#include "swift/Runtime/Config.h"
33+
#include "swift/Runtime/Once.h"
3334
#include "swift/ABI/MetadataValues.h"
3435
#include "swift/ABI/System.h"
3536
#include "swift/ABI/TrailingObjects.h"
@@ -3796,6 +3797,11 @@ struct TargetCanonicalSpecializedMetadataAccessorsListEntry {
37963797
TargetRelativeDirectPointer<Runtime, MetadataResponse(MetadataRequest), /*Nullable*/ false> accessor;
37973798
};
37983799

3800+
template <typename Runtime>
3801+
struct TargetCanonicalSpecializedMetadatasCachingOnceToken {
3802+
TargetRelativeDirectPointer<Runtime, swift_once_t, /*Nullable*/ false> token;
3803+
};
3804+
37993805
template <typename Runtime>
38003806
class TargetTypeContextDescriptor
38013807
: public TargetContextDescriptor<Runtime> {
@@ -3882,7 +3888,9 @@ class TargetTypeContextDescriptor
38823888
}
38833889

38843890
const llvm::ArrayRef<TargetRelativeDirectPointer<Runtime, TargetMetadata<Runtime>, /*Nullable*/ false>>
3885-
getCanonicicalMetadataPrespecializations() const;
3891+
getCanonicicalMetadataPrespecializations() const;
3892+
3893+
swift_once_t *getCanonicalMetadataPrespecializationCachingOnceToken() const;
38863894

38873895
static bool classof(const TargetContextDescriptor<Runtime> *cd) {
38883896
return cd->getKind() >= ContextDescriptorKind::Type_First
@@ -4024,7 +4032,8 @@ class TargetClassDescriptor final
40244032
TargetObjCResilientClassStubInfo<Runtime>,
40254033
TargetCanonicalSpecializedMetadatasListCount<Runtime>,
40264034
TargetCanonicalSpecializedMetadatasListEntry<Runtime>,
4027-
TargetCanonicalSpecializedMetadataAccessorsListEntry<Runtime>> {
4035+
TargetCanonicalSpecializedMetadataAccessorsListEntry<Runtime>,
4036+
TargetCanonicalSpecializedMetadatasCachingOnceToken<Runtime>> {
40284037
private:
40294038
using TrailingGenericContextObjects =
40304039
swift::TrailingGenericContextObjects<TargetClassDescriptor<Runtime>,
@@ -4039,7 +4048,8 @@ class TargetClassDescriptor final
40394048
TargetObjCResilientClassStubInfo<Runtime>,
40404049
TargetCanonicalSpecializedMetadatasListCount<Runtime>,
40414050
TargetCanonicalSpecializedMetadatasListEntry<Runtime>,
4042-
TargetCanonicalSpecializedMetadataAccessorsListEntry<Runtime>>;
4051+
TargetCanonicalSpecializedMetadataAccessorsListEntry<Runtime>,
4052+
TargetCanonicalSpecializedMetadatasCachingOnceToken<Runtime>>;
40434053

40444054
using TrailingObjects =
40454055
typename TrailingGenericContextObjects::TrailingObjects;
@@ -4067,6 +4077,8 @@ class TargetClassDescriptor final
40674077
TargetRelativeDirectPointer<Runtime, MetadataResponse(MetadataRequest), /*Nullable*/ false>;
40684078
using MetadataAccessorListEntry =
40694079
TargetCanonicalSpecializedMetadataAccessorsListEntry<Runtime>;
4080+
using MetadataCachingOnceToken =
4081+
TargetCanonicalSpecializedMetadatasCachingOnceToken<Runtime>;
40704082

40714083
using StoredPointer = typename Runtime::StoredPointer;
40724084
using StoredPointerDifference = typename Runtime::StoredPointerDifference;
@@ -4204,6 +4216,10 @@ class TargetClassDescriptor final
42044216
: 0;
42054217
}
42064218

4219+
size_t numTrailingObjects(OverloadToken<MetadataCachingOnceToken>) const {
4220+
return this->hasCanonicicalMetadataPrespecializations() ? 1 : 0;
4221+
}
4222+
42074223
public:
42084224
const TargetRelativeDirectPointer<Runtime, const void, /*nullable*/true> &
42094225
getResilientSuperclass() const {
@@ -4367,6 +4383,14 @@ class TargetClassDescriptor final
43674383
);
43684384
}
43694385

4386+
swift_once_t *getCanonicalMetadataPrespecializationCachingOnceToken() const {
4387+
if (!this->hasCanonicicalMetadataPrespecializations()) {
4388+
return nullptr;
4389+
}
4390+
auto box = this->template getTrailingObjects<MetadataCachingOnceToken>();
4391+
return box->token.get();
4392+
}
4393+
43704394
static bool classof(const TargetContextDescriptor<Runtime> *cd) {
43714395
return cd->getKind() == ContextDescriptorKind::Class;
43724396
}
@@ -4394,7 +4418,8 @@ class TargetStructDescriptor final
43944418
TargetForeignMetadataInitialization<Runtime>,
43954419
TargetSingletonMetadataInitialization<Runtime>,
43964420
TargetCanonicalSpecializedMetadatasListCount<Runtime>,
4397-
TargetCanonicalSpecializedMetadatasListEntry<Runtime>> {
4421+
TargetCanonicalSpecializedMetadatasListEntry<Runtime>,
4422+
TargetCanonicalSpecializedMetadatasCachingOnceToken<Runtime>> {
43984423
public:
43994424
using ForeignMetadataInitialization =
44004425
TargetForeignMetadataInitialization<Runtime>;
@@ -4406,6 +4431,8 @@ class TargetStructDescriptor final
44064431
TargetCanonicalSpecializedMetadatasListCount<Runtime>;
44074432
using MetadataListEntry =
44084433
TargetCanonicalSpecializedMetadatasListEntry<Runtime>;
4434+
using MetadataCachingOnceToken =
4435+
TargetCanonicalSpecializedMetadatasCachingOnceToken<Runtime>;
44094436

44104437
private:
44114438
using TrailingGenericContextObjects =
@@ -4414,7 +4441,8 @@ class TargetStructDescriptor final
44144441
ForeignMetadataInitialization,
44154442
SingletonMetadataInitialization,
44164443
MetadataListCount,
4417-
MetadataListEntry>;
4444+
MetadataListEntry,
4445+
MetadataCachingOnceToken>;
44184446

44194447
using TrailingObjects =
44204448
typename TrailingGenericContextObjects::TrailingObjects;
@@ -4444,6 +4472,10 @@ class TargetStructDescriptor final
44444472
: 0;
44454473
}
44464474

4475+
size_t numTrailingObjects(OverloadToken<MetadataCachingOnceToken>) const {
4476+
return this->hasCanonicicalMetadataPrespecializations() ? 1 : 0;
4477+
}
4478+
44474479
public:
44484480
using TrailingGenericContextObjects::getGenericContext;
44494481
using TrailingGenericContextObjects::getGenericContextHeader;
@@ -4489,6 +4521,14 @@ class TargetStructDescriptor final
44894521
);
44904522
}
44914523

4524+
swift_once_t *getCanonicalMetadataPrespecializationCachingOnceToken() const {
4525+
if (!this->hasCanonicicalMetadataPrespecializations()) {
4526+
return nullptr;
4527+
}
4528+
auto box = this->template getTrailingObjects<MetadataCachingOnceToken>();
4529+
return box->token.get();
4530+
}
4531+
44924532
static bool classof(const TargetContextDescriptor<Runtime> *cd) {
44934533
return cd->getKind() == ContextDescriptorKind::Struct;
44944534
}
@@ -4505,7 +4545,8 @@ class TargetEnumDescriptor final
45054545
TargetForeignMetadataInitialization<Runtime>,
45064546
TargetSingletonMetadataInitialization<Runtime>,
45074547
TargetCanonicalSpecializedMetadatasListCount<Runtime>,
4508-
TargetCanonicalSpecializedMetadatasListEntry<Runtime>> {
4548+
TargetCanonicalSpecializedMetadatasListEntry<Runtime>,
4549+
TargetCanonicalSpecializedMetadatasCachingOnceToken<Runtime>> {
45094550
public:
45104551
using SingletonMetadataInitialization =
45114552
TargetSingletonMetadataInitialization<Runtime>;
@@ -4517,6 +4558,8 @@ class TargetEnumDescriptor final
45174558
TargetCanonicalSpecializedMetadatasListCount<Runtime>;
45184559
using MetadataListEntry =
45194560
TargetCanonicalSpecializedMetadatasListEntry<Runtime>;
4561+
using MetadataCachingOnceToken =
4562+
TargetCanonicalSpecializedMetadatasCachingOnceToken<Runtime>;
45204563

45214564
private:
45224565
using TrailingGenericContextObjects =
@@ -4525,7 +4568,8 @@ class TargetEnumDescriptor final
45254568
ForeignMetadataInitialization,
45264569
SingletonMetadataInitialization,
45274570
MetadataListCount,
4528-
MetadataListEntry>;
4571+
MetadataListEntry,
4572+
MetadataCachingOnceToken>;
45294573

45304574
using TrailingObjects =
45314575
typename TrailingGenericContextObjects::TrailingObjects;
@@ -4555,6 +4599,10 @@ class TargetEnumDescriptor final
45554599
: 0;
45564600
}
45574601

4602+
size_t numTrailingObjects(OverloadToken<MetadataCachingOnceToken>) const {
4603+
return this->hasCanonicicalMetadataPrespecializations() ? 1 : 0;
4604+
}
4605+
45584606
public:
45594607
using TrailingGenericContextObjects::getGenericContext;
45604608
using TrailingGenericContextObjects::getGenericContextHeader;
@@ -4614,6 +4662,14 @@ class TargetEnumDescriptor final
46144662
);
46154663
}
46164664

4665+
swift_once_t *getCanonicalMetadataPrespecializationCachingOnceToken() const {
4666+
if (!this->hasCanonicicalMetadataPrespecializations()) {
4667+
return nullptr;
4668+
}
4669+
auto box = this->template getTrailingObjects<MetadataCachingOnceToken>();
4670+
return box->token.get();
4671+
}
4672+
46174673
static bool classof(const TargetContextDescriptor<Runtime> *cd) {
46184674
return cd->getKind() == ContextDescriptorKind::Enum;
46194675
}
@@ -4766,6 +4822,24 @@ TargetTypeContextDescriptor<Runtime>::getCanonicicalMetadataPrespecializations()
47664822
}
47674823
}
47684824

4825+
template <typename Runtime>
4826+
inline swift_once_t *TargetTypeContextDescriptor<
4827+
Runtime>::getCanonicalMetadataPrespecializationCachingOnceToken() const {
4828+
switch (this->getKind()) {
4829+
case ContextDescriptorKind::Enum:
4830+
return llvm::cast<TargetEnumDescriptor<Runtime>>(this)
4831+
->getCanonicalMetadataPrespecializationCachingOnceToken();
4832+
case ContextDescriptorKind::Struct:
4833+
return llvm::cast<TargetStructDescriptor<Runtime>>(this)
4834+
->getCanonicalMetadataPrespecializationCachingOnceToken();
4835+
case ContextDescriptorKind::Class:
4836+
return llvm::cast<TargetClassDescriptor<Runtime>>(this)
4837+
->getCanonicalMetadataPrespecializationCachingOnceToken();
4838+
default:
4839+
swift_unreachable("Not a type context descriptor.");
4840+
}
4841+
}
4842+
47694843
/// An entry in the chain of dynamic replacement functions.
47704844
struct DynamicReplacementChainEntry {
47714845
void *implementationFunction;

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ NODE(NoncanonicalSpecializedGenericTypeMetadataCache)
302302
NODE(GlobalVariableOnceFunction)
303303
NODE(GlobalVariableOnceToken)
304304
NODE(GlobalVariableOnceDeclList)
305+
NODE(CanonicalPrespecializedGenericTypeCachingOnceToken)
305306

306307
#undef CONTEXT_NODE
307308
#undef NODE

include/swift/IRGen/Linking.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,13 @@ class LinkEntity {
286286
/// The pointer is a AbstractStorageDecl*.
287287
DynamicallyReplaceableFunctionImpl,
288288

289+
/// The once token used by cacheCanonicalSpecializedMetadata, by way of
290+
/// swift_getCanonicalSpecializedMetadata and
291+
/// swift_getCanonicalPrespecializedGenericMetadata, to
292+
/// ensure that canonical prespecialized generic records are only added to
293+
/// the metadata cache once.
294+
CanonicalPrespecializedGenericTypeCachingOnceToken,
295+
289296
/// The pointer is a SILFunction*.
290297
DynamicallyReplaceableFunctionKey,
291298

@@ -399,7 +406,7 @@ class LinkEntity {
399406
/// The pointer is a canonical TypeBase*.
400407
NoncanonicalSpecializedGenericTypeMetadata,
401408

402-
/// A cache variable for noncanonical specialized type metadata, to be
409+
/// A cache variable for noncanonical specialized type metadata, to be
403410
/// passed to swift_getCanonicalSpecializedMetadata.
404411
/// The pointer is a canonical TypeBase*.
405412
NoncanonicalSpecializedGenericTypeMetadataCacheVariable,
@@ -411,7 +418,7 @@ class LinkEntity {
411418
}
412419

413420
static bool isDeclKind(Kind k) {
414-
return k <= Kind::DynamicallyReplaceableFunctionImpl;
421+
return k <= Kind::CanonicalPrespecializedGenericTypeCachingOnceToken;
415422
}
416423
static bool isTypeKind(Kind k) {
417424
return k >= Kind::ProtocolWitnessTableLazyAccessFunction;
@@ -1039,6 +1046,14 @@ class LinkEntity {
10391046
return entity;
10401047
}
10411048

1049+
static LinkEntity
1050+
forCanonicalPrespecializedGenericTypeCachingOnceToken(NominalTypeDecl *decl) {
1051+
LinkEntity entity;
1052+
entity.setForDecl(Kind::CanonicalPrespecializedGenericTypeCachingOnceToken,
1053+
decl);
1054+
return entity;
1055+
}
1056+
10421057
static LinkEntity
10431058
forSpecializedGenericSwiftMetaclassStub(CanType concreteType) {
10441059
LinkEntity entity;

lib/Demangling/Demangler.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,6 +2001,9 @@ NodePointer Demangler::demangleMetatype() {
20012001
popNode(isEntity));
20022002
case 'X':
20032003
return demanglePrivateContextDescriptor();
2004+
case 'z':
2005+
return createWithPoppedType(
2006+
Node::Kind::CanonicalPrespecializedGenericTypeCachingOnceToken);
20042007
default:
20052008
return nullptr;
20062009
}

lib/Demangling/NodePrinter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,7 @@ class NodePrinter {
561561
case Node::Kind::GlobalVariableOnceDeclList:
562562
case Node::Kind::GlobalVariableOnceFunction:
563563
case Node::Kind::GlobalVariableOnceToken:
564+
case Node::Kind::CanonicalPrespecializedGenericTypeCachingOnceToken:
564565
return false;
565566
}
566567
printer_unreachable("bad node kind");
@@ -2537,6 +2538,11 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
25372538
Printer << "@objc completion handler block implementation for ";
25382539
print(Node->getChild(0));
25392540
return nullptr;
2541+
case Node::Kind::CanonicalPrespecializedGenericTypeCachingOnceToken:
2542+
Printer << "flag for loading of canonical specialized generic type "
2543+
"metadata for ";
2544+
print(Node->getChild(0));
2545+
return nullptr;
25402546
}
25412547
printer_unreachable("bad node kind!");
25422548
}

lib/Demangling/OldRemangler.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2191,6 +2191,12 @@ void Remangler::mangleNoncanonicalSpecializedGenericTypeMetadataCache(Node *node
21912191
Buffer << "MJ";
21922192
}
21932193

2194+
void Remangler::mangleCanonicalPrespecializedGenericTypeCachingOnceToken(
2195+
Node *node) {
2196+
mangleSingleChildNode(node);
2197+
Buffer << "Mz";
2198+
}
2199+
21942200
/// The top-level interface to the remangler.
21952201
std::string Demangle::mangleNodeOld(NodePointer node) {
21962202
if (!node) return "";

lib/Demangling/Remangler.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2633,6 +2633,12 @@ void Remangler::mangleNoncanonicalSpecializedGenericTypeMetadataCache(Node *node
26332633
Buffer << "MJ";
26342634
}
26352635

2636+
void Remangler::mangleCanonicalPrespecializedGenericTypeCachingOnceToken(
2637+
Node *node) {
2638+
mangleSingleChildNode(node);
2639+
Buffer << "Mz";
2640+
}
2641+
26362642
void Remangler::mangleGlobalVariableOnceToken(Node *node) {
26372643
mangleChildNodes(node);
26382644
Buffer << "Wz";

lib/IRGen/GenDecl.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3906,6 +3906,24 @@ IRGenModule::getAddrOfTypeMetadataLazyCacheVariable(CanType type) {
39063906
return variable;
39073907
}
39083908

3909+
llvm::Constant *
3910+
IRGenModule::getAddrOfCanonicalPrespecializedGenericTypeCachingOnceToken(
3911+
NominalTypeDecl *decl) {
3912+
assert(decl->isGenericContext());
3913+
LinkEntity entity =
3914+
LinkEntity::forCanonicalPrespecializedGenericTypeCachingOnceToken(decl);
3915+
if (auto &entry = GlobalVars[entity]) {
3916+
return entry;
3917+
}
3918+
auto variable = getAddrOfLLVMVariable(entity, ForDefinition, DebugTypeInfo());
3919+
3920+
// Zero-initialize if we're asking for a definition.
3921+
cast<llvm::GlobalVariable>(variable)->setInitializer(
3922+
llvm::ConstantInt::get(OnceTy, 0));
3923+
3924+
return variable;
3925+
}
3926+
39093927
llvm::Constant *
39103928
IRGenModule::getAddrOfNoncanonicalSpecializedGenericTypeMetadataCacheVariable(CanType type) {
39113929
assert(!type->hasArchetype() && !type->hasTypeParameter());

lib/IRGen/GenMeta.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,6 +1329,7 @@ namespace {
13291329
void maybeAddCanonicalMetadataPrespecializations() {
13301330
if (Type->isGenericContext() && hasCanonicalMetadataPrespecializations()) {
13311331
asImpl().addCanonicalMetadataPrespecializations();
1332+
asImpl().addCanonicalMetadataPrespecializationCachingOnceToken();
13321333
}
13331334
}
13341335

@@ -1348,6 +1349,12 @@ namespace {
13481349
}
13491350
}
13501351

1352+
void addCanonicalMetadataPrespecializationCachingOnceToken() {
1353+
auto *cachingOnceToken =
1354+
IGM.getAddrOfCanonicalPrespecializedGenericTypeCachingOnceToken(Type);
1355+
B.addRelativeAddress(cachingOnceToken);
1356+
}
1357+
13511358
// Subclasses should provide:
13521359
// ContextDescriptorKind getContextKind();
13531360
// void addLayoutInfo();

lib/IRGen/IRGenMangler.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ class IRGenMangler : public Mangle::ASTMangler {
122122
return mangleTypeSymbol(type, "MN");
123123
}
124124

125+
std::string mangleCanonicalPrespecializedGenericTypeCachingOnceToken(
126+
const NominalTypeDecl *decl) {
127+
return mangleNominalTypeSymbol(decl, "Mz");
128+
}
129+
125130
std::string mangleNoncanonicalSpecializedGenericTypeMetadataCache(Type type) {
126131
return mangleTypeSymbol(type, "MJ");
127132
}

0 commit comments

Comments
 (0)