package Analysis.TaskStateAnalysis; import java.util.Hashtable; import java.util.Stack; import java.util.Set; import java.util.HashSet; import java.util.Iterator; import java.util.Arrays; import java.util.Vector; import Util.Edge; import Analysis.CallGraph.CallGraph; import IR.SymbolTable; import IR.State; import IR.TagDescriptor; import IR.TaskDescriptor; import IR.MethodDescriptor; import IR.Flat.*; public class TagAnalysis { State state; Hashtable flagmap; Stack tovisit; Hashtable discovered; Hashtable tasktotagbindings; Hashtable tasktoflagstates; CallGraph callgraph; public TagAnalysis(State state, CallGraph callgraph) { this.state=state; this.flagmap=new Hashtable(); this.discovered=new Hashtable(); this.tovisit=new Stack(); this.tasktoflagstates=new Hashtable(); this.tasktotagbindings=new Hashtable(); this.callgraph=callgraph; doAnalysis(); } public Set getFlagStates(TaskDescriptor task) { return (Set)tasktoflagstates.get(task); } private void doAnalysis() { Set rootset=computeRootSet(); computeTagBindings(rootset); TagBinding.SCC scc=TagBinding.DFS.computeSCC(discovered.keySet()); for(int i=0; i targetFStates = ffan.getTargetFStates4NewObj(ffantemp.getType().getClassDesc()); FlagState fs=new FlagState(ffantemp.getType().getClassDesc()); for(Iterator it=ffan.getTempFlagPairs(); it.hasNext();) { TempFlagPair tfp=(TempFlagPair)it.next(); if (ffan.getFlagChange(tfp)) fs=fs.setFlag(tfp.getFlag(), true); else fs=fs.setFlag(tfp.getFlag(), false); } HashSet fsset=new HashSet(); fsset.add(fs); for(Iterator it=ffan.getTempTagPairs(); it.hasNext();) { HashSet oldfsset=fsset; fsset=new HashSet(); TempTagPair ttp=(TempTagPair)it.next(); if (ffan.getTagChange(ttp)) { TagDescriptor tag=ttp.getTag(); if (tag==null&¶mmap!=null&¶mmap.containsKey(ttp.getTagTemp())) { tag=(TagDescriptor)parammap.get(ttp.getTagTemp()); } for(Iterator setit=oldfsset.iterator(); setit.hasNext();) { FlagState fs2=(FlagState)setit.next(); fsset.addAll(Arrays.asList(fs2.setTag(tag))); } } else throw new Error("Don't clear tag in new object allocation"); } for(Iterator setit=fsset.iterator(); setit.hasNext();) { FlagState fs2=(FlagState)setit.next(); if (!flagmap.containsKey(fs2)) flagmap.put(fs2,fs2); else fs2=(FlagState) flagmap.get(fs2); newflags.add(fs2); if(!targetFStates.contains(fs2)) { targetFStates.addElement(fs2); } } } } } } private void computeTagBindings(Set roots) { tovisit.addAll(roots); for(Iterator it=roots.iterator(); it.hasNext();) { TagBinding tb=(TagBinding)it.next(); discovered.put(tb,tb); } while(!tovisit.empty()) { TagBinding tb=(TagBinding) tovisit.pop(); MethodDescriptor md=tb.getMethod(); FlatMethod fm=state.getMethodFlat(md); /* Build map from temps -> tagdescriptors */ Hashtable parammap=new Hashtable(); int offset=md.isStatic() ? 0 : 1; for(int i=0; i=0) { TagDescriptor tag=tb.getBinding(offsetindex); if (tag!=null) { parammap.put(temp,tag); } } } HashSet newtags=new HashSet(); computeCallsFlags(fm, parammap, newtags, tb.getAllocations()); for(Iterator tagit=newtags.iterator(); tagit.hasNext();) { TagBinding newtag=(TagBinding)tagit.next(); Edge e=new Edge(newtag); tb.addEdge(e); } } } }