ClassDescriptor[] cdarray;
TypeDescriptor[] arraytable;
LocalityAnalysis locality;
+ Hashtable<TempDescriptor, TempDescriptor> backuptable;
public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) {
state=st;
public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality) {
this(st, temptovar, typeutil);
this.locality=locality;
+ this.backuptable=new Hashtable<TempDescriptor, TempDescriptor>();
}
/** The buildCode method outputs C code for all the methods. The Flat
* These objects tell the compiler which temps need to be
* allocated. */
- private void generateTempStructs(FlatMethod fm) {
+ private void generateTempStructs(FlatMethod fm, LocalityBinding lb) {
MethodDescriptor md=fm.getMethod();
TaskDescriptor task=fm.getTask();
-
+ Set<TempDescriptor> saveset=state.DSM?locality.getTempSet(lb):null;
ParamsObject objectparams=md!=null?new ParamsObject(md,tag++):new ParamsObject(task, tag++);
+
if (md!=null)
paramstable.put(md, objectparams);
else
objectparams.addPtr(temp);
else
objectparams.addPrim(temp);
+ if(state.DSM&&saveset.contains(temp)) {
+ backuptable.put(temp, temp.createNew());
+ }
}
for(int i=0;i<fm.numTags();i++) {
objecttemps.addPtr(temp);
else
objecttemps.addPrim(temp);
+ if(state.DSM&&saveset.contains(temp)&&
+ !backuptable.containsKey(temp))
+ backuptable.put(temp, temp.createNew());
}
}
+
+ /* Create backup temps */
+ if (state.DSM)
+ for(Iterator<TempDescriptor> tmpit=backuptable.values().iterator();tmpit.hasNext();) {
+ TempDescriptor tmp=tmpit.next();
+ TypeDescriptor type=tmp.getType();
+ if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
+ objecttemps.addPtr(tmp);
+ else
+ objecttemps.addPrim(tmp);
+ }
}
/** This method outputs the following information about classes
/* Classify parameters */
MethodDescriptor md=(MethodDescriptor)methodit.next();
FlatMethod fm=state.getMethodFlat(md);
- generateTempStructs(fm);
+ generateTempStructs(fm, null);
ParamsObject objectparams=(ParamsObject) paramstable.get(md);
TempObject objecttemps=(TempObject) tempstable.get(md);
/* Classify parameters */
TaskDescriptor task=(TaskDescriptor)taskit.next();
FlatMethod fm=state.getMethodFlat(task);
- generateTempStructs(fm);
+ generateTempStructs(fm, null);
ParamsObject objectparams=(ParamsObject) paramstable.get(task);
TempObject objecttemps=(TempObject) tempstable.get(task);
ClassDescriptor cn=md!=null?md.getClassDesc():null;
ParamsObject objectparams=(ParamsObject)paramstable.get(md!=null?md:task);
-
generateHeader(fm, lb, md!=null?md:task,output);
-
TempObject objecttemp=(TempObject) tempstable.get(md!=null?md:task);
if (GENERATEPRECISEGC) {
}
if (current_node.numNext()==0) {
output.print(" ");
- generateFlatNode(fm, current_node, output);
+ generateFlatNode(fm, lb, current_node, output);
if (current_node.kind()!=FKind.FlatReturnNode) {
output.println(" return;");
}
current_node=null;
} else if(current_node.numNext()==1) {
output.print(" ");
- generateFlatNode(fm, current_node, output);
+ generateFlatNode(fm, lb, current_node, output);
FlatNode nextnode=current_node.getNext(0);
if (visited.contains(nextnode)) {
output.println("goto L"+nodetolabel.get(nextnode)+";");
output.println("}\n\n");
}
- /** This method assigns labels to flatnodes */
+ /** This method assigns labels to FlatNodes */
private Hashtable<FlatNode, Integer> assignLabels(FlatMethod fm) {
HashSet tovisit=new HashSet();
}
- /** Generate text string that corresponds to the Temp td. */
+ /** Generate text string that corresponds to the TempDescriptor td. */
private String generateTemp(FlatMethod fm, TempDescriptor td) {
MethodDescriptor md=fm.getMethod();
TaskDescriptor task=fm.getTask();
throw new Error();
}
- private void generateFlatNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
+ private void generateFlatNode(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output) {
switch(fn.kind()) {
case FKind.FlatAtomicEnterNode:
- generateFlatAtomicEnterNode(fm, (FlatAtomicEnterNode) fn, output);
+ generateFlatAtomicEnterNode(fm, lb, (FlatAtomicEnterNode) fn, output);
return;
case FKind.FlatAtomicExitNode:
- generateFlatAtomicExitNode(fm, (FlatAtomicExitNode) fn, output);
+ generateFlatAtomicExitNode(fm, lb, (FlatAtomicExitNode) fn, output);
return;
case FKind.FlatTagDeclaration:
generateFlatTagDeclaration(fm, (FlatTagDeclaration) fn,output);
}
- public void generateFlatAtomicEnterNode(FlatMethod fm, FlatAtomicEnterNode faen, PrintWriter output) {
+ public void generateFlatAtomicEnterNode(FlatMethod fm, LocalityBinding lb, FlatAtomicEnterNode faen, PrintWriter output) {
+ /* Check to see if we need to generate code for this atomic */
+ if (locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
+ return;
+ /* Backup the temps. */
+ for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator();tmpit.hasNext();) {
+ TempDescriptor tmp=tmpit.next();
+ output.println(generateTemp(fm, backuptable.get(tmp))+"="+generateTemp(fm,tmp)+";");
+ }
+ output.println("goto transstart"+faen.getIdentifier()+";");
+
+ /******* Print code to abort transaction *******/
+ output.println("transabort"+faen.getIdentifier()+":");
+
+ /* Restore temps */
+ for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator();tmpit.hasNext();) {
+ TempDescriptor tmp=tmpit.next();
+ output.println(generateTemp(fm, tmp)+"="+generateTemp(fm,backuptable.get(tmp))+";");
+ }
+
+ /******* Tell the runtime to start the transaction *******/
+
+ output.println("transstart"+faen.getIdentifier()+":");
+ output.println("trans=transStart();");
}
- public void generateFlatAtomicExitNode(FlatMethod fm, FlatAtomicExitNode faen, PrintWriter output) {
+ public void generateFlatAtomicExitNode(FlatMethod fm, LocalityBinding lb, FlatAtomicExitNode faen, PrintWriter output) {
+ /* Check to see if we need to generate code for this atomic */
+ if (locality.getAtomic(lb).get(faen).intValue()>0)
+ return;
+
}
private void generateFlatCheckNode(FlatMethod fm, FlatCheckNode fcn, PrintWriter output) {
if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
} else {
-
output.print("((");
if (md.getReturnType().isClass()||md.getReturnType().isArray())
output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
}
}
+ FlatAtomicEnterNode curran=null;
+
private void flattenClass(ClassDescriptor cn) {
Iterator methodit=cn.getMethods();
while(methodit.hasNext()) {
currmd=(MethodDescriptor)methodit.next();
BlockNode bn=state.getMethodBody(currmd);
+
+ if (state.DSM&&currmd.getModifiers().isAtomic()) {
+ curran=new FlatAtomicEnterNode();
+ } else
+ curran=null;
NodePair np=flattenBlockNode(bn);
FlatNode fn=np.getBegin();
if (state.THREAD&&currmd.getModifiers().isSynchronized()) {
fcunlock.addNext(rnflat);
}
} else if (state.DSM&&currmd.getModifiers().isAtomic()) {
- FlatAtomicEnterNode an=new FlatAtomicEnterNode();
- an.addNext(fn);
- fn=an;
+ curran.addNext(fn);
+ fn=curran;
if (np.getEnd().kind()!=FKind.FlatReturnNode) {
- FlatAtomicExitNode aen=new FlatAtomicExitNode();
+ FlatAtomicExitNode aen=new FlatAtomicExitNode(curran);
np.getEnd().addNext(aen);
FlatReturnNode rnflat=new FlatReturnNode(null);
aen.addNext(rnflat);
MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
TempDescriptor thistd=getTempforVar(currmd.getThis());
FlatCall fc=new FlatCall(memd, null, thistd, new TempDescriptor[0]);
- fc.addNext(rnflat);
+ fc.addNext(ln);
ln=fc;
}
+ if (state.DSM&&currmd.getModifiers().isAtomic()) {
+ FlatAtomicExitNode faen=new FlatAtomicExitNode(curran);
+ faen.addNext(ln);
+ ln=faen;
+ }
if (cond!=null) {
cond.getEnd().addNext(ln);
private NodePair flattenAtomicNode(AtomicNode sbn) {
NodePair np=flattenBlockNode(sbn.getBlockNode());
FlatAtomicEnterNode faen=new FlatAtomicEnterNode();
- FlatAtomicExitNode faexn=new FlatAtomicExitNode();
+ FlatAtomicExitNode faexn=new FlatAtomicExitNode(faen);
faen.addNext(np.getBegin());
np.getEnd().addNext(faexn);
return new NodePair(faen, faexn);