DFG: Added function attributes to FunctionSymbol

This commit is contained in:
Igor Chevdar
2018-04-24 15:53:09 +03:00
parent e9622bd347
commit 5212fd8189
2 changed files with 42 additions and 22 deletions
@@ -309,14 +309,14 @@ internal object DFGSerializer {
} }
} }
class FunctionSymbolBase(val parameterTypes: IntArray, val returnType: Int, val isGlobalInitializer: Boolean) { class FunctionSymbolBase(val parameterTypes: IntArray, val returnType: Int, val attributes: Int) {
constructor(data: ArraySlice) : this(data.readIntArray(), data.readInt(), data.readBoolean()) constructor(data: ArraySlice) : this(data.readIntArray(), data.readInt(), data.readInt())
fun write(result: ArraySlice) { fun write(result: ArraySlice) {
result.writeIntArray(parameterTypes) result.writeIntArray(parameterTypes)
result.writeInt(returnType) result.writeInt(returnType)
result.writeBoolean(isGlobalInitializer) result.writeInt(attributes)
} }
} }
@@ -807,7 +807,7 @@ internal object DFGSerializer {
FunctionSymbolBase( FunctionSymbolBase(
symbol.parameterTypes.map { typeMap[it]!! }.toIntArray(), symbol.parameterTypes.map { typeMap[it]!! }.toIntArray(),
typeMap[symbol.returnType]!!, typeMap[symbol.returnType]!!,
symbol.isGlobalInitializer symbol.attributes
) )
val symbol = it.key val symbol = it.key
@@ -971,21 +971,21 @@ internal object DFGSerializer {
} }
val functionSymbols = symbolTable.functionSymbols.map { val functionSymbols = symbolTable.functionSymbols.map {
val isGlobalInitializer = it.base.isGlobalInitializer val attributes = it.base.attributes
val external = it.external val external = it.external
val public = it.public val public = it.public
val private = it.private val private = it.private
when { when {
external != null -> external != null ->
DataFlowIR.FunctionSymbol.External(external.hash, DataFlowIR.FunctionSymbol.External(external.hash,
isGlobalInitializer, external.escapes, external.pointsTo, external.name) attributes, external.escapes, external.pointsTo, external.name)
public != null -> { public != null -> {
val symbolTableIndex = public.index val symbolTableIndex = public.index
if (symbolTableIndex >= 0) if (symbolTableIndex >= 0)
++module.numberOfFunctions ++module.numberOfFunctions
DataFlowIR.FunctionSymbol.Public(public.hash, DataFlowIR.FunctionSymbol.Public(public.hash,
module, symbolTableIndex, isGlobalInitializer, null, public.name).also { module, symbolTableIndex, attributes, null, public.name).also {
publicFunctionsMap.put(it.hash, it) publicFunctionsMap.put(it.hash, it)
} }
} }
@@ -995,7 +995,7 @@ internal object DFGSerializer {
if (symbolTableIndex >= 0) if (symbolTableIndex >= 0)
++module.numberOfFunctions ++module.numberOfFunctions
DataFlowIR.FunctionSymbol.Private(privateFunIndex++, DataFlowIR.FunctionSymbol.Private(privateFunIndex++,
module, symbolTableIndex, isGlobalInitializer, null, private.name) module, symbolTableIndex, attributes, null, private.name)
} }
}.apply { }.apply {
parameterTypes = it.base.parameterTypes.map { types[it] }.toTypedArray() parameterTypes = it.base.parameterTypes.map { types[it] }.toTypedArray()
@@ -43,6 +43,8 @@ import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.IntValue import org.jetbrains.kotlin.resolve.constants.IntValue
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes
import org.jetbrains.kotlin.types.typeUtil.isNothing
import org.jetbrains.kotlin.types.typeUtil.isUnit
internal object DataFlowIR { internal object DataFlowIR {
@@ -122,13 +124,23 @@ internal object DataFlowIR {
var numberOfClasses = 0 var numberOfClasses = 0
} }
abstract class FunctionSymbol(val isGlobalInitializer: Boolean, val name: String?) { object FunctionAttributes {
val IS_GLOBAL_INITIALIZER = 1
val RETURNS_UNIT = 2
val RETURNS_NOTHING = 4
}
abstract class FunctionSymbol(val attributes: Int, val name: String?) {
lateinit var parameterTypes: Array<Type> lateinit var parameterTypes: Array<Type>
lateinit var returnType: Type lateinit var returnType: Type
class External(val hash: Long, isGlobalInitializer: Boolean, val isGlobalInitializer = attributes.and(FunctionAttributes.IS_GLOBAL_INITIALIZER) != 0
val returnsUnit = attributes.and(FunctionAttributes.RETURNS_UNIT) != 0
val returnsNothing = attributes.and(FunctionAttributes.RETURNS_NOTHING) != 0
class External(val hash: Long, attributes: Int,
val escapes: Int?, val pointsTo: IntArray?, name: String? = null) val escapes: Int?, val pointsTo: IntArray?, name: String? = null)
: FunctionSymbol(isGlobalInitializer, name) { : FunctionSymbol(attributes, name) {
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
@@ -147,14 +159,14 @@ internal object DataFlowIR {
} }
abstract class Declared(val module: Module, val symbolTableIndex: Int, abstract class Declared(val module: Module, val symbolTableIndex: Int,
isGlobalInitializer: Boolean, var bridgeTarget: FunctionSymbol?, name: String?) attributes: Int, var bridgeTarget: FunctionSymbol?, name: String?)
: FunctionSymbol(isGlobalInitializer, name) { : FunctionSymbol(attributes, name) {
} }
class Public(val hash: Long, module: Module, symbolTableIndex: Int, class Public(val hash: Long, module: Module, symbolTableIndex: Int,
isGlobalInitializer: Boolean, bridgeTarget: FunctionSymbol?, name: String? = null) attributes: Int, bridgeTarget: FunctionSymbol?, name: String? = null)
: Declared(module, symbolTableIndex, isGlobalInitializer, bridgeTarget, name) { : Declared(module, symbolTableIndex, attributes, bridgeTarget, name) {
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
@@ -173,8 +185,8 @@ internal object DataFlowIR {
} }
class Private(val index: Int, module: Module, symbolTableIndex: Int, class Private(val index: Int, module: Module, symbolTableIndex: Int,
isGlobalInitializer: Boolean, bridgeTarget: FunctionSymbol?, name: String? = null) attributes: Int, bridgeTarget: FunctionSymbol?, name: String? = null)
: Declared(module, symbolTableIndex, isGlobalInitializer, bridgeTarget, name) { : Declared(module, symbolTableIndex, attributes, bridgeTarget, name) {
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
@@ -538,6 +550,13 @@ internal object DataFlowIR {
functionMap[it]?.let { return it } functionMap[it]?.let { return it }
val name = if (it.isExported()) it.symbolName else it.internalName val name = if (it.isExported()) it.symbolName else it.internalName
val returnsUnit = it is ConstructorDescriptor || (!it.isSuspend && it.returnType.isUnit())
val returnsNothing = !it.isSuspend && it.returnType.isNothing()
var attributes = 0
if (returnsUnit)
attributes = attributes or FunctionAttributes.RETURNS_UNIT
if (returnsNothing)
attributes = attributes or FunctionAttributes.RETURNS_NOTHING
val symbol = when { val symbol = when {
it.module != irModule.descriptor || it.isExternal || (it.origin == IrDeclarationOrigin.IR_BUILTINS_STUB) -> { it.module != irModule.descriptor || it.isExternal || (it.origin == IrDeclarationOrigin.IR_BUILTINS_STUB) -> {
val escapesAnnotation = it.descriptor.annotations.findAnnotation(FQ_NAME_ESCAPES) val escapesAnnotation = it.descriptor.annotations.findAnnotation(FQ_NAME_ESCAPES)
@@ -546,7 +565,7 @@ internal object DataFlowIR {
val escapesBitMask = (escapesAnnotation?.allValueArguments?.get(escapesWhoDescriptor.name) as? ConstantValue<Int>)?.value val escapesBitMask = (escapesAnnotation?.allValueArguments?.get(escapesWhoDescriptor.name) as? ConstantValue<Int>)?.value
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val pointsToBitMask = (pointsToAnnotation?.allValueArguments?.get(pointsToOnWhomDescriptor.name) as? ConstantValue<List<IntValue>>)?.value val pointsToBitMask = (pointsToAnnotation?.allValueArguments?.get(pointsToOnWhomDescriptor.name) as? ConstantValue<List<IntValue>>)?.value
FunctionSymbol.External(name.localHash.value, false, escapesBitMask, FunctionSymbol.External(name.localHash.value, attributes, escapesBitMask,
pointsToBitMask?.let { it.map { it.value }.toIntArray() }, takeName { name }) pointsToBitMask?.let { it.map { it.value }.toIntArray() }, takeName { name })
} }
@@ -560,12 +579,12 @@ internal object DataFlowIR {
val bridgeTargetSymbol = if (isSpecialBridge || bridgeTarget == null) null else mapFunction(bridgeTarget) val bridgeTargetSymbol = if (isSpecialBridge || bridgeTarget == null) null else mapFunction(bridgeTarget)
val placeToFunctionsTable = !isAbstract && it !is ConstructorDescriptor && classDescriptor != null val placeToFunctionsTable = !isAbstract && it !is ConstructorDescriptor && classDescriptor != null
&& classDescriptor.kind != ClassKind.ANNOTATION_CLASS && classDescriptor.kind != ClassKind.ANNOTATION_CLASS
&& (it.isOverridableOrOverrides || bridgeTarget != null || !classDescriptor.isFinal()) && (it.isOverridableOrOverrides || bridgeTarget != null || descriptor.name.asString().contains("<bridge-") || !classDescriptor.isFinal())
val symbolTableIndex = if (placeToFunctionsTable) module.numberOfFunctions++ else -1 val symbolTableIndex = if (placeToFunctionsTable) module.numberOfFunctions++ else -1
if (it.isExported()) if (it.isExported())
FunctionSymbol.Public(name.localHash.value, module, symbolTableIndex, false, bridgeTargetSymbol, takeName { name }) FunctionSymbol.Public(name.localHash.value, module, symbolTableIndex, attributes, bridgeTargetSymbol, takeName { name })
else else
FunctionSymbol.Private(privateFunIndex++, module, symbolTableIndex, false, bridgeTargetSymbol, takeName { name }) FunctionSymbol.Private(privateFunIndex++, module, symbolTableIndex, attributes, bridgeTargetSymbol, takeName { name })
} }
} }
functionMap[it] = symbol functionMap[it] = symbol
@@ -586,7 +605,8 @@ internal object DataFlowIR {
functionMap[it]?.let { return it } functionMap[it]?.let { return it }
assert(it.parent !is IrClass) { "All local properties initializers should've been lowered" } assert(it.parent !is IrClass) { "All local properties initializers should've been lowered" }
val symbol = FunctionSymbol.Private(privateFunIndex++, module, -1, true, null, takeName { "${it.symbolName}_init" }) val attributes = FunctionAttributes.IS_GLOBAL_INITIALIZER or FunctionAttributes.RETURNS_UNIT
val symbol = FunctionSymbol.Private(privateFunIndex++, module, -1, attributes, null, takeName { "${it.symbolName}_init" })
functionMap[it] = symbol functionMap[it] = symbol