Class PurityGraph
- java.lang.Object
-
- soot.jimple.toolkits.annotation.purity.PurityGraph
-
public class PurityGraph extends Object
Purity graphs are mutable structures that are updated in-place. You can safely hash graphs. Equality comparison means isomorphism (equal nodes, equal edges). Modifications with respect to the article: - "unanalizable call" are treated by first constructing a conservative callee graph where all parameters escape globally and return points to the global node, and then applying the standard analysable call construction - unanalysable calls add a mutation on the global node; the "field" is named "outside-world" and models the mutation of any static field, but also side-effects by native methods, such as I/O, that make methods impure (see below). - Whenever a method mutates the global node, it is marked as "impure" (this can be due to a side-effect or static field mutation), even if the global node is not reachable from parameter nodes through outside edges. It seems to me it was a defect from the article ? TODO: see if we must take the global node into account also when stating whether a parameter is read-only or safe. - "simplifyXXX" functions are experimental... they may be unsound, and thus, not used now. NOTE: A lot of precision degradation comes from sequences of the form this.field = y; z = this.field in initialisers: the second statement creates a load node because, as a parameter, this may have escaped and this.field may be externally modified in-between the two instructions. I am not sure this can actually happen in an initialiser... in a a function called directly and only by initialisers. For the moment, summary of unanalised methods are either pure, completely impure (modify args & side-effects) or partially impure (modify args but not the global node). We should really be able to specify more precisely which arguments are r/o or safe within this methods. E.g., the analysis java.lang.String: void getChars(int,int,char [],int) imprecisely finds that this is not safe (because of the internal call to System.arraycopy that, in general, may introduce aliases) => it pollutes many things (e.g., StringBuffer append(String), and thus, exception constructors, etc.)
-
-
Field Summary
Fields Modifier and Type Field Description protected MultiMap<PurityNode,PurityEdge>backEdgesprotected MultiMap<PurityNode,Local>backLocalsstatic booleandoCheckprotected MultiMap<PurityNode,PurityEdge>edgesprotected Set<PurityNode>globEscapeprotected MultiMap<Local,PurityNode>localsprotected MultiMap<PurityNode,String>mutatedprotected Set<PurityNode>nodesprotected Set<PurityNode>paramNodesprotected Set<PurityNode>ret
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description Objectclone()static PurityGraphconservativeGraph(SootMethod m, boolean withEffect)Conservative constructor for unanalysable calls.booleanequals(Object o)static PurityGraphfreshGraph(SootMethod m)Special constructor for "pure" methods returning a fresh object.protected Set<PurityNode>getEscaping()inthashCode()protected intinternalParamStatus(PurityNode p)protected voidinternalPassEdges(Set<PurityEdge> toColor, Set<PurityNode> dest, boolean consider_inside)protected voidinternalPassNode(PurityNode node, Set<PurityNode> dest, boolean consider_inside)protected voidinternalPassNodes(Set<PurityNode> toColor, Set<PurityNode> dest, boolean consider_inside)booleanisPure()Call this on the merge of graphs at all return points of a method to know whether the method is pure.booleanisPureConstructor()We use a less restrictive notion of purity for constructors: pure constructors can mutate fields of this.protected booleanlocalsPut(Local local, PurityNode node)protected booleanlocalsPutAll(Local local, Set<PurityNode> nodes)protected booleanlocalsRemove(Local local)protected voidmergeNodes(PurityNode src, PurityNode dst)Utility function to merge node src into dst; src is removedintparamStatus(int param)Call this on the merge of graphs at all return points of a method to know whether an object passed as method parameter is read only (PARAM_RO), read write (PARAM_RW), or safe (PARAM_SAFE).protected voidremoveNode(PurityNode n)Utility function to remove a node & all adjacent edgesprotected voidsanityCheck()Sanity check.intthisStatus()
-
-
-
Field Detail
-
doCheck
public static final boolean doCheck
- See Also:
- Constant Field Values
-
nodes
protected Set<PurityNode> nodes
-
paramNodes
protected Set<PurityNode> paramNodes
-
edges
protected MultiMap<PurityNode,PurityEdge> edges
-
locals
protected MultiMap<Local,PurityNode> locals
-
ret
protected Set<PurityNode> ret
-
globEscape
protected Set<PurityNode> globEscape
-
backEdges
protected MultiMap<PurityNode,PurityEdge> backEdges
-
backLocals
protected MultiMap<PurityNode,Local> backLocals
-
mutated
protected MultiMap<PurityNode,String> mutated
-
-
Method Detail
-
conservativeGraph
public static PurityGraph conservativeGraph(SootMethod m, boolean withEffect)
Conservative constructor for unanalysable calls.Note: this gives a valid summary for all native methods, including Thread.start().
- Parameters:
withEffect- add a mutated abstract field for the global node to account for side-effects in the environment (I/O, etc.).
-
freshGraph
public static PurityGraph freshGraph(SootMethod m)
Special constructor for "pure" methods returning a fresh object. (or simply pure if returns void or primitive).
-
sanityCheck
protected void sanityCheck()
Sanity check. Used internally for debugging!
-
internalPassEdges
protected void internalPassEdges(Set<PurityEdge> toColor, Set<PurityNode> dest, boolean consider_inside)
-
internalPassNode
protected void internalPassNode(PurityNode node, Set<PurityNode> dest, boolean consider_inside)
-
internalPassNodes
protected void internalPassNodes(Set<PurityNode> toColor, Set<PurityNode> dest, boolean consider_inside)
-
getEscaping
protected Set<PurityNode> getEscaping()
-
isPure
public boolean isPure()
Call this on the merge of graphs at all return points of a method to know whether the method is pure.
-
isPureConstructor
public boolean isPureConstructor()
We use a less restrictive notion of purity for constructors: pure constructors can mutate fields of this.- See Also:
isPure()
-
internalParamStatus
protected int internalParamStatus(PurityNode p)
-
paramStatus
public int paramStatus(int param)
Call this on the merge of graphs at all return points of a method to know whether an object passed as method parameter is read only (PARAM_RO), read write (PARAM_RW), or safe (PARAM_SAFE). Returns PARAM_RW for primitive-type parameters.
-
thisStatus
public int thisStatus()
- See Also:
isParamReadOnly
-
localsRemove
protected final boolean localsRemove(Local local)
-
localsPut
protected final boolean localsPut(Local local, PurityNode node)
-
localsPutAll
protected final boolean localsPutAll(Local local, Set<PurityNode> nodes)
-
removeNode
protected final void removeNode(PurityNode n)
Utility function to remove a node & all adjacent edges
-
mergeNodes
protected final void mergeNodes(PurityNode src, PurityNode dst)
Utility function to merge node src into dst; src is removed
-
-