runtime, backend: simplify static objects layout:
mark static objects with container_offset_negative_ == 0
This commit is contained in:
committed by
SvyatoslavScherbina
parent
ddf47e9359
commit
361bb7a101
+12
-38
@@ -11,36 +11,17 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import org.jetbrains.kotlin.types.TypeProjection
|
import org.jetbrains.kotlin.types.TypeProjection
|
||||||
import org.jetbrains.kotlin.types.replace
|
import org.jetbrains.kotlin.types.replace
|
||||||
|
|
||||||
private fun StaticData.objHeader(containerOffsetNegative: Int, typeInfo: ConstPointer): Struct {
|
private fun StaticData.objHeader(typeInfo: ConstPointer): Struct {
|
||||||
assert (containerOffsetNegative >= 0)
|
val containerOffsetNegative = 0 // Static object mark.
|
||||||
return Struct(runtime.objHeaderType, typeInfo, Int32(containerOffsetNegative))
|
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)
|
assert (length >= 0)
|
||||||
|
val containerOffsetNegative = 0 // Static object mark.
|
||||||
return Struct(runtime.arrayHeaderType, typeInfo, Int32(containerOffsetNegative), Int32(length))
|
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<String>) = createKotlinStringLiteral(value.value)
|
internal fun StaticData.createKotlinStringLiteral(value: IrConst<String>) = createKotlinStringLiteral(value.value)
|
||||||
|
|
||||||
internal fun StaticData.createKotlinStringLiteral(value: String): ConstPointer {
|
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)
|
// (use [0 x i8] as body if there are no elements)
|
||||||
val arrayBody = ConstArray(bodyElementType, elements)
|
val arrayBody = ConstArray(bodyElementType, elements)
|
||||||
|
|
||||||
val containerHeader = staticContainerHeader()
|
val compositeType = structType(runtime.arrayHeaderType, arrayBody.llvmType)
|
||||||
|
|
||||||
val compositeType = structType(containerHeader.llvmType, runtime.arrayHeaderType, arrayBody.llvmType)
|
|
||||||
|
|
||||||
val global = this.createGlobal(compositeType, "")
|
val global = this.createGlobal(compositeType, "")
|
||||||
|
|
||||||
val objHeaderPtr = global.pointer.getElementPtr(1)
|
val objHeaderPtr = global.pointer.getElementPtr(0)
|
||||||
val containerHeaderPtr = global.pointer.getElementPtr(0)
|
val arrayHeader = arrayHeader(typeInfo, elements.size)
|
||||||
val containerOffsetNegative = objHeaderPtr.sub(containerHeaderPtr)
|
|
||||||
val arrayHeader = arrayHeader(containerOffsetNegative, typeInfo, elements.size)
|
|
||||||
|
|
||||||
global.setInitializer(Struct(compositeType, containerHeader, arrayHeader, arrayBody))
|
global.setInitializer(Struct(compositeType, arrayHeader, arrayBody))
|
||||||
|
|
||||||
return createRef(arrayType, objHeaderPtr)
|
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 {
|
internal fun StaticData.createKotlinObject(type: KotlinType, body: ConstValue): ConstPointer {
|
||||||
val typeInfo = type.typeInfoPtr!!
|
val typeInfo = type.typeInfoPtr!!
|
||||||
|
|
||||||
val containerHeader = staticContainerHeader()
|
val compositeType = structType(runtime.objHeaderType, body.llvmType)
|
||||||
val compositeType = structType(containerHeader.llvmType, runtime.objHeaderType, body.llvmType)
|
|
||||||
|
|
||||||
val global = this.createGlobal(compositeType, "")
|
val global = this.createGlobal(compositeType, "")
|
||||||
|
|
||||||
val objHeaderPtr = global.pointer.getElementPtr(1)
|
val objHeaderPtr = global.pointer.getElementPtr(0)
|
||||||
val containerHeaderPtr = global.pointer.getElementPtr(0)
|
val objHeader = objHeader(typeInfo)
|
||||||
val containerOffsetNegative = objHeaderPtr.sub(containerHeaderPtr)
|
|
||||||
val objHeader = objHeader(containerOffsetNegative, typeInfo)
|
|
||||||
|
|
||||||
global.setInitializer(Struct(compositeType, containerHeader, objHeader, body))
|
global.setInitializer(Struct(compositeType, objHeader, body))
|
||||||
|
|
||||||
return createRef(type, objHeaderPtr)
|
return createRef(type, objHeaderPtr)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
// Define to 1 to use in multithreaded environment.
|
// Define to 1 to use in multithreaded environment.
|
||||||
#define CONCURRENT 0
|
#define CONCURRENT 0
|
||||||
|
|
||||||
|
ContainerHeader ObjHeader::theStaticObjectsContainer = { CONTAINER_TAG_NOCOUNT };
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Current number of allocated containers.
|
// Current number of allocated containers.
|
||||||
|
|||||||
@@ -63,9 +63,15 @@ struct ObjHeader {
|
|||||||
type_info_ = type_info;
|
type_info_ = type_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ContainerHeader theStaticObjectsContainer;
|
||||||
|
|
||||||
ContainerHeader* container() const {
|
ContainerHeader* container() const {
|
||||||
return reinterpret_cast<ContainerHeader*>(
|
if (container_offset_negative_ == 0) {
|
||||||
reinterpret_cast<uintptr_t>(this) - container_offset_negative_);
|
return &theStaticObjectsContainer;
|
||||||
|
} else {
|
||||||
|
return reinterpret_cast<ContainerHeader*>(
|
||||||
|
reinterpret_cast<uintptr_t>(this) - container_offset_negative_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unsafe cast to ArrayHeader. Use carefully!
|
// Unsafe cast to ArrayHeader. Use carefully!
|
||||||
|
|||||||
Reference in New Issue
Block a user