Debug: Get rid of descriptors in DebugUtils

This commit is contained in:
Ilya Matveev
2019-07-08 19:58:52 +07:00
committed by Ilya Matveev
parent acdf62fa2e
commit 1b49ea8465
2 changed files with 39 additions and 47 deletions
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * 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. * that can be found in the LICENSE file.
*/ */
@@ -9,18 +9,18 @@ import kotlinx.cinterop.allocArrayOf
import kotlinx.cinterop.memScoped import kotlinx.cinterop.memScoped
import llvm.* import llvm.*
import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.builtins.UnsignedTypes
import org.jetbrains.kotlin.ir.SourceManager.FileEntry import org.jetbrains.kotlin.ir.SourceManager.FileEntry
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.util.SYNTHETIC_OFFSET import org.jetbrains.kotlin.ir.util.SYNTHETIC_OFFSET
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName import org.jetbrains.kotlin.ir.util.isTypeParameter
import org.jetbrains.kotlin.ir.util.isUnsigned
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.konan.CURRENT import org.jetbrains.kotlin.konan.CURRENT
import org.jetbrains.kotlin.konan.KonanVersion import org.jetbrains.kotlin.konan.KonanVersion
import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
internal object DWARF { internal object DWARF {
val producer = "konanc ${KonanVersion.CURRENT} / kotlin-compiler: ${KotlinVersion.CURRENT}" val producer = "konanc ${KonanVersion.CURRENT} / kotlin-compiler: ${KotlinVersion.CURRENT}"
@@ -65,19 +65,17 @@ internal class DebugInfo internal constructor(override val context: Context):Con
val inlinedSubprograms = mutableMapOf<IrFunction, DISubprogramRef>() val inlinedSubprograms = mutableMapOf<IrFunction, DISubprogramRef>()
var builder: DIBuilderRef? = null var builder: DIBuilderRef? = null
var module: DIModuleRef? = null var module: DIModuleRef? = null
var types = mutableMapOf<KotlinType, DITypeOpaqueRef>() var types = mutableMapOf<IrType, DITypeOpaqueRef>()
val llvmTypes = mapOf<KotlinType, LLVMTypeRef>( val llvmTypes = mapOf<IrType, LLVMTypeRef>(
context.builtIns.booleanType to context.llvm.llvmInt8, context.irBuiltIns.booleanType to context.llvm.llvmInt8,
context.builtIns.byteType to context.llvm.llvmInt8, context.irBuiltIns.byteType to context.llvm.llvmInt8,
context.builtIns.charType to context.llvm.llvmInt8, context.irBuiltIns.charType to context.llvm.llvmInt8,
context.builtIns.shortType to context.llvm.llvmInt16, context.irBuiltIns.shortType to context.llvm.llvmInt16,
context.builtIns.intType to context.llvm.llvmInt32, context.irBuiltIns.intType to context.llvm.llvmInt32,
context.builtIns.longType to context.llvm.llvmInt64, context.irBuiltIns.longType to context.llvm.llvmInt64,
context.builtIns.floatType to context.llvm.llvmFloat, context.irBuiltIns.floatType to context.llvm.llvmFloat,
context.builtIns.doubleType to context.llvm.llvmDouble) context.irBuiltIns.doubleType to context.llvm.llvmDouble)
val intTypes = listOf<KotlinType>(context.builtIns.byteType, context.builtIns.shortType, context.builtIns.intType, context.builtIns.longType)
val realTypes = listOf<KotlinType>(context.builtIns.floatType, context.builtIns.doubleType)
val llvmTypeSizes = llvmTypes.map { it.key to LLVMSizeOfTypeInBits(llvmTargetData, it.value) }.toMap() val llvmTypeSizes = llvmTypes.map { it.key to LLVMSizeOfTypeInBits(llvmTargetData, it.value) }.toMap()
val llvmTypeAlignments = llvmTypes.map {it.key to LLVMPreferredAlignmentOfType(llvmTargetData, it.value)}.toMap() val llvmTypeAlignments = llvmTypes.map {it.key to LLVMPreferredAlignmentOfType(llvmTargetData, it.value)}.toMap()
val otherLlvmType = LLVMPointerType(LLVMInt64Type(), 0)!! val otherLlvmType = LLVMPointerType(LLVMInt64Type(), 0)!!
@@ -159,13 +157,12 @@ internal fun generateDebugInfoHeader(context: Context) {
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
internal fun KotlinType.dwarfType(context: Context, targetData: LLVMTargetDataRef): DITypeOpaqueRef { internal fun IrType.dwarfType(context: Context, targetData: LLVMTargetDataRef): DITypeOpaqueRef {
when { when {
this.computePrimitiveBinaryTypeOrNull() != null -> return debugInfoBaseType(context, targetData, this.getJetTypeFqName(false), llvmType(context), encoding(context).value.toInt()) this.computePrimitiveBinaryTypeOrNull() != null -> return debugInfoBaseType(context, targetData, this.render(), llvmType(context), encoding(context).value.toInt())
else -> { else -> {
val classDescriptor = TypeUtils.getClassDescriptor(this)
return when { return when {
classDescriptor != null -> { classOrNull != null -> {
val type = DICreateStructType( val type = DICreateStructType(
refBuilder = context.debugInfo.builder, refBuilder = context.debugInfo.builder,
// TODO: here should be DIFile as scope. // TODO: here should be DIFile as scope.
@@ -182,7 +179,7 @@ internal fun KotlinType.dwarfType(context: Context, targetData: LLVMTargetDataRe
refPlace = null)!! as DITypeOpaqueRef refPlace = null)!! as DITypeOpaqueRef
dwarfPointerType(context, type) dwarfPointerType(context, type)
} }
TypeUtils.isTypeParameter(this) -> //TODO: Type parameter, how to deal with if? this.isTypeParameter() -> //TODO: Type parameter, how to deal with if?
debugInfoBaseType(context, targetData, this.toString(), llvmType(context), encoding(context).value.toInt()) debugInfoBaseType(context, targetData, this.toString(), llvmType(context), encoding(context).value.toInt())
else -> TODO("$this: Does this case really exist?") else -> TODO("$this: Does this case really exist?")
} }
@@ -190,7 +187,7 @@ internal fun KotlinType.dwarfType(context: Context, targetData: LLVMTargetDataRe
} }
} }
internal fun KotlinType.diType(context: Context, llvmTargetData: LLVMTargetDataRef): DITypeOpaqueRef = internal fun IrType.diType(context: Context, llvmTargetData: LLVMTargetDataRef): DITypeOpaqueRef =
context.debugInfo.types.getOrPut(this) { context.debugInfo.types.getOrPut(this) {
dwarfType(context, llvmTargetData) dwarfType(context, llvmTargetData)
} }
@@ -201,17 +198,17 @@ private fun debugInfoBaseType(context:Context, targetData:LLVMTargetDataRef, typ
LLVMSizeOfTypeInBits(targetData, type), LLVMSizeOfTypeInBits(targetData, type),
LLVMPreferredAlignmentOfType(targetData, type).toLong(), encoding) as DITypeOpaqueRef LLVMPreferredAlignmentOfType(targetData, type).toLong(), encoding) as DITypeOpaqueRef
internal val IrFunction.types:List<KotlinType> internal val IrFunction.types:List<IrType>
get() { get() {
val parameters = descriptor.valueParameters.map{it.type} val parameters = valueParameters.map { it.type }
return listOf(descriptor.returnType!!, *parameters.toTypedArray()) return listOf(returnType, *parameters.toTypedArray())
} }
internal fun KotlinType.size(context:Context) = context.debugInfo.llvmTypeSizes.getOrDefault(this, context.debugInfo.otherTypeSize) internal fun IrType.size(context:Context) = context.debugInfo.llvmTypeSizes.getOrDefault(this, context.debugInfo.otherTypeSize)
internal fun KotlinType.alignment(context:Context) = context.debugInfo.llvmTypeAlignments.getOrDefault(this, context.debugInfo.otherTypeAlignment).toLong() internal fun IrType.alignment(context:Context) = context.debugInfo.llvmTypeAlignments.getOrDefault(this, context.debugInfo.otherTypeAlignment).toLong()
internal fun KotlinType.llvmType(context:Context): LLVMTypeRef = context.debugInfo.llvmTypes.getOrElse(this) { internal fun IrType.llvmType(context:Context): LLVMTypeRef = context.debugInfo.llvmTypes.getOrElse(this) {
when(computePrimitiveBinaryTypeOrNull()) { when(computePrimitiveBinaryTypeOrNull()) {
PrimitiveBinaryType.BYTE -> context.llvm.llvmInt8 PrimitiveBinaryType.BYTE -> context.llvm.llvmInt8
PrimitiveBinaryType.SHORT -> context.llvm.llvmInt16 PrimitiveBinaryType.SHORT -> context.llvm.llvmInt16
@@ -223,14 +220,14 @@ internal fun KotlinType.llvmType(context:Context): LLVMTypeRef = context.debugIn
} }
} }
internal fun KotlinType.encoding(context: Context): DwarfTypeKind = when(computePrimitiveBinaryTypeOrNull()) { internal fun IrType.encoding(context: Context): DwarfTypeKind = when(computePrimitiveBinaryTypeOrNull()) {
PrimitiveBinaryType.FLOAT -> DwarfTypeKind.DW_ATE_float PrimitiveBinaryType.FLOAT -> DwarfTypeKind.DW_ATE_float
PrimitiveBinaryType.DOUBLE -> DwarfTypeKind.DW_ATE_float PrimitiveBinaryType.DOUBLE -> DwarfTypeKind.DW_ATE_float
PrimitiveBinaryType.BOOLEAN -> DwarfTypeKind.DW_ATE_boolean PrimitiveBinaryType.BOOLEAN -> DwarfTypeKind.DW_ATE_boolean
PrimitiveBinaryType.POINTER -> DwarfTypeKind.DW_ATE_address PrimitiveBinaryType.POINTER -> DwarfTypeKind.DW_ATE_address
else -> { else -> {
//TODO: not recursive. //TODO: not recursive.
if (UnsignedTypes.isUnsignedType(this)) DwarfTypeKind.DW_ATE_unsigned if (this.isUnsigned()) DwarfTypeKind.DW_ATE_unsigned
else DwarfTypeKind.DW_ATE_signed else DwarfTypeKind.DW_ATE_signed
} }
} }
@@ -242,7 +239,7 @@ internal fun IrFunction.subroutineType(context: Context, llvmTargetData: LLVMTar
return subroutineType(context, llvmTargetData, types) return subroutineType(context, llvmTargetData, types)
} }
internal fun subroutineType(context: Context, llvmTargetData: LLVMTargetDataRef, types: List<KotlinType>): DISubroutineTypeRef { internal fun subroutineType(context: Context, llvmTargetData: LLVMTargetDataRef, types: List<IrType>): DISubroutineTypeRef {
return memScoped { return memScoped {
DICreateSubroutineType(context.debugInfo.builder, allocArrayOf( DICreateSubroutineType(context.debugInfo.builder, allocArrayOf(
types.map { it.diType(context, llvmTargetData) }), types.map { it.diType(context, llvmTargetData) }),
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * 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. * that can be found in the LICENSE file.
*/ */
@@ -11,21 +11,16 @@ import org.jetbrains.kotlin.backend.common.descriptors.allParameters
import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.common.ir.ir2string
import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.backend.konan.descriptors.*
import org.jetbrains.kotlin.backend.konan.descriptors.isArray
import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.backend.konan.ir.*
import org.jetbrains.kotlin.backend.konan.ir.NaiveSourceBasedFileEntryImpl import org.jetbrains.kotlin.backend.konan.llvm.coverage.LLVMCoverageInstrumentation
import org.jetbrains.kotlin.backend.konan.ir.containsNull import org.jetbrains.kotlin.backend.konan.optimizations.DataFlowIR
import org.jetbrains.kotlin.backend.konan.llvm.coverage.*
import org.jetbrains.kotlin.backend.konan.optimizations.*
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.UnsignedType import org.jetbrains.kotlin.builtins.UnsignedType
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptor
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
@@ -615,7 +610,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
private val scope by lazy { private val scope by lazy {
if (!context.shouldContainDebugInfo()) if (!context.shouldContainDebugInfo())
return@lazy null return@lazy null
declaration?.scope() ?: llvmFunction!!.scope(0, subroutineType(context, codegen.llvmTargetData, listOf(context.builtIns.intType))) declaration?.scope() ?: llvmFunction!!.scope(0, subroutineType(context, codegen.llvmTargetData, listOf(context.irBuiltIns.intType)))
} }
override fun location(line: Int, column: Int) = scope?.let { LocationInfo(it, line, column) } override fun location(line: Int, column: Int) = scope?.let { LocationInfo(it, line, column) }
@@ -1174,7 +1169,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
is IrVariable -> if (shouldGenerateDebugInfo(element)) debugInfoLocalVariableLocation( is IrVariable -> if (shouldGenerateDebugInfo(element)) debugInfoLocalVariableLocation(
builder = context.debugInfo.builder, builder = context.debugInfo.builder,
functionScope = locationInfo.scope, functionScope = locationInfo.scope,
diType = element.descriptor.type.diType(context, codegen.llvmTargetData), diType = element.type.diType(context, codegen.llvmTargetData),
name = element.descriptor.name, name = element.descriptor.name,
file = file, file = file,
line = locationInfo.line, line = locationInfo.line,
@@ -1183,7 +1178,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
is IrValueParameter -> debugInfoParameterLocation( is IrValueParameter -> debugInfoParameterLocation(
builder = context.debugInfo.builder, builder = context.debugInfo.builder,
functionScope = locationInfo.scope, functionScope = locationInfo.scope,
diType = element.descriptor.type.diType(context, codegen.llvmTargetData), diType = element.type.diType(context, codegen.llvmTargetData),
name = element.descriptor.name, name = element.descriptor.name,
argNo = function.allParameters.indexOf(element) + 1, argNo = function.allParameters.indexOf(element) + 1,
file = file, file = file,
@@ -1768,9 +1763,9 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
val scope = currentCodeContext.classScope() as? ClassScope ?: return val scope = currentCodeContext.classScope() as? ClassScope ?: return
if (!scope.isExported || !context.shouldContainDebugInfo()) return if (!scope.isExported || !context.shouldContainDebugInfo()) return
val irFile = (currentCodeContext.fileScope() as FileScope).file val irFile = (currentCodeContext.fileScope() as FileScope).file
val sizeInBits = expression.descriptor.type.size(context) val sizeInBits = expression.type.size(context)
scope.offsetInBits += sizeInBits scope.offsetInBits += sizeInBits
val alignInBits = expression.descriptor.type.alignment(context) val alignInBits = expression.type.alignment(context)
scope.offsetInBits = alignTo(scope.offsetInBits, alignInBits) scope.offsetInBits = alignTo(scope.offsetInBits, alignInBits)
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
scope.members.add(DICreateMemberType( scope.members.add(DICreateMemberType(
@@ -1783,7 +1778,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
alignInBits = alignInBits, alignInBits = alignInBits,
offsetInBits = scope.offsetInBits, offsetInBits = scope.offsetInBits,
flags = 0, flags = 0,
type = expression.descriptor.type.diType(context, codegen.llvmTargetData) type = expression.type.diType(context, codegen.llvmTargetData)
)!!) )!!)
} }