Native: don't dispatch release for null Obj-C refs to the main thread
Currently, if a Kotlin object happens to have null for an associated object but FLAGS_RELEASE_ON_MAIN_QUEUE flag set, GC will dispatch Kotlin_ObjCExport_releaseAssociatedObject(null) to the main thread anyway. This couldn't happen before, but can now, with disposeObjCObject. The commit prevents this, by moving the null check out from Kotlin_ObjCExport_releaseAssociatedObject to call sites. ^KT-59134
This commit is contained in:
committed by
Space Team
parent
1bf3d55bdf
commit
063e7258ee
@@ -3085,7 +3085,9 @@ void ObjHeader::destroyMetaObject(ObjHeader* object) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef KONAN_OBJC_INTEROP
|
#ifdef KONAN_OBJC_INTEROP
|
||||||
Kotlin_ObjCExport_releaseAssociatedObject(meta->associatedObject_);
|
if (void* associatedObject = meta->associatedObject_) {
|
||||||
|
Kotlin_ObjCExport_releaseAssociatedObject(associatedObject);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std_support::allocator_delete(objectAllocator, meta);
|
std_support::allocator_delete(objectAllocator, meta);
|
||||||
|
|||||||
@@ -107,11 +107,10 @@ ALWAYS_INLINE void send_releaseAsAssociatedObject(void* associatedObject) {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
extern "C" ALWAYS_INLINE void Kotlin_ObjCExport_releaseAssociatedObject(void* associatedObject) {
|
extern "C" ALWAYS_INLINE void Kotlin_ObjCExport_releaseAssociatedObject(void* associatedObject) {
|
||||||
if (associatedObject != nullptr) {
|
RuntimeAssert(associatedObject != nullptr, "Kotlin_ObjCExport_releaseAssociatedObject(nullptr)");
|
||||||
// May already be in the native state if was scheduled on the main queue.
|
// May already be in the native state if was scheduled on the main queue.
|
||||||
NativeOrUnregisteredThreadGuard guard(/*reentrant=*/ true);
|
NativeOrUnregisteredThreadGuard guard(/*reentrant=*/ true);
|
||||||
send_releaseAsAssociatedObject(associatedObject);
|
send_releaseAsAssociatedObject(associatedObject);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" id Kotlin_ObjCExport_convertUnitToRetained(ObjHeader* unitInstance) {
|
extern "C" id Kotlin_ObjCExport_convertUnitToRetained(ObjHeader* unitInstance) {
|
||||||
|
|||||||
@@ -60,14 +60,16 @@ void mm::ExtraObjectData::Uninstall() noexcept {
|
|||||||
this);
|
this);
|
||||||
|
|
||||||
#ifdef KONAN_OBJC_INTEROP
|
#ifdef KONAN_OBJC_INTEROP
|
||||||
if (getFlag(FLAGS_RELEASE_ON_MAIN_QUEUE) && isMainQueueProcessorAvailable()) {
|
if (void* associatedObject = associatedObject_) {
|
||||||
runOnMainQueue(associatedObject_, [](void* obj) {
|
if (getFlag(FLAGS_RELEASE_ON_MAIN_QUEUE) && isMainQueueProcessorAvailable()) {
|
||||||
Kotlin_ObjCExport_releaseAssociatedObject(obj);
|
runOnMainQueue(associatedObject, [](void* obj) {
|
||||||
});
|
Kotlin_ObjCExport_releaseAssociatedObject(obj);
|
||||||
} else {
|
});
|
||||||
Kotlin_ObjCExport_releaseAssociatedObject(associatedObject_);
|
} else {
|
||||||
|
Kotlin_ObjCExport_releaseAssociatedObject(associatedObject);
|
||||||
|
}
|
||||||
|
associatedObject_ = nullptr;
|
||||||
}
|
}
|
||||||
associatedObject_ = nullptr;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user