From 0a5e64f6175f63db833e32e88df2e5c715ee8fc2 Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Wed, 9 Sep 2020 19:26:16 +0500 Subject: [PATCH] [runtime][codegen] Added lifetime constraint check Current memory model forbids a heap object to reference a stack object, so check that explicitly on each field store for now --- .../jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt | 1 + .../jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt | 3 +++ runtime/src/main/cpp/Memory.cpp | 8 ++++++++ runtime/src/main/cpp/Memory.h | 1 + 4 files changed, 13 insertions(+) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt index 2f03641df97..74d8d884641 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt @@ -519,6 +519,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) { val lookupTLS = importRtFunction("LookupTLS") val initRuntimeIfNeeded = importRtFunction("Kotlin_initRuntimeIfNeeded") val mutationCheck = importRtFunction("MutationCheck") + val checkLifetimesConstraint = importRtFunction("CheckLifetimesConstraint") val freezeSubgraph = importRtFunction("FreezeSubgraph") val checkMainThread = importRtFunction("CheckIsMainThread") diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 0b3aef5223a..a9810c8c5ed 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -1633,6 +1633,9 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Maplocal() && pointee != nullptr && pointee->local()) { + konan::consolePrintf("Attempt to store a stack object %p into a heap object %p\n", pointee, obj); + konan::consolePrintf("This is a compiler bug, please report it to https://kotl.in/issue\n"); + konan::abort(); + } +} + void EnsureNeverFrozen(ObjHeader* object) { ensureNeverFrozen(object); } diff --git a/runtime/src/main/cpp/Memory.h b/runtime/src/main/cpp/Memory.h index cffc8a6e69c..46be88de207 100644 --- a/runtime/src/main/cpp/Memory.h +++ b/runtime/src/main/cpp/Memory.h @@ -541,6 +541,7 @@ OBJ_GETTER(DerefStablePointer, void*) RUNTIME_NOTHROW; OBJ_GETTER(AdoptStablePointer, void*) RUNTIME_NOTHROW; // Check mutability state. void MutationCheck(ObjHeader* obj); +void CheckLifetimesConstraint(ObjHeader* obj, ObjHeader* pointee) RUNTIME_NOTHROW; // Freeze object subgraph. void FreezeSubgraph(ObjHeader* obj); // Ensure this object shall block freezing.