5 import Analysis.CallGraph.*;
7 public class SESETree {
12 Hashtable<MethodDescriptor, Set<SESENode>> toanalyze=new Hashtable<MethodDescriptor,Set<SESENode>>();
13 Hashtable<MethodDescriptor, Set<SESENode>> discovered=new Hashtable<MethodDescriptor,Set<SESENode>>();
14 Hashtable<FlatSESEEnterNode, SESENode> sesemap=new Hashtable<FlatSESEEnterNode, SESENode>();
16 public SESETree(State state, TypeUtil typeutil, CallGraph callgraph) {
18 this.typeutil=typeutil;
19 this.callgraph=callgraph;
20 root=new SESENode(null, true);
24 public SESENode getRoot() {
28 public void doAnalysis() {
29 MethodDescriptor main=typeutil.getMain();
30 add(toanalyze, main, root);
31 add(discovered, main, root);
33 while(!toanalyze.isEmpty()) {
34 MethodDescriptor md=toanalyze.keySet().iterator().next();
35 Set<SESENode> context=toanalyze.get(md);
37 FlatMethod fm=state.getMethodFlat(md);
38 analyzeMethod(fm, context);
42 public SESENode getSESE(FlatSESEEnterNode enter) {
43 if (!sesemap.containsKey(enter)) {
44 sesemap.put(enter, new SESENode(enter, false));
46 return sesemap.get(enter);
49 private void analyzeMethod(FlatMethod fm, Set<SESENode> context) {
50 Hashtable<FlatNode, Stack<SESENode>> stacks=new Hashtable<FlatNode, Stack<SESENode>> ();
51 stacks.put(fm, new Stack<SESENode>());
52 HashSet<FlatNode> tovisit=new HashSet<FlatNode>();
53 HashSet<FlatNode> fndiscovered=new HashSet<FlatNode>();
56 while(!tovisit.isEmpty()) {
57 FlatNode fn=tovisit.iterator().next();
59 Stack<SESENode> instack=stacks.get(fm);
61 case FKind.FlatCall: {
62 FlatCall fc=(FlatCall)fn;
64 Set<SESENode> parents;
65 if (instack.isEmpty()) {
68 parents=new HashSet<SESENode>();
69 parents.add(instack.peek());
71 for(Iterator<SESENode> parentit=parents.iterator();parentit.hasNext();) {
72 SESENode parentsese=parentit.next();
73 for(Iterator<MethodDescriptor> calleeit=(fc.getThis()==null?callgraph.getMethods(fc.getMethod()):callgraph.getMethods(fc.getMethod(), fc.getThis().getType())).iterator(); calleeit.hasNext();) {
74 MethodDescriptor md=calleeit.next();
75 if (add(discovered,md, parentsese)) {
76 add(toanalyze, md, parentsese);
82 case FKind.FlatSESEEnterNode: {
83 FlatSESEEnterNode enter=(FlatSESEEnterNode)fn;
84 Set<SESENode> parents;
85 if (instack.isEmpty()) {
88 parents=new HashSet<SESENode>();
89 parents.add(instack.peek());
91 SESENode sese=getSESE(enter);
92 for(Iterator<SESENode> parentit=parents.iterator();parentit.hasNext();) {
93 SESENode parentsese=parentit.next();
94 parentsese.addChild(sese);
96 Stack<SESENode> copy=(Stack<SESENode>)instack.clone();
101 case FKind.FlatSESEExitNode: {
102 FlatSESEExitNode exit=(FlatSESEExitNode)fn;
103 Stack<SESENode> copy=(Stack<SESENode>)instack.clone();
109 for(int i=0;i<fn.numNext();i++) {
110 FlatNode fnext=fn.getNext(i);
111 if (!fndiscovered.contains(fnext)) {
112 fndiscovered.add(fnext);
114 stacks.put(fnext, instack);
122 public static boolean add(Hashtable<MethodDescriptor, Set<SESENode>> discovered, MethodDescriptor md, SESENode sese) {
123 if (!discovered.containsKey(md))
124 discovered.put(md, new HashSet<SESENode>());
125 if (discovered.get(md).contains(sese))
127 discovered.get(md).add(sese);
134 HashSet<SESENode> children;
135 FlatSESEEnterNode node;
136 SESENode(FlatSESEEnterNode node, boolean isRoot) {
137 children=new HashSet<SESENode>();
142 public boolean isLeaf() {
143 return children.isEmpty();
146 public void addChild(SESENode child) {
150 public Set<SESENode> getChildren() {