Mark safe points in code generator (#4640)

This commit is contained in:
Alexander Shabalin
2021-01-22 16:35:45 +03:00
committed by Nikolay Krasko
parent 9e62134ea0
commit d633b1c545
7 changed files with 48 additions and 2 deletions
@@ -1251,6 +1251,8 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
returnType == voidType -> { returnType == voidType -> {
releaseVars() releaseVars()
assert(returnSlot == null) assert(returnSlot == null)
if (context.memoryModel == MemoryModel.EXPERIMENTAL)
call(context.llvm.Kotlin_mm_safePointFunctionEpilogue, emptyList())
LLVMBuildRetVoid(builder) LLVMBuildRetVoid(builder)
} }
returns.isNotEmpty() -> { returns.isNotEmpty() -> {
@@ -1260,6 +1262,8 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
updateReturnRef(returnPhi, returnSlot!!) updateReturnRef(returnPhi, returnSlot!!)
} }
releaseVars() releaseVars()
if (context.memoryModel == MemoryModel.EXPERIMENTAL)
call(context.llvm.Kotlin_mm_safePointFunctionEpilogue, emptyList())
LLVMBuildRet(builder, returnPhi) LLVMBuildRet(builder, returnPhi)
} }
// Do nothing, all paths throw. // Do nothing, all paths throw.
@@ -1300,6 +1304,8 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
} }
releaseVars() releaseVars()
if (context.memoryModel == MemoryModel.EXPERIMENTAL)
call(context.llvm.Kotlin_mm_safePointExceptionUnwind, emptyList())
LLVMBuildResume(builder, landingpad) LLVMBuildResume(builder, landingpad)
} }
@@ -546,6 +546,10 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
val Kotlin_ObjCExport_createContinuationArgument by lazyRtFunction val Kotlin_ObjCExport_createContinuationArgument by lazyRtFunction
val Kotlin_ObjCExport_resumeContinuation by lazyRtFunction val Kotlin_ObjCExport_resumeContinuation by lazyRtFunction
val Kotlin_mm_safePointFunctionEpilogue by lazyRtFunction
val Kotlin_mm_safePointWhileLoopBody by lazyRtFunction
val Kotlin_mm_safePointExceptionUnwind by lazyRtFunction
val tlsMode by lazy { val tlsMode by lazy {
when (target) { when (target) {
KonanTarget.WASM32, KonanTarget.WASM32,
@@ -534,9 +534,9 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
} }
override fun genContinue(destination: IrContinue) { override fun genContinue(destination: IrContinue) {
if (destination.loop == loop) if (destination.loop == loop) {
functionGenerationContext.br(loopCheck) functionGenerationContext.br(loopCheck)
else } else
super.genContinue(destination) super.genContinue(destination)
} }
@@ -1240,6 +1240,8 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
functionGenerationContext.condBr(condition, loopBody, loopScope.loopExit) functionGenerationContext.condBr(condition, loopBody, loopScope.loopExit)
functionGenerationContext.positionAtEnd(loopBody) functionGenerationContext.positionAtEnd(loopBody)
if (context.memoryModel == MemoryModel.EXPERIMENTAL)
call(context.llvm.Kotlin_mm_safePointWhileLoopBody, emptyList())
loop.body?.generate() loop.body?.generate()
functionGenerationContext.br(loopScope.loopCheck) functionGenerationContext.br(loopScope.loopCheck)
@@ -1260,6 +1262,8 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
functionGenerationContext.br(loopBody) functionGenerationContext.br(loopBody)
functionGenerationContext.positionAtEnd(loopBody) functionGenerationContext.positionAtEnd(loopBody)
if (context.memoryModel == MemoryModel.EXPERIMENTAL)
call(context.llvm.Kotlin_mm_safePointWhileLoopBody, emptyList())
loop.body?.generate() loop.body?.generate()
functionGenerationContext.br(loopScope.loopCheck) functionGenerationContext.br(loopScope.loopCheck)
@@ -3684,4 +3684,16 @@ ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateRunnable() {
// no-op, used by the new MM only. // no-op, used by the new MM only.
} }
ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_safePointFunctionEpilogue() {
// no-op, used by the new MM only.
}
ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_safePointWhileLoopBody() {
// no-op, used by the new MM only.
}
ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_safePointExceptionUnwind() {
// no-op, used by the new MM only.
}
} // extern "C" } // extern "C"
@@ -44,4 +44,7 @@ void EnsureDeclarationsEmitted() {
ensureUsed(CheckGlobalsAccessible); ensureUsed(CheckGlobalsAccessible);
ensureUsed(Kotlin_mm_switchThreadStateNative); ensureUsed(Kotlin_mm_switchThreadStateNative);
ensureUsed(Kotlin_mm_switchThreadStateRunnable); ensureUsed(Kotlin_mm_switchThreadStateRunnable);
ensureUsed(Kotlin_mm_safePointFunctionEpilogue);
ensureUsed(Kotlin_mm_safePointWhileLoopBody);
ensureUsed(Kotlin_mm_safePointExceptionUnwind);
} }
@@ -283,6 +283,11 @@ ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateNative();
// Sets state of the current thread to RUNNABLE (used by the new MM). // Sets state of the current thread to RUNNABLE (used by the new MM).
ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateRunnable(); ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateRunnable();
// Safe point callbacks from Kotlin code generator.
void Kotlin_mm_safePointFunctionEpilogue() RUNTIME_NOTHROW;
void Kotlin_mm_safePointWhileLoopBody() RUNTIME_NOTHROW;
void Kotlin_mm_safePointExceptionUnwind() RUNTIME_NOTHROW;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@@ -102,4 +102,16 @@ ForeignRefContext InitLocalForeignRef(ObjHeader* object) {
TODO(); TODO();
} }
RUNTIME_NOTHROW void Kotlin_mm_safePointFunctionEpilogue() {
TODO();
}
RUNTIME_NOTHROW void Kotlin_mm_safePointWhileLoopBody() {
TODO();
}
RUNTIME_NOTHROW void Kotlin_mm_safePointExceptionUnwind() {
TODO();
}
} // extern "C" } // extern "C"