Skip to content

Commit 46bba7a

Browse files
authored
Memoize the ObjCBridgeable conformance for Swift.String (#30329)
This seems to be the single most common bridge cast, and repeated lookup seems to be a performance issue for the common operation of bridging a string-valued NSDictionary into Swift. Spending a couple of static words of memory to memoize it should be a nice perf win. Resolves rdar://55237013
1 parent 04c20b8 commit 46bba7a

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

stdlib/public/runtime/Casting.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2876,10 +2876,30 @@ id _bridgeAnythingNonVerbatimToObjectiveC(OpaqueValue *src,
28762876
extern "C" const _ObjectiveCBridgeableWitnessTable BRIDGING_CONFORMANCE_SYM;
28772877
#endif
28782878

2879+
/// Nominal type descriptor for Swift.String.
2880+
extern "C" const StructDescriptor NOMINAL_TYPE_DESCR_SYM(SS);
2881+
2882+
static const _ObjectiveCBridgeableWitnessTable *
2883+
swift_conformsToObjectiveCBridgeable(const Metadata *T) {
2884+
return reinterpret_cast<const _ObjectiveCBridgeableWitnessTable *>
2885+
(swift_conformsToProtocol(T, &PROTOCOL_DESCR_SYM(s21_ObjectiveCBridgeable)));
2886+
}
2887+
28792888
static const _ObjectiveCBridgeableWitnessTable *
28802889
findBridgeWitness(const Metadata *T) {
2881-
auto w = swift_conformsToProtocol(T,
2882-
&PROTOCOL_DESCR_SYM(s21_ObjectiveCBridgeable));
2890+
// Special case: Memoize the bridge witness for Swift.String.
2891+
// Swift.String is the most heavily used bridge because of the prevalence of
2892+
// string-keyed dictionaries in Obj-C. It's worth burning a few words of static
2893+
// storage to avoid repeatedly looking up this conformance.
2894+
if (T->getKind() == MetadataKind::Struct) {
2895+
auto structDescription = cast<StructMetadata>(T)->Description;
2896+
if (structDescription == &NOMINAL_TYPE_DESCR_SYM(SS)) {
2897+
static auto *Swift_String_ObjectiveCBridgeable = swift_conformsToObjectiveCBridgeable(T);
2898+
return Swift_String_ObjectiveCBridgeable;
2899+
}
2900+
}
2901+
2902+
auto w = swift_conformsToObjectiveCBridgeable(T);
28832903
if (LLVM_LIKELY(w))
28842904
return reinterpret_cast<const _ObjectiveCBridgeableWitnessTable *>(w);
28852905
// Class and ObjC existential metatypes can be bridged, but metatypes can't

0 commit comments

Comments
 (0)