@@ -389,7 +389,35 @@ namespace {
389389 };
390390
391391 using LazyGenericMetadataCache = Lazy<GenericMetadataCache>;
392- }
392+
393+ class GlobalMetadataCacheEntry {
394+ public:
395+ const TypeContextDescriptor *Description;
396+ GenericMetadataCache Cache;
397+
398+ GlobalMetadataCacheEntry (const TypeContextDescriptor *description)
399+ : Description(description), Cache(*description->getGenericContext ()) {}
400+
401+ intptr_t getKeyIntValueForDump () {
402+ return reinterpret_cast <intptr_t >(Description);
403+ }
404+ bool matchesKey (const TypeContextDescriptor *description) const {
405+ return description == Description;
406+ }
407+ friend llvm::hash_code hash_value (const GlobalMetadataCacheEntry &value) {
408+ return llvm::hash_value (value.Description );
409+ }
410+ static size_t
411+ getExtraAllocationSize (const TypeContextDescriptor *description) {
412+ return 0 ;
413+ }
414+ size_t getExtraAllocationSize () const { return 0 ; }
415+ };
416+
417+ static SimpleGlobalCache<GlobalMetadataCacheEntry, GlobalMetadataCacheTag>
418+ GlobalMetadataCache;
419+
420+ } // end anonymous namespace
393421
394422// / Fetch the metadata cache for a generic metadata structure.
395423static GenericMetadataCache &getCache (
@@ -401,6 +429,11 @@ static GenericMetadataCache &getCache(
401429 sizeof (GenericMetadataInstantiationCache::PrivateData),
402430 " metadata cache is larger than the allowed space" );
403431
432+ auto *cacheStorage = generics.getInstantiationCache ();
433+ if (cacheStorage == nullptr ) {
434+ return GlobalMetadataCache.getOrInsert (&description).first ->Cache ;
435+ }
436+
404437 auto lazyCache =
405438 reinterpret_cast <LazyGenericMetadataCache*>(
406439 generics.getInstantiationCache ()->PrivateData );
@@ -4606,19 +4639,50 @@ class WitnessTableCacheEntry :
46064639 const void * const *instantiationArgs);
46074640};
46084641
4609- } // end anonymous namespace
4610-
46114642using GenericWitnessTableCache =
46124643 MetadataCache<WitnessTableCacheEntry, GenericWitnessTableCacheTag>;
46134644using LazyGenericWitnessTableCache = Lazy<GenericWitnessTableCache>;
46144645
4646+ class GlobalWitnessTableCacheEntry {
4647+ public:
4648+ const GenericWitnessTable *Gen;
4649+ GenericWitnessTableCache Cache;
4650+
4651+ GlobalWitnessTableCacheEntry (const GenericWitnessTable *gen)
4652+ : Gen(gen), Cache() {}
4653+
4654+ intptr_t getKeyIntValueForDump () {
4655+ return reinterpret_cast <intptr_t >(Gen);
4656+ }
4657+ bool matchesKey (const GenericWitnessTable *gen) const {
4658+ return gen == Gen;
4659+ }
4660+ friend llvm::hash_code hash_value (const GlobalWitnessTableCacheEntry &value) {
4661+ return llvm::hash_value (value.Gen );
4662+ }
4663+ static size_t
4664+ getExtraAllocationSize (const GenericWitnessTable *gen) {
4665+ return 0 ;
4666+ }
4667+ size_t getExtraAllocationSize () const { return 0 ; }
4668+ };
4669+
4670+ static SimpleGlobalCache<GlobalWitnessTableCacheEntry, GlobalWitnessTableCacheTag>
4671+ GlobalWitnessTableCache;
4672+
4673+ } // end anonymous namespace
4674+
46154675// / Fetch the cache for a generic witness-table structure.
46164676static GenericWitnessTableCache &getCache (const GenericWitnessTable *gen) {
46174677 // Keep this assert even if you change the representation above.
46184678 static_assert (sizeof (LazyGenericWitnessTableCache) <=
46194679 sizeof (GenericWitnessTable::PrivateDataType),
46204680 " metadata cache is larger than the allowed space" );
46214681
4682+ if (gen->PrivateData == nullptr ) {
4683+ return GlobalWitnessTableCache.getOrInsert (gen).first ->Cache ;
4684+ }
4685+
46224686 auto lazyCache =
46234687 reinterpret_cast <LazyGenericWitnessTableCache*>(gen->PrivateData .get ());
46244688 return lazyCache->get ();
0 commit comments