Native, old MM: fix releasing foreign refs to circular frozen graphs

^KT-49497
This commit is contained in:
Svyatoslav Scherbina
2021-12-10 10:09:49 +03:00
committed by Space
parent b82c306530
commit 2bd53e3dea
6 changed files with 74 additions and 4 deletions
@@ -2433,6 +2433,13 @@ __attribute__((swift_name("TestRememberNewObject")))
- (void)waitForCleanup __attribute__((swift_name("waitForCleanup()")));
@end;
__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("KT49497Model")))
@interface KtKT49497Model : KtBase
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
@end;
__attribute__((swift_name("ClassForTypeCheck")))
@interface KtClassForTypeCheck : KtBase
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
@@ -2375,6 +2375,13 @@ __attribute__((swift_name("TestRememberNewObject")))
- (void)waitForCleanup __attribute__((swift_name("waitForCleanup()")));
@end;
__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("KT49497Model")))
@interface KtKT49497Model : KtBase
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
@end;
__attribute__((swift_name("ClassForTypeCheck")))
@interface KtClassForTypeCheck : KtBase
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
@@ -2375,6 +2375,13 @@ __attribute__((swift_name("TestRememberNewObject")))
- (void)waitForCleanup __attribute__((swift_name("waitForCleanup()")));
@end;
__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("KT49497Model")))
@interface KtKT49497Model : KtBase
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
@end;
__attribute__((swift_name("ClassForTypeCheck")))
@interface KtClassForTypeCheck : KtBase
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
@@ -896,6 +896,17 @@ fun testRememberNewObject(test: TestRememberNewObject) {
assertNotEquals("", obj.toString()) // Likely crashes if object is removed.
}
class KT49497Model {
private class SelfRef(val self: KT49497Model)
// Wrapping `this` to make the strongly connected component non-trival, just in case:
private val selfRef = SelfRef(this)
init {
freeze()
}
}
open class ClassForTypeCheck
fun testClassTypeCheck(x: Any) = x is ClassForTypeCheck
@@ -1123,6 +1123,24 @@ class TestSharedRefs {
try assertFalse(refs.hasAliveObjects())
}
// Based on https://youtrack.jetbrains.com/issue/KT-49497.
func testKT49497() throws {
var model: KT49497Model? = nil
for i in 1...10 {
model = KT49497Model() // Frozen and has a reference to itself, so becomes aggregating frozen container.
ValuesKt.gc() // Just in case, to ensure there are no other references except `model`.
runInNewThread(initializeKotlinRuntime: false) {
// Thread has no runtime initialized, so this should enqueue release ref to the original thread:
model = nil
}
ValuesKt.gc() // Process the enqueued release ref.
}
}
func test() throws {
try testLambdaSimple()
try testObjectPartialRelease()
@@ -1144,6 +1162,8 @@ class TestSharedRefs {
try testRememberNewObject(createObject: { $0.createFrozenCollection() })
#endif
try testKT49497()
usleep(300 * 1000)
}
}