Skip to content

Commit b7d7159

Browse files
committed
[Runtime] Support lazy ObjC realization of Swift classes.
When the ObjC runtime indicates that it supports lazy realization, avoid forcing realization of classes while setting them up. This saves time and memory for classes that never touch the parts of the ObjC runtime that trigger realization rdar://136102084
1 parent 0bd4e4e commit b7d7159

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

stdlib/public/runtime/SwiftObject.mm

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,12 +1377,25 @@ id swift_dynamicCastObjCProtocolConditional(id object,
13771377
return object;
13781378
}
13791379

1380+
// Check whether the current ObjC runtime supports lazy realization. If it does,
1381+
// then we can avoid forcing realization of classes before we use them.
1382+
static bool objcSupportsLazyRealization() {
1383+
#if OBJC_SUPPORTSLAZYREALIZATION_DEFINED
1384+
return SWIFT_LAZY_CONSTANT(_objc_supportsLazyRealization());
1385+
#else
1386+
return false;
1387+
#endif
1388+
}
1389+
13801390
void swift::swift_instantiateObjCClass(const ClassMetadata *_c) {
13811391
static const objc_image_info ImageInfo = {0, 0};
13821392

1383-
// Ensure the superclass is realized.
13841393
Class c = class_const_cast(_c);
1385-
[class_getSuperclass(c) class];
1394+
1395+
if (!objcSupportsLazyRealization()) {
1396+
// Ensure the superclass is realized.
1397+
[class_getSuperclass(c) class];
1398+
}
13861399

13871400
// Register the class.
13881401
Class registered = objc_readClassPair(c, &ImageInfo);
@@ -1392,14 +1405,16 @@ id swift_dynamicCastObjCProtocolConditional(id object,
13921405
}
13931406

13941407
Class swift::swift_getInitializedObjCClass(Class c) {
1395-
// Used when we have class metadata and we want to ensure a class has been
1396-
// initialized by the Objective-C runtime. We need to do this because the
1397-
// class "c" might be valid metadata, but it hasn't been initialized yet.
1398-
// Send a message that's likely not to be overridden to minimize potential
1399-
// side effects. Ignore the return value in case it is overridden to
1400-
// return something different. See
1401-
// https://github.com/apple/swift/issues/52863 for an example.
1402-
[c self];
1408+
if (!objcSupportsLazyRealization()) {
1409+
// Used when we have class metadata and we want to ensure a class has been
1410+
// initialized by the Objective-C runtime. We need to do this because the
1411+
// class "c" might be valid metadata, but it hasn't been initialized yet.
1412+
// Send a message that's likely not to be overridden to minimize potential
1413+
// side effects. Ignore the return value in case it is overridden to
1414+
// return something different. See
1415+
// https://github.com/apple/swift/issues/52863 for an example.
1416+
[c self];
1417+
}
14031418
return c;
14041419
}
14051420

0 commit comments

Comments
 (0)