Move main thread check to legacy mm (#4483)
This commit is contained in:
committed by
Stanislav Erokhin
parent
14526e57bc
commit
8dc5b95337
+2
-2
@@ -452,9 +452,9 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
call(context.llvm.freezeSubgraph, listOf(value), Lifetime.IRRELEVANT, exceptionHandler)
|
||||
}
|
||||
|
||||
fun checkMainThread(exceptionHandler: ExceptionHandler) {
|
||||
fun checkGlobalsAccessible(exceptionHandler: ExceptionHandler) {
|
||||
if (context.memoryModel == MemoryModel.STRICT)
|
||||
call(context.llvm.checkMainThread, emptyList(), Lifetime.IRRELEVANT, exceptionHandler)
|
||||
call(context.llvm.checkGlobalsAccessible, emptyList(), Lifetime.IRRELEVANT, exceptionHandler)
|
||||
}
|
||||
|
||||
private fun updateReturnRef(value: LLVMValueRef, address: LLVMValueRef) {
|
||||
|
||||
+1
-1
@@ -521,7 +521,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
||||
val mutationCheck = importRtFunction("MutationCheck")
|
||||
val checkLifetimesConstraint = importRtFunction("CheckLifetimesConstraint")
|
||||
val freezeSubgraph = importRtFunction("FreezeSubgraph")
|
||||
val checkMainThread = importRtFunction("CheckIsMainThread")
|
||||
val checkGlobalsAccessible = importRtFunction("CheckGlobalsAccessible")
|
||||
|
||||
val kRefSharedHolderInitLocal = importRtFunction("KRefSharedHolder_initLocal")
|
||||
val kRefSharedHolderInit = importRtFunction("KRefSharedHolder_init")
|
||||
|
||||
+14
-14
@@ -38,8 +38,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
|
||||
internal enum class FieldStorageKind {
|
||||
MAIN_THREAD,
|
||||
SHARED,
|
||||
GLOBAL, // In the old memory model these are only accessible from the "main" thread.
|
||||
SHARED_FROZEN,
|
||||
THREAD_LOCAL
|
||||
}
|
||||
|
||||
@@ -55,12 +55,12 @@ internal val IrField.storageKind: FieldStorageKind get() {
|
||||
val annotations = correspondingPropertySymbol?.owner?.annotations ?: annotations
|
||||
return when {
|
||||
annotations.hasAnnotation(KonanFqNames.threadLocal) -> FieldStorageKind.THREAD_LOCAL
|
||||
!isFinal -> FieldStorageKind.MAIN_THREAD
|
||||
annotations.hasAnnotation(KonanFqNames.sharedImmutable) -> FieldStorageKind.SHARED
|
||||
!isFinal -> FieldStorageKind.GLOBAL
|
||||
annotations.hasAnnotation(KonanFqNames.sharedImmutable) -> FieldStorageKind.SHARED_FROZEN
|
||||
// TODO: simplify, once IR types are fully there.
|
||||
(type.classifierOrNull?.owner as? IrAnnotationContainer)
|
||||
?.annotations?.hasAnnotation(KonanFqNames.frozen) == true -> FieldStorageKind.SHARED
|
||||
else -> FieldStorageKind.MAIN_THREAD
|
||||
?.annotations?.hasAnnotation(KonanFqNames.frozen) == true -> FieldStorageKind.SHARED_FROZEN
|
||||
else -> FieldStorageKind.GLOBAL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,9 +71,9 @@ internal fun IrClass.storageKind(context: Context): ObjectStorageKind = when {
|
||||
else -> ObjectStorageKind.SHARED
|
||||
}
|
||||
|
||||
val IrField.isMainOnlyNonPrimitive get() = when {
|
||||
val IrField.isGlobalNonPrimitive get() = when {
|
||||
type.computePrimitiveBinaryTypeOrNull() != null -> false
|
||||
else -> storageKind == FieldStorageKind.MAIN_THREAD
|
||||
else -> storageKind == FieldStorageKind.GLOBAL
|
||||
}
|
||||
|
||||
internal class RTTIGeneratorVisitor(context: Context) : IrElementVisitorVoid {
|
||||
@@ -423,7 +423,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
val address = context.llvmDeclarations.forStaticField(irField).storageAddressAccess.getAddress(
|
||||
functionGenerationContext
|
||||
)
|
||||
if (irField.storageKind == FieldStorageKind.SHARED)
|
||||
if (irField.storageKind == FieldStorageKind.SHARED_FROZEN)
|
||||
freeze(initialization, currentCodeContext.exceptionHandler)
|
||||
storeAny(initialization, address, false)
|
||||
}
|
||||
@@ -1573,8 +1573,8 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
if (value.symbol.owner.correspondingPropertySymbol?.owner?.isConst == true) {
|
||||
evaluateConst(value.symbol.owner.initializer?.expression as IrConst<*>)
|
||||
} else {
|
||||
if (context.config.threadsAreAllowed && value.symbol.owner.isMainOnlyNonPrimitive) {
|
||||
functionGenerationContext.checkMainThread(currentCodeContext.exceptionHandler)
|
||||
if (context.config.threadsAreAllowed && value.symbol.owner.isGlobalNonPrimitive) {
|
||||
functionGenerationContext.checkGlobalsAccessible(currentCodeContext.exceptionHandler)
|
||||
}
|
||||
val ptr = context.llvmDeclarations.forStaticField(value.symbol.owner).storageAddressAccess.getAddress(
|
||||
functionGenerationContext
|
||||
@@ -1642,9 +1642,9 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
val globalAddress = context.llvmDeclarations.forStaticField(value.symbol.owner).storageAddressAccess.getAddress(
|
||||
functionGenerationContext
|
||||
)
|
||||
if (context.config.threadsAreAllowed && value.symbol.owner.storageKind == FieldStorageKind.MAIN_THREAD)
|
||||
functionGenerationContext.checkMainThread(currentCodeContext.exceptionHandler)
|
||||
if (value.symbol.owner.storageKind == FieldStorageKind.SHARED)
|
||||
if (context.config.threadsAreAllowed && value.symbol.owner.storageKind == FieldStorageKind.GLOBAL)
|
||||
functionGenerationContext.checkGlobalsAccessible(currentCodeContext.exceptionHandler)
|
||||
if (value.symbol.owner.storageKind == FieldStorageKind.SHARED_FROZEN)
|
||||
functionGenerationContext.freeze(valueToAssign, currentCodeContext.exceptionHandler)
|
||||
functionGenerationContext.storeAny(valueToAssign, globalAddress, false)
|
||||
}
|
||||
|
||||
@@ -641,6 +641,8 @@ struct MemoryState {
|
||||
// A stack of initializing singletons.
|
||||
KStdVector<std::pair<ObjHeader**, ObjHeader*>> initializingSingletons;
|
||||
|
||||
bool isMainThread = false;
|
||||
|
||||
#if COLLECT_STATISTIC
|
||||
#define CONTAINER_ALLOC_STAT(state, size, container) state->statistic.incAlloc(size, container);
|
||||
#define CONTAINER_DESTROY_STAT(state, container) \
|
||||
@@ -2007,6 +2009,7 @@ MemoryState* initMemory() {
|
||||
#if USE_CYCLIC_GC
|
||||
cyclicInit();
|
||||
#endif // USE_CYCLIC_GC
|
||||
memoryState->isMainThread = true;
|
||||
}
|
||||
return memoryState;
|
||||
}
|
||||
@@ -3608,4 +3611,9 @@ void PerformFullGC() {
|
||||
garbageCollect(::memoryState, true);
|
||||
}
|
||||
|
||||
void CheckGlobalsAccessible() {
|
||||
if (!::memoryState->isMainThread)
|
||||
ThrowIncorrectDereferenceException();
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@@ -41,4 +41,5 @@ void EnsureDeclarationsEmitted() {
|
||||
ensureUsed(CheckLifetimesConstraint);
|
||||
ensureUsed(FreezeSubgraph);
|
||||
ensureUsed(FreezeSubgraph);
|
||||
ensureUsed(CheckGlobalsAccessible);
|
||||
}
|
||||
|
||||
@@ -254,6 +254,8 @@ bool IsForeignRefAccessible(ObjHeader* object, ForeignRefContext context);
|
||||
// and there's nothing else keeping the object alive.
|
||||
void AdoptReferenceFromSharedVariable(ObjHeader* object);
|
||||
|
||||
void CheckGlobalsAccessible();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -69,7 +69,6 @@ KBoolean g_checkLeakedCleaners = KonanNeedDebugInfo;
|
||||
constexpr RuntimeState* kInvalidRuntime = nullptr;
|
||||
|
||||
THREAD_LOCAL_VARIABLE RuntimeState* runtimeState = kInvalidRuntime;
|
||||
THREAD_LOCAL_VARIABLE int isMainThread = 0;
|
||||
|
||||
inline bool isValidRuntime() {
|
||||
return ::runtimeState != kInvalidRuntime;
|
||||
@@ -88,7 +87,6 @@ RuntimeState* initRuntime() {
|
||||
bool firstRuntime = atomicAdd(&aliveRuntimesCount, 1) == 1;
|
||||
// Keep global variables in state as well.
|
||||
if (firstRuntime) {
|
||||
isMainThread = 1;
|
||||
konan::consoleInit();
|
||||
#if KONAN_OBJC_INTEROP
|
||||
Kotlin_ObjCExport_initialize();
|
||||
@@ -151,11 +149,6 @@ void Kotlin_deinitRuntimeIfNeeded() {
|
||||
}
|
||||
}
|
||||
|
||||
void CheckIsMainThread() {
|
||||
if (!isMainThread)
|
||||
ThrowIncorrectDereferenceException();
|
||||
}
|
||||
|
||||
KInt Konan_Platform_canAccessUnaligned() {
|
||||
#if KONAN_NO_UNALIGNED_ACCESS
|
||||
return 0;
|
||||
|
||||
@@ -234,4 +234,8 @@ void AdoptReferenceFromSharedVariable(ObjHeader* object) {
|
||||
RuntimeCheck(false, "Unimplemented");
|
||||
}
|
||||
|
||||
void CheckGlobalsAccessible() {
|
||||
// Globals are always accessible.
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
Reference in New Issue
Block a user