Java: Refactor to improve performance.

This commit is contained in:
Anders Schack-Mulligen
2019-10-08 11:12:46 +02:00
parent 3c4e877913
commit bf14889077
23 changed files with 353 additions and 224 deletions

View File

@@ -916,7 +916,7 @@ private predicate localFlowStepPlus(
additionalLocalFlowStep(node1, node2, config) and preservesValue = false
) and
node1 != node2 and
cc.validFor(node1) and
cc.relevantFor(node1.getEnclosingCallable()) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
nodeCand(node2, unbind(config))
or
@@ -941,7 +941,7 @@ private predicate localFlowStepPlus(
* Holds if `node1` can step to `node2` in one or more local steps and this
* path can occur as a maximal subsequence of local steps in a dataflow path.
*/
pragma[noinline]
pragma[nomagic]
private predicate localFlowBigStep(
Node node1, Node node2, boolean preservesValue, Configuration config, LocalCallContext callContext
) {
@@ -1734,14 +1734,17 @@ private class PathNodeSink extends PathNode, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, AccessPath ap) {
exists(LocalCallContext localCC | localCC = getMatchingLocalCallContext(cc, node) |
localFlowBigStep(mid.getNode(), node, true, mid.getConfiguration(), localCC) and
exists(LocalCallContext localCC, AccessPath ap0, boolean preservesValue |
localCC = getLocalCallContext(cc, mid.getNode().getEnclosingCallable()) and
localFlowBigStep(mid.getNode(), node, preservesValue, mid.getConfiguration(), localCC) and
cc = mid.getCallContext() and
ap = mid.getAp()
ap0 = mid.getAp()
|
preservesValue = true and
ap = ap0
or
localFlowBigStep(mid.getNode(), node, false, mid.getConfiguration(), localCC) and
cc = mid.getCallContext() and
mid.getAp() instanceof AccessPathNil and
preservesValue = false and
ap0 instanceof AccessPathNil and
ap = node.(AccessPathNilNode).getAp()
)
or

View File

@@ -916,7 +916,7 @@ private predicate localFlowStepPlus(
additionalLocalFlowStep(node1, node2, config) and preservesValue = false
) and
node1 != node2 and
cc.validFor(node1) and
cc.relevantFor(node1.getEnclosingCallable()) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
nodeCand(node2, unbind(config))
or
@@ -941,7 +941,7 @@ private predicate localFlowStepPlus(
* Holds if `node1` can step to `node2` in one or more local steps and this
* path can occur as a maximal subsequence of local steps in a dataflow path.
*/
pragma[noinline]
pragma[nomagic]
private predicate localFlowBigStep(
Node node1, Node node2, boolean preservesValue, Configuration config, LocalCallContext callContext
) {
@@ -1734,14 +1734,17 @@ private class PathNodeSink extends PathNode, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, AccessPath ap) {
exists(LocalCallContext localCC | localCC = getMatchingLocalCallContext(cc, node) |
localFlowBigStep(mid.getNode(), node, true, mid.getConfiguration(), localCC) and
exists(LocalCallContext localCC, AccessPath ap0, boolean preservesValue |
localCC = getLocalCallContext(cc, mid.getNode().getEnclosingCallable()) and
localFlowBigStep(mid.getNode(), node, preservesValue, mid.getConfiguration(), localCC) and
cc = mid.getCallContext() and
ap = mid.getAp()
ap0 = mid.getAp()
|
preservesValue = true and
ap = ap0
or
localFlowBigStep(mid.getNode(), node, false, mid.getConfiguration(), localCC) and
cc = mid.getCallContext() and
mid.getAp() instanceof AccessPathNil and
preservesValue = false and
ap0 instanceof AccessPathNil and
ap = node.(AccessPathNilNode).getAp()
)
or

View File

@@ -916,7 +916,7 @@ private predicate localFlowStepPlus(
additionalLocalFlowStep(node1, node2, config) and preservesValue = false
) and
node1 != node2 and
cc.validFor(node1) and
cc.relevantFor(node1.getEnclosingCallable()) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
nodeCand(node2, unbind(config))
or
@@ -941,7 +941,7 @@ private predicate localFlowStepPlus(
* Holds if `node1` can step to `node2` in one or more local steps and this
* path can occur as a maximal subsequence of local steps in a dataflow path.
*/
pragma[noinline]
pragma[nomagic]
private predicate localFlowBigStep(
Node node1, Node node2, boolean preservesValue, Configuration config, LocalCallContext callContext
) {
@@ -1734,14 +1734,17 @@ private class PathNodeSink extends PathNode, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, AccessPath ap) {
exists(LocalCallContext localCC | localCC = getMatchingLocalCallContext(cc, node) |
localFlowBigStep(mid.getNode(), node, true, mid.getConfiguration(), localCC) and
exists(LocalCallContext localCC, AccessPath ap0, boolean preservesValue |
localCC = getLocalCallContext(cc, mid.getNode().getEnclosingCallable()) and
localFlowBigStep(mid.getNode(), node, preservesValue, mid.getConfiguration(), localCC) and
cc = mid.getCallContext() and
ap = mid.getAp()
ap0 = mid.getAp()
|
preservesValue = true and
ap = ap0
or
localFlowBigStep(mid.getNode(), node, false, mid.getConfiguration(), localCC) and
cc = mid.getCallContext() and
mid.getAp() instanceof AccessPathNil and
preservesValue = false and
ap0 instanceof AccessPathNil and
ap = node.(AccessPathNilNode).getAp()
)
or

View File

@@ -916,7 +916,7 @@ private predicate localFlowStepPlus(
additionalLocalFlowStep(node1, node2, config) and preservesValue = false
) and
node1 != node2 and
cc.validFor(node1) and
cc.relevantFor(node1.getEnclosingCallable()) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
nodeCand(node2, unbind(config))
or
@@ -941,7 +941,7 @@ private predicate localFlowStepPlus(
* Holds if `node1` can step to `node2` in one or more local steps and this
* path can occur as a maximal subsequence of local steps in a dataflow path.
*/
pragma[noinline]
pragma[nomagic]
private predicate localFlowBigStep(
Node node1, Node node2, boolean preservesValue, Configuration config, LocalCallContext callContext
) {
@@ -1734,14 +1734,17 @@ private class PathNodeSink extends PathNode, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, AccessPath ap) {
exists(LocalCallContext localCC | localCC = getMatchingLocalCallContext(cc, node) |
localFlowBigStep(mid.getNode(), node, true, mid.getConfiguration(), localCC) and
exists(LocalCallContext localCC, AccessPath ap0, boolean preservesValue |
localCC = getLocalCallContext(cc, mid.getNode().getEnclosingCallable()) and
localFlowBigStep(mid.getNode(), node, preservesValue, mid.getConfiguration(), localCC) and
cc = mid.getCallContext() and
ap = mid.getAp()
ap0 = mid.getAp()
|
preservesValue = true and
ap = ap0
or
localFlowBigStep(mid.getNode(), node, false, mid.getConfiguration(), localCC) and
cc = mid.getCallContext() and
mid.getAp() instanceof AccessPathNil and
preservesValue = false and
ap0 instanceof AccessPathNil and
ap = node.(AccessPathNilNode).getAp()
)
or

View File

@@ -916,7 +916,7 @@ private predicate localFlowStepPlus(
additionalLocalFlowStep(node1, node2, config) and preservesValue = false
) and
node1 != node2 and
cc.validFor(node1) and
cc.relevantFor(node1.getEnclosingCallable()) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
nodeCand(node2, unbind(config))
or
@@ -941,7 +941,7 @@ private predicate localFlowStepPlus(
* Holds if `node1` can step to `node2` in one or more local steps and this
* path can occur as a maximal subsequence of local steps in a dataflow path.
*/
pragma[noinline]
pragma[nomagic]
private predicate localFlowBigStep(
Node node1, Node node2, boolean preservesValue, Configuration config, LocalCallContext callContext
) {
@@ -1734,14 +1734,17 @@ private class PathNodeSink extends PathNode, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, AccessPath ap) {
exists(LocalCallContext localCC | localCC = getMatchingLocalCallContext(cc, node) |
localFlowBigStep(mid.getNode(), node, true, mid.getConfiguration(), localCC) and
exists(LocalCallContext localCC, AccessPath ap0, boolean preservesValue |
localCC = getLocalCallContext(cc, mid.getNode().getEnclosingCallable()) and
localFlowBigStep(mid.getNode(), node, preservesValue, mid.getConfiguration(), localCC) and
cc = mid.getCallContext() and
ap = mid.getAp()
ap0 = mid.getAp()
|
preservesValue = true and
ap = ap0
or
localFlowBigStep(mid.getNode(), node, false, mid.getConfiguration(), localCC) and
cc = mid.getCallContext() and
mid.getAp() instanceof AccessPathNil and
preservesValue = false and
ap0 instanceof AccessPathNil and
ap = node.(AccessPathNilNode).getAp()
)
or

View File

@@ -648,10 +648,15 @@ private module ImplCommon {
*/
abstract class CallContext extends TCallContext {
abstract string toString();
/** Holds if this call context is relevant for `callable`. */
abstract predicate relevantFor(DataFlowCallable callable);
}
class CallContextAny extends CallContext, TAnyCallContext {
override string toString() { result = "CcAny" }
override predicate relevantFor(DataFlowCallable callable) { any() }
}
abstract class CallContextCall extends CallContext { }
@@ -663,17 +668,29 @@ private module ImplCommon {
)
}
override predicate relevantFor(DataFlowCallable callable) {
recordDataFlowCallSite(getCall(), callable)
}
DataFlowCall getCall() { this = TSpecificCall(result, _, _) }
}
class CallContextSomeCall extends CallContextCall, TSomeCall {
override string toString() { result = "CcSomeCall" }
override predicate relevantFor(DataFlowCallable callable) {
exists(ParameterNode p | this = TSomeCall(p, _) and p.getEnclosingCallable() = callable)
}
}
class CallContextReturn extends CallContext, TReturn {
override string toString() {
exists(DataFlowCall call | this = TReturn(_, call) | result = "CcReturn(" + call + ")")
}
override predicate relevantFor(DataFlowCallable callable) {
exists(DataFlowCall call | this = TReturn(_, call) and call.getEnclosingCallable() = callable)
}
}
/**
@@ -682,28 +699,14 @@ private module ImplCommon {
abstract class LocalCallContext extends TLocalFlowCallContext {
abstract string toString();
abstract predicate validFor(Node n);
}
/**
* Gets a matching local call context given the call context and a node which is in
* the callable the call is targeting.
*/
LocalCallContext getMatchingLocalCallContext(CallContext ctx, Node n) {
if hasUnreachableNode(ctx.(CallContextSpecificCall).getCall(), n.getEnclosingCallable())
then result.(LocalCallContextSpecificCall).getCall() = ctx.(CallContextSpecificCall).getCall()
else result instanceof LocalCallContextAny
/** Holds if this call context is relevant for `callable`. */
abstract predicate relevantFor(DataFlowCallable callable);
}
class LocalCallContextAny extends LocalCallContext, TAnyLocalCall {
override string toString() { result = "LocalCcAny" }
override predicate validFor(Node n) { any() }
}
pragma[noinline]
private predicate hasUnreachableNode(DataFlowCall call, DataFlowCallable callable) {
isUnreachableInCall(any(Node n | n.getEnclosingCallable() = callable), call)
override predicate relevantFor(DataFlowCallable callable) { any() }
}
class LocalCallContextSpecificCall extends LocalCallContext, TSpecificLocalCall {
@@ -715,7 +718,22 @@ private module ImplCommon {
override string toString() { result = "LocalCcCall(" + call + ")" }
override predicate validFor(Node n) { hasUnreachableNode(call, n.getEnclosingCallable()) }
override predicate relevantFor(DataFlowCallable callable) { relevantLocalCCtx(call, callable) }
}
private predicate relevantLocalCCtx(DataFlowCall call, DataFlowCallable callable) {
exists(Node n | n.getEnclosingCallable() = callable and isUnreachableInCall(n, call))
}
/**
* Gets the local call context given the call context and the callable that
* the contexts apply to.
*/
LocalCallContext getLocalCallContext(CallContext ctx, DataFlowCallable callable) {
ctx.relevantFor(callable) and
if relevantLocalCCtx(ctx.(CallContextSpecificCall).getCall(), callable)
then result.(LocalCallContextSpecificCall).getCall() = ctx.(CallContextSpecificCall).getCall()
else result instanceof LocalCallContextAny
}
/** A callable tagged with a relevant return kind. */