Skip to content

Commit 5c59bab

Browse files
Merge pull request #34490 from nate-chandler/generic-metadata-prespecialization-components/special-entry
[metadata prespecialization] Add canonical records to cache.
2 parents 096edf1 + 1bbd0f4 commit 5c59bab

File tree

72 files changed

+421
-158
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+421
-158
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"
@@ -3787,6 +3788,11 @@ struct TargetCanonicalSpecializedMetadataAccessorsListEntry {
37873788
TargetRelativeDirectPointer<Runtime, MetadataResponse(MetadataRequest), /*Nullable*/ false> accessor;
37883789
};
37893790

3791+
template <typename Runtime>
3792+
struct TargetCanonicalSpecializedMetadatasCachingOnceToken {
3793+
TargetRelativeDirectPointer<Runtime, swift_once_t, /*Nullable*/ false> token;
3794+
};
3795+
37903796
template <typename Runtime>
37913797
class TargetTypeContextDescriptor
37923798
: public TargetContextDescriptor<Runtime> {
@@ -3873,7 +3879,9 @@ class TargetTypeContextDescriptor
38733879
}
38743880

38753881
const llvm::ArrayRef<TargetRelativeDirectPointer<Runtime, TargetMetadata<Runtime>, /*Nullable*/ false>>
3876-
getCanonicicalMetadataPrespecializations() const;
3882+
getCanonicicalMetadataPrespecializations() const;
3883+
3884+
swift_once_t *getCanonicalMetadataPrespecializationCachingOnceToken() const;
38773885

38783886
static bool classof(const TargetContextDescriptor<Runtime> *cd) {
38793887
return cd->getKind() >= ContextDescriptorKind::Type_First
@@ -4015,7 +4023,8 @@ class TargetClassDescriptor final
40154023
TargetObjCResilientClassStubInfo<Runtime>,
40164024
TargetCanonicalSpecializedMetadatasListCount<Runtime>,
40174025
TargetCanonicalSpecializedMetadatasListEntry<Runtime>,
4018-
TargetCanonicalSpecializedMetadataAccessorsListEntry<Runtime>> {
4026+
TargetCanonicalSpecializedMetadataAccessorsListEntry<Runtime>,
4027+
TargetCanonicalSpecializedMetadatasCachingOnceToken<Runtime>> {
40194028
private:
40204029
using TrailingGenericContextObjects =
40214030
swift::TrailingGenericContextObjects<TargetClassDescriptor<Runtime>,
@@ -4030,7 +4039,8 @@ class TargetClassDescriptor final
40304039
TargetObjCResilientClassStubInfo<Runtime>,
40314040
TargetCanonicalSpecializedMetadatasListCount<Runtime>,
40324041
TargetCanonicalSpecializedMetadatasListEntry<Runtime>,
4033-
TargetCanonicalSpecializedMetadataAccessorsListEntry<Runtime>>;
4042+
TargetCanonicalSpecializedMetadataAccessorsListEntry<Runtime>,
4043+
TargetCanonicalSpecializedMetadatasCachingOnceToken<Runtime>>;
40344044

40354045
using TrailingObjects =
40364046
typename TrailingGenericContextObjects::TrailingObjects;
@@ -4058,6 +4068,8 @@ class TargetClassDescriptor final
40584068
TargetRelativeDirectPointer<Runtime, MetadataResponse(MetadataRequest), /*Nullable*/ false>;
40594069
using MetadataAccessorListEntry =
40604070
TargetCanonicalSpecializedMetadataAccessorsListEntry<Runtime>;
4071+
using MetadataCachingOnceToken =
4072+
TargetCanonicalSpecializedMetadatasCachingOnceToken<Runtime>;
40614073

40624074
using StoredPointer = typename Runtime::StoredPointer;
40634075
using StoredPointerDifference = typename Runtime::StoredPointerDifference;
@@ -4195,6 +4207,10 @@ class TargetClassDescriptor final
41954207
: 0;
41964208
}
41974209

4210+
size_t numTrailingObjects(OverloadToken<MetadataCachingOnceToken>) const {
4211+
return this->hasCanonicicalMetadataPrespecializations() ? 1 : 0;
4212+
}
4213+
41984214
public:
41994215
const TargetRelativeDirectPointer<Runtime, const void, /*nullable*/true> &
42004216
getResilientSuperclass() const {
@@ -4358,6 +4374,14 @@ class TargetClassDescriptor final
43584374
);
43594375
}
43604376

4377+
swift_once_t *getCanonicalMetadataPrespecializationCachingOnceToken() const {
4378+
if (!this->hasCanonicicalMetadataPrespecializations()) {
4379+
return nullptr;
4380+
}
4381+
auto box = this->template getTrailingObjects<MetadataCachingOnceToken>();
4382+
return box->token.get();
4383+
}
4384+
43614385
static bool classof(const TargetContextDescriptor<Runtime> *cd) {
43624386
return cd->getKind() == ContextDescriptorKind::Class;
43634387
}
@@ -4385,7 +4409,8 @@ class TargetStructDescriptor final
43854409
TargetForeignMetadataInitialization<Runtime>,
43864410
TargetSingletonMetadataInitialization<Runtime>,
43874411
TargetCanonicalSpecializedMetadatasListCount<Runtime>,
4388-
TargetCanonicalSpecializedMetadatasListEntry<Runtime>> {
4412+
TargetCanonicalSpecializedMetadatasListEntry<Runtime>,
4413+
TargetCanonicalSpecializedMetadatasCachingOnceToken<Runtime>> {
43894414
public:
43904415
using ForeignMetadataInitialization =
43914416
TargetForeignMetadataInitialization<Runtime>;
@@ -4397,6 +4422,8 @@ class TargetStructDescriptor final
43974422
TargetCanonicalSpecializedMetadatasListCount<Runtime>;
43984423
using MetadataListEntry =
43994424
TargetCanonicalSpecializedMetadatasListEntry<Runtime>;
4425+
using MetadataCachingOnceToken =
4426+
TargetCanonicalSpecializedMetadatasCachingOnceToken<Runtime>;
44004427

44014428
private:
44024429
using TrailingGenericContextObjects =
@@ -4405,7 +4432,8 @@ class TargetStructDescriptor final
44054432
ForeignMetadataInitialization,
44064433
SingletonMetadataInitialization,
44074434
MetadataListCount,
4408-
MetadataListEntry>;
4435+
MetadataListEntry,
4436+
MetadataCachingOnceToken>;
44094437

44104438
using TrailingObjects =
44114439
typename TrailingGenericContextObjects::TrailingObjects;
@@ -4435,6 +4463,10 @@ class TargetStructDescriptor final
44354463
: 0;
44364464
}
44374465

4466+
size_t numTrailingObjects(OverloadToken<MetadataCachingOnceToken>) const {
4467+
return this->hasCanonicicalMetadataPrespecializations() ? 1 : 0;
4468+
}
4469+
44384470
public:
44394471
using TrailingGenericContextObjects::getGenericContext;
44404472
using TrailingGenericContextObjects::getGenericContextHeader;
@@ -4480,6 +4512,14 @@ class TargetStructDescriptor final
44804512
);
44814513
}
44824514

