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.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<String>) = 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)
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -63,9 +63,15 @@ struct ObjHeader {
|
||||
type_info_ = type_info;
|
||||
}
|
||||
|
||||
static ContainerHeader theStaticObjectsContainer;
|
||||
|
||||
ContainerHeader* container() const {
|
||||
return reinterpret_cast<ContainerHeader*>(
|
||||
reinterpret_cast<uintptr_t>(this) - container_offset_negative_);
|
||||
if (container_offset_negative_ == 0) {
|
||||
return &theStaticObjectsContainer;
|
||||
} else {
|
||||
return reinterpret_cast<ContainerHeader*>(
|
||||
reinterpret_cast<uintptr_t>(this) - container_offset_negative_);
|
||||
}
|
||||
}
|
||||
|
||||
// Unsafe cast to ArrayHeader. Use carefully!
|
||||
|
||||
Reference in New Issue
Block a user