From 77c04e7d71853494d1cc95dfd172b33bc1d87840 Mon Sep 17 00:00:00 2001 From: Sergey Bogolepov Date: Fri, 18 Mar 2022 14:26:36 +0300 Subject: [PATCH] [K/N] Do not inline runtime functions in case of armv7 darwin targets ^KT-51649 fixed --- kotlin-native/konan/konan.properties | 2 ++ .../runtime/src/legacymm/cpp/Memory.cpp | 8 ++++---- kotlin-native/runtime/src/main/cpp/Common.h | 10 +++++++++- kotlin-native/runtime/src/main/cpp/Memory.h | 16 ++++++++++++---- kotlin-native/runtime/src/mm/cpp/Memory.cpp | 8 ++++---- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/kotlin-native/konan/konan.properties b/kotlin-native/konan/konan.properties index f832c93c0e4..59062b0ec7b 100644 --- a/kotlin-native/konan/konan.properties +++ b/kotlin-native/konan/konan.properties @@ -191,6 +191,7 @@ clangFlags.ios_arm32 = -cc1 -emit-obj -disable-llvm-optzns -x ir clangNooptFlags.ios_arm32 = -O1 clangOptFlags.ios_arm32 = -O3 clangDebugFlags.ios_arm32 = -O0 +llvmInlineThreshold.ios_arm32 = 50 linkerNoDebugFlags.ios_arm32 = -S stripFlags.ios_arm32 = -S linkerDynamicFlags.ios_arm32 = -dylib @@ -372,6 +373,7 @@ clangFlags.watchos_arm32 = -cc1 -emit-obj -disable-llvm-passes -x ir clangNooptFlags.watchos_arm32 = -O1 clangOptFlags.watchos_arm32 = -O3 clangDebugFlags.watchos_arm32 = -O0 +llvmInlineThreshold.watchos_arm32 = 50 linkerKonanFlags.watchos_arm32 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 8.0 linkerOptimizationFlags.watchos_arm32 = -dead_strip diff --git a/kotlin-native/runtime/src/legacymm/cpp/Memory.cpp b/kotlin-native/runtime/src/legacymm/cpp/Memory.cpp index f05dac9cb6c..6bc933bd30a 100644 --- a/kotlin-native/runtime/src/legacymm/cpp/Memory.cpp +++ b/kotlin-native/runtime/src/legacymm/cpp/Memory.cpp @@ -3767,19 +3767,19 @@ void CheckGlobalsAccessible() { ThrowIncorrectDereferenceException(); } -ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateNative() { +CODEGEN_INLINE_POLICY RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateNative() { // no-op, used by the new MM only. } -ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateRunnable() { +CODEGEN_INLINE_POLICY RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateRunnable() { // no-op, used by the new MM only. } -ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_safePointFunctionPrologue() { +CODEGEN_INLINE_POLICY RUNTIME_NOTHROW void Kotlin_mm_safePointFunctionPrologue() { // no-op, used by the new MM only. } -ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_safePointWhileLoopBody() { +CODEGEN_INLINE_POLICY RUNTIME_NOTHROW void Kotlin_mm_safePointWhileLoopBody() { // no-op, used by the new MM only. } diff --git a/kotlin-native/runtime/src/main/cpp/Common.h b/kotlin-native/runtime/src/main/cpp/Common.h index 7b3aded7b0a..4f9e315315b 100644 --- a/kotlin-native/runtime/src/main/cpp/Common.h +++ b/kotlin-native/runtime/src/main/cpp/Common.h @@ -25,7 +25,15 @@ #define RUNTIME_WEAK __attribute__((weak)) #define RUNTIME_NODEBUG __attribute__((nodebug)) -#define ALWAYS_INLINE __attribute__((always_inline)) +#if KONAN_ARM32 && (KONAN_IOS || KONAN_WATCHOS) + // On the one hand, ALWAYS_INLINE forces many performance-critical function to be, well, + // inlined. Which is good for performance, of course. + // On the other hand, 32-bit Mach-O object files can't be really big. + // As a compromise, we let the compiler decide what should be inlined or not. + #define ALWAYS_INLINE +#else + #define ALWAYS_INLINE __attribute__((always_inline)) +#endif #define NO_INLINE __attribute__((noinline)) #define NO_EXTERNAL_CALLS_CHECK __attribute__((annotate("no_external_calls_check"))) diff --git a/kotlin-native/runtime/src/main/cpp/Memory.h b/kotlin-native/runtime/src/main/cpp/Memory.h index 07f2ead314a..6401d4cce79 100644 --- a/kotlin-native/runtime/src/main/cpp/Memory.h +++ b/kotlin-native/runtime/src/main/cpp/Memory.h @@ -26,6 +26,14 @@ #include "PointerBits.h" #include "Utils.hpp" +#if KONAN_ARM32 && (KONAN_IOS || KONAN_WATCHOS) + // Currently, codegen places a lot of unnecessary calls to MM functions. + // By forcing NO_INLINE on these functions we keep binaries from growing too big. + #define CODEGEN_INLINE_POLICY NO_INLINE +#else + #define CODEGEN_INLINE_POLICY ALWAYS_INLINE +#endif + typedef enum { // Must match to permTag() in Kotlin. OBJECT_TAG_PERMANENT_CONTAINER = 1 << 0, @@ -327,13 +335,13 @@ void AdoptReferenceFromSharedVariable(ObjHeader* object); void CheckGlobalsAccessible(); // Sets state of the current thread to NATIVE (used by the new MM). -ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateNative(); +CODEGEN_INLINE_POLICY RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateNative(); // Sets state of the current thread to RUNNABLE (used by the new MM). -ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateRunnable(); +CODEGEN_INLINE_POLICY RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateRunnable(); // Safe point callbacks from Kotlin code generator. -void Kotlin_mm_safePointFunctionPrologue() RUNTIME_NOTHROW; -void Kotlin_mm_safePointWhileLoopBody() RUNTIME_NOTHROW; +CODEGEN_INLINE_POLICY void Kotlin_mm_safePointFunctionPrologue() RUNTIME_NOTHROW; +CODEGEN_INLINE_POLICY void Kotlin_mm_safePointWhileLoopBody() RUNTIME_NOTHROW; #ifdef __cplusplus } diff --git a/kotlin-native/runtime/src/mm/cpp/Memory.cpp b/kotlin-native/runtime/src/mm/cpp/Memory.cpp index e742d5b4a34..b94fad9eb18 100644 --- a/kotlin-native/runtime/src/mm/cpp/Memory.cpp +++ b/kotlin-native/runtime/src/mm/cpp/Memory.cpp @@ -568,23 +568,23 @@ extern "C" void CheckGlobalsAccessible() { // Always accessible } -extern "C" RUNTIME_NOTHROW ALWAYS_INLINE void Kotlin_mm_safePointFunctionPrologue() { +extern "C" RUNTIME_NOTHROW CODEGEN_INLINE_POLICY void Kotlin_mm_safePointFunctionPrologue() { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); AssertThreadState(threadData, ThreadState::kRunnable); threadData->gc().SafePointFunctionPrologue(); } -extern "C" RUNTIME_NOTHROW ALWAYS_INLINE void Kotlin_mm_safePointWhileLoopBody() { +extern "C" RUNTIME_NOTHROW CODEGEN_INLINE_POLICY void Kotlin_mm_safePointWhileLoopBody() { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); AssertThreadState(threadData, ThreadState::kRunnable); threadData->gc().SafePointLoopBody(); } -extern "C" ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateNative() { +extern "C" CODEGEN_INLINE_POLICY RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateNative() { SwitchThreadState(mm::ThreadRegistry::Instance().CurrentThreadData(), ThreadState::kNative); } -extern "C" ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateRunnable() { +extern "C" CODEGEN_INLINE_POLICY RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateRunnable() { SwitchThreadState(mm::ThreadRegistry::Instance().CurrentThreadData(), ThreadState::kRunnable); }