Native: switch to "Native" thread state for some Obj-C runtime calls
A lot of calls to Objective-C runtime are potentially blocking. This commit adds a number of thread state switches to ensure these Obj-C runtime calls happen in "Native" thread state. Also, remove a bunch of such functions from CallsChecker exclude list.
This commit is contained in:
committed by
Space
parent
2e8c25aeff
commit
ad1b10cdb0
@@ -135,6 +135,9 @@ void DisposeCString(char* cstring) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ObjHeader* CreatePermanentStringFromCString(const char* nullTerminatedUTF8) {
|
ObjHeader* CreatePermanentStringFromCString(const char* nullTerminatedUTF8) {
|
||||||
|
// Note: this function can be called in "Native" thread state. But this is fine:
|
||||||
|
// while it indeed manipulates Kotlin objects, it doesn't in fact access _Kotlin heap_,
|
||||||
|
// because the accessed object is off-heap, imitating permanent static objects.
|
||||||
const char* end = nullTerminatedUTF8 + strlen(nullTerminatedUTF8);
|
const char* end = nullTerminatedUTF8 + strlen(nullTerminatedUTF8);
|
||||||
size_t count = utf8::with_replacement::utf16_length(nullTerminatedUTF8, end);
|
size_t count = utf8::with_replacement::utf16_length(nullTerminatedUTF8, end);
|
||||||
size_t headerSize = alignUp(sizeof(ArrayHeader), alignof(char16_t));
|
size_t headerSize = alignUp(sizeof(ArrayHeader), alignof(char16_t));
|
||||||
|
|||||||
@@ -121,6 +121,8 @@ extern "C" const TypeInfo* Kotlin_ObjCExport_getAssociatedTypeInfo(Class clazz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void setAssociatedTypeInfo(Class clazz, const TypeInfo* typeInfo) {
|
static void setAssociatedTypeInfo(Class clazz, const TypeInfo* typeInfo) {
|
||||||
|
kotlin::NativeOrUnregisteredThreadGuard threadStateGuard(/* reentrant = */ true);
|
||||||
|
|
||||||
// Note: [NSValue valueWithPointer:] uses autorelease (without possibility to eliminate this at the call site),
|
// Note: [NSValue valueWithPointer:] uses autorelease (without possibility to eliminate this at the call site),
|
||||||
// so using alloc-init sequence to avoid this.
|
// so using alloc-init sequence to avoid this.
|
||||||
NSValue* value = [[NSValue alloc] initWithBytes:&typeInfo objCType:@encode(void*)];
|
NSValue* value = [[NSValue alloc] initWithBytes:&typeInfo objCType:@encode(void*)];
|
||||||
@@ -315,6 +317,8 @@ extern "C" void Kotlin_ObjCExport_initializeClass(Class clazz) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlin::NativeOrUnregisteredThreadGuard threadStateGuard(/* reentrant = */ true);
|
||||||
|
|
||||||
const TypeInfo* typeInfo = typeAdapter->kotlinTypeInfo;
|
const TypeInfo* typeInfo = typeAdapter->kotlinTypeInfo;
|
||||||
bool isClassForPackage = typeInfo == nullptr;
|
bool isClassForPackage = typeInfo == nullptr;
|
||||||
if (!isClassForPackage) {
|
if (!isClassForPackage) {
|
||||||
@@ -379,6 +383,8 @@ static void Kotlin_ObjCExport_initializeImpl() {
|
|||||||
RuntimeCheck(Kotlin_ObjCExport_toKotlinSelector != nullptr, "unexpected initialization order");
|
RuntimeCheck(Kotlin_ObjCExport_toKotlinSelector != nullptr, "unexpected initialization order");
|
||||||
RuntimeCheck(Kotlin_ObjCExport_releaseAsAssociatedObjectSelector != nullptr, "unexpected initialization order");
|
RuntimeCheck(Kotlin_ObjCExport_releaseAsAssociatedObjectSelector != nullptr, "unexpected initialization order");
|
||||||
|
|
||||||
|
kotlin::NativeOrUnregisteredThreadGuard threadStateGuard(/* reentrant = */ true);
|
||||||
|
|
||||||
initTypeAdapters();
|
initTypeAdapters();
|
||||||
|
|
||||||
SEL toKotlinSelector = Kotlin_ObjCExport_toKotlinSelector;
|
SEL toKotlinSelector = Kotlin_ObjCExport_toKotlinSelector;
|
||||||
@@ -865,6 +871,8 @@ static void throwIfCantBeOverridden(Class clazz, const KotlinToObjCMethodAdapter
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, const TypeInfo* fieldsInfo) {
|
static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, const TypeInfo* fieldsInfo) {
|
||||||
|
kotlin::NativeOrUnregisteredThreadGuard threadStateGuard(/* reentrant = */ true);
|
||||||
|
|
||||||
std_support::unordered_set<SEL> definedSelectors;
|
std_support::unordered_set<SEL> definedSelectors;
|
||||||
addDefinedSelectors(clazz, definedSelectors);
|
addDefinedSelectors(clazz, definedSelectors);
|
||||||
|
|
||||||
@@ -1053,6 +1061,8 @@ static void addVirtualAdapters(Class clazz, const ObjCTypeAdapter* typeAdapter)
|
|||||||
static Class createClass(const TypeInfo* typeInfo, Class superClass) {
|
static Class createClass(const TypeInfo* typeInfo, Class superClass) {
|
||||||
RuntimeAssert(typeInfo->superType_ != nullptr, "");
|
RuntimeAssert(typeInfo->superType_ != nullptr, "");
|
||||||
|
|
||||||
|
kotlin::NativeOrUnregisteredThreadGuard threadStateGuard(/* reentrant = */ true);
|
||||||
|
|
||||||
int classIndex = (anonymousClassNextId++);
|
int classIndex = (anonymousClassNextId++);
|
||||||
std_support::string className = Kotlin_ObjCInterop_getUniquePrefix();
|
std_support::string className = Kotlin_ObjCInterop_getUniquePrefix();
|
||||||
className += "_kobjcc";
|
className += "_kobjcc";
|
||||||
|
|||||||
@@ -298,6 +298,8 @@ void* CreateKotlinObjCClass(const KotlinObjCClassInfo* info) {
|
|||||||
return createdClass;
|
return createdClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlin::NativeOrUnregisteredThreadGuard threadStateGuard(/* reentrant = */ true);
|
||||||
|
|
||||||
Class newClass = allocateClass(info);
|
Class newClass = allocateClass(info);
|
||||||
|
|
||||||
RuntimeAssert(newClass != nullptr, "Failed to allocate Objective-C class");
|
RuntimeAssert(newClass != nullptr, "Failed to allocate Objective-C class");
|
||||||
|
|||||||
@@ -189,14 +189,6 @@ extern "C" const char* Kotlin_callsCheckerGoodFunctionNames[] = {
|
|||||||
"CFStringGetCharacters",
|
"CFStringGetCharacters",
|
||||||
"CFStringGetLength",
|
"CFStringGetLength",
|
||||||
"_Block_object_assign",
|
"_Block_object_assign",
|
||||||
"class_addIvar",
|
|
||||||
"class_addMethod",
|
|
||||||
"class_addProtocol",
|
|
||||||
"class_copyMethodList",
|
|
||||||
"class_copyProtocolList",
|
|
||||||
"class_getClassMethod",
|
|
||||||
"class_getInstanceMethod",
|
|
||||||
"class_getInstanceVariable",
|
|
||||||
"class_getName",
|
"class_getName",
|
||||||
"class_getSuperclass",
|
"class_getSuperclass",
|
||||||
"class_isMetaClass",
|
"class_isMetaClass",
|
||||||
@@ -205,7 +197,6 @@ extern "C" const char* Kotlin_callsCheckerGoodFunctionNames[] = {
|
|||||||
"method_getTypeEncoding",
|
"method_getTypeEncoding",
|
||||||
"objc_alloc",
|
"objc_alloc",
|
||||||
"objc_alloc_init",
|
"objc_alloc_init",
|
||||||
"objc_allocateClassPair",
|
|
||||||
"objc_autorelease",
|
"objc_autorelease",
|
||||||
"objc_autoreleasePoolPush",
|
"objc_autoreleasePoolPush",
|
||||||
"objc_autoreleaseReturnValue",
|
"objc_autoreleaseReturnValue",
|
||||||
@@ -213,18 +204,13 @@ extern "C" const char* Kotlin_callsCheckerGoodFunctionNames[] = {
|
|||||||
"objc_getClass",
|
"objc_getClass",
|
||||||
"objc_getProtocol",
|
"objc_getProtocol",
|
||||||
"objc_lookUpClass",
|
"objc_lookUpClass",
|
||||||
"objc_registerClassPair",
|
|
||||||
"objc_retain",
|
"objc_retain",
|
||||||
"objc_retainAutoreleaseReturnValue",
|
"objc_retainAutoreleaseReturnValue",
|
||||||
"objc_retainBlock",
|
"objc_retainBlock",
|
||||||
"objc_setAssociatedObject",
|
|
||||||
"objc_storeWeak",
|
"objc_storeWeak",
|
||||||
"object_getClass",
|
"object_getClass",
|
||||||
"object_isClass",
|
"object_isClass",
|
||||||
"protocol_copyProtocolList",
|
|
||||||
"protocol_getMethodDescription",
|
|
||||||
"protocol_getName",
|
"protocol_getName",
|
||||||
"sel_registerName",
|
|
||||||
|
|
||||||
"llvm.assume",
|
"llvm.assume",
|
||||||
"llvm.ceil.*",
|
"llvm.ceil.*",
|
||||||
|
|||||||
Reference in New Issue
Block a user