import java.util.*;
import IR.ClassDescriptor;
import IR.MethodDescriptor;
+import IR.TypeDescriptor;
public class CallGraph {
State state;
}
}
+
+ public Set getMethods(MethodDescriptor md, TypeDescriptor type) {
+ return getMethods(md);
+ }
+
/** Given a call to MethodDescriptor, lists the methods which
could actually be called due to virtual dispatch. */
public Set getMethods(MethodDescriptor md) {
if (fn.kind()==FKind.FlatCall) {
FlatCall fc=(FlatCall)fn;
MethodDescriptor calledmethod=fc.getMethod();
- Set methodsthatcouldbecalled=getMethods(calledmethod);
+ Set methodsthatcouldbecalled=fc.getThis()==null?getMethods(calledmethod):
+ getMethods(calledmethod, fc.getThis().getType());
if (!methodmap.containsKey(md))
methodmap.put(md,new HashSet());
((HashSet)methodmap.get(md)).addAll(methodsthatcouldbecalled);
for (Enumeration en_tags=getTags();en_tags.hasMoreElements();){
TagDescriptor td=(TagDescriptor)en_tags.nextElement();
switch (tags.get(td).intValue()){
- case ONETAG:
- label+=", "+td.toString()+"(1)";
- break;
- case MULTITAGS:
- label+=", "+td.toString()+"(n)";
- break;
- default:
- break;
+ case ONETAG:
+ if (label==null)
+ label=td.toString()+"(1)";
+ else
+ label+=", "+td.toString()+"(1)";
+ break;
+ case MULTITAGS:
+ if (label==null)
+ label=td.toString()+"(n)";
+ else
+ label+=", "+td.toString()+"(n)";
+ break;
+ default:
+ break;
}
}
+ if (label==null)
+ return "";
return label;
}
--- /dev/null
+package Analysis.TaskStateAnalysis;
+
+import java.util.Hashtable;
+import java.util.Stack;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Iterator;
+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<scc.numSCC();i++) {
+ Set component=scc.getSCC(i);
+ HashSet flagset=new HashSet();
+ for(Iterator compit=flagset.iterator();compit.hasNext();) {
+ TagBinding tb=(TagBinding)compit.next();
+ flagset.addAll(tb.getAllocations());
+ for(Iterator edgeit=tb.edges();edgeit.hasNext();) {
+ Edge e=(Edge)edgeit.next();
+ TagBinding tb2=(TagBinding)e.getTarget();
+ flagset.addAll(tb2.getAllocations());
+ }
+ }
+ for(Iterator compit=flagset.iterator();compit.hasNext();) {
+ TagBinding tb=(TagBinding)compit.next();
+ tb.getAllocations().addAll(flagset);
+ }
+ }
+
+ SymbolTable tasktable=state.getTaskSymbolTable();
+ for(Iterator taskit=tasktable.getDescriptorsIterator();taskit.hasNext();) {
+ TaskDescriptor task=(TaskDescriptor)taskit.next();
+ HashSet roottags=(HashSet)tasktotagbindings.get(task);
+ HashSet taskflags=(HashSet)tasktoflagstates.get(task);
+ for(Iterator tagit=roottags.iterator();tagit.hasNext();) {
+ TagBinding tb=(TagBinding)tagit.next();
+ taskflags.addAll(tb.getAllocations());
+ }
+ }
+ }
+
+ private Set computeRootSet() {
+ HashSet rootset=new HashSet();
+ SymbolTable tasktable=state.getTaskSymbolTable();
+ for(Iterator taskit=tasktable.getDescriptorsIterator();taskit.hasNext();) {
+ TaskDescriptor task=(TaskDescriptor)taskit.next();
+ HashSet roottags=new HashSet();
+ HashSet taskflags=new HashSet();
+ FlatMethod fm=state.getMethodFlat(task);
+ computeCallsFlags(fm, null, roottags, taskflags);
+ rootset.addAll(roottags);
+ tasktotagbindings.put(task,roottags);
+ tasktoflagstates.put(task,taskflags);
+ }
+ return rootset;
+ }
+
+private void computeCallsFlags(FlatMethod fm, Hashtable parammap, Set tagbindings, Set newflags) {
+ Set nodeset=fm.getNodeSet();
+ for(Iterator nodeit=nodeset.iterator();nodeit.hasNext();) {
+ FlatNode fn=(FlatNode)nodeit.next();
+ if(fn.kind()==FKind.FlatCall) {
+ FlatCall fc=(FlatCall)fn;
+ MethodDescriptor nodemd=fc.getMethod();
+ Set methodset=fc.getThis()==null?callgraph.getMethods(nodemd):
+ callgraph.getMethods(nodemd, fc.getThis().getType());
+
+ for(Iterator methodit=methodset.iterator();methodit.hasNext();) {
+ MethodDescriptor md=(MethodDescriptor) methodit.next();
+ TagBinding nodetb=new TagBinding(md);
+ for(int i=0;i<md.numParameters();i++) {
+ TempDescriptor temp=fc.getArg(i);
+ TagDescriptor tag=temp.getTag();
+ if (tag==null&¶mmap!=null&¶mmap.containsKey(temp)) {
+ tag=(TagDescriptor)parammap.get(temp);
+ }
+ if (tag!=null)
+ nodetb.setBinding(i,tag);
+ }
+ if (!discovered.containsKey(nodetb)) {
+ discovered.put(nodetb,nodetb);
+ tovisit.add(nodetb);
+ } else
+ nodetb=(TagBinding)discovered.get(nodetb);
+ tagbindings.add(nodetb);
+ }
+ } else if (fn.kind()==FKind.FlatFlagActionNode) {
+ FlatFlagActionNode ffan=(FlatFlagActionNode)fn;
+ if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
+ TempDescriptor ffantemp=null;
+ {
+ /* Compute type */
+
+ Iterator it=ffan.getTempFlagPairs();
+ if (it.hasNext()) {
+ TempFlagPair tfp=(TempFlagPair)it.next();
+ ffantemp=tfp.getTemp();
+ } else {
+ it=ffan.getTempTagPairs();
+ if (!it.hasNext())
+ throw new Error();
+ TempTagPair ttp=(TempTagPair)it.next();
+ ffantemp=ttp.getTemp();
+ }
+ }
+ 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);
+ }
+ for(Iterator it=ffan.getTempTagPairs();it.hasNext();) {
+ 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());
+ }
+ fs=fs.setTag(tag);
+ } else
+ throw new Error("Don't clear tag in new object allocation");
+ }
+ if (!flagmap.containsKey(fs))
+ flagmap.put(fs,fs);
+ else
+ fs=(FlagState) flagmap.get(fs);
+ newflags.add(fs);
+ }
+ }
+ }
+}
+
+ 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<fm.numParameters();i++) {
+ TempDescriptor temp=fm.getParameter(i);
+ int offsetindex=i-offset;
+ if (offsetindex>=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);
+ }
+ }
+ }
+}
--- /dev/null
+package Analysis.TaskStateAnalysis;
+import IR.MethodDescriptor;
+import IR.TagDescriptor;
+import Util.GraphNode;
+import java.util.HashSet;
+import java.util.Set;
+
+public class TagBinding extends GraphNode {
+ private MethodDescriptor md;
+ private TagDescriptor[] tdarray;
+ private HashSet allocations;
+
+ public TagBinding(MethodDescriptor md) {
+ this.md=md;
+ tdarray=new TagDescriptor[md.numParameters()];
+ allocations=new HashSet();
+ }
+
+ public String toString() {
+ String st=md.toString();
+ for(int i=0;i<tdarray.length;i++)
+ st+=tdarray[i]+" ";
+ return st;
+ }
+
+ public Set getAllocations() {
+ return allocations;
+ }
+
+ public void setBinding(int i, TagDescriptor td) {
+ tdarray[i]=td;
+ }
+
+ public MethodDescriptor getMethod() {
+ return md;
+ }
+
+ public TagDescriptor getBinding(int i) {
+ return tdarray[i];
+ }
+
+ public boolean equals(Object o) {
+ if (o instanceof TagBinding) {
+ TagBinding tb=(TagBinding)o;
+ if (md!=tb.md)
+ return false;
+ for(int i=0;i<tdarray.length;i++)
+ if (tdarray[i]!=null) {
+ if (!tdarray[i].equals(tb.tdarray[i]))
+ return false;
+ } else if(tb.tdarray[i]!=null)
+ return false;
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ int hashcode=md.hashCode();
+ for(int i=0;i<tdarray.length;i++) {
+ if (tdarray[i]!=null)
+ hashcode^=tdarray[i].hashCode();
+ }
+ return hashcode;
+ }
+}
import java.io.FileWriter;
import java.io.FileOutputStream;
-
public class TaskAnalysis {
State state;
Hashtable flagstates;
Hashtable flags;
Hashtable extern_flags;
Queue<FlagState> toprocess;
-
+ TagAnalysis taganalysis;
+
TypeUtil typeutil;
-
+
/**
* Class Constructor
*
* @param state a flattened State object
* @see State
*/
- public TaskAnalysis(State state)
+ public TaskAnalysis(State state, TagAnalysis taganalysis)
{
this.state=state;
this.typeutil=new TypeUtil(state);
+ this.taganalysis=taganalysis;
}
/** Builds a table of flags for each class in the Bristlecone program.
* @see FlagState
*/
- private void analyseTasks(FlagState fs) {
+private void analyseTasks(FlagState fs) {
ClassDescriptor cd=fs.getClassDescriptor();
Hashtable<FlagState,FlagState> sourcenodes=(Hashtable<FlagState,FlagState>)flagstates.get(cd);
System.out.println("Task: "+taskname);
//***********
-
-
/** counter to keep track of the number of parameters (of the task being analyzed) that
* are satisfied by the flagstate.
*/
int trigger_ctr=0;
TempDescriptor temp=null;
FlatMethod fm = state.getMethodFlat(td);
-
+
for(int i=0; i < td.numParameters(); i++) {
FlagExpressionNode fen=td.getFlag(td.getParameter(i));
TagExpressionList tel=td.getTag(td.getParameter(i));
-
+
/** Checking to see if the parameter is of the same type/class as the
* flagstate's and also if the flagstate fs triggers the given task*/
if (typeutil.isSuperorType(td.getParamType(i).getClassDesc(),cd)
if (trigger_ctr>1)
throw new Error("Illegal Operation: A single flagstate cannot satisfy more than one parameter of a task.");
-
+
//** debug
System.out.println("Task:" + taskname +" is triggered");
-
-
- //Iterating through the nodes
- FlatNode fn=fm.methodEntryNode();
-
- HashSet tovisit= new HashSet();
- HashSet visited= new HashSet();
-
- tovisit.add(fn);
- while(!tovisit.isEmpty()) {
- FlatNode fn1 = (FlatNode)tovisit.iterator().next();
- tovisit.remove(fn1);
- visited.add(fn1);
- // Queue all of the next nodes
- for(int i = 0; i < fn1.numNext(); i++) {
- FlatNode nn=fn1.getNext(i);
- if (!visited.contains(nn))
- tovisit.add(nn);
+
+
+ Set newstates=taganalysis.getFlagStates(td);
+ for(Iterator fsit=newstates.iterator();fsit.hasNext();) {
+ FlagState fsnew=(FlagState) fsit.next();
+ if (! ((Hashtable<FlagState,FlagState>)flagstates.get(fsnew.getClassDescriptor())).containsKey(fsnew)) {
+ ((Hashtable<FlagState,FlagState>)flagstates.get(fsnew.getClassDescriptor())).put(fsnew, fsnew);
+ toprocess.add(fsnew);
}
+ }
+
+ //Iterating through the nodes
+ Set nodeset=fm.getNodeSet();
+
+ for(Iterator nodeit=nodeset.iterator();nodeit.hasNext();) {
+ FlatNode fn1 = (FlatNode) nodeit.next();
+
if (fn1.kind()==FKind.FlatFlagActionNode) {
FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
if (ffan.getTaskType() == FlatFlagActionNode.PRE) {
if (ffan.getTempFlagPairs().hasNext()||ffan.getTempTagPairs().hasNext())
throw new Error("PRE FlagActions not supported");
- } else if (ffan.getTaskType() == FlatFlagActionNode.NEWOBJECT) {
- //***
- System.out.println("NEWOBJ");
- //***
- FlagState fsnew=evalNewObjNode(ffan);
- //Have we seen this node yet
- if(fsnew!=null){
- if (! ((Hashtable<FlagState,FlagState>)flagstates.get(fsnew.getClassDescriptor())).containsKey(fsnew)) {
- ((Hashtable<FlagState,FlagState>)flagstates.get(fsnew.getClassDescriptor())).put(fsnew, fsnew);
- toprocess.add(fsnew);
- }
- }
+
} else if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
//***
System.out.println("TASKEXIT");
//***
-
- Vector<FlagState> fsv_taskexit=evalTaskExitNode(ffan,cd,fs,temp);
+
+ Vector<FlagState> fsv_taskexit=evalTaskExitNode(ffan,cd,fs,temp);
for(Enumeration en=fsv_taskexit.elements();en.hasMoreElements();){
- FlagState fs_taskexit=(FlagState)en.nextElement();
- if (!sourcenodes.containsKey(fs_taskexit)) {
- toprocess.add(fs_taskexit);
-
- }
- //seen this node already
- fs_taskexit=canonicalizeFlagState(sourcenodes,fs_taskexit);
- FEdge newedge=new FEdge(fs_taskexit,taskname);
- //FEdge newedge=new FEdge(fs_taskexit,td);
- fs.addEdge(newedge);
- }
+ FlagState fs_taskexit=(FlagState)en.nextElement();
+ if (!sourcenodes.containsKey(fs_taskexit)) {
+ toprocess.add(fs_taskexit);
+
+ }
+ //seen this node already
+ fs_taskexit=canonicalizeFlagState(sourcenodes,fs_taskexit);
+ FEdge newedge=new FEdge(fs_taskexit,taskname);
+ //FEdge newedge=new FEdge(fs_taskexit,td);
+ fs.addEdge(newedge);
+ }
}
}
}
}
}
+
/** Determines whether the given flagstate satisfies a
* single parameter in the given task.
* @param fen FlagExpressionNode
* @see FlagState
*/
- private FlagState evalNewObjNode(FlatNode nn){
+private FlagState evalNewObjNode(FlatNode nn){
- ClassDescriptor cd_new=((FlatNew)nn.getPrev(0)).getType().getClassDesc();
+ ClassDescriptor cd_new=((FlatNew)nn.getPrev(0)).getType().getClassDesc();
- //TempDescriptor[] tdArray = ((FlatFlagActionNode)nn).readsTemps();
-
- //if (tdArray.length==0)
- // return null;
-
- //Under the safe assumption that all the temps in FFAN.NewObject node are of the same type(class)
- //ClassDescriptor cd_new=tdArray[0].getType().getClassDesc();
-
- FlagState fstemp=new FlagState(cd_new);
-
- for(Iterator it_tfp=((FlatFlagActionNode)nn).getTempFlagPairs();it_tfp.hasNext();) {
- TempFlagPair tfp=(TempFlagPair)it_tfp.next();
- if (! (tfp.getFlag()==null))// condition checks if the new object was created without any flag setting
- {
- fstemp=fstemp.setFlag(tfp.getFlag(),((FlatFlagActionNode)nn).getFlagChange(tfp));
- }
-
- else
- break;
- }
- for(Iterator it_ttp=((FlatFlagActionNode)nn).getTempTagPairs();it_ttp.hasNext();) {
- TempTagPair ttp=(TempTagPair)it_ttp.next();
- if (! (ttp.getTag()==null)){
- fstemp=fstemp.setTag(ttp.getTag());
- }
- else
- break;
-
- }
- return fstemp;
+ //TempDescriptor[] tdArray = ((FlatFlagActionNode)nn).readsTemps();
+
+ //if (tdArray.length==0)
+ // return null;
+
+ //Under the safe assumption that all the temps in FFAN.NewObject node are of the same type(class)
+ //ClassDescriptor cd_new=tdArray[0].getType().getClassDesc();
+
+ FlagState fstemp=new FlagState(cd_new);
+
+ for(Iterator it_tfp=((FlatFlagActionNode)nn).getTempFlagPairs();it_tfp.hasNext();) {
+ TempFlagPair tfp=(TempFlagPair)it_tfp.next();
+ if (! (tfp.getFlag()==null))// condition checks if the new object was created without any flag setting
+ {
+ fstemp=fstemp.setFlag(tfp.getFlag(),((FlatFlagActionNode)nn).getFlagChange(tfp));
+ }
+
+ else
+ break;
+ }
+ for(Iterator it_ttp=((FlatFlagActionNode)nn).getTempTagPairs();it_ttp.hasNext();) {
+ TempTagPair ttp=(TempTagPair)it_ttp.next();
+ if (! (ttp.getTag()==null)){
+ fstemp=fstemp.setTag(ttp.getTag());
+ }
+ else
+ break;
+
+ }
+ return fstemp;
}
private Vector<FlagState> evalTaskExitNode(FlatNode nn,ClassDescriptor cd,FlagState fs, TempDescriptor temp){
task AcceptConnection(ServerSocket ss{SocketPending}) {
tag t=new tag(link);
ChatSocket cs=new ChatSocket() {Initialized}{t};
- Socket s=new Socket() {}{t};
- cs.sock=s;
- ss.accept(s);
- s.write("Please choose a chatroom".getBytes());
+ cs.sock=ss.accept(t);
+ cs.sock.write("Please choose a chatroom".getBytes());
}
task ReadRequest(ChatSocket cs{Initialized}{link l}, Socket s{IOPending}{link l}) {
return s;
}
+ public Socket accept(tag td) {
+ Socket s=new Socket(){}{td};
+ int newfd=nativeaccept(s);
+ s.setFD(newfd);
+ return s;
+ }
+
/* Lets caller pass in their own Socket object. */
public void accept(Socket s) {
int newfd=nativeaccept(s);
MethodDescriptor md=(MethodDescriptor)mainit.next();
if (md.numParameters()!=1)
continue;
- if (md.getParameter(0).getType().getArrayCount()!=1)
+ Descriptor pd=md.getParameter(0);
+ TypeDescriptor tpd=(pd instanceof TagVarDescriptor)?((TagVarDescriptor)pd).getType():((VarDescriptor)pd).getType();
+ if (tpd.getArrayCount()!=1)
continue;
- if (!md.getParameter(0).getType().getSymbol().equals("String"))
+ if (!tpd.getSymbol().equals("String"))
continue;
if (!md.getModifiers().isStatic())
TempDescriptor temp=objecttemps.getPointer(i);
if (temp.getType().isNull())
output.println(" void * "+temp.getSafeSymbol()+";");
+ else if(temp.getType().isTag())
+ output.println(" struct "+
+ (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
else
output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
}
output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis()));
}
for(int i=0;i<fc.numArgs();i++) {
- VarDescriptor var=md.getParameter(i);
+ Descriptor var=md.getParameter(i);
TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
if (objectparams.isParamPtr(paramtemp)) {
TempDescriptor targ=fc.getArg(i);
output.print(", ");
- output.print("(struct "+md.getParamType(i).getSafeSymbol() +" *)"+generateTemp(fm, targ));
+ TypeDescriptor td=md.getParamType(i);
+ if (td.isTag())
+ output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol() +" *)"+generateTemp(fm, targ));
+ else
+ output.print("(struct "+md.getParamType(i).getSafeSymbol() +" *)"+generateTemp(fm, targ));
}
}
output.println("};");
}
}
for(int i=0;i<fc.numArgs();i++) {
- VarDescriptor var=md.getParameter(i);
+ Descriptor var=md.getParameter(i);
TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
if (objectparams.isParamPrim(paramtemp)) {
TempDescriptor targ=fc.getArg(i);
FlatFieldNode ffn=new FlatFieldNode(nn.getField(), tmp, out_temp);
return new NodePair(ffn,ffn);
} else {
- TempDescriptor tmp=getTempforVar(nn.getVar());
+ TempDescriptor tmp=getTempforVar(nn.isTag()?nn.getTagVar():nn.getVar());
+ if (nn.isTag()) {
+ //propagate tag
+ out_temp.setTag(tmp.getTag());
+ }
FlatOpNode fon=new FlatOpNode(out_temp, tmp, null, new Operation(Operation.ASSIGN));
return new NodePair(fon,fon);
}
public static final int FlatCheckNode=14;
public static final int FlatBackEdge=15;
public static final int FlatTagDeclaration=16;
+ public static final int FlatMethod=17;
}
for(Iterator it=temptagpairs.keySet().iterator();it.hasNext();) {
TempTagPair ttp=(TempTagPair)it.next();
temps.add(ttp.getTemp());
+ temps.add(ttp.getTagTemp());
}
return (TempDescriptor[]) temps.toArray(new TempDescriptor [temps.size()]);
}
}
public String toString() {
- return "FlatFlagActionNode";
+ String st="FlatFlagActionNode";
+ for(Iterator it=tempflagpairs.keySet().iterator();it.hasNext();) {
+ TempFlagPair tfp=(TempFlagPair)it.next();
+ st+=getFlagChange(tfp)?"":"!";
+ st+=tfp.getTemp()+" "+tfp.getFlag()+",";
+ }
+ for(Iterator it=temptagpairs.keySet().iterator();it.hasNext();) {
+ TempTagPair ttp=(TempTagPair)it.next();
+ st+=getTagChange(ttp)?"":"!";
+ st+=ttp.getTemp()+" "+ttp.getTag()+"("+ttp.getTagTemp()+"),";
+ }
+
+ return st;
}
}
return task;
}
+ public int kind() {
+ return FKind.FlatMethod;
+ }
+
public void addParameterTemp(TempDescriptor t) {
parameterTemps.add(t);
}
return method_entry;
}
+ /** This method returns a set of the nodes in this flat representation */
public Set getNodeSet() {
HashSet tovisit=new HashSet();
public TagDescriptor getTag() {
return tag;
}
+
+ public void setTag(TagDescriptor tag) {
+ this.tag=tag;
+ }
}
this.td=td;
}
public int hashCode() {
- return tagd.hashCode()^td.hashCode()^tagt.hashCode();
+ return td.hashCode()^tagt.hashCode();
}
public TempDescriptor getTemp() {
if (!(o instanceof TempTagPair))
return false;
TempTagPair ttp=(TempTagPair)o;
- return ttp.tagd.equals(tagd)&&ttp.tagt==tagt&&ttp.td==td;
+ if (ttp.tagt==tagt&&ttp.td==td) {
+ if (ttp.tagd!=null) {
+ if (!ttp.tagd.equals(tagd))
+ throw new Error();
+ } else if (tagd!=null)
+ throw new Error();
+
+ return true;
+ } else return false;
}
public String toString() {
if (numParameters()!=md.numParameters())
return false;
for(int i=0;i<numParameters();i++) {
- TypeDescriptor td1=getParameter(i).getType();
- TypeDescriptor td2=md.getParameter(i).getType();
+ Descriptor d1=getParameter(i);
+ Descriptor d2=md.getParameter(i);
+ TypeDescriptor td1=(d1 instanceof TagVarDescriptor)?((TagVarDescriptor)d1).getType():((VarDescriptor)d1).getType();
+ TypeDescriptor td2=(d2 instanceof TagVarDescriptor)?((TagVarDescriptor)d2).getType():((VarDescriptor)d2).getType();
if (!td1.equals(td2))
return false;
}
paramtable.add(vd);
}
+ public void addTagParameter(TypeDescriptor type, String paramname) {
+ if (paramname.equals("this"))
+ throw new Error("Can't have parameter named this");
+ TagVarDescriptor vd=new TagVarDescriptor(null, paramname);
+
+ params.add(vd);
+ if (paramtable.getFromSameScope(paramname)!=null) {
+ throw new Error("Parameter "+paramname+" already defined");
+ }
+ paramtable.add(vd);
+ }
+
public int numParameters() {
return params.size();
}
- public VarDescriptor getParameter(int i) {
- return (VarDescriptor)params.get(i);
+ public Descriptor getParameter(int i) {
+ return (Descriptor) params.get(i);
}
public String getParamName(int i) {
- return ((VarDescriptor)params.get(i)).getName();
+ return ((Descriptor)params.get(i)).getSymbol();
}
public TypeDescriptor getParamType(int i) {
- return ((VarDescriptor)params.get(i)).getType();
+ Descriptor d=(Descriptor)params.get(i);
+ if (d instanceof VarDescriptor)
+ return ((VarDescriptor)params.get(i)).getType();
+ else if (d instanceof TagVarDescriptor)
+ return new TypeDescriptor(TypeDescriptor.TAG);
+ else throw new Error();
}
public String toString() {
return td;
}
+ public TypeDescriptor getType() {
+ return new TypeDescriptor(TypeDescriptor.TAG);
+ }
+
public boolean equals(Object o) {
if (o instanceof TagVarDescriptor) {
TagVarDescriptor tvd=(TagVarDescriptor)o;
- return tvd.identifier.equals(identifier)&&tvd.td.equals(td);
+ if (tvd.identifier.equals(identifier)) {
+ if (tvd.td!=null) {
+ if (!tvd.td.equals(td))
+ throw new Error();
+ } else if (td!=null)
+ throw new Error();
+ return true;
+ }
}
return false;
}
public int hashCode() {
- return identifier.hashCode()^td.hashCode();
+ return identifier.hashCode();
}
public String toString() {
ParseNodeVector pnv=paramlist.getChildren();
for(int i=0;i<pnv.size();i++) {
ParseNode paramn=pnv.elementAt(i);
- TypeDescriptor type=parseTypeDescriptor(paramn);
- ParseNode tmp=paramn;
- while (tmp.getChild("single")==null) {
- type=type.makeArray(state);
- tmp=tmp.getChild("array");
+ if (isNode(paramn, "tag_parameter")) {
+ String paramname=paramn.getChild("single").getTerminal();
+ TypeDescriptor type=new TypeDescriptor(TypeDescriptor.TAG);
+ md.addTagParameter(type, paramname);
+ } else {
+ TypeDescriptor type=parseTypeDescriptor(paramn);
+
+ ParseNode tmp=paramn;
+ while (tmp.getChild("single")==null) {
+ type=type.makeArray(state);
+ tmp=tmp.getChild("array");
+ }
+ String paramname=tmp.getChild("single").getTerminal();
+
+ md.addParameter(type, paramname);
}
- String paramname=tmp.getChild("single").getTerminal();
-
- md.addParameter(type,paramname);
}
}
package IR.Tree;
import IR.NameDescriptor;
+import IR.Descriptor;
import IR.VarDescriptor;
+import IR.TagVarDescriptor;
import IR.TypeDescriptor;
import IR.FieldDescriptor;
public class NameNode extends ExpressionNode {
NameDescriptor name;
- VarDescriptor vd;
+ Descriptor vd;
FieldDescriptor fd;
ExpressionNode en;
this.en=en;
}
- public void setVar(VarDescriptor vd) {
+ public void setVar(Descriptor vd) {
this.vd=vd;
}
return fd;
}
+ public boolean isTag() {
+ return (vd instanceof TagVarDescriptor);
+ }
+
public VarDescriptor getVar() {
- return vd;
+ return (VarDescriptor) vd;
+ }
+
+ public TagVarDescriptor getTagVar() {
+ return (TagVarDescriptor) vd;
}
public TypeDescriptor getType() {
return en.getType();
else if (fd!=null)
return fd.getType();
+ else if (isTag())
+ return new TypeDescriptor(TypeDescriptor.TAG);
else
- return vd.getType();
+ return ((VarDescriptor)vd).getType();
}
NameDescriptor getName() {
throw new Error("Undefined class "+name);
td.setClassDescriptor(field_cd);
return;
- }
- throw new Error();
+ } else if (td.isTag())
+ return;
+ else
+ throw new Error();
}
public void checkField(ClassDescriptor cd, FieldDescriptor fd) {
throw new Error("Name "+varname+" undefined");
}
if (d instanceof VarDescriptor) {
- nn.setVar((VarDescriptor)d);
+ nn.setVar(d);
} else if (d instanceof FieldDescriptor) {
nn.setField((FieldDescriptor)d);
nn.setVar((VarDescriptor)nametable.get("this")); /* Need a pointer to this */
+ } else if (d instanceof TagVarDescriptor) {
+ nn.setVar(d);
} else throw new Error("Wrong type of descriptor");
if (td!=null)
if (!typeutil.isSuperorType(td,nn.getType()))
public class TagDeclarationNode extends BlockStatementNode {
String name;
- String type;
+ String tagtype;
TagVarDescriptor tvd;
- public TagDeclarationNode(String name, String type) {
+ public TagDeclarationNode(String name, String tagtype) {
this.name=name;
- this.type=type;
- tvd=new TagVarDescriptor(new TagDescriptor(type), name);
+ this.tagtype=tagtype;
+ tvd=new TagVarDescriptor(new TagDescriptor(tagtype), name);
}
public String printNode(int indent) {
- return "Tag "+name+"=new("+type+")";
+ return "Tag "+name+"=new("+tagtype+")";
}
public TagVarDescriptor getTagVarDescriptor() {
return name;
}
- public String getType() {
- return type;
+ public String getTagType() {
+ return tagtype;
}
public int kind() {
public static final int DOUBLE=8;
public static final int VOID=9;
public static final int NULL=10;
- public static final int CLASS=11;
+ public static final int TAG=11;
+ public static final int CLASS=12;
int arraycount;
return "D";
else if (isFloat())
return "F";
+ else if (isTag())
+ return "T";
else throw new Error();
}
}
public boolean isPtr() {
- return (isClass()||isNull());
+ return (isClass()||isNull()||isTag());
}
public boolean isIntegerType() {
public boolean isClass() {
return type==CLASS;
}
+
+ public boolean isTag() {
+ return type==TAG;
+ }
public TypeDescriptor(NameDescriptor name) {
super(name.toString());
this.arraycount=0;
}
- private TypeDescriptor(String st) {
+ public TypeDescriptor(String st) {
super(st);
+ this.type=CLASS;
+ this.class_desc=null;
+ this.arraycount=0;
}
public ClassDescriptor getClassDesc() {
return "void";
else if (type==NULL)
return "null";
+ else if (type==TAG)
+ return TypeUtil.TagClass;
else throw new Error();
}
}
if (possiblesuper.equals(cd2))
return true;
+ if ((possiblesuper.isTag() && !cd2.isTag())||
+ (!possiblesuper.isTag() && cd2.isTag()))
+ return false;
+
//Handle arrays
if (cd2.isArray()||possiblesuper.isArray()) {
// Object is super class of all arrays
(possiblesuper.isArray()||possiblesuper.isPtr()))
return false;
else
- throw new Error();
+ throw new Error("Case not handled:"+possiblesuper+" "+cd2);
}
import IR.State;
import IR.TypeUtil;
import Analysis.TaskStateAnalysis.TaskAnalysis;
+import Analysis.CallGraph.CallGraph;
+import Analysis.TaskStateAnalysis.TagAnalysis;
public class Main {
bf.buildFlat();
if (state.TASKSTATE) {
- TaskAnalysis ta=new TaskAnalysis(state);
+ CallGraph callgraph=new CallGraph(state);
+ TagAnalysis taganalysis=new TagAnalysis(state, callgraph);
+
+ TaskAnalysis ta=new TaskAnalysis(state, taganalysis);
ta.taskAnalysis();
}
IR/AssignOperation.class IR/ClassDescriptor.class IR/Descriptor.class \
IR/FieldDescriptor.class IR/FlagDescriptor.class \
IR/MethodDescriptor.class IR/NameDescriptor.class IR/Operation.class \
-IR/State.class IR/SymbolTable.class IR/TaskDescriptor.class \
+IR/State.class IR/SymbolTable.class IR/TagDescriptor.class \
+IR/TagVarDescriptor.class IR/TaskDescriptor.class \
IR/TypeDescriptor.class IR/TypeUtil.class IR/VarDescriptor.class \
-IR/Virtual.class IR/Tree/ArrayAccessNode.class \
+IR/Virtual.class IR/Flat/BuildCode.class IR/Flat/BuildFlat.class \
+IR/Flat/FKind.class IR/Flat/FlatBackEdge.class IR/Flat/FlatCall.class \
+IR/Flat/FlatCastNode.class IR/Flat/FlatCheckNode.class \
+IR/Flat/FlatCondBranch.class IR/Flat/FlatElementNode.class \
+IR/Flat/FlatFieldNode.class IR/Flat/FlatFlagActionNode.class \
+IR/Flat/FlatLiteralNode.class IR/Flat/FlatMethod.class \
+IR/Flat/FlatNew.class IR/Flat/FlatNode.class IR/Flat/FlatNop.class \
+IR/Flat/FlatOpNode.class IR/Flat/FlatReturnNode.class \
+IR/Flat/FlatSetElementNode.class IR/Flat/FlatSetFieldNode.class \
+IR/Flat/FlatTagDeclaration.class IR/Flat/NodePair.class \
+IR/Flat/ParamsObject.class IR/Flat/TempDescriptor.class \
+IR/Flat/TempFlagPair.class IR/Flat/TempObject.class \
+IR/Flat/TempTagPair.class IR/Tree/ArrayAccessNode.class \
IR/Tree/AssignmentNode.class IR/Tree/BlockExpressionNode.class \
IR/Tree/BlockNode.class IR/Tree/BlockStatementNode.class \
IR/Tree/BuildIR.class IR/Tree/CastNode.class \
IR/Tree/NameNode.class IR/Tree/OpNode.class IR/Tree/ParseNode.class \
IR/Tree/ParseNodeDOTVisitor.class IR/Tree/ParseNodeVector.class \
IR/Tree/ReturnNode.class IR/Tree/SemanticCheck.class \
-IR/Tree/SubBlockNode.class IR/Tree/TaskExitNode.class \
-IR/Tree/TreeNode.class IR/Tree/Walkable.class IR/Flat/BuildCode.class \
-IR/Flat/BuildFlat.class IR/Flat/FKind.class IR/Flat/FlatCall.class \
-IR/Flat/FlatCastNode.class IR/Flat/FlatCheckNode.class \
-IR/Flat/FlatCondBranch.class IR/Flat/FlatElementNode.class \
-IR/Flat/FlatFieldNode.class IR/Flat/FlatFlagActionNode.class \
-IR/Flat/FlatLiteralNode.class IR/Flat/FlatMethod.class \
-IR/Flat/FlatNew.class IR/Flat/FlatNode.class IR/Flat/FlatNop.class \
-IR/Flat/FlatOpNode.class IR/Flat/FlatReturnNode.class \
-IR/Flat/FlatSetElementNode.class IR/Flat/FlatSetFieldNode.class \
-IR/Flat/NodePair.class IR/Flat/ParamsObject.class \
-IR/Flat/TempDescriptor.class IR/Flat/TempFlagPair.class \
-IR/Flat/TempObject.class Util/Relation.class
+IR/Tree/SubBlockNode.class IR/Tree/TagDeclarationNode.class \
+IR/Tree/TagEffect.class IR/Tree/TagExpressionList.class \
+IR/Tree/TaskExitNode.class IR/Tree/TreeNode.class \
+IR/Tree/Walkable.class Analysis/TaskStateAnalysis/FEdge.class \
+Analysis/TaskStateAnalysis/FlagState.class \
+Analysis/TaskStateAnalysis/TEdge.class \
+Analysis/TaskStateAnalysis/TagAnalysis.class \
+Analysis/TaskStateAnalysis/TagBinding.class \
+Analysis/TaskStateAnalysis/TaskAnalysis.class \
+Analysis/TaskStateAnalysis/TaskNode.class \
+Analysis/CallGraph/CallGraph.class Util/Edge.class \
+Util/GraphNode.class Util/Relation.class
+
all: Parse/Sym.class Parse/Parser.class $(CLASSFILES) javadoc
pn.addChild(name);
RESULT=pn;
:}
+ |
+ TAG variable_declarator_id:name {:
+ ParseNode pn=new ParseNode("tag_parameter");
+ pn.addChild(name);
+ RESULT=pn;
+ :}
// | FINAL type variable_declarator_id
;
//throws_opt ::=