[K/N] Handle permanent objects in new MM MemorySharedRefs ^KT-56233

Do not create a foreign ref to the permanent objects. There's no need to
do it, and, moreover, this ref would have leaked.
This commit is contained in:
Alexander Shabalin
2023-03-31 16:55:29 +02:00
committed by Space Team
parent 1f1b26f2a5
commit 8a8aeed998
4 changed files with 35 additions and 4 deletions
@@ -104,6 +104,10 @@ void KRefSharedHolder::dispose() {
DeinitForeignRef(obj_, context_);
}
void BackRefFromAssociatedObject::initForPermanentObject(ObjHeader* obj) {
initAndAddRef(obj);
}
void BackRefFromAssociatedObject::initAndAddRef(ObjHeader* obj) {
RuntimeAssert(obj != nullptr, "must not be null");
obj_ = obj;
@@ -198,3 +202,7 @@ ObjHeader* BackRefFromAssociatedObject::ref() const {
template ObjHeader* BackRefFromAssociatedObject::ref<ErrorPolicy::kDefaultValue>() const;
template ObjHeader* BackRefFromAssociatedObject::ref<ErrorPolicy::kThrow>() const;
template ObjHeader* BackRefFromAssociatedObject::ref<ErrorPolicy::kTerminate>() const;
ObjHeader* BackRefFromAssociatedObject::refPermanent() const {
return ref<ErrorPolicy::kIgnore>();
}
@@ -46,6 +46,7 @@ static_assert(std::is_trivially_destructible_v<KRefSharedHolder>, "KRefSharedHol
class BackRefFromAssociatedObject {
public:
void initForPermanentObject(ObjHeader* obj);
void initAndAddRef(ObjHeader* obj);
// Error if refCount is zero and it's called from the wrong worker with non-frozen obj_.
@@ -65,6 +66,8 @@ class BackRefFromAssociatedObject {
template <ErrorPolicy errorPolicy>
ObjHeader* ref() const;
ObjHeader* refPermanent() const;
private:
ObjHeader* obj_; // May be null before [initAndAddRef] or after [detach].
ForeignRefContext context_;
@@ -41,8 +41,15 @@ void KRefSharedHolder::dispose() {
DeinitForeignRef(obj_, context_);
}
void BackRefFromAssociatedObject::initForPermanentObject(ObjHeader* obj) {
RuntimeAssert(obj != nullptr, "must not be null");
RuntimeAssert(obj->permanent(), "Can only be called with permanent object");
obj_ = obj;
}
void BackRefFromAssociatedObject::initAndAddRef(ObjHeader* obj) {
RuntimeAssert(obj != nullptr, "must not be null");
RuntimeAssert(!obj->permanent(), "Can only be called with non-permanent object");
obj_ = obj;
// Generally a specialized addRef below:
@@ -126,3 +133,7 @@ ObjHeader* BackRefFromAssociatedObject::ref() const {
template ObjHeader* BackRefFromAssociatedObject::ref<ErrorPolicy::kDefaultValue>() const;
template ObjHeader* BackRefFromAssociatedObject::ref<ErrorPolicy::kThrow>() const;
template ObjHeader* BackRefFromAssociatedObject::ref<ErrorPolicy::kTerminate>() const;
ObjHeader* BackRefFromAssociatedObject::refPermanent() const {
return obj_;
}
@@ -42,7 +42,11 @@ static void injectToRuntime();
}
-(KRef)toKotlin:(KRef*)OBJ_RESULT {
RETURN_OBJ(refHolder.ref<ErrorPolicy::kTerminate>());
if (permanent) {
RETURN_OBJ(refHolder.refPermanent());
} else {
RETURN_OBJ(refHolder.ref<ErrorPolicy::kTerminate>());
}
}
+(void)load {
@@ -88,10 +92,11 @@ static void injectToRuntime();
KotlinBase* candidate = [super allocWithZone:nil];
// TODO: should we call NSObject.init ?
candidate->refHolder.initAndAddRef(obj);
candidate->permanent = obj->permanent();
bool permanent = obj->permanent();
candidate->permanent = permanent;
if (!obj->permanent()) { // TODO: permanent objects should probably be supported as custom types.
if (!permanent) { // TODO: permanent objects should probably be supported as custom types.
candidate->refHolder.initAndAddRef(obj);
if (!isShareable(obj)) {
SetAssociatedObject(obj, candidate);
} else {
@@ -105,6 +110,8 @@ static void injectToRuntime();
return objc_retain(old);
}
}
} else {
candidate->refHolder.initForPermanentObject(obj);
}
return candidate;
@@ -136,6 +143,8 @@ static void injectToRuntime();
}
-(void)releaseAsAssociatedObject:(ReleaseMode)mode {
RuntimeAssert(!permanent, "Cannot be called on permanent objects");
// This function is called by the GC. It made a decision to reclaim Kotlin object, and runs
// deallocation hooks at the moment, including deallocation of the "associated object" ([self])
// using the [super release] call below.