28
28
#include < dlfcn.h>
29
29
#include < mach-o/getsect.h>
30
30
31
+ #include < CoreFoundation/CFDictionary.h>
32
+
31
33
// / The "public" interface follows. All of these functions are the same
32
34
// / as the corresponding swift_reflection_* functions, except for taking
33
35
// / or returning _interop data types in some circumstances.
@@ -295,6 +297,8 @@ struct SwiftReflectionInteropContext {
295
297
296
298
struct SwiftReflectionInteropContextFreeList *FreeList;
297
299
struct SwiftReflectionInteropContextLegacyImageRangeList *LegacyImageRangeList;
300
+
301
+ CFMutableDictionaryRef AddressToLibraryCache;
298
302
};
299
303
300
304
#define FOREACH_LIBRARY \
@@ -324,30 +328,57 @@ swift_reflection_interop_libraryOwnsAddress(
324
328
return 0 ;
325
329
}
326
330
327
- static inline int
328
- swift_reflection_interop_libraryOwnsObject (
331
+ static inline struct SwiftReflectionInteropContextLibrary *
332
+ swift_reflection_interop_libraryForAddress (
329
333
struct SwiftReflectionInteropContext *ContextRef,
330
- struct SwiftReflectionInteropContextLibrary *Library,
331
- uintptr_t Object) {
332
- if (!Library->IsLegacy )
333
- return Library->Functions .ownsObject (Library->Context , Object);
334
+ uintptr_t Address) {
335
+ uintptr_t cachedIndex;
336
+ if (CFDictionaryGetValueIfPresent (ContextRef->AddressToLibraryCache ,
337
+ (void *)Address,
338
+ (const void **)&cachedIndex)) {
339
+ return &ContextRef->Libraries [cachedIndex];
340
+ }
334
341
335
- // The legacy library doesn't have this. Do it ourselves if we can. We need
336
- // metadataForObject from a non-legacy library to do it.
337
- uintptr_t Metadata = 0 ;
342
+ FOREACH_LIBRARY {
343
+ if (swift_reflection_interop_libraryOwnsAddress (ContextRef, Library, Address)) {
344
+ CFDictionarySetValue (ContextRef->AddressToLibraryCache ,
345
+ (void *)Address,
346
+ (void *)LIBRARY_INDEX);
347
+ return Library;
348
+ }
349
+ }
350
+ return NULL ;
351
+ }
352
+
353
+ static inline uintptr_t
354
+ swift_reflection_interop_metadataForObject (
355
+ struct SwiftReflectionInteropContext *ContextRef,
356
+ uintptr_t Object) {
338
357
FOREACH_LIBRARY {
339
358
if (Library->IsLegacy )
340
359
continue ;
341
-
342
- Metadata = Library->Functions .metadataForObject (Library->Context , Object);
343
- break ;
360
+ uintptr_t Metadata = Library->Functions .metadataForObject (Library->Context , Object);
361
+ if (Metadata != 0 )
362
+ return Metadata;
363
+ }
364
+ return 0 ;
365
+ }
366
+
367
+ static inline struct SwiftReflectionInteropContextLibrary *
368
+ swift_reflection_interop_libraryForObject (
369
+ struct SwiftReflectionInteropContext *ContextRef,
370
+ uintptr_t Object) {
371
+ uintptr_t Metadata = swift_reflection_interop_metadataForObject (ContextRef, Object);
372
+ if (Metadata == 0 ) {
373
+ // If we couldn't retrieve metadata, assume it belongs to a legacy library.
374
+ FOREACH_LIBRARY {
375
+ if (Library->IsLegacy )
376
+ return Library;
377
+ }
378
+ return NULL ;
344
379
}
345
380
346
- // If we couldn't retrieve metadata, assume it's ours.
347
- if (Metadata == 0 )
348
- return 1 ;
349
-
350
- return swift_reflection_interop_libraryOwnsAddress (ContextRef, Library, Metadata);
381
+ return swift_reflection_interop_libraryForAddress (ContextRef, Metadata);
351
382
}
352
383
353
384
static inline void
@@ -500,6 +531,8 @@ swift_reflection_interop_createReflectionContext(
500
531
ContextRef->GetStringLength = GetStringLength;
501
532
ContextRef->GetSymbolAddress = GetSymbolAddress;
502
533
534
+ ContextRef->AddressToLibraryCache = CFDictionaryCreateMutable (NULL , 0 , NULL , NULL );
535
+
503
536
return ContextRef;
504
537
}
505
538
@@ -525,6 +558,9 @@ swift_reflection_interop_destroyReflectionContext(
525
558
free (FreeList);
526
559
FreeList = Next;
527
560
}
561
+
562
+ CFRelease (ContextRef->AddressToLibraryCache );
563
+
528
564
free (ContextRef);
529
565
}
530
566
@@ -696,12 +732,11 @@ static inline swift_metadata_interop_t
696
732
swift_reflection_interop_lookupMetadata (SwiftReflectionInteropContextRef ContextRef,
697
733
uintptr_t Metadata) {
698
734
swift_metadata_interop_t Result = {};
699
- FOREACH_LIBRARY {
700
- if (swift_reflection_interop_libraryOwnsAddress (ContextRef, Library, Metadata)) {
701
- Result.Metadata = Metadata;
702
- Result.Library = LIBRARY_INDEX;
703
- break ;
704
- }
735
+ struct SwiftReflectionInteropContextLibrary *Library =
736
+ swift_reflection_interop_libraryForAddress (ContextRef, Metadata);
737
+ if (Library != NULL ) {
738
+ Result.Metadata = Metadata;
739
+ Result.Library = LIBRARY_INDEX;
705
740
}
706
741
return Result;
707
742
}
@@ -720,22 +755,15 @@ swift_reflection_interop_typeRefForMetadata(SwiftReflectionInteropContextRef Con
720
755
static inline swift_typeref_interop_t
721
756
swift_reflection_interop_typeRefForInstance (SwiftReflectionInteropContextRef ContextRef,
722
757
uintptr_t Object) {
723
- swift_typeref_interop_t Result;
724
- FOREACH_LIBRARY {
725
- if (! swift_reflection_interop_libraryOwnsObject ( ContextRef, Library, Object))
726
- continue ;
758
+ swift_typeref_interop_t Result = {} ;
759
+ struct SwiftReflectionInteropContextLibrary *Library
760
+ = swift_reflection_interop_libraryForObject ( ContextRef, Object);
761
+ if (Library != NULL ) {
727
762
swift_typeref_t Typeref = Library->Functions .typeRefForInstance (Library->Context ,
728
- Object);
729
- if (Typeref == 0 )
730
- continue ;
731
-
763
+ Object);
732
764
Result.Typeref = Typeref;
733
765
Result.Library = LIBRARY_INDEX;
734
- return Result;
735
766
}
736
-
737
- Result.Typeref = 0 ;
738
- Result.Library = 0 ;
739
767
return Result;
740
768
}
741
769
@@ -813,42 +841,36 @@ static inline swift_typeinfo_interop_t
813
841
swift_reflection_interop_infoForInstance (SwiftReflectionInteropContextRef ContextRef,
814
842
uintptr_t Object) {
815
843
swift_typeinfo_t Result = {};
816
- FOREACH_LIBRARY {
817
- if (! swift_reflection_interop_libraryOwnsObject ( ContextRef, Library, Object))
818
- continue ;
819
-
844
+ struct SwiftReflectionInteropContextLibrary *Library
845
+ = swift_reflection_interop_libraryForObject ( ContextRef, Object);
846
+
847
+ if (Library != NULL ) {
820
848
Result = Library->Functions .infoForInstance (Library->Context , Object);
821
- if (Result.Kind == SWIFT_UNKNOWN)
822
- continue ;
823
-
824
- return Result;
849
+ } else {
850
+ Result.Kind = SWIFT_UNKNOWN;
825
851
}
826
852
827
- Result.Kind = SWIFT_UNKNOWN;
828
853
return Result;
829
854
}
830
855
831
856
static inline swift_childinfo_interop_t
832
857
swift_reflection_interop_childOfInstance (SwiftReflectionInteropContextRef ContextRef,
833
858
uintptr_t Object,
834
859
unsigned Index) {
835
- FOREACH_LIBRARY {
836
- if (! swift_reflection_interop_libraryOwnsObject (ContextRef, Library, Object))
837
- continue ;
838
-
860
+ swift_childinfo_interop_t Result = {};
861
+ struct SwiftReflectionInteropContextLibrary * Library
862
+ = swift_reflection_interop_libraryForObject (ContextRef, Object) ;
863
+ if (Library != NULL ) {
839
864
swift_childinfo_t LibResult = Library->Functions .childOfInstance (Library->Context ,
840
865
Object, Index);
841
- swift_childinfo_interop_t Result;
842
866
Result.Name = LibResult.Name ;
843
867
Result.Offset = LibResult.Offset ;
844
868
Result.Kind = LibResult.Kind ;
845
869
Result.TR .Typeref = LibResult.TR ;
846
870
Result.TR .Library = LIBRARY_INDEX;
847
- return Result;
871
+ } else {
872
+ Result.Kind = SWIFT_UNKNOWN;
848
873
}
849
-
850
- swift_childinfo_interop_t Result = {};
851
- Result.Kind = SWIFT_UNKNOWN;
852
874
return Result;
853
875
}
854
876
@@ -914,12 +936,10 @@ swift_reflection_interop_dumpInfoForMetadata(SwiftReflectionInteropContextRef Co
914
936
static inline void
915
937
swift_reflection_interop_dumpInfoForInstance (SwiftReflectionInteropContextRef ContextRef,
916
938
uintptr_t Object) {
917
- FOREACH_LIBRARY {
918
- if (!swift_reflection_interop_libraryOwnsObject (ContextRef, Library, Object))
919
- continue ;
920
-
939
+ struct SwiftReflectionInteropContextLibrary *Library
940
+ = swift_reflection_interop_libraryForObject (ContextRef, Object);
941
+ if (Library != NULL ) {
921
942
Library->Functions .dumpInfoForInstance (Library->Context , Object);
922
- return ;
923
943
}
924
944
}
925
945
0 commit comments