@@ -389,7 +389,35 @@ namespace {
389
389
};
390
390
391
391
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
393
421
394
422
// / Fetch the metadata cache for a generic metadata structure.
395
423
static GenericMetadataCache &getCache (
@@ -401,6 +429,11 @@ static GenericMetadataCache &getCache(
401
429
sizeof (GenericMetadataInstantiationCache::PrivateData),
402
430
" metadata cache is larger than the allowed space" );
403
431
432
+ auto *cacheStorage = generics.getInstantiationCache ();
433
+ if (cacheStorage == nullptr ) {
434
+ return GlobalMetadataCache.getOrInsert (&description).first ->Cache ;
435
+ }
436
+
404
437
auto lazyCache =
405
438
reinterpret_cast <LazyGenericMetadataCache*>(
406
439
generics.getInstantiationCache ()->PrivateData );
@@ -4606,19 +4639,50 @@ class WitnessTableCacheEntry :
4606
4639
const void * const *instantiationArgs);
4607
4640
};
4608
4641
4609
- } // end anonymous namespace
4610
-
4611
4642
using GenericWitnessTableCache =
4612
4643
MetadataCache<WitnessTableCacheEntry, GenericWitnessTableCacheTag>;
4613
4644
using LazyGenericWitnessTableCache = Lazy<GenericWitnessTableCache>;
4614
4645
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
+
4615
4675
// / Fetch the cache for a generic witness-table structure.
4616
4676
static GenericWitnessTableCache &getCache (const GenericWitnessTable *gen) {
4617
4677
// Keep this assert even if you change the representation above.
4618
4678
static_assert (sizeof (LazyGenericWitnessTableCache) <=
4619
4679
sizeof (GenericWitnessTable::PrivateDataType),
4620
4680
" metadata cache is larger than the allowed space" );
4621
4681
4682
+ if (gen->PrivateData == nullptr ) {
4683
+ return GlobalWitnessTableCache.getOrInsert (gen).first ->Cache ;
4684
+ }
4685
+
4622
4686
auto lazyCache =
4623
4687
reinterpret_cast <LazyGenericWitnessTableCache*>(gen->PrivateData .get ());
4624
4688
return lazyCache->get ();
0 commit comments