@@ -706,24 +706,13 @@ swift::swift_allocateGenericValueMetadata(const ValueTypeDescriptor *description
706
706
return metadata;
707
707
}
708
708
709
- MetadataResponse swift::swift_getCanonicalSpecializedMetadata (
710
- MetadataRequest request, const Metadata *candidate,
711
- const Metadata **cacheMetadataPtr) {
712
- assert (candidate->isStaticallySpecializedGenericMetadata () &&
713
- !candidate->isCanonicalStaticallySpecializedGenericMetadata ());
714
- auto *description = candidate->getDescription ();
715
- assert (description);
716
-
717
- using CachedMetadata = std::atomic<const Metadata *>;
718
- auto cachedMetadataAddr = ((CachedMetadata *)cacheMetadataPtr);
719
- auto *cachedMetadata = cachedMetadataAddr->load (SWIFT_MEMORY_ORDER_CONSUME);
720
- if (SWIFT_LIKELY (cachedMetadata != nullptr )) {
721
- // Cached metadata pointers are always complete.
722
- return MetadataResponse{(const Metadata *)cachedMetadata,
723
- MetadataState::Complete};
724
- }
725
-
709
+ // Look into the canonical prespecialized metadata attached to the type
710
+ // descriptor and add them to the metadata cache.
711
+ static void
712
+ _cacheCanonicalSpecializedMetadata (const TypeContextDescriptor *description) {
726
713
auto &cache = getCache (*description);
714
+ auto request =
715
+ MetadataRequest (MetadataState::Complete, /* isNonBlocking*/ true );
727
716
assert (description->getFullGenericContextHeader ().Base .NumKeyArguments ==
728
717
cache.NumKeyParameters + cache.NumWitnessTables );
729
718
if (auto *classDescription = dyn_cast<ClassDescriptor>(description)) {
@@ -753,8 +742,47 @@ MetadataResponse swift::swift_getCanonicalSpecializedMetadata(
753
742
assert (result.second .Value == canonicalMetadata);
754
743
}
755
744
}
745
+ }
746
+
747
+ static void
748
+ cacheCanonicalSpecializedMetadata (const TypeContextDescriptor *description,
749
+ swift_once_t *token) {
750
+ swift_once (
751
+ token,
752
+ [](void *uncastDescription) {
753
+ auto *description = (const TypeContextDescriptor *)uncastDescription;
754
+ _cacheCanonicalSpecializedMetadata (description);
755
+ },
756
+ (void *)description);
757
+ }
758
+
759
+ MetadataResponse swift::swift_getCanonicalSpecializedMetadata (
760
+ MetadataRequest request, const Metadata *candidate,
761
+ const Metadata **cacheMetadataPtr) {
762
+ assert (candidate->isStaticallySpecializedGenericMetadata () &&
763
+ !candidate->isCanonicalStaticallySpecializedGenericMetadata ());
764
+ auto *description = candidate->getDescription ();
765
+ assert (description);
766
+
767
+ using CachedMetadata = std::atomic<const Metadata *>;
768
+ auto cachedMetadataAddr = ((CachedMetadata *)cacheMetadataPtr);
769
+ auto *cachedMetadata = cachedMetadataAddr->load (SWIFT_MEMORY_ORDER_CONSUME);
770
+ if (SWIFT_LIKELY (cachedMetadata != nullptr )) {
771
+ // Cached metadata pointers are always complete.
772
+ return MetadataResponse{(const Metadata *)cachedMetadata,
773
+ MetadataState::Complete};
774
+ }
775
+
776
+ if (auto *token =
777
+ description
778
+ ->getCanonicalMetadataPrespecializationCachingOnceToken ()) {
779
+ cacheCanonicalSpecializedMetadata (description, token);
780
+ // NOTE: If there is no token, then there are no canonical prespecialized
781
+ // metadata records, either.
782
+ }
756
783
const void *const *arguments =
757
784
reinterpret_cast <const void *const *>(candidate->getGenericArgs ());
785
+ auto &cache = getCache (*description);
758
786
auto key = MetadataCacheKey (cache.NumKeyParameters , cache.NumWitnessTables ,
759
787
arguments);
760
788
auto result = cache.getOrInsert (key, request, candidate);
@@ -764,64 +792,38 @@ MetadataResponse swift::swift_getCanonicalSpecializedMetadata(
764
792
return result.second ;
765
793
}
766
794
767
- // Look into the canonical prespecialized metadata attached to the type
768
- // descriptor and return matching records, if any.
769
- static Metadata *
770
- findCanonicalSpecializedMetadata (MetadataRequest request,
771
- const void *const *arguments,
772
- const TypeContextDescriptor *description) {
795
+ SWIFT_CC (swift)
796
+ static MetadataResponse
797
+ _swift_getGenericMetadata(MetadataRequest request, const void *const *arguments,
798
+ const TypeContextDescriptor *description) {
773
799
auto &cache = getCache (*description);
800
+ assert (description->getFullGenericContextHeader ().Base .NumKeyArguments ==
801
+ cache.NumKeyParameters + cache.NumWitnessTables );
774
802
auto key = MetadataCacheKey (cache.NumKeyParameters , cache.NumWitnessTables ,
775
803
arguments);
776
- auto prespecializedMetadatas =
777
- description->getCanonicicalMetadataPrespecializations ();
778
- int index = 0 ;
779
- for (auto &prespecializedMetadataPtr : prespecializedMetadatas) {
780
- Metadata *prespecializationMetadata = prespecializedMetadataPtr.get ();
781
- const void *const *prespecializationArguments =
782
- reinterpret_cast <const void *const *>(
783
- prespecializationMetadata->getGenericArgs ());
784
- auto prespecializationKey =
785
- MetadataCacheKey (cache.NumKeyParameters , cache.NumWitnessTables ,
786
- prespecializationArguments);
787
- if (key == prespecializationKey) {
788
- if (auto *classDescription = dyn_cast<ClassDescriptor>(description)) {
789
- auto canonicalMetadataAccessors =
790
- classDescription->getCanonicalMetadataPrespecializationAccessors ();
791
- auto &canonicalMetadataAccessorPtr = canonicalMetadataAccessors[index];
792
- auto *canonicalMetadataAccessor = canonicalMetadataAccessorPtr.get ();
793
- auto response = canonicalMetadataAccessor (request);
794
- return const_cast <Metadata *>(response.Value );
795
- } else {
796
- return prespecializationMetadata;
797
- }
798
- }
799
- ++index;
800
- }
801
- return nullptr ;
804
+ auto result = cache.getOrInsert (key, request, description, arguments);
805
+
806
+ return result.second ;
802
807
}
803
808
804
809
// / The primary entrypoint.
805
810
MetadataResponse
806
811
swift::swift_getGenericMetadata (MetadataRequest request,
807
- const void * const *arguments,
812
+ const void *const *arguments,
808
813
const TypeContextDescriptor *description) {
809
- description = swift_auth_data_non_address (description, SpecialPointerAuthDiscriminators::TypeDescriptor);
810
- if (auto *prespecialization =
811
- findCanonicalSpecializedMetadata (request, arguments, description)) {
812
- return {prespecialization, MetadataState::Complete};
813
- }
814
- auto &cache = getCache (*description);
815
- assert (description->getFullGenericContextHeader ().Base .NumKeyArguments ==
816
- cache.NumKeyParameters + cache.NumWitnessTables );
817
- auto key = MetadataCacheKey (cache.NumKeyParameters , cache.NumWitnessTables ,
818
- arguments);
819
- auto result = cache.getOrInsert (key, request, description, arguments);
814
+ description = swift_auth_data_non_address (
815
+ description, SpecialPointerAuthDiscriminators::TypeDescriptor);
816
+ return _swift_getGenericMetadata (request, arguments, description);
817
+ }
820
818
821
- assert (
822
- !result.second .Value ->isCanonicalStaticallySpecializedGenericMetadata ());
819
+ MetadataResponse swift::swift_getCanonicalPrespecializedGenericMetadata (
820
+ MetadataRequest request, const void *const *arguments,
821
+ const TypeContextDescriptor *description, swift_once_t *token) {
822
+ description = swift_auth_data_non_address (
823
+ description, SpecialPointerAuthDiscriminators::TypeDescriptor);
824
+ cacheCanonicalSpecializedMetadata (description, token);
823
825
824
- return result. second ;
826
+ return _swift_getGenericMetadata (request, arguments, description) ;
825
827
}
826
828
827
829
/* **************************************************************************/
0 commit comments