Tracking globals (#4542)

This commit is contained in:
Alexander Shabalin
2020-11-27 09:30:32 +03:00
committed by Stanislav Erokhin
parent 66de5dceb9
commit 2057e5c8f1
17 changed files with 302 additions and 56 deletions
@@ -1092,9 +1092,9 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
val ctor = codegen.llvmFunction(defaultConstructor)
val initFunction =
if (storageKind == ObjectStorageKind.SHARED && context.config.threadsAreAllowed) {
context.llvm.initSharedInstanceFunction
context.llvm.initSingletonFunction
} else {
context.llvm.initInstanceFunction
context.llvm.initThreadLocalSingleton
}
val args = listOf(objectPtr, typeInfo, ctor)
val newValue = call(initFunction, args, Lifetime.GLOBAL, exceptionHandler)
@@ -499,8 +499,9 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
val allocInstanceFunction = importRtFunction("AllocInstance")
val allocArrayFunction = importRtFunction("AllocArrayInstance")
val initInstanceFunction = importRtFunction("InitInstance")
val initSharedInstanceFunction = importRtFunction("InitSharedInstance")
val initThreadLocalSingleton = importRtFunction("InitThreadLocalSingleton")
val initSingletonFunction = importRtFunction("InitSingleton")
val initAndRegisterGlobalFunction = importRtFunction("InitAndRegisterGlobal")
val updateHeapRefFunction = importRtFunction("UpdateHeapRef")
val updateStackRefFunction = importRtFunction("UpdateStackRef")
val updateReturnRefFunction = importRtFunction("UpdateReturnRef")
@@ -412,15 +412,28 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
appendingTo(bbInit) {
context.llvm.fileInitializers
.forEach { irField ->
if (irField.initializer?.expression !is IrConst<*>?) {
if (irField.storageKind != FieldStorageKind.THREAD_LOCAL) {
if (irField.storageKind != FieldStorageKind.THREAD_LOCAL) {
val address = context.llvmDeclarations.forStaticField(irField).storageAddressAccess.getAddress(
functionGenerationContext
)
val initialValue = if (irField.initializer?.expression !is IrConst<*>?) {
val initialization = evaluateExpression(irField.initializer!!.expression)
val address = context.llvmDeclarations.forStaticField(irField).storageAddressAccess.getAddress(
functionGenerationContext
)
if (irField.storageKind == FieldStorageKind.SHARED_FROZEN)
freeze(initialization, currentCodeContext.exceptionHandler)
storeAny(initialization, address, false)
initialization
} else {
null
}
val needRegistration =
context.memoryModel == MemoryModel.EXPERIMENTAL && // only for the new MM
irField.type.binaryTypeIsReference() && // only for references
(initialValue != null || // which are initialized from heap object
!irField.isFinal) // or are not final
if (needRegistration) {
call(context.llvm.initAndRegisterGlobalFunction, listOf(address, initialValue
?: kNullObjHeaderPtr))
} else if (initialValue != null) {
storeAny(initialValue, address, false)
}
}
}