From 48e3df5224305f5a3177b4426d904ee30ac29096 Mon Sep 17 00:00:00 2001 From: Elena Lepilkina Date: Mon, 25 Oct 2021 12:43:10 +0300 Subject: [PATCH] [K/N] Small refactoring (review fixes) --- .../kotlin/backend/konan/CAdapterGenerator.kt | 4 ++-- .../kotlin/backend/konan/llvm/CodeGenerator.kt | 11 ++++++----- .../konan/llvm/objcexport/ObjCExportCodeGenerator.kt | 4 +++- kotlin-native/runtime/src/main/cpp/Exceptions.cpp | 4 +--- kotlin-native/runtime/src/main/cpp/Exceptions.h | 2 +- kotlin-native/runtime/src/main/cpp/Memory.h | 1 - kotlin-native/runtime/src/main/cpp/Worker.cpp | 2 +- kotlin-native/runtime/src/mm/cpp/ShadowStack.cpp | 2 +- kotlin-native/runtime/src/mm/cpp/ShadowStack.hpp | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt index 6bfa0fe1804..2fe04eb10c7 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt @@ -469,7 +469,7 @@ private class ExportedElement(val kind: ElementKind, } builder.append(" } catch (...) {") builder.append(" SetCurrentFrame(reinterpret_cast(frame));\n") - builder.append(" HandleCurrentExceptionForCInterop();\n") + builder.append(" HandleCurrentExceptionWhenLeavingKotlinCode();\n") builder.append(" } \n") builder.append("}\n") @@ -936,7 +936,7 @@ internal class CAdapterGenerator(val context: Context) : DeclarationDescriptorVi |void Kotlin_initRuntimeIfNeeded(); |void Kotlin_mm_switchThreadStateRunnable() RUNTIME_NOTHROW; |void Kotlin_mm_switchThreadStateNative() RUNTIME_NOTHROW; - |void HandleCurrentExceptionForCInterop(); + |void HandleCurrentExceptionWhenLeavingKotlinCode(); | |KObjHeader* CreateStringFromCString(const char*, KObjHeader**); |char* CreateCStringFromString(const KObjHeader*); diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index f01bfb8d222..d16d6bb5386 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -475,10 +475,12 @@ internal abstract class FunctionGenerationContext( private val entryBb = basicBlockInFunction("entry", startLocation) protected val cleanupLandingpad = basicBlockInFunction("cleanup_landingpad", endLocation) - protected open val needLeaveFrameInUnwindEpilogue: Boolean + // Functions that can be exported and called not only from Kotlin code should have `LeaveFrame` + // because there is no guarantee of catching Kotlin exception in Kotlin code. + protected open val needLeaveFrame: Boolean get() = irFunction?.annotations?.hasAnnotation(RuntimeNames.exportForCppRuntime) == true - || forwardingForeignExceptionsTerminatedWith != null || irFunction?.origin == CBridgeOrigin.C_TO_KOTLIN_BRIDGE + private var setCurrentFrameIsCalled: Boolean = false val stackLocalsManager = StackLocalsManagerImpl(this, stackLocalsInitBb) @@ -1051,7 +1053,6 @@ internal abstract class FunctionGenerationContext( } fun generateFrameCheck() { - assert(slotsPhi != null) call(context.llvm.checkCurrentFrameFunction, listOf(slotsPhi!!)) } @@ -1426,7 +1427,7 @@ internal abstract class FunctionGenerationContext( } internal fun epilogue() { - val needLeaveFrameInUnwindEpilogue = this.needLeaveFrameInUnwindEpilogue + val needLeaveFrameInUnwindEpilogue = this.needLeaveFrame appendingTo(prologueBb) { val slots = if (needSlotsPhi || needLeaveFrameInUnwindEpilogue) @@ -1715,7 +1716,7 @@ internal abstract class FunctionGenerationContext( } private fun releaseVars() { - if (needLeaveFrameInUnwindEpilogue || needSlots) { + if (needLeaveFrame || needSlots) { check(!forbidRuntime) { "Attempt to leave a frame where runtime usage is forbidden" } call(context.llvm.leaveFrameFunction, listOf(slotsPhi!!, Int32(vars.skipSlots).llvm, Int32(slotCount).llvm)) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt index df1882df4eb..8a0a50abc1a 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt @@ -53,7 +53,9 @@ internal class ObjCExportFunctionGenerationContext( ) : FunctionGenerationContext(builder) { private val objCExportCodegen = builder.objCExportCodegen - override val needLeaveFrameInUnwindEpilogue: Boolean + // All generated bridges by ObjCExport should have `LeaveFrame` + // because there is no guarantee of catching Kotlin exception in Kotlin code. + override val needLeaveFrame: Boolean get() = true // Note: we could generate single "epilogue" and make all [ret]s just branch to it (like [DefaultFunctionGenerationContext]), diff --git a/kotlin-native/runtime/src/main/cpp/Exceptions.cpp b/kotlin-native/runtime/src/main/cpp/Exceptions.cpp index b2c5d11a4af..2f33dbcfca7 100644 --- a/kotlin-native/runtime/src/main/cpp/Exceptions.cpp +++ b/kotlin-native/runtime/src/main/cpp/Exceptions.cpp @@ -45,13 +45,11 @@ void ThrowException(KRef exception) { #endif } -void HandleCurrentExceptionForCInterop() { +void HandleCurrentExceptionWhenLeavingKotlinCode() { try { std::rethrow_exception(std::current_exception()); } catch (ExceptionObjHolder& e) { std::terminate(); // Terminate when it's a kotlin exception. - } catch (...) { - throw; // Just rethrow if it's unknown. } } diff --git a/kotlin-native/runtime/src/main/cpp/Exceptions.h b/kotlin-native/runtime/src/main/cpp/Exceptions.h index 9f998fdf1f2..0046a14c6c3 100644 --- a/kotlin-native/runtime/src/main/cpp/Exceptions.h +++ b/kotlin-native/runtime/src/main/cpp/Exceptions.h @@ -28,7 +28,7 @@ void ThrowException(KRef exception); void SetKonanTerminateHandler(); -void HandleCurrentExceptionForCInterop(); +void HandleCurrentExceptionWhenLeavingKotlinCode(); RUNTIME_NOTHROW OBJ_GETTER(Kotlin_getExceptionObject, void* holder); diff --git a/kotlin-native/runtime/src/main/cpp/Memory.h b/kotlin-native/runtime/src/main/cpp/Memory.h index f7f50ed94be..665127a0e3e 100644 --- a/kotlin-native/runtime/src/main/cpp/Memory.h +++ b/kotlin-native/runtime/src/main/cpp/Memory.h @@ -18,7 +18,6 @@ #define RUNTIME_MEMORY_H #include -#include #include "KAssert.h" #include "Common.h" diff --git a/kotlin-native/runtime/src/main/cpp/Worker.cpp b/kotlin-native/runtime/src/main/cpp/Worker.cpp index 81f4f12d2f6..b659835ae26 100644 --- a/kotlin-native/runtime/src/main/cpp/Worker.cpp +++ b/kotlin-native/runtime/src/main/cpp/Worker.cpp @@ -1080,7 +1080,7 @@ JobKind Worker::processQueueElement(bool blocking) { #if !KONAN_NO_EXCEPTIONS FrameOverlay* currentFrame = getCurrentFrame(); #else - RuntimeFail("Exceptions aren't supported!\n"); + #error "Exceptions aren't supported!" #endif try { #if KONAN_OBJC_INTEROP diff --git a/kotlin-native/runtime/src/mm/cpp/ShadowStack.cpp b/kotlin-native/runtime/src/mm/cpp/ShadowStack.cpp index 3ed757a9cc8..a129188f2cf 100644 --- a/kotlin-native/runtime/src/mm/cpp/ShadowStack.cpp +++ b/kotlin-native/runtime/src/mm/cpp/ShadowStack.cpp @@ -45,6 +45,6 @@ FrameOverlay* mm::ShadowStack::getCurrentFrame() noexcept { return currentFrame_; } -void mm::ShadowStack::checkCurrentFrame(FrameOverlay* frame) noexcept { +ALWAYS_INLINE void mm::ShadowStack::checkCurrentFrame(FrameOverlay* frame) noexcept { RuntimeAssert(currentFrame_ == frame, "Frame is expected to be %p, but current frame is %p", frame, currentFrame_); } \ No newline at end of file diff --git a/kotlin-native/runtime/src/mm/cpp/ShadowStack.hpp b/kotlin-native/runtime/src/mm/cpp/ShadowStack.hpp index 4622bd7fa00..a8b8e2140c3 100644 --- a/kotlin-native/runtime/src/mm/cpp/ShadowStack.hpp +++ b/kotlin-native/runtime/src/mm/cpp/ShadowStack.hpp @@ -55,7 +55,7 @@ public: void LeaveFrame(ObjHeader** start, int parameters, int count) noexcept; void SetCurrentFrame(ObjHeader** start) noexcept; FrameOverlay* getCurrentFrame() noexcept; - void checkCurrentFrame(FrameOverlay* frame) noexcept; + ALWAYS_INLINE void checkCurrentFrame(FrameOverlay* frame) noexcept; Iterator begin() noexcept { return Iterator(currentFrame_); } Iterator end() noexcept { return Iterator(nullptr); }