Devritualization analysis enhancement
This commit is contained in:
+2
-2
@@ -231,7 +231,8 @@ internal object DataFlowIR {
|
||||
: Call(callee, arguments, returnType, irCallSite)
|
||||
|
||||
// TODO: It can be replaced with a pair(AllocInstance, constructor Call), remove.
|
||||
class NewObject(constructor: FunctionSymbol, arguments: List<Edge>, val constructedType: Type, override val irCallSite: IrConstructorCall?)
|
||||
class NewObject(constructor: FunctionSymbol, arguments: List<Edge>,
|
||||
val constructedType: Type, override val irCallSite: IrConstructorCall?)
|
||||
: Call(constructor, arguments, constructedType, irCallSite)
|
||||
|
||||
open class VirtualCall(callee: FunctionSymbol, arguments: List<Edge>,
|
||||
@@ -252,7 +253,6 @@ internal object DataFlowIR {
|
||||
|
||||
class FunctionReference(val symbol: FunctionSymbol, val type: Type, val returnType: Type) : Node()
|
||||
|
||||
// TODO: Add type (similar to arrays)?
|
||||
class FieldRead(val receiver: Edge?, val field: Field, val type: Type, val ir: IrGetField?) : Node()
|
||||
|
||||
class FieldWrite(val receiver: Edge?, val field: Field, val value: Edge, val type: Type) : Node()
|
||||
|
||||
+31
-10
@@ -472,7 +472,7 @@ internal object Devirtualization {
|
||||
|
||||
val nodesMap = mutableMapOf<DataFlowIR.Node, Node>()
|
||||
val constraintGraphBuilder =
|
||||
ConstraintGraphBuilder(nodesMap, functions, typeHierarchy, instantiatingClasses, allTypes, rootSet)
|
||||
ConstraintGraphBuilder(nodesMap, functions, typeHierarchy, instantiatingClasses, allTypes, rootSet, true)
|
||||
constraintGraphBuilder.build()
|
||||
|
||||
DEBUG_OUTPUT(0) {
|
||||
@@ -678,7 +678,8 @@ internal object Devirtualization {
|
||||
val typeHierarchy: TypeHierarchy,
|
||||
val instantiatingClasses: Map<DataFlowIR.Type.Declared, Int>,
|
||||
val allTypes: List<DataFlowIR.Type.Declared>,
|
||||
val rootSet: List<DataFlowIR.FunctionSymbol>) {
|
||||
val rootSet: List<DataFlowIR.FunctionSymbol>,
|
||||
val useTypes: Boolean) {
|
||||
|
||||
private val variables = mutableMapOf<DataFlowIR.Node.Variable, Node>()
|
||||
|
||||
@@ -827,7 +828,10 @@ internal object Devirtualization {
|
||||
val argument = argumentToConstraintNode(arguments[index])
|
||||
argument.addEdge(parameter)
|
||||
}
|
||||
return callee.returns
|
||||
return if (!useTypes || returnType == callee.symbol.returnParameter.type.resolved())
|
||||
callee.returns
|
||||
else
|
||||
doCast(function, callee.returns, returnType)
|
||||
}
|
||||
|
||||
fun doCall(callee: DataFlowIR.FunctionSymbol,
|
||||
@@ -853,7 +857,7 @@ internal object Devirtualization {
|
||||
}
|
||||
} else {
|
||||
calleeConstraintGraph.throws.addEdge(function.throws)
|
||||
if (receiverType == null)
|
||||
if (!useTypes || receiverType == null || receiverType == callee.parameters[0].type.resolved())
|
||||
doCall(calleeConstraintGraph, arguments, returnType)
|
||||
else {
|
||||
val receiverNode = argumentToConstraintNode(arguments[0])
|
||||
@@ -864,6 +868,25 @@ internal object Devirtualization {
|
||||
}
|
||||
}
|
||||
|
||||
fun readField(field: DataFlowIR.Field, actualType: DataFlowIR.Type.Declared): Node {
|
||||
val fieldNode = fieldNode(field)
|
||||
val expectedType = field.type.resolved()
|
||||
return if (!useTypes || actualType == expectedType)
|
||||
fieldNode
|
||||
else
|
||||
doCast(function, fieldNode, actualType)
|
||||
}
|
||||
|
||||
fun writeField(field: DataFlowIR.Field, actualType: DataFlowIR.Type.Declared, value: Node) {
|
||||
val fieldNode = fieldNode(field)
|
||||
val expectedType = field.type.resolved()
|
||||
val castedValue = if (!useTypes || actualType == expectedType)
|
||||
value
|
||||
else
|
||||
doCast(function, value, actualType)
|
||||
castedValue.addEdge(fieldNode)
|
||||
}
|
||||
|
||||
if (node is DataFlowIR.Node.Variable && node.kind != DataFlowIR.VariableKind.Temporary) {
|
||||
var variableNode = variables[node]
|
||||
if (variableNode == null) {
|
||||
@@ -983,20 +1006,18 @@ internal object Devirtualization {
|
||||
}
|
||||
|
||||
is DataFlowIR.Node.FieldRead ->
|
||||
doCast(function, fieldNode(node.field), node.type.resolved())
|
||||
readField(node.field, node.field.type.resolved())
|
||||
|
||||
is DataFlowIR.Node.FieldWrite -> {
|
||||
val fieldNode = fieldNode(node.field)
|
||||
doCast(function, edgeToConstraintNode(node.value), node.type.resolved()).addEdge(fieldNode)
|
||||
writeField(node.field, node.field.type.resolved(), edgeToConstraintNode(node.value))
|
||||
constraintGraph.voidNode
|
||||
}
|
||||
|
||||
is DataFlowIR.Node.ArrayRead ->
|
||||
doCast(function, fieldNode(constraintGraph.arrayItemField), node.type.resolved())
|
||||
readField(constraintGraph.arrayItemField, node.type.resolved())
|
||||
|
||||
is DataFlowIR.Node.ArrayWrite -> {
|
||||
val fieldNode = fieldNode(constraintGraph.arrayItemField)
|
||||
doCast(function, edgeToConstraintNode(node.value), node.type.resolved()).addEdge(fieldNode)
|
||||
writeField(constraintGraph.arrayItemField, node.type.resolved(), edgeToConstraintNode(node.value))
|
||||
constraintGraph.voidNode
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user