diff --git a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt index 1ec43707df3..d2e9268944f 100644 --- a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt +++ b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt @@ -177,6 +177,18 @@ class K2Native : CLICompiler() { put(ENABLE_ASSERTIONS, arguments.enableAssertions) + put(MEMORY_MODEL, when (arguments.memoryModel) { + "relaxed" -> { + configuration.report(STRONG_WARNING, "Relaxed memory model is not yet functional") + MemoryModel.RELAXED + } + "strict" -> MemoryModel.STRICT + else -> { + configuration.report(ERROR, "Unsupported memory model ${arguments.memoryModel}") + return + } + }) + when { arguments.generateWorkerTestRunner -> put(GENERATE_TEST_RUNNER, TestRunnerKind.WORKER) arguments.generateTestRunner -> put(GENERATE_TEST_RUNNER, TestRunnerKind.MAIN_THREAD) diff --git a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt index 5297afe7738..6736a091073 100644 --- a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt +++ b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt @@ -48,7 +48,10 @@ class K2NativeCompilerArguments : CommonCompilerArguments() { @Argument(value = "-manifest", valueDescription = "", description = "Provide a maniferst addend file") var manifestFile: String? = null - @Argument(value="-module-name", deprecatedName = "-module_name", valueDescription = "", description = "Spicify a name for the compilation module") + @Argument(value="-memory-model", valueDescription = "", description = "Memory model to use, 'strict' and 'relaxed' are currently supported") + var memoryModel: String? = "strict" + + @Argument(value="-module-name", deprecatedName = "-module_name", valueDescription = "", description = "Specify a name for the compilation module") var moduleName: String? = null @Argument(value = "-native-library", deprecatedName = "-nativelibrary", shortName = "-nl", valueDescription = "", description = "Include the native bitcode library") diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt index 090d33fc455..b9f4d3f622e 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt @@ -450,6 +450,8 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) { fun shouldOptimize() = config.configuration.getBoolean(KonanConfigKeys.OPTIMIZATION) + val memoryModel = config.memoryModel + override var inVerbosePhase = false override fun log(message: () -> String) { if (inVerbosePhase) { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt index a91673a044f..186c22b4b90 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt @@ -46,6 +46,8 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration val debug: Boolean get() = configuration.getBoolean(KonanConfigKeys.DEBUG) + val memoryModel: MemoryModel get() = configuration.get(KonanConfigKeys.MEMORY_MODEL)!! + init { if (!platformManager.isEnabled(target)) { error("Target ${target.visibleName} is not available on the ${HostManager.hostName} host") diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt index 23609643421..dec1e9c4527 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt @@ -52,6 +52,8 @@ class KonanConfigKeys { = CompilerConfigurationKey.create("list available targets") val MANIFEST_FILE: CompilerConfigurationKey = CompilerConfigurationKey.create("provide manifest addend file") + val MEMORY_MODEL: CompilerConfigurationKey + = CompilerConfigurationKey.create("memory model") val META_INFO: CompilerConfigurationKey> = CompilerConfigurationKey.create("generate metadata") val MODULE_KIND: CompilerConfigurationKey diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/MemoryModel.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/MemoryModel.kt new file mode 100644 index 00000000000..07fe13ca864 --- /dev/null +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/MemoryModel.kt @@ -0,0 +1,10 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ +package org.jetbrains.kotlin.backend.konan + +enum class MemoryModel(val suffix: String) { + STRICT("Strict"), + RELAXED("Relaxed)") +} \ No newline at end of file diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/TestRunnerKind.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/TestRunnerKind.kt index 9abad940da5..1f364540966 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/TestRunnerKind.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/TestRunnerKind.kt @@ -2,8 +2,6 @@ * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ - - package org.jetbrains.kotlin.backend.konan enum class TestRunnerKind { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index 72e4983de7c..50694cce7d3 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -307,12 +307,18 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, } private fun updateReturnRef(value: LLVMValueRef, address: LLVMValueRef) { - store(value, address) + if (context.memoryModel == MemoryModel.STRICT) + store(value, address) + else + call(context.llvm.updateReturnRefFunction, listOf(address, value)) } private fun updateRef(value: LLVMValueRef, address: LLVMValueRef, onStack: Boolean) { if (onStack) { - store(value, address) + if (context.memoryModel == MemoryModel.STRICT) + store(value, address) + else + call(context.llvm.updateStackRefFunction, listOf(address, value)) } else { call(context.llvm.updateHeapRefFunction, listOf(address, value)) } @@ -340,24 +346,6 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, SlotType.ANONYMOUS -> vars.createAnonymousSlot() - SlotType.RETURN_IF_ARENA -> returnSlot.let { - if (it != null) - call(context.llvm.getReturnSlotIfArenaFunction, listOf(it, vars.createAnonymousSlot())) - else { - // Return type is not an object type - can allocate locally. - localAllocs++ - arenaSlot!! - } - } - - is SlotType.PARAM_IF_ARENA -> - if (LLVMTypeOf(vars.load(resultLifetime.slotType.parameter)) != codegen.runtime.objHeaderPtrType) - vars.createAnonymousSlot() - else { - call(context.llvm.getParamSlotIfArenaFunction, - listOf(vars.load(resultLifetime.slotType.parameter), vars.createAnonymousSlot())) - } - else -> throw Error("Incorrect slot type: ${resultLifetime.slotType}") } args + resultSlot @@ -958,7 +946,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, releaseVars() LLVMBuildRet(builder, returnPhi) } - // Do nothing, all paths throw. + // Do nothing, all paths throw. else -> LLVMBuildUnreachable(builder) } } 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 22b64aaa65c..ca06daaea48 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 @@ -426,10 +426,10 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) { val initInstanceFunction = importRtFunction("InitInstance") val initSharedInstanceFunction = importRtFunction("InitSharedInstance") val updateHeapRefFunction = importRtFunction("UpdateHeapRef") + val updateStackRefFunction = importRtFunction("UpdateStackRef") + val updateReturnRefFunction = importRtFunction("UpdateReturnRef") val enterFrameFunction = importRtFunction("EnterFrame") val leaveFrameFunction = importRtFunction("LeaveFrame") - val getReturnSlotIfArenaFunction = importRtFunction("GetReturnSlotIfArena") - val getParamSlotIfArenaFunction = importRtFunction("GetParamSlotIfArena") val lookupOpenMethodFunction = importRtFunction("LookupOpenMethod") val isInstanceFunction = importRtFunction("IsInstance") val checkInstanceFunction = importRtFunction("CheckInstance") 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 265225693de..e3822525c82 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 @@ -1484,39 +1484,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: MapfieldX; - - in llvm ir: - %struct.ObjHeader = type { i32, i32 } - %struct.Object = type { i32, i32 } - - ; Function Attrs: nounwind ssp uwtable - define i32 @fooField2(i8*) #0 { - %2 = alloca i8*, align 8 - %3 = alloca %struct.ObjHeader*, align 8 - %4 = alloca %struct.Object*, align 8 - store i8* %0, i8** %2, align 8 - %5 = load i8*, i8** %2, align 8 - %6 = bitcast i8* %5 to %struct.ObjHeader* - store %struct.ObjHeader* %6, %struct.ObjHeader** %3, align 8 - %7 = load %struct.ObjHeader*, %struct.ObjHeader** %3, align 8 - - %8 = getelementptr inbounds %struct.ObjHeader, %struct.ObjHeader* %7, i64 1; <- (T*)&header[1]; - - %9 = bitcast %struct.ObjHeader* %8 to %struct.Object* - store %struct.Object* %9, %struct.Object** %4, align 8 - %10 = load %struct.Object*, %struct.Object** %4, align 8 - %11 = getelementptr inbounds %struct.Object, %struct.Object* %10, i32 0, i32 0 <- &obj->fieldX - %12 = load i32, i32* %11, align 4 - ret i32 %12 - } - - */ private fun fieldPtrOfClass(thisPtr: LLVMValueRef, value: IrField): LLVMValueRef { val fieldInfo = context.llvmDeclarations.forField(value) diff --git a/runtime/src/main/cpp/Memory.cpp b/runtime/src/main/cpp/Memory.cpp index 57ccfb674b9..cd12a30501e 100644 --- a/runtime/src/main/cpp/Memory.cpp +++ b/runtime/src/main/cpp/Memory.cpp @@ -2365,8 +2365,6 @@ KBoolean Konan_ensureAcyclicAndSet(ObjHeader* where, KInt index, ObjHeader* what return true; } - - void Kotlin_Any_share(ObjHeader* obj) { auto* container = obj->container(); if (Shareable(container)) return;