Skip to content

Commit ef863ab

Browse files
committed
[RemoteMirrors] Have interop header cache address->library lookups.
rdar://problem/37538580
1 parent cdf890b commit ef863ab

File tree

1 file changed

+78
-58
lines changed

1 file changed

+78
-58
lines changed

include/swift/SwiftRemoteMirror/SwiftRemoteMirrorLegacyInterop.h

Lines changed: 78 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include <dlfcn.h>
2929
#include <mach-o/getsect.h>
3030

31+
#include <CoreFoundation/CFDictionary.h>
32+
3133
/// The "public" interface follows. All of these functions are the same
3234
/// as the corresponding swift_reflection_* functions, except for taking
3335
/// or returning _interop data types in some circumstances.
@@ -295,6 +297,8 @@ struct SwiftReflectionInteropContext {
295297

296298
struct SwiftReflectionInteropContextFreeList *FreeList;
297299
struct SwiftReflectionInteropContextLegacyImageRangeList *LegacyImageRangeList;
300+
301+
CFMutableDictionaryRef AddressToLibraryCache;
298302
};
299303

300304
#define FOREACH_LIBRARY \
@@ -324,30 +328,57 @@ swift_reflection_interop_libraryOwnsAddress(
324328
return 0;
325329
}
326330

327-
static inline int
328-
swift_reflection_interop_libraryOwnsObject(
331+
static inline struct SwiftReflectionInteropContextLibrary *
332+
swift_reflection_interop_libraryForAddress(
329333
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+
}
334341

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) {
338357
FOREACH_LIBRARY {
339358
if (Library->IsLegacy)
340359
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;
344379
}
345380

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);
351382
}
352383

353384
static inline void
@@ -500,6 +531,8 @@ swift_reflection_interop_createReflectionContext(
500531
ContextRef->GetStringLength = GetStringLength;
501532
ContextRef->GetSymbolAddress = GetSymbolAddress;
502533

534+
ContextRef->AddressToLibraryCache = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
535+
503536
return ContextRef;
504537
}
505538

@@ -525,6 +558,9 @@ swift_reflection_interop_destroyReflectionContext(
525558
free(FreeList);
526559
FreeList = Next;
527560
}
561+
562+
CFRelease(ContextRef->AddressToLibraryCache);
563+
528564
free(ContextRef);
529565
}
530566

@@ -696,12 +732,11 @@ static inline swift_metadata_interop_t
696732
swift_reflection_interop_lookupMetadata(SwiftReflectionInteropContextRef ContextRef,
697733
uintptr_t Metadata) {
698734
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;
705740
}
706741
return Result;
707742
}
@@ -720,22 +755,15 @@ swift_reflection_interop_typeRefForMetadata(SwiftReflectionInteropContextRef Con
720755
static inline swift_typeref_interop_t
721756
swift_reflection_interop_typeRefForInstance(SwiftReflectionInteropContextRef ContextRef,
722757
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) {
727762
swift_typeref_t Typeref = Library->Functions.typeRefForInstance(Library->Context,
728-
Object);
729-
if (Typeref == 0)
730-
continue;
731-
763+
Object);
732764
Result.Typeref = Typeref;
733765
Result.Library = LIBRARY_INDEX;
734-
return Result;
735766
}
736-
737-
Result.Typeref = 0;
738-
Result.Library = 0;
739767
return Result;
740768
}
741769

@@ -813,42 +841,36 @@ static inline swift_typeinfo_interop_t
813841
swift_reflection_interop_infoForInstance(SwiftReflectionInteropContextRef ContextRef,
814842
uintptr_t Object) {
815843
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) {
820848
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;
825851
}
826852

827-
Result.Kind = SWIFT_UNKNOWN;
828853
return Result;
829854
}
830855

831856
static inline swift_childinfo_interop_t
832857
swift_reflection_interop_childOfInstance(SwiftReflectionInteropContextRef ContextRef,
833858
uintptr_t Object,
834859
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) {
839864
swift_childinfo_t LibResult = Library->Functions.childOfInstance(Library->Context,
840865
Object, Index);
841-
swift_childinfo_interop_t Result;
842866
Result.Name = LibResult.Name;
843867
Result.Offset = LibResult.Offset;
844868
Result.Kind = LibResult.Kind;
845869
Result.TR.Typeref = LibResult.TR;
846870
Result.TR.Library = LIBRARY_INDEX;
847-
return Result;
871+
} else {
872+
Result.Kind = SWIFT_UNKNOWN;
848873
}
849-
850-
swift_childinfo_interop_t Result = {};
851-
Result.Kind = SWIFT_UNKNOWN;
852874
return Result;
853875
}
854876

@@ -914,12 +936,10 @@ swift_reflection_interop_dumpInfoForMetadata(SwiftReflectionInteropContextRef Co
914936
static inline void
915937
swift_reflection_interop_dumpInfoForInstance(SwiftReflectionInteropContextRef ContextRef,
916938
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) {
921942
Library->Functions.dumpInfoForInstance(Library->Context, Object);
922-
return;
923943
}
924944
}
925945

0 commit comments

Comments
 (0)