4515+
swift_once_t *getCanonicalMetadataPrespecializationCachingOnceToken() const {
4516+
if (!this->hasCanonicicalMetadataPrespecializations()) {
4517+
return nullptr;
4518+
}
4519+
auto box = this->template getTrailingObjects<MetadataCachingOnceToken>();
4520+
return box->token.get();
4521+
}
4522+
44834523
static bool classof(const TargetContextDescriptor<Runtime> *cd) {
44844524
return cd->getKind() == ContextDescriptorKind::Struct;
44854525
}
@@ -4496,7 +4536,8 @@ class TargetEnumDescriptor final
44964536
TargetForeignMetadataInitialization<Runtime>,
44974537
TargetSingletonMetadataInitialization<Runtime>,
44984538
TargetCanonicalSpecializedMetadatasListCount<Runtime>,
4499-
TargetCanonicalSpecializedMetadatasListEntry<Runtime>> {
4539+
TargetCanonicalSpecializedMetadatasListEntry<Runtime>,
4540+
TargetCanonicalSpecializedMetadatasCachingOnceToken<Runtime>> {
45004541
public:
45014542
using SingletonMetadataInitialization =
45024543
TargetSingletonMetadataInitialization<Runtime>;
@@ -4508,6 +4549,8 @@ class TargetEnumDescriptor final
45084549
TargetCanonicalSpecializedMetadatasListCount<Runtime>;
45094550
using MetadataListEntry =
45104551
TargetCanonicalSpecializedMetadatasListEntry<Runtime>;
4552+
using MetadataCachingOnceToken =
4553+
TargetCanonicalSpecializedMetadatasCachingOnceToken<Runtime>;
45114554

45124555
private:
45134556
using TrailingGenericContextObjects =
@@ -4516,7 +4559,8 @@ class TargetEnumDescriptor final
45164559
ForeignMetadataInitialization,
45174560
SingletonMetadataInitialization,
45184561
MetadataListCount,
4519-
MetadataListEntry>;
4562+
MetadataListEntry,
4563+
MetadataCachingOnceToken>;
45204564

45214565
using TrailingObjects =
45224566
typename TrailingGenericContextObjects::TrailingObjects;
@@ -4546,6 +4590,10 @@ class TargetEnumDescriptor final
45464590
: 0;
45474591
}
45484592

4593+
size_t numTrailingObjects(OverloadToken<MetadataCachingOnceToken>) const {
4594+
return this->hasCanonicicalMetadataPrespecializations() ? 1 : 0;
4595+
}
4596+
45494597
public:
45504598
using TrailingGenericContextObjects::getGenericContext;
45514599
using TrailingGenericContextObjects::getGenericContextHeader;
@@ -4605,6 +4653,14 @@ class TargetEnumDescriptor final
46054653
);
46064654
}
46074655

4656+
swift_once_t *getCanonicalMetadataPrespecializationCachingOnceToken() const {
4657+
if (!this->hasCanonicicalMetadataPrespecializations()) {
4658+
return nullptr;
4659+
}
4660+
auto box = this->template getTrailingObjects<MetadataCachingOnceToken>();
4661+
return box->token.get();
4662+
}
4663+
46084664
static bool classof(const TargetContextDescriptor<Runtime> *cd) {
46094665
return cd->getKind() == ContextDescriptorKind::Enum;
46104666
}
@@ -4757,6 +4813,24 @@ TargetTypeContextDescriptor<Runtime>::getCanonicicalMetadataPrespecializations()
47574813
}
47584814
}
47594815

4816+
template <typename Runtime>
4817+
inline swift_once_t *TargetTypeContextDescriptor<
4818+
Runtime>::getCanonicalMetadataPrespecializationCachingOnceToken() const {
4819+
switch (this->getKind()) {
4820+
case ContextDescriptorKind::Enum:
4821+
return llvm::cast<TargetEnumDescriptor<Runtime>>(this)
4822+
->getCanonicalMetadataPrespecializationCachingOnceToken();
4823+
case ContextDescriptorKind::Struct:
4824+
return llvm::cast<TargetStructDescriptor<Runtime>>(this)
4825+
->getCanonicalMetadataPrespecializationCachingOnceToken();
4826+
case ContextDescriptorKind::Class:
4827+
return llvm::cast<TargetClassDescriptor<Runtime>>(this)
4828+
->getCanonicalMetadataPrespecializationCachingOnceToken();
4829+
default:
4830+
swift_unreachable("Not a type context descriptor.");
4831+
}
4832+
}
4833+
47604834
/// An entry in the chain of dynamic replacement functions.
47614835
struct DynamicReplacementChainEntry {
47624836
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;

include/swift/Runtime/Metadata.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "swift/ABI/Metadata.h"
2121
#include "swift/Reflection/Records.h"
22+
#include "swift/Runtime/Once.h"
2223

2324
namespace swift {
2425

@@ -340,6 +341,31 @@ SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) MetadataResponse
340341
const Metadata *candidate,
341342
const Metadata **cache);
342343

344+
/// Fetch a uniqued metadata object for the generic nominal type described by
345+
/// the provided description and arguments, adding the canonical
346+
/// prespecializations attached to the type descriptor to the metadata cache on
347+
/// first run.
348+
///
349+
/// In contrast to swift_getGenericMetadata, this function is for use by
350+
/// metadata accessors for which canonical generic metadata has been specialized
351+
/// at compile time.
352+
///
353+
/// Runtime availability: Swift 5.4
354+
///
355+
/// \param request A specification of the metadata to be returned.
356+
/// \param arguments The generic arguments--metadata and witness tables--which
357+
/// the returned metadata is to have been instantiated with.
358+
/// \param description The type descriptor for the generic type whose
359+
/// generic metadata is to have been instantiated.
360+
/// \param token The token that ensures that prespecialized records are added to
361+
/// the metadata cache only once.
362+
/// \returns The canonical metadata for the specialized generic type described
363+
/// by the provided candidate metadata.
364+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) MetadataResponse
365+
swift_getCanonicalPrespecializedGenericMetadata(
366+
MetadataRequest request, const void *const *arguments,
367+
const TypeContextDescriptor *description, swift_once_t *token);
368+
343369
/// Fetch a uniqued metadata object for a generic nominal type.
344370
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
345371
MetadataResponse

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,18 @@ FUNCTION(GetCanonicalSpecializedMetadata, swift_getCanonicalSpecializedMetadata,
653653
ARGS(SizeTy, TypeMetadataPtrTy, TypeMetadataPtrPtrTy),
654654
ATTRS(NoUnwind, ReadOnly))
655655

656+
// MetadataResponse
657+
// swift_getCanonicalPrespecializedGenericMetadata(MetadataRequest request,
658+
// const void * const *arguments,
659+
// const TypeContextDescriptor *description,
660+
// swift_once_t *cachedFlag)
661+
FUNCTION(GetCanonicalPrespecializedGenericMetadata,
662+
swift_getCanonicalPrespecializedGenericMetadata,
663+
SwiftCC, GetCanonicalPrespecializedGenericMetadataAvailability,
664+
RETURNS(TypeMetadataResponseTy),
665+
ARGS(SizeTy, Int8PtrTy, TypeContextDescriptorPtrTy, OnceTy->getPointerTo()),
666+
ATTRS(NoUnwind, ReadOnly))
667+
656668
// MetadataResponse swift_getOpaqueTypeMetadata(MetadataRequest request,
657669
// const void * const *arguments,
658670
// const OpaqueTypeDescriptor *descriptor,

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";

0 commit comments

Comments
 (0)