From 361bb7a1011842225dca15aaa3b1d7360111a7b2 Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Mon, 26 Dec 2016 16:33:24 +0700 Subject: [PATCH] runtime, backend: simplify static objects layout: mark static objects with container_offset_negative_ == 0 --- .../backend/konan/llvm/StaticObjects.kt | 50 +++++-------------- runtime/src/main/cpp/Memory.cpp | 2 + runtime/src/main/cpp/Memory.h | 10 +++- 3 files changed, 22 insertions(+), 40 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticObjects.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticObjects.kt index ba66483a302..7d319411f58 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticObjects.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticObjects.kt @@ -11,36 +11,17 @@ import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeProjection import org.jetbrains.kotlin.types.replace -private fun StaticData.objHeader(containerOffsetNegative: Int, typeInfo: ConstPointer): Struct { - assert (containerOffsetNegative >= 0) +private fun StaticData.objHeader(typeInfo: ConstPointer): Struct { + val containerOffsetNegative = 0 // Static object mark. return Struct(runtime.objHeaderType, typeInfo, Int32(containerOffsetNegative)) } -private fun StaticData.arrayHeader(containerOffsetNegative: Int, typeInfo: ConstPointer, length: Int): Struct { +private fun StaticData.arrayHeader(typeInfo: ConstPointer, length: Int): Struct { assert (length >= 0) + val containerOffsetNegative = 0 // Static object mark. return Struct(runtime.arrayHeaderType, typeInfo, Int32(containerOffsetNegative), Int32(length)) } -private fun requiredPadding(size: Int, align: Int): Int { - val rem = size % align - return (align - rem) % align -} - -private fun StaticData.staticContainerHeader(): Struct { - val CONTAINER_TAG_NOCOUNT = 1 // FIXME: copy-pasted from runtime - val header = Struct(runtime.containerHeaderType, Int32(CONTAINER_TAG_NOCOUNT)) - - // ArrayHeader struct is represented as packed in LLVM; - // so add explicit padding to container's header to make its objects properly aligned: - val llvmSize = LLVMABISizeOfType(llvmTargetData, header.type).toInt() - val paddingSize = requiredPadding(llvmSize, 8) - val padding = ConstArray(int8Type, ByteArray(paddingSize).map { Int8(it) }) - - // TODO: handle such cases more generally by using C types alignments instead of LLVM ones. - - return Struct(header, padding) -} - internal fun StaticData.createKotlinStringLiteral(value: IrConst) = createKotlinStringLiteral(value.value) internal fun StaticData.createKotlinStringLiteral(value: String): ConstPointer { @@ -75,18 +56,14 @@ internal fun StaticData.createKotlinArray(arrayType: KotlinType, elements: List< // (use [0 x i8] as body if there are no elements) val arrayBody = ConstArray(bodyElementType, elements) - val containerHeader = staticContainerHeader() - - val compositeType = structType(containerHeader.llvmType, runtime.arrayHeaderType, arrayBody.llvmType) + val compositeType = structType(runtime.arrayHeaderType, arrayBody.llvmType) val global = this.createGlobal(compositeType, "") - val objHeaderPtr = global.pointer.getElementPtr(1) - val containerHeaderPtr = global.pointer.getElementPtr(0) - val containerOffsetNegative = objHeaderPtr.sub(containerHeaderPtr) - val arrayHeader = arrayHeader(containerOffsetNegative, typeInfo, elements.size) + val objHeaderPtr = global.pointer.getElementPtr(0) + val arrayHeader = arrayHeader(typeInfo, elements.size) - global.setInitializer(Struct(compositeType, containerHeader, arrayHeader, arrayBody)) + global.setInitializer(Struct(compositeType, arrayHeader, arrayBody)) return createRef(arrayType, objHeaderPtr) } @@ -94,17 +71,14 @@ internal fun StaticData.createKotlinArray(arrayType: KotlinType, elements: List< internal fun StaticData.createKotlinObject(type: KotlinType, body: ConstValue): ConstPointer { val typeInfo = type.typeInfoPtr!! - val containerHeader = staticContainerHeader() - val compositeType = structType(containerHeader.llvmType, runtime.objHeaderType, body.llvmType) + val compositeType = structType(runtime.objHeaderType, body.llvmType) val global = this.createGlobal(compositeType, "") - val objHeaderPtr = global.pointer.getElementPtr(1) - val containerHeaderPtr = global.pointer.getElementPtr(0) - val containerOffsetNegative = objHeaderPtr.sub(containerHeaderPtr) - val objHeader = objHeader(containerOffsetNegative, typeInfo) + val objHeaderPtr = global.pointer.getElementPtr(0) + val objHeader = objHeader(typeInfo) - global.setInitializer(Struct(compositeType, containerHeader, objHeader, body)) + global.setInitializer(Struct(compositeType, objHeader, body)) return createRef(type, objHeaderPtr) } diff --git a/runtime/src/main/cpp/Memory.cpp b/runtime/src/main/cpp/Memory.cpp index 2a64f890bc4..289ede0de8d 100644 --- a/runtime/src/main/cpp/Memory.cpp +++ b/runtime/src/main/cpp/Memory.cpp @@ -16,6 +16,8 @@ // Define to 1 to use in multithreaded environment. #define CONCURRENT 0 +ContainerHeader ObjHeader::theStaticObjectsContainer = { CONTAINER_TAG_NOCOUNT }; + namespace { // Current number of allocated containers. diff --git a/runtime/src/main/cpp/Memory.h b/runtime/src/main/cpp/Memory.h index 7927862edfe..e888f2ed2b9 100644 --- a/runtime/src/main/cpp/Memory.h +++ b/runtime/src/main/cpp/Memory.h @@ -63,9 +63,15 @@ struct ObjHeader { type_info_ = type_info; } + static ContainerHeader theStaticObjectsContainer; + ContainerHeader* container() const { - return reinterpret_cast( - reinterpret_cast(this) - container_offset_negative_); + if (container_offset_negative_ == 0) { + return &theStaticObjectsContainer; + } else { + return reinterpret_cast( + reinterpret_cast(this) - container_offset_negative_); + } } // Unsafe cast to ArrayHeader. Use carefully!