From e5e164846219c942d090c123e6b64c19e094fd19 Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Wed, 7 Oct 2020 14:40:28 +0300 Subject: [PATCH] Keep permanent flag in KotlinBase instead of requesting from the object This works better when the object becomes invalid --- .../kotlin/backend/konan/llvm/objc/linkObjC.kt | 2 +- runtime/src/main/cpp/MemorySharedRefs.hpp | 4 ---- runtime/src/objc/cpp/ObjCExportClasses.mm | 10 +++++++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/linkObjC.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/linkObjC.kt index 13fa16b387f..6240faaa294 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/linkObjC.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/linkObjC.kt @@ -121,7 +121,7 @@ private fun PatchBuilder.addObjCPatches() { addPrivateCategory("NSDictionaryToKotlin") addPrivateCategory("NSEnumeratorAsAssociatedObject") - addExportedClass(objCExportNamer.kotlinAnyName, "KotlinBase", "refHolder") + addExportedClass(objCExportNamer.kotlinAnyName, "KotlinBase", "refHolder", "permanent") addExportedClass(objCExportNamer.mutableSetName, "KotlinMutableSet", "setHolder") addExportedClass(objCExportNamer.mutableMapName, "KotlinMutableDictionary", "mapHolder") diff --git a/runtime/src/main/cpp/MemorySharedRefs.hpp b/runtime/src/main/cpp/MemorySharedRefs.hpp index cc634b0d5ee..f81a6945f40 100644 --- a/runtime/src/main/cpp/MemorySharedRefs.hpp +++ b/runtime/src/main/cpp/MemorySharedRefs.hpp @@ -58,10 +58,6 @@ class BackRefFromAssociatedObject { template ObjHeader* ref() const; - inline bool permanent() const { - return obj_->permanent(); // Safe to query from any thread. - } - private: ObjHeader* obj_; ForeignRefContext context_; diff --git a/runtime/src/objc/cpp/ObjCExportClasses.mm b/runtime/src/objc/cpp/ObjCExportClasses.mm index cdadd6dac97..ff38fd4f6ed 100644 --- a/runtime/src/objc/cpp/ObjCExportClasses.mm +++ b/runtime/src/objc/cpp/ObjCExportClasses.mm @@ -42,6 +42,7 @@ static void injectToRuntime(); @implementation KotlinBase { BackRefFromAssociatedObject refHolder; + bool permanent; } -(KRef)toKotlin:(KRef*)OBJ_RESULT { @@ -79,6 +80,8 @@ static void injectToRuntime(); ObjHolder holder; AllocInstanceWithAssociatedObject(typeInfo, result, holder.slot()); result->refHolder.initAndAddRef(holder.obj()); + RuntimeAssert(!holder.obj()->permanent(), "dynamically allocated object is permanent"); + result->permanent = false; return result; } @@ -86,6 +89,7 @@ static void injectToRuntime(); KotlinBase* candidate = [super allocWithZone:nil]; // TODO: should we call NSObject.init ? candidate->refHolder.initAndAddRef(obj); + candidate->permanent = obj->permanent(); if (!obj->permanent()) { // TODO: permanent objects should probably be supported as custom types. if (!obj->container()->shareable()) { @@ -104,7 +108,7 @@ static void injectToRuntime(); } -(instancetype)retain { - if (refHolder.permanent()) { // TODO: consider storing `isPermanent` to self field. + if (permanent) { [super retain]; } else { refHolder.addRef(); @@ -113,7 +117,7 @@ static void injectToRuntime(); } -(BOOL)_tryRetain { - if (refHolder.permanent()) { + if (permanent) { return [super _tryRetain]; } else { return refHolder.tryAddRef(); @@ -121,7 +125,7 @@ static void injectToRuntime(); } -(oneway void)release { - if (refHolder.permanent()) { + if (permanent) { [super release]; } else { refHolder.releaseRef();