2 import IR.Tree.FlagExpressionNode;
3 import IR.Tree.DNFFlag;
4 import IR.Tree.DNFFlagAtom;
5 import IR.Tree.TagExpressionList;
6 import IR.Tree.OffsetNode;
12 import Analysis.TaskStateAnalysis.FlagState;
13 import Analysis.TaskStateAnalysis.FlagComparator;
14 import Analysis.TaskStateAnalysis.OptionalTaskDescriptor;
15 import Analysis.TaskStateAnalysis.Predicate;
16 import Analysis.TaskStateAnalysis.SafetyAnalysis;
17 import Analysis.TaskStateAnalysis.TaskIndex;
18 import Analysis.Locality.LocalityAnalysis;
19 import Analysis.Locality.LocalityBinding;
20 import Analysis.Locality.DiscoverConflicts;
21 import Analysis.CallGraph.CallGraph;
22 import Analysis.Prefetch.*;
23 import Analysis.Loops.WriteBarrier;
24 import Analysis.Locality.TypeAnalysis;
26 public class BuildCode {
29 Hashtable paramstable;
34 String localsprefix="___locals___";
35 String fcrevert="___fcrevert___";
36 String paramsprefix="___params___";
37 String oidstr="___nextobject___";
38 String nextobjstr="___nextobject___";
39 String localcopystr="___localcopy___";
40 public static boolean GENERATEPRECISEGC=false;
41 public static String PREFIX="";
42 public static String arraytype="ArrayObject";
43 public static int flagcount = 0;
46 protected int maxtaskparams=0;
47 private int maxcount=0;
48 ClassDescriptor[] cdarray;
49 TypeDescriptor[] arraytable;
50 LocalityAnalysis locality;
51 Hashtable<LocalityBinding, TempDescriptor> reverttable;
52 Hashtable<LocalityBinding, Hashtable<TempDescriptor, TempDescriptor>> backuptable;
55 HashSet<FlatSESEEnterNode> setSESEtoGen;
56 boolean nonSESEpass=true;
61 public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, PrefetchAnalysis pa) {
62 this(st, temptovar, typeutil, null, sa, pa);
65 public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, PrefetchAnalysis pa) {
66 this(st, temptovar, typeutil, locality, null, pa);
69 public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, SafetyAnalysis sa, PrefetchAnalysis pa) {
73 callgraph=new CallGraph(state);
75 oidstr="___objlocation___";
76 this.temptovar=temptovar;
77 paramstable=new Hashtable();
78 tempstable=new Hashtable();
79 fieldorder=new Hashtable();
80 flagorder=new Hashtable();
81 this.typeutil=typeutil;
82 virtualcalls=new Virtual(state,locality);
84 this.locality=locality;
85 this.reverttable=new Hashtable<LocalityBinding, TempDescriptor>();
86 this.backuptable=new Hashtable<LocalityBinding, Hashtable<TempDescriptor, TempDescriptor>>();
87 this.wb=new WriteBarrier(locality, st);
89 if (state.SINGLETM&&state.DCOPTS) {
90 TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph);
91 this.dc=new DiscoverConflicts(locality, st, typeanalysis);
95 setSESEtoGen = new HashSet<FlatSESEEnterNode>();
98 /** The buildCode method outputs C code for all the methods. The Flat
99 * versions of the methods must already be generated and stored in
100 * the State object. */
102 public void buildCode() {
103 /* Create output streams to write to */
104 PrintWriter outclassdefs=null;
105 PrintWriter outstructs=null;
106 PrintWriter outrepairstructs=null;
107 PrintWriter outmethodheader=null;
108 PrintWriter outmethod=null;
109 PrintWriter outvirtual=null;
110 PrintWriter outtask=null;
111 PrintWriter outtaskdefs=null;
112 PrintWriter outoptionalarrays=null;
113 PrintWriter optionalheaders=null;
116 outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
117 outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
118 outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
119 outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
120 outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
122 outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
123 outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
124 if (state.OPTIONAL) {
125 outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
126 optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
129 if (state.structfile!=null) {
130 outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
132 } catch (Exception e) {
137 /* Build the virtual dispatch tables */
138 buildVirtualTables(outvirtual);
140 /* Output includes */
141 outmethodheader.println("#ifndef METHODHEADERS_H");
142 outmethodheader.println("#define METHODHEADERS_H");
143 outmethodheader.println("#include \"structdefs.h\"");
145 outmethodheader.println("#include \"dstm.h\"");
147 outmethodheader.println("#include \"tm.h\"");
148 if (state.ABORTREADERS) {
149 outmethodheader.println("#include \"abortreaders.h\"");
150 outmethodheader.println("#include <setjmp.h>");
153 /* Output Structures */
154 outputStructs(outstructs);
156 // Output the C class declarations
157 // These could mutually reference each other
158 outputClassDeclarations(outclassdefs);
160 // Output function prototypes and structures for parameters
161 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
162 while(it.hasNext()) {
163 ClassDescriptor cn=(ClassDescriptor)it.next();
164 generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
166 outclassdefs.close();
169 /* Map flags to integers */
170 /* The runtime keeps track of flags using these integers */
171 it=state.getClassSymbolTable().getDescriptorsIterator();
172 while(it.hasNext()) {
173 ClassDescriptor cn=(ClassDescriptor)it.next();
177 generateTaskStructs(outstructs, outmethodheader);
179 /* Outputs generic task structures if this is a task
181 outputTaskTypes(outtask);
184 /* Build the actual methods */
185 outputMethods(outmethod);
189 while( !setSESEtoGen.isEmpty() ) {
190 FlatSESEEnterNode fsen = setSESEtoGen.iterator().next();
191 setSESEtoGen.remove(fsen);
192 generateMethodSESE(fsen, fsen.getEnclosingFlatMeth(), null, outmethod);
195 assert setSESEtoGen.isEmpty();
199 /* Output code for tasks */
200 outputTaskCode(outtaskdefs, outmethod);
202 /* Record maximum number of task parameters */
203 outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
204 } else if (state.main!=null) {
205 /* Generate main method */
206 outputMainMethod(outmethod);
209 /* Generate information for task with optional parameters */
210 if (state.TASK&&state.OPTIONAL) {
211 generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
212 outoptionalarrays.close();
215 /* Output structure definitions for repair tool */
216 if (state.structfile!=null) {
217 buildRepairStructs(outrepairstructs);
218 outrepairstructs.close();
222 outmethodheader.println("#endif");
223 outmethodheader.close();
225 outstructs.println("#endif");
230 /* This code just generates the main C method for java programs.
231 * The main C method packs up the arguments into a string array
232 * and passes it to the java main method. */
234 private void outputMainMethod(PrintWriter outmethod) {
235 outmethod.println("int main(int argc, const char *argv[]) {");
236 outmethod.println(" int i;");
238 outmethod.println("#ifdef TRANSSTATS \n");
239 outmethod.println("handle();\n");
240 outmethod.println("#endif\n");
242 if (state.THREAD||state.DSM||state.SINGLETM) {
243 outmethod.println("initializethreads();");
246 outmethod.println("if (dstmStartup(argv[1])) {");
247 if (GENERATEPRECISEGC) {
248 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-2);");
250 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-2);");
253 if (GENERATEPRECISEGC) {
254 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
256 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
260 outmethod.println(" for(i=2;i<argc;i++) {");
262 outmethod.println(" for(i=1;i<argc;i++) {");
263 outmethod.println(" int length=strlen(argv[i]);");
264 if (GENERATEPRECISEGC) {
265 outmethod.println(" struct ___String___ *newstring=NewString(NULL, argv[i], length);");
267 outmethod.println(" struct ___String___ *newstring=NewString(argv[i], length);");
270 outmethod.println(" ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-2]=newstring;");
272 outmethod.println(" ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
273 outmethod.println(" }");
276 MethodDescriptor md=typeutil.getMain();
277 ClassDescriptor cd=typeutil.getMainClass();
279 outmethod.println(" {");
280 if (GENERATEPRECISEGC) {
281 if (state.DSM||state.SINGLETM) {
282 outmethod.print(" struct "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
284 outmethod.print(" struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
285 outmethod.println("1, NULL,"+"stringarray};");
286 if (state.DSM||state.SINGLETM)
287 outmethod.println(" "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
289 outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
291 if (state.DSM||state.SINGLETM)
292 outmethod.println(" "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
294 outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
296 outmethod.println(" }");
299 outmethod.println("}");
302 if (state.THREAD||state.DSM||state.SINGLETM) {
303 outmethod.println("pthread_mutex_lock(&gclistlock);");
304 outmethod.println("threadcount--;");
305 outmethod.println("pthread_cond_signal(&gccond);");
306 outmethod.println("pthread_mutex_unlock(&gclistlock);");
309 if (state.DSM||state.SINGLETM) {
310 outmethod.println("#ifdef TRANSSTATS \n");
311 outmethod.println("printf(\"****** Transaction Stats ******\\n\");");
312 outmethod.println("printf(\"numTransAbort= %d\\n\", numTransAbort);");
313 outmethod.println("printf(\"numTransCommit= %d\\n\", numTransCommit);");
314 outmethod.println("printf(\"nSoftAbort= %d\\n\", nSoftAbort);");
316 outmethod.println("printf(\"nchashSearch= %d\\n\", nchashSearch);");
317 outmethod.println("printf(\"nmhashSearch= %d\\n\", nmhashSearch);");
318 outmethod.println("printf(\"nprehashSearch= %d\\n\", nprehashSearch);");
319 outmethod.println("printf(\"nRemoteReadSend= %d\\n\", nRemoteSend);");
320 outmethod.println("printf(\"bytesSent= %d\\n\", bytesSent);");
321 outmethod.println("printf(\"bytesRecv= %d\\n\", bytesRecv);");
322 } else if (state.SINGLETM) {
323 outmethod.println("printf(\"nSoftAbortAbort= %d\\n\", nSoftAbortAbort);");
324 outmethod.println("printf(\"nSoftAbortCommit= %d\\n\", nSoftAbortCommit);");
325 outmethod.println("#ifdef STMSTATS\n");
326 outmethod.println("for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {\n");
327 outmethod.println(" printf(\"typesCausingAbort[%d]= %d\\n\", i, typesCausingAbort[i]);\n");
328 outmethod.println("}\n");
329 outmethod.println("#endif\n");
330 outmethod.println("fflush(stdout);");
332 outmethod.println("#endif\n");
335 if (state.THREAD||state.SINGLETM)
336 outmethod.println("pthread_exit(NULL);");
338 outmethod.println("}");
342 /* This method outputs code for each task. */
344 private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod) {
345 /* Compile task based program */
346 outtaskdefs.println("#include \"task.h\"");
347 outtaskdefs.println("#include \"methodheaders.h\"");
348 Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
349 while(taskit.hasNext()) {
350 TaskDescriptor td=(TaskDescriptor)taskit.next();
351 FlatMethod fm=state.getMethodFlat(td);
352 generateFlatMethod(fm, null, outmethod);
353 generateTaskDescriptor(outtaskdefs, fm, td);
356 //Output task descriptors
357 taskit=state.getTaskSymbolTable().getDescriptorsIterator();
358 outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
360 while(taskit.hasNext()) {
361 TaskDescriptor td=(TaskDescriptor)taskit.next();
365 outtaskdefs.println(",");
366 outtaskdefs.print("&task_"+td.getSafeSymbol());
368 outtaskdefs.println("};");
370 outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
373 /* This method outputs most of the methods.c file. This includes
374 * some standard includes and then an array with the sizes of
375 * objets and array that stores supertype and then the code for
376 * the Java methods.. */
378 protected void outputMethods(PrintWriter outmethod) {
379 outmethod.println("#include \"methodheaders.h\"");
380 outmethod.println("#include \"virtualtable.h\"");
381 outmethod.println("#include \"runtime.h\"");
383 outmethod.println("#include \"addPrefetchEnhance.h\"");
384 outmethod.println("#include \"localobjects.h\"");
386 if (state.FASTCHECK) {
387 outmethod.println("#include \"localobjects.h\"");
389 if(state.MULTICORE) {
390 outmethod.println("#include \"task.h\"");
391 outmethod.println("#include \"multicoreruntime.h\"");
392 outmethod.println("#include \"runtime_arch.h\"");
394 if (state.THREAD||state.DSM||state.SINGLETM)
395 outmethod.println("#include <thread.h>");
396 if (state.main!=null) {
397 outmethod.println("#include <string.h>");
399 if (state.CONSCHECK) {
400 outmethod.println("#include \"checkers.h\"");
403 outmethod.println("#include \"mlp_runtime.h\"");
406 //Store the sizes of classes & array elements
407 generateSizeArray(outmethod);
409 //Store table of supertypes
410 generateSuperTypeTable(outmethod);
412 //Store the layout of classes
413 generateLayoutStructs(outmethod);
415 /* Generate code for methods */
416 if (state.DSM||state.SINGLETM) {
417 for(Iterator<LocalityBinding> lbit=locality.getLocalityBindings().iterator(); lbit.hasNext();) {
418 LocalityBinding lb=lbit.next();
419 MethodDescriptor md=lb.getMethod();
420 FlatMethod fm=state.getMethodFlat(md);
422 if (!md.getModifiers().isNative()) {
423 generateFlatMethod(fm, lb, outmethod);
427 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
428 while(classit.hasNext()) {
429 ClassDescriptor cn=(ClassDescriptor)classit.next();
430 if(state.MULTICORE) {
431 if(cn.getSymbol().equals("Math")) {
435 Iterator methodit=cn.getMethods();
436 while(methodit.hasNext()) {
437 /* Classify parameters */
438 MethodDescriptor md=(MethodDescriptor)methodit.next();
439 FlatMethod fm=state.getMethodFlat(md);
440 if (!md.getModifiers().isNative()) {
441 generateFlatMethod(fm, null, outmethod);
448 protected void outputStructs(PrintWriter outstructs) {
449 outstructs.println("#ifndef STRUCTDEFS_H");
450 outstructs.println("#define STRUCTDEFS_H");
451 outstructs.println("#include \"classdefs.h\"");
452 outstructs.println("#ifndef INTPTR");
453 outstructs.println("#ifdef BIT64");
454 outstructs.println("#define INTPTR long");
455 outstructs.println("#else");
456 outstructs.println("#define INTPTR int");
457 outstructs.println("#endif");
458 outstructs.println("#endif");
460 /* Output #defines that the runtime uses to determine type
461 * numbers for various objects it needs */
462 outstructs.println("#define MAXCOUNT "+maxcount);
463 if (state.DSM||state.SINGLETM) {
464 LocalityBinding lb=new LocalityBinding(typeutil.getRun(), false);
466 lb.setGlobalThis(LocalityAnalysis.GLOBAL);
467 else if (state.SINGLETM)
468 lb.setGlobalThis(LocalityAnalysis.NORMAL);
469 outstructs.println("#define RUNMETHOD "+virtualcalls.getLocalityNumber(lb));
472 outstructs.println("#define STRINGARRAYTYPE "+
473 (state.getArrayNumber(
474 (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
476 outstructs.println("#define OBJECTARRAYTYPE "+
477 (state.getArrayNumber(
478 (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
481 outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
482 outstructs.println("#define CHARARRAYTYPE "+
483 (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
485 outstructs.println("#define BYTEARRAYTYPE "+
486 (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses()));
488 outstructs.println("#define BYTEARRAYARRAYTYPE "+
489 (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
491 outstructs.println("#define NUMCLASSES "+state.numClasses());
492 int totalClassSize = state.numClasses() + state.numArrays();
493 outstructs.println("#define TOTALNUMCLASSANDARRAY "+ totalClassSize);
495 outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
496 outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
497 outstructs.println("#define TAGARRAYTYPE "+
498 (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses()));
502 protected void outputClassDeclarations(PrintWriter outclassdefs) {
503 if (state.THREAD||state.DSM||state.SINGLETM)
504 outclassdefs.println("#include <pthread.h>");
505 outclassdefs.println("#ifndef INTPTR");
506 outclassdefs.println("#ifdef BIT64");
507 outclassdefs.println("#define INTPTR long");
508 outclassdefs.println("#else");
509 outclassdefs.println("#define INTPTR int");
510 outclassdefs.println("#endif");
511 outclassdefs.println("#endif");
513 outclassdefs.println("#include \"optionalstruct.h\"");
514 outclassdefs.println("struct "+arraytype+";");
515 /* Start by declaring all structs */
516 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
517 while(it.hasNext()) {
518 ClassDescriptor cn=(ClassDescriptor)it.next();
519 outclassdefs.println("struct "+cn.getSafeSymbol()+";");
521 outclassdefs.println("");
522 //Print out definition for array type
523 outclassdefs.println("struct "+arraytype+" {");
524 outclassdefs.println(" int type;");
526 outclassdefs.println(" pthread_t tid;");
527 outclassdefs.println(" void * lockentry;");
528 outclassdefs.println(" int lockcount;");
531 outclassdefs.println(" int flag;");
532 if(!state.MULTICORE) {
533 outclassdefs.println(" void * flagptr;");
535 outclassdefs.println(" int isolate;"); // indicate if this object is shared or not
536 outclassdefs.println(" int version;");
537 outclassdefs.println(" struct ___Object___ * original;");
538 //outclassdefs.println(" int numlocks;"); // array for locks
539 outclassdefs.println(" int * lock;");
542 outclassdefs.println(" int numfses;");
543 outclassdefs.println(" int * fses;");
546 printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
548 outclassdefs.println(" int ___length___;");
549 outclassdefs.println("};\n");
550 outclassdefs.println("extern int classsize[];");
551 outclassdefs.println("extern int hasflags[];");
552 outclassdefs.println("extern unsigned INTPTR * pointerarray[];");
553 outclassdefs.println("extern int supertypes[];");
556 /** Prints out definitions for generic task structures */
558 private void outputTaskTypes(PrintWriter outtask) {
559 outtask.println("#ifndef _TASK_H");
560 outtask.println("#define _TASK_H");
561 outtask.println("struct parameterdescriptor {");
562 outtask.println("int type;");
563 outtask.println("int numberterms;");
564 outtask.println("int *intarray;");
565 outtask.println("void * queue;");
566 outtask.println("int numbertags;");
567 outtask.println("int *tagarray;");
568 outtask.println("};");
570 outtask.println("struct taskdescriptor {");
571 outtask.println("void * taskptr;");
572 outtask.println("int numParameters;");
573 outtask.println(" int numTotal;");
574 outtask.println("struct parameterdescriptor **descriptorarray;");
575 outtask.println("char * name;");
576 outtask.println("};");
577 outtask.println("extern struct taskdescriptor * taskarray[];");
578 outtask.println("extern numtasks;");
579 outtask.println("#endif");
583 private void buildRepairStructs(PrintWriter outrepairstructs) {
584 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
585 while(classit.hasNext()) {
586 ClassDescriptor cn=(ClassDescriptor)classit.next();
587 outrepairstructs.println("structure "+cn.getSymbol()+" {");
588 outrepairstructs.println(" int __type__;");
590 outrepairstructs.println(" int __flag__;");
591 if(!state.MULTICORE) {
592 outrepairstructs.println(" int __flagptr__;");
595 printRepairStruct(cn, outrepairstructs);
596 outrepairstructs.println("}\n");
599 for(int i=0; i<state.numArrays(); i++) {
600 TypeDescriptor tdarray=arraytable[i];
601 TypeDescriptor tdelement=tdarray.dereference();
602 outrepairstructs.println("structure "+arraytype+"_"+state.getArrayNumber(tdarray)+" {");
603 outrepairstructs.println(" int __type__;");
604 printRepairStruct(typeutil.getClass(TypeUtil.ObjectClass), outrepairstructs);
605 outrepairstructs.println(" int length;");
607 // Need to add support to repair tool for this
608 if (tdelement.isClass()||tdelement.isArray())
609 outrepairstructs.println(" "+tdelement.getRepairSymbol()+" * elem[this.length];");
611 outrepairstructs.println(" "+tdelement.getRepairSymbol()+" elem[this.length];");
613 outrepairstructs.println("}\n");
617 private void printRepairStruct(ClassDescriptor cn, PrintWriter output) {
618 ClassDescriptor sp=cn.getSuperDesc();
620 printRepairStruct(sp, output);
622 Vector fields=(Vector)fieldorder.get(cn);
624 for(int i=0; i<fields.size(); i++) {
625 FieldDescriptor fd=(FieldDescriptor)fields.get(i);
626 if (fd.getType().isArray()) {
627 output.println(" "+arraytype+"_"+ state.getArrayNumber(fd.getType()) +" * "+fd.getSymbol()+";");
628 } else if (fd.getType().isClass())
629 output.println(" "+fd.getType().getRepairSymbol()+" * "+fd.getSymbol()+";");
630 else if (fd.getType().isFloat())
631 output.println(" int "+fd.getSymbol()+"; /* really float */");
633 output.println(" "+fd.getType().getRepairSymbol()+" "+fd.getSymbol()+";");
637 /** This method outputs TaskDescriptor information */
638 private void generateTaskDescriptor(PrintWriter output, FlatMethod fm, TaskDescriptor task) {
639 for (int i=0; i<task.numParameters(); i++) {
640 VarDescriptor param_var=task.getParameter(i);
641 TypeDescriptor param_type=task.getParamType(i);
642 FlagExpressionNode param_flag=task.getFlag(param_var);
643 TagExpressionList param_tag=task.getTag(param_var);
646 if (param_flag==null) {
647 output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
648 output.println("0x0, 0x0 };");
651 DNFFlag dflag=param_flag.getDNF();
652 dnfterms=dflag.size();
654 Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
655 output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
656 for(int j=0; j<dflag.size(); j++) {
659 Vector term=dflag.get(j);
662 for(int k=0; k<term.size(); k++) {
663 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
664 FlagDescriptor fd=dfa.getFlag();
665 boolean negated=dfa.getNegated();
666 int flagid=1<<((Integer)flags.get(fd)).intValue();
671 output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
673 output.println("};");
676 output.println("int parametertag_"+i+"_"+task.getSafeSymbol()+"[]={");
677 //BUG...added next line to fix, test with any task program
679 for(int j=0; j<param_tag.numTags(); j++) {
682 /* for each tag we need */
683 /* which slot it is */
684 /* what type it is */
685 TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
686 TempDescriptor tmp=param_tag.getTemp(j);
687 int slot=fm.getTagInt(tmp);
688 output.println(slot+", "+state.getTagId(tvd.getTag()));
690 output.println("};");
692 output.println("struct parameterdescriptor parameter_"+i+"_"+task.getSafeSymbol()+"={");
693 output.println("/* type */"+param_type.getClassDesc().getId()+",");
694 output.println("/* number of DNF terms */"+dnfterms+",");
695 output.println("parameterdnf_"+i+"_"+task.getSafeSymbol()+",");
696 output.println("0,");
697 //BUG, added next line to fix and else statement...test
698 //with any task program
700 output.println("/* number of tags */"+param_tag.numTags()+",");
702 output.println("/* number of tags */ 0,");
703 output.println("parametertag_"+i+"_"+task.getSafeSymbol());
704 output.println("};");
708 output.println("struct parameterdescriptor * parameterdescriptors_"+task.getSafeSymbol()+"[] = {");
709 for (int i=0; i<task.numParameters(); i++) {
712 output.print("¶meter_"+i+"_"+task.getSafeSymbol());
714 output.println("};");
716 output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={");
717 output.println("&"+task.getSafeSymbol()+",");
718 output.println("/* number of parameters */" +task.numParameters() + ",");
719 int numtotal=task.numParameters()+fm.numTags();
720 output.println("/* number total parameters */" +numtotal + ",");
721 output.println("parameterdescriptors_"+task.getSafeSymbol()+",");
722 output.println("\""+task.getSymbol()+"\"");
723 output.println("};");
727 /** The buildVirtualTables method outputs the virtual dispatch
728 * tables for methods. */
730 protected void buildVirtualTables(PrintWriter outvirtual) {
731 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
732 while(classit.hasNext()) {
733 ClassDescriptor cd=(ClassDescriptor)classit.next();
734 if (virtualcalls.getMethodCount(cd)>maxcount)
735 maxcount=virtualcalls.getMethodCount(cd);
737 MethodDescriptor[][] virtualtable=null;
738 LocalityBinding[][] lbvirtualtable=null;
739 if (state.DSM||state.SINGLETM)
740 lbvirtualtable=new LocalityBinding[state.numClasses()+state.numArrays()][maxcount];
742 virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount];
744 /* Fill in virtual table */
745 classit=state.getClassSymbolTable().getDescriptorsIterator();
746 while(classit.hasNext()) {
747 ClassDescriptor cd=(ClassDescriptor)classit.next();
748 if (state.DSM||state.SINGLETM)
749 fillinRow(cd, lbvirtualtable, cd.getId());
751 fillinRow(cd, virtualtable, cd.getId());
754 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
755 Iterator arrayit=state.getArrayIterator();
756 while(arrayit.hasNext()) {
757 TypeDescriptor td=(TypeDescriptor)arrayit.next();
758 int id=state.getArrayNumber(td);
759 if (state.DSM||state.SINGLETM)
760 fillinRow(objectcd, lbvirtualtable, id+state.numClasses());
762 fillinRow(objectcd, virtualtable, id+state.numClasses());
765 outvirtual.print("void * virtualtable[]={");
766 boolean needcomma=false;
767 for(int i=0; i<state.numClasses()+state.numArrays(); i++) {
768 for(int j=0; j<maxcount; j++) {
770 outvirtual.print(", ");
771 if ((state.DSM||state.SINGLETM)&&lbvirtualtable[i][j]!=null) {
772 LocalityBinding lb=lbvirtualtable[i][j];
773 MethodDescriptor md=lb.getMethod();
774 outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
775 } else if (!(state.DSM||state.SINGLETM)&&virtualtable[i][j]!=null) {
776 MethodDescriptor md=virtualtable[i][j];
777 outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
779 outvirtual.print("0");
783 outvirtual.println("");
785 outvirtual.println("};");
789 private void fillinRow(ClassDescriptor cd, MethodDescriptor[][] virtualtable, int rownum) {
790 /* Get inherited methods */
791 if (cd.getSuperDesc()!=null)
792 fillinRow(cd.getSuperDesc(), virtualtable, rownum);
793 /* Override them with our methods */
794 for(Iterator it=cd.getMethods(); it.hasNext();) {
795 MethodDescriptor md=(MethodDescriptor)it.next();
796 if (md.isStatic()||md.getReturnType()==null)
798 int methodnum=virtualcalls.getMethodNumber(md);
799 virtualtable[rownum][methodnum]=md;
803 private void fillinRow(ClassDescriptor cd, LocalityBinding[][] virtualtable, int rownum) {
804 /* Get inherited methods */
805 if (cd.getSuperDesc()!=null)
806 fillinRow(cd.getSuperDesc(), virtualtable, rownum);
807 /* Override them with our methods */
808 if (locality.getClassBindings(cd)!=null)
809 for(Iterator<LocalityBinding> lbit=locality.getClassBindings(cd).iterator(); lbit.hasNext();) {
810 LocalityBinding lb=lbit.next();
811 MethodDescriptor md=lb.getMethod();
812 //Is the method static or a constructor
813 if (md.isStatic()||md.getReturnType()==null)
815 int methodnum=virtualcalls.getLocalityNumber(lb);
816 virtualtable[rownum][methodnum]=lb;
820 /** Generate array that contains the sizes of class objects. The
821 * object allocation functions in the runtime use this
824 private void generateSizeArray(PrintWriter outclassdefs) {
825 outclassdefs.print("extern struct prefetchCountStats * evalPrefetch;\n");
826 outclassdefs.print("#ifdef TRANSSTATS \n");
827 outclassdefs.print("extern int numTransAbort;\n");
828 outclassdefs.print("extern int numTransCommit;\n");
829 outclassdefs.print("extern int nSoftAbort;\n");
831 outclassdefs.print("extern int nchashSearch;\n");
832 outclassdefs.print("extern int nmhashSearch;\n");
833 outclassdefs.print("extern int nprehashSearch;\n");
834 outclassdefs.print("extern int nRemoteSend;\n");
835 outclassdefs.print("extern int bytesSent;\n");
836 outclassdefs.print("extern int bytesRecv;\n");
837 outclassdefs.print("extern void handle();\n");
838 } else if (state.SINGLETM) {
839 outclassdefs.println("extern int nSoftAbortAbort;");
840 outclassdefs.println("extern int nSoftAbortCommit;");
841 outclassdefs.println("#ifdef STMSTATS\n");
842 outclassdefs.println("extern int typesCausingAbort[];");
843 outclassdefs.println("#endif\n");
845 outclassdefs.print("#endif\n");
846 outclassdefs.print("int numprefetchsites = " + pa.prefetchsiteid + ";\n");
848 outclassdefs.print("int classsize[]={");
849 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
850 cdarray=new ClassDescriptor[state.numClasses()];
851 while(it.hasNext()) {
852 ClassDescriptor cd=(ClassDescriptor)it.next();
853 cdarray[cd.getId()]=cd;
855 boolean needcomma=false;
856 for(int i=0; i<state.numClasses(); i++) {
858 outclassdefs.print(", ");
859 outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");
864 arraytable=new TypeDescriptor[state.numArrays()];
866 Iterator arrayit=state.getArrayIterator();
867 while(arrayit.hasNext()) {
868 TypeDescriptor td=(TypeDescriptor)arrayit.next();
869 int id=state.getArrayNumber(td);
873 for(int i=0; i<state.numArrays(); i++) {
875 outclassdefs.print(", ");
876 TypeDescriptor tdelement=arraytable[i].dereference();
877 if (tdelement.isArray()||tdelement.isClass())
878 outclassdefs.print("sizeof(void *)");
880 outclassdefs.print("sizeof("+tdelement.getSafeSymbol()+")");
884 outclassdefs.println("};");
886 ClassDescriptor objectclass=typeutil.getClass(TypeUtil.ObjectClass);
888 outclassdefs.print("int typearray[]={");
889 for(int i=0; i<state.numClasses(); i++) {
890 ClassDescriptor cd=cdarray[i];
891 ClassDescriptor supercd=cd.getSuperDesc();
893 outclassdefs.print(", ");
895 outclassdefs.print("-1");
897 outclassdefs.print(supercd.getId());
901 for(int i=0; i<state.numArrays(); i++) {
902 TypeDescriptor arraytd=arraytable[i];
903 ClassDescriptor arraycd=arraytd.getClassDesc();
906 outclassdefs.print(", ");
907 outclassdefs.print(objectclass.getId());
911 ClassDescriptor cd=arraycd.getSuperDesc();
914 TypeDescriptor supertd=new TypeDescriptor(cd);
915 supertd.setArrayCount(arraytd.getArrayCount());
916 type=state.getArrayNumber(supertd);
918 type+=state.numClasses();
921 cd=cd.getSuperDesc();
924 outclassdefs.print(", ");
925 outclassdefs.print(type);
929 outclassdefs.println("};");
934 outclassdefs.print("int typearray2[]={");
935 for(int i=0; i<state.numArrays(); i++) {
936 TypeDescriptor arraytd=arraytable[i];
937 ClassDescriptor arraycd=arraytd.getClassDesc();
940 outclassdefs.print(", ");
941 outclassdefs.print("-1");
945 ClassDescriptor cd=arraycd.getSuperDesc();
946 int level=arraytd.getArrayCount()-1;
948 for(; level>0; level--) {
949 TypeDescriptor supertd=new TypeDescriptor(objectclass);
950 supertd.setArrayCount(level);
951 type=state.getArrayNumber(supertd);
953 type+=state.numClasses();
958 outclassdefs.print(", ");
959 outclassdefs.print(type);
963 outclassdefs.println("};");
966 /** Constructs params and temp objects for each method or task.
967 * These objects tell the compiler which temps need to be
970 protected void generateTempStructs(FlatMethod fm, LocalityBinding lb) {
971 MethodDescriptor md=fm.getMethod();
972 TaskDescriptor task=fm.getTask();
973 Set<TempDescriptor> saveset=lb!=null ? locality.getTempSet(lb) : null;
974 ParamsObject objectparams=md!=null ? new ParamsObject(md,tag++) : new ParamsObject(task, tag++);
976 paramstable.put(lb, objectparams);
977 backuptable.put(lb, new Hashtable<TempDescriptor, TempDescriptor>());
979 paramstable.put(md, objectparams);
981 paramstable.put(task, objectparams);
983 for(int i=0; i<fm.numParameters(); i++) {
984 TempDescriptor temp=fm.getParameter(i);
985 TypeDescriptor type=temp.getType();
986 if (type.isPtr()&&GENERATEPRECISEGC)
987 objectparams.addPtr(temp);
989 objectparams.addPrim(temp);
990 if(lb!=null&&saveset.contains(temp)) {
991 backuptable.get(lb).put(temp, temp.createNew());
995 for(int i=0; i<fm.numTags(); i++) {
996 TempDescriptor temp=fm.getTag(i);
997 if (GENERATEPRECISEGC)
998 objectparams.addPtr(temp);
1000 objectparams.addPrim(temp);
1003 TempObject objecttemps=md!=null ? new TempObject(objectparams,md,tag++) : new TempObject(objectparams, task, tag++);
1005 tempstable.put(lb, objecttemps);
1007 tempstable.put(md, objecttemps);
1009 tempstable.put(task, objecttemps);
1011 for(Iterator nodeit=fm.getNodeSet().iterator(); nodeit.hasNext();) {
1012 FlatNode fn=(FlatNode)nodeit.next();
1013 TempDescriptor[] writes=fn.writesTemps();
1014 for(int i=0; i<writes.length; i++) {
1015 TempDescriptor temp=writes[i];
1016 TypeDescriptor type=temp.getType();
1017 if (type.isPtr()&&GENERATEPRECISEGC)
1018 objecttemps.addPtr(temp);
1020 objecttemps.addPrim(temp);
1021 if(lb!=null&&saveset.contains(temp)&&
1022 !backuptable.get(lb).containsKey(temp))
1023 backuptable.get(lb).put(temp, temp.createNew());
1027 /* Create backup temps */
1029 for(Iterator<TempDescriptor> tmpit=backuptable.get(lb).values().iterator(); tmpit.hasNext();) {
1030 TempDescriptor tmp=tmpit.next();
1031 TypeDescriptor type=tmp.getType();
1032 if (type.isPtr()&&GENERATEPRECISEGC)
1033 objecttemps.addPtr(tmp);
1035 objecttemps.addPrim(tmp);
1037 /* Create temp to hold revert table */
1038 if (state.DSM&&(lb.getHasAtomic()||lb.isAtomic())) {
1039 TempDescriptor reverttmp=new TempDescriptor("revertlist", typeutil.getClass(TypeUtil.ObjectClass));
1040 if (GENERATEPRECISEGC)
1041 objecttemps.addPtr(reverttmp);
1043 objecttemps.addPrim(reverttmp);
1044 reverttable.put(lb, reverttmp);
1049 /** This method outputs the following information about classes
1051 * (1) For classes, what are the locations of pointers.
1052 * (2) For arrays, does the array contain pointers or primitives.
1053 * (3) For classes, does the class contain flags.
1056 private void generateLayoutStructs(PrintWriter output) {
1057 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
1058 while(it.hasNext()) {
1059 ClassDescriptor cn=(ClassDescriptor)it.next();
1060 output.println("unsigned INTPTR "+cn.getSafeSymbol()+"_pointers[]={");
1061 Iterator allit=cn.getFieldTable().getAllDescriptorsIterator();
1063 while(allit.hasNext()) {
1064 FieldDescriptor fd=(FieldDescriptor)allit.next();
1065 TypeDescriptor type=fd.getType();
1066 if (state.DSM&&fd.isGlobal()) //Don't GC the global objects for now
1071 output.print(count);
1072 allit=cn.getFieldTable().getAllDescriptorsIterator();
1073 while(allit.hasNext()) {
1074 FieldDescriptor fd=(FieldDescriptor)allit.next();
1075 TypeDescriptor type=fd.getType();
1076 if (state.DSM&&fd.isGlobal()) //Don't GC the global objects for now
1079 output.println(",");
1080 output.print("((unsigned INTPTR)&(((struct "+cn.getSafeSymbol() +" *)0)->"+fd.getSafeSymbol()+"))");
1083 output.println("};");
1085 output.println("unsigned INTPTR * pointerarray[]={");
1086 boolean needcomma=false;
1087 for(int i=0; i<state.numClasses(); i++) {
1088 ClassDescriptor cn=cdarray[i];
1090 output.println(",");
1092 output.print(cn.getSafeSymbol()+"_pointers");
1095 for(int i=0; i<state.numArrays(); i++) {
1097 output.println(", ");
1098 TypeDescriptor tdelement=arraytable[i].dereference();
1099 if (tdelement.isArray()||tdelement.isClass())
1100 output.print("((unsigned INTPTR *)1)");
1106 output.println("};");
1108 output.println("int hasflags[]={");
1109 for(int i=0; i<state.numClasses(); i++) {
1110 ClassDescriptor cn=cdarray[i];
1112 output.println(", ");
1119 output.println("};");
1122 /** Print out table to give us supertypes */
1123 private void generateSuperTypeTable(PrintWriter output) {
1124 output.println("int supertypes[]={");
1125 boolean needcomma=false;
1126 for(int i=0; i<state.numClasses(); i++) {
1127 ClassDescriptor cn=cdarray[i];
1129 output.println(",");
1131 if (cn.getSuperDesc()!=null) {
1132 ClassDescriptor cdsuper=cn.getSuperDesc();
1133 output.print(cdsuper.getId());
1137 output.println("};");
1140 /** Force consistent field ordering between inherited classes. */
1142 private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) {
1144 ClassDescriptor sp=cn.getSuperDesc();
1146 printClassStruct(sp, classdefout);
1148 if (!fieldorder.containsKey(cn)) {
1149 Vector fields=new Vector();
1150 fieldorder.put(cn,fields);
1151 if (sp==null&&!state.TASK) {
1152 fields.add(cn.getFieldTable().get("cachedCode"));
1154 Iterator fieldit=cn.getFields();
1155 while(fieldit.hasNext()) {
1156 FieldDescriptor fd=(FieldDescriptor)fieldit.next();
1157 if ((sp==null||!sp.getFieldTable().contains(fd.getSymbol()))&&
1158 (!fd.getSymbol().equals("cachedCode")||state.TASK))
1162 Vector fields=(Vector)fieldorder.get(cn);
1164 for(int i=0; i<fields.size(); i++) {
1165 FieldDescriptor fd=(FieldDescriptor)fields.get(i);
1166 if (fd.getType().isClass()||fd.getType().isArray())
1167 classdefout.println(" struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
1169 classdefout.println(" "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
1174 /* Map flags to integers consistently between inherited
1177 protected void mapFlags(ClassDescriptor cn) {
1178 ClassDescriptor sp=cn.getSuperDesc();
1182 if (!flagorder.containsKey(cn)) {
1183 Hashtable flags=new Hashtable();
1184 flagorder.put(cn,flags);
1186 Hashtable superflags=(Hashtable)flagorder.get(sp);
1187 Iterator superflagit=superflags.keySet().iterator();
1188 while(superflagit.hasNext()) {
1189 FlagDescriptor fd=(FlagDescriptor)superflagit.next();
1190 Integer number=(Integer)superflags.get(fd);
1191 flags.put(fd, number);
1192 if ((number.intValue()+1)>max)
1193 max=number.intValue()+1;
1197 Iterator flagit=cn.getFlags();
1198 while(flagit.hasNext()) {
1199 FlagDescriptor fd=(FlagDescriptor)flagit.next();
1200 if (sp==null||!sp.getFlagTable().contains(fd.getSymbol()))
1201 flags.put(fd, new Integer(max++));
1207 /** This function outputs (1) structures that parameters are
1208 * passed in (when PRECISE GC is enabled) and (2) function
1209 * prototypes for the methods */
1211 protected void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) {
1212 /* Output class structure */
1213 classdefout.println("struct "+cn.getSafeSymbol()+" {");
1214 classdefout.println(" int type;");
1216 classdefout.println(" pthread_t tid;");
1217 classdefout.println(" void * lockentry;");
1218 classdefout.println(" int lockcount;");
1222 classdefout.println(" int flag;");
1223 if((!state.MULTICORE) || (cn.getSymbol().equals("TagDescriptor"))) {
1224 classdefout.println(" void * flagptr;");
1225 } else if (state.MULTICORE) {
1226 classdefout.println(" int isolate;"); // indicate if this object is shared or not
1227 classdefout.println(" int version;");
1228 classdefout.println(" struct ___Object___ * original;");
1229 //classdefout.println(" int numlocks;"); // array for locks
1230 classdefout.println(" int * lock;");
1232 if (state.OPTIONAL) {
1233 classdefout.println(" int numfses;");
1234 classdefout.println(" int * fses;");
1237 printClassStruct(cn, classdefout);
1238 classdefout.println("};\n");
1240 if (state.DSM||state.SINGLETM) {
1241 /* Cycle through LocalityBindings */
1242 HashSet<MethodDescriptor> nativemethods=new HashSet<MethodDescriptor>();
1243 Set<LocalityBinding> lbset=locality.getClassBindings(cn);
1245 for(Iterator<LocalityBinding> lbit=lbset.iterator(); lbit.hasNext();) {
1246 LocalityBinding lb=lbit.next();
1247 MethodDescriptor md=lb.getMethod();
1248 if (md.getModifiers().isNative()) {
1249 //make sure we only print a native method once
1250 if (nativemethods.contains(md)) {
1251 FlatMethod fm=state.getMethodFlat(md);
1252 generateTempStructs(fm, lb);
1255 nativemethods.add(md);
1257 generateMethod(cn, md, lb, headersout, output);
1260 for(Iterator methodit=cn.getMethods(); methodit.hasNext();) {
1261 MethodDescriptor md=(MethodDescriptor)methodit.next();
1262 if (md.getModifiers().isNative()&&!nativemethods.contains(md)) {
1263 //Need to build param structure for library code
1264 FlatMethod fm=state.getMethodFlat(md);
1265 generateTempStructs(fm, null);
1266 generateMethodParam(cn, md, null, output);
1271 for(Iterator methodit=cn.getMethods(); methodit.hasNext();) {
1272 MethodDescriptor md=(MethodDescriptor)methodit.next();
1273 generateMethod(cn, md, null, headersout, output);
1277 private void generateMethodParam(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter output) {
1278 /* Output parameter structure */
1279 if (GENERATEPRECISEGC) {
1280 ParamsObject objectparams=(ParamsObject) paramstable.get(lb!=null ? lb : md);
1281 if ((state.DSM||state.SINGLETM)&&lb!=null)
1282 output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
1284 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
1285 output.println(" INTPTR size;");
1286 output.println(" void * next;");
1287 for(int i=0; i<objectparams.numPointers(); i++) {
1288 TempDescriptor temp=objectparams.getPointer(i);
1289 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1291 output.println("};\n");
1296 private void generateMethod(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter headersout, PrintWriter output) {
1297 FlatMethod fm=state.getMethodFlat(md);
1298 generateTempStructs(fm, lb);
1300 ParamsObject objectparams=(ParamsObject) paramstable.get(lb!=null ? lb : md);
1301 TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md);
1303 generateMethodParam(cn, md, lb, output);
1305 /* Output temp structure */
1306 if (GENERATEPRECISEGC) {
1307 if (state.DSM||state.SINGLETM)
1308 output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
1310 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
1311 output.println(" INTPTR size;");
1312 output.println(" void * next;");
1313 for(int i=0; i<objecttemps.numPointers(); i++) {
1314 TempDescriptor temp=objecttemps.getPointer(i);
1315 if (temp.getType().isNull())
1316 output.println(" void * "+temp.getSafeSymbol()+";");
1318 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1320 output.println("};\n");
1323 /********* Output method declaration ***********/
1324 if (state.DSM||state.SINGLETM) {
1325 headersout.println("#define D"+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+" 1");
1327 headersout.println("#define D"+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+" 1");
1329 /* First the return type */
1330 if (md.getReturnType()!=null) {
1331 if (md.getReturnType().isClass()||md.getReturnType().isArray())
1332 headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1334 headersout.print(md.getReturnType().getSafeSymbol()+" ");
1336 //catch the constructor case
1337 headersout.print("void ");
1339 /* Next the method name */
1340 if (state.DSM||state.SINGLETM) {
1341 headersout.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1343 headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1345 boolean printcomma=false;
1346 if (GENERATEPRECISEGC) {
1347 if (state.DSM||state.SINGLETM) {
1348 headersout.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1350 headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1354 /* Output parameter list*/
1355 for(int i=0; i<objectparams.numPrimitives(); i++) {
1356 TempDescriptor temp=objectparams.getPrimitive(i);
1358 headersout.print(", ");
1360 if (temp.getType().isClass()||temp.getType().isArray())
1361 headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1363 headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1365 headersout.println(");\n");
1369 /** This function outputs (1) structures that parameters are
1370 * passed in (when PRECISE GC is enabled) and (2) function
1371 * prototypes for the tasks */
1373 private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
1374 /* Cycle through tasks */
1375 Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
1377 while(taskit.hasNext()) {
1378 /* Classify parameters */
1379 TaskDescriptor task=(TaskDescriptor)taskit.next();
1380 FlatMethod fm=state.getMethodFlat(task);
1381 generateTempStructs(fm, null);
1383 ParamsObject objectparams=(ParamsObject) paramstable.get(task);
1384 TempObject objecttemps=(TempObject) tempstable.get(task);
1386 /* Output parameter structure */
1387 if (GENERATEPRECISEGC) {
1388 output.println("struct "+task.getSafeSymbol()+"_params {");
1390 output.println(" INTPTR size;");
1391 output.println(" void * next;");
1392 for(int i=0; i<objectparams.numPointers(); i++) {
1393 TempDescriptor temp=objectparams.getPointer(i);
1394 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1397 output.println("};\n");
1398 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
1399 maxtaskparams=objectparams.numPointers()+fm.numTags();
1403 /* Output temp structure */
1404 if (GENERATEPRECISEGC) {
1405 output.println("struct "+task.getSafeSymbol()+"_locals {");
1406 output.println(" INTPTR size;");
1407 output.println(" void * next;");
1408 for(int i=0; i<objecttemps.numPointers(); i++) {
1409 TempDescriptor temp=objecttemps.getPointer(i);
1410 if (temp.getType().isNull())
1411 output.println(" void * "+temp.getSafeSymbol()+";");
1412 else if(temp.getType().isTag())
1413 output.println(" struct "+
1414 (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1416 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1418 output.println("};\n");
1421 /* Output task declaration */
1422 headersout.print("void " + task.getSafeSymbol()+"(");
1424 boolean printcomma=false;
1425 if (GENERATEPRECISEGC) {
1426 headersout.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1428 headersout.print("void * parameterarray[]");
1429 headersout.println(");\n");
1433 /***** Generate code for FlatMethod fm. *****/
1435 private void generateFlatMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
1436 if (State.PRINTFLAT)
1437 System.out.println(fm.printMethod());
1438 MethodDescriptor md=fm.getMethod();
1440 TaskDescriptor task=fm.getTask();
1442 ClassDescriptor cn=md!=null ? md.getClassDesc() : null;
1444 ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : md!=null ? md : task);
1445 generateHeader(fm, lb, md!=null ? md : task,output);
1446 TempObject objecttemp=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
1448 if (GENERATEPRECISEGC) {
1449 if (md!=null&&(state.DSM||state.SINGLETM))
1450 output.print(" struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1451 else if (md!=null&&!(state.DSM||state.SINGLETM))
1452 output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1454 output.print(" struct "+task.getSafeSymbol()+"_locals "+localsprefix+"={");
1456 output.print(objecttemp.numPointers()+",");
1457 output.print(paramsprefix);
1458 for(int j=0; j<objecttemp.numPointers(); j++)
1459 output.print(", NULL");
1460 output.println("};");
1463 for(int i=0; i<objecttemp.numPrimitives(); i++) {
1464 TempDescriptor td=objecttemp.getPrimitive(i);
1465 TypeDescriptor type=td.getType();
1467 output.println(" void * "+td.getSafeSymbol()+";");
1468 else if (type.isClass()||type.isArray())
1469 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
1471 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
1474 /* Check to see if we need to do a GC if this is a
1475 * multi-threaded program...*/
1477 if ((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC) {
1478 //Don't bother if we aren't in recursive methods...The loops case will catch it
1479 if (callgraph.getAllMethods(md).contains(md)) {
1480 if (state.DSM&&lb.isAtomic())
1481 output.println("if (needtocollect) checkcollect2(&"+localsprefix+");");
1483 output.println("if (needtocollect) checkcollect(&"+localsprefix+");");
1487 generateCode(fm.getNext(0), fm, lb, null, output);
1489 output.println("}\n\n");
1493 protected void generateMethodSESE(FlatSESEEnterNode fsen,
1496 PrintWriter output) {
1498 //output.println( "void _SESE"+fsen.getPrettyIdentifier()+
1500 //generateCode( fsen.getNext(0), fm, lb, fsen.getFlatExit(), output );
1501 //output.println( "}\n\n" );
1504 output.println("struct sese"+faen.getPrettyIdentifier()+"in {");
1505 Iterator<TempDescriptor> itr = faen.getInVarSet().iterator();
1506 while( itr.hasNext() ) {
1507 TempDescriptor td = itr.next();
1508 output.println(" "+td+";");
1510 output.println("}");
1512 output.println("struct sese"+faen.getPrettyIdentifier()+"out {");
1513 itr = faen.getOutVarSet().iterator();
1514 while( itr.hasNext() ) {
1515 TempDescriptor td = itr.next();
1516 output.println(" "+td+";");
1518 output.println("}");
1524 protected void generateCode(FlatNode first,
1527 FlatSESEExitNode stop,
1528 PrintWriter output) {
1530 /* Assign labels to FlatNode's if necessary.*/
1531 Hashtable<FlatNode, Integer> nodetolabel=assignLabels(first);
1533 /* Do the actual code generation */
1534 FlatNode current_node=null;
1535 HashSet tovisit=new HashSet();
1536 HashSet visited=new HashSet();
1538 while(current_node!=null||!tovisit.isEmpty()) {
1539 if (current_node==null) {
1540 current_node=(FlatNode)tovisit.iterator().next();
1541 tovisit.remove(current_node);
1542 } else if (tovisit.contains(current_node)) {
1543 tovisit.remove(current_node);
1545 if(current_node==stop) {
1548 visited.add(current_node);
1549 if (nodetolabel.containsKey(current_node))
1550 output.println("L"+nodetolabel.get(current_node)+":");
1551 if (state.INSTRUCTIONFAILURE) {
1552 if (state.THREAD||state.DSM||state.SINGLETM) {
1553 output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
1555 output.println("if ((--instructioncount)==0) injectinstructionfailure();");
1557 if (current_node.numNext()==0) {
1559 generateFlatNode(fm, lb, current_node, output);
1560 if (current_node.kind()!=FKind.FlatReturnNode) {
1561 output.println(" return;");
1564 } else if(current_node.numNext()==1) {
1566 if (state.MLP && current_node.kind()==FKind.FlatSESEEnterNode) {
1567 FlatSESEEnterNode fsen = (FlatSESEEnterNode)current_node;
1569 setSESEtoGen.add(fsen);
1570 fsen.setEnclosingFlatMeth(fm);
1572 nextnode=fsen.getFlatExit().getNext(0);
1575 generateFlatNode(fm, lb, current_node, output);
1576 nextnode=current_node.getNext(0);
1578 if (visited.contains(nextnode)) {
1579 output.println("goto L"+nodetolabel.get(nextnode)+";");
1582 current_node=nextnode;
1583 } else if (current_node.numNext()==2) {
1586 generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
1587 if (!visited.contains(current_node.getNext(1)))
1588 tovisit.add(current_node.getNext(1));
1589 if (visited.contains(current_node.getNext(0))) {
1590 output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
1593 current_node=current_node.getNext(0);
1594 } else throw new Error();
1599 /** This method assigns labels to FlatNodes */
1601 protected Hashtable<FlatNode, Integer> assignLabels(FlatNode first) {
1602 HashSet tovisit=new HashSet();
1603 HashSet visited=new HashSet();
1605 Hashtable<FlatNode, Integer> nodetolabel=new Hashtable<FlatNode, Integer>();
1608 /*Assign labels first. A node needs a label if the previous
1609 * node has two exits or this node is a join point. */
1611 while(!tovisit.isEmpty()) {
1612 FlatNode fn=(FlatNode)tovisit.iterator().next();
1615 for(int i=0; i<fn.numNext(); i++) {
1616 FlatNode nn=fn.getNext(i);
1618 //1) Edge >1 of node
1619 nodetolabel.put(nn,new Integer(labelindex++));
1621 if (!visited.contains(nn)&&!tovisit.contains(nn)) {
1625 nodetolabel.put(nn,new Integer(labelindex++));
1633 /** Generate text string that corresponds to the TempDescriptor td. */
1634 protected String generateTemp(FlatMethod fm, TempDescriptor td, LocalityBinding lb) {
1635 MethodDescriptor md=fm.getMethod();
1636 TaskDescriptor task=fm.getTask();
1637 TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
1638 if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1639 //System.out.println("generateTemp returns " + td.getSafeSymbol());
1640 return td.getSafeSymbol();
1643 if (objecttemps.isLocalPtr(td)) {
1644 return localsprefix+"."+td.getSafeSymbol();
1647 if (objecttemps.isParamPtr(td)) {
1648 return paramsprefix+"->"+td.getSafeSymbol();
1653 protected void generateFlatNode(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output) {
1655 case FKind.FlatAtomicEnterNode:
1656 generateFlatAtomicEnterNode(fm, lb, (FlatAtomicEnterNode) fn, output);
1659 case FKind.FlatAtomicExitNode:
1660 generateFlatAtomicExitNode(fm, lb, (FlatAtomicExitNode) fn, output);
1663 case FKind.FlatInstanceOfNode:
1664 generateFlatInstanceOfNode(fm, lb, (FlatInstanceOfNode)fn, output);
1667 case FKind.FlatSESEEnterNode:
1671 case FKind.FlatSESEExitNode:
1675 case FKind.FlatGlobalConvNode:
1676 generateFlatGlobalConvNode(fm, lb, (FlatGlobalConvNode) fn, output);
1679 case FKind.FlatTagDeclaration:
1680 generateFlatTagDeclaration(fm, lb, (FlatTagDeclaration) fn,output);
1683 case FKind.FlatCall:
1684 generateFlatCall(fm, lb, (FlatCall) fn,output);
1687 case FKind.FlatFieldNode:
1688 generateFlatFieldNode(fm, lb, (FlatFieldNode) fn,output);
1691 case FKind.FlatElementNode:
1692 generateFlatElementNode(fm, lb, (FlatElementNode) fn,output);
1695 case FKind.FlatSetElementNode:
1696 generateFlatSetElementNode(fm, lb, (FlatSetElementNode) fn,output);
1699 case FKind.FlatSetFieldNode:
1700 generateFlatSetFieldNode(fm, lb, (FlatSetFieldNode) fn,output);
1704 generateFlatNew(fm, lb, (FlatNew) fn,output);
1707 case FKind.FlatOpNode:
1708 generateFlatOpNode(fm, lb, (FlatOpNode) fn,output);
1711 case FKind.FlatCastNode:
1712 generateFlatCastNode(fm, lb, (FlatCastNode) fn,output);
1715 case FKind.FlatLiteralNode:
1716 generateFlatLiteralNode(fm, lb, (FlatLiteralNode) fn,output);
1719 case FKind.FlatReturnNode:
1720 generateFlatReturnNode(fm, lb, (FlatReturnNode) fn,output);
1724 output.println("/* nop */");
1727 case FKind.FlatExit:
1728 output.println("/* exit */");
1731 case FKind.FlatBackEdge:
1732 if ((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC) {
1733 if(state.DSM&&locality.getAtomic(lb).get(fn).intValue()>0) {
1734 output.println("if (needtocollect) checkcollect2(&"+localsprefix+");");
1736 output.println("if (needtocollect) checkcollect(&"+localsprefix+");");
1738 output.println("/* nop */");
1741 case FKind.FlatCheckNode:
1742 generateFlatCheckNode(fm, lb, (FlatCheckNode) fn, output);
1745 case FKind.FlatFlagActionNode:
1746 generateFlatFlagActionNode(fm, lb, (FlatFlagActionNode) fn, output);
1749 case FKind.FlatPrefetchNode:
1750 generateFlatPrefetchNode(fm,lb, (FlatPrefetchNode) fn, output);
1753 case FKind.FlatOffsetNode:
1754 generateFlatOffsetNode(fm, lb, (FlatOffsetNode)fn, output);
1760 public void generateFlatOffsetNode(FlatMethod fm, LocalityBinding lb, FlatOffsetNode fofn, PrintWriter output) {
1761 output.println("/* FlatOffsetNode */");
1762 FieldDescriptor fd=fofn.getField();
1763 output.println(generateTemp(fm, fofn.getDst(),lb)+ " = (short)(int) (&((struct "+fofn.getClassType().getSafeSymbol() +" *)0)->"+ fd.getSafeSymbol()+");");
1764 output.println("/* offset */");
1767 public void generateFlatPrefetchNode(FlatMethod fm, LocalityBinding lb, FlatPrefetchNode fpn, PrintWriter output) {
1768 if (state.PREFETCH) {
1769 Vector oids = new Vector();
1770 Vector fieldoffset = new Vector();
1771 Vector endoffset = new Vector();
1772 int tuplecount = 0; //Keeps track of number of prefetch tuples that need to be generated
1773 for(Iterator it = fpn.hspp.iterator(); it.hasNext();) {
1774 PrefetchPair pp = (PrefetchPair) it.next();
1775 Integer statusbase = locality.getNodePreTempInfo(lb,fpn).get(pp.base);
1776 /* Find prefetches that can generate oid */
1777 if(statusbase == LocalityAnalysis.GLOBAL) {
1778 generateTransCode(fm, lb, pp, oids, fieldoffset, endoffset, tuplecount, locality.getAtomic(lb).get(fpn).intValue()>0, false);
1780 } else if (statusbase == LocalityAnalysis.LOCAL) {
1781 generateTransCode(fm,lb,pp,oids,fieldoffset,endoffset,tuplecount,false,true);
1788 System.out.println("Adding prefetch "+fpn+ " to method:" +fm);
1789 output.println("{");
1790 output.println("/* prefetch */");
1791 output.println("/* prefetchid_" + fpn.siteid + " */");
1792 output.println("void * prefptr;");
1793 output.println("int tmpindex;");
1795 output.println("if((evalPrefetch["+fpn.siteid+"].operMode) || (evalPrefetch["+fpn.siteid+"].retrycount <= 0)) {");
1796 /*Create C code for oid array */
1797 output.print(" unsigned int oidarray_[] = {");
1798 boolean needcomma=false;
1799 for (Iterator it = oids.iterator(); it.hasNext();) {
1802 output.print(it.next());
1805 output.println("};");
1807 /*Create C code for endoffset values */
1808 output.print(" unsigned short endoffsetarry_[] = {");
1810 for (Iterator it = endoffset.iterator(); it.hasNext();) {
1813 output.print(it.next());
1816 output.println("};");
1818 /*Create C code for Field Offset Values */
1819 output.print(" short fieldarry_[] = {");
1821 for (Iterator it = fieldoffset.iterator(); it.hasNext();) {
1824 output.print(it.next());
1827 output.println("};");
1828 /* make the prefetch call to Runtime */
1829 output.println(" if(!evalPrefetch["+fpn.siteid+"].operMode) {");
1830 output.println(" evalPrefetch["+fpn.siteid+"].retrycount = RETRYINTERVAL;");
1831 output.println(" }");
1832 output.println(" prefetch("+fpn.siteid+" ,"+tuplecount+", oidarray_, endoffsetarry_, fieldarry_);");
1833 output.println(" } else {");
1834 output.println(" evalPrefetch["+fpn.siteid+"].retrycount--;");
1835 output.println(" }");
1836 output.println("}");
1840 public void generateTransCode(FlatMethod fm, LocalityBinding lb,PrefetchPair pp, Vector oids, Vector fieldoffset, Vector endoffset, int tuplecount, boolean inside, boolean localbase) {
1841 short offsetcount = 0;
1845 } else if (localbase) {
1846 for(; breakindex<pp.desc.size(); breakindex++) {
1847 Descriptor desc=pp.getDescAt(breakindex);
1848 if (desc instanceof FieldDescriptor) {
1849 FieldDescriptor fd=(FieldDescriptor)desc;
1850 if (fd.isGlobal()) {
1858 if (breakindex>pp.desc.size()) //all local
1861 TypeDescriptor lasttype=pp.base.getType();
1862 String basestr=generateTemp(fm, pp.base, lb);
1864 boolean maybenull=fm.getMethod().isStatic()||
1865 !pp.base.equals(fm.getParameter(0));
1867 for(int i=0; i<breakindex; i++) {
1868 String indexcheck="";
1870 Descriptor desc=pp.getDescAt(i);
1871 if (desc instanceof FieldDescriptor) {
1872 FieldDescriptor fd=(FieldDescriptor)desc;
1874 if (!teststr.equals(""))
1876 teststr+="((prefptr="+basestr+")!=NULL)";
1877 basestr="((struct "+lasttype.getSafeSymbol()+" *)prefptr)->"+fd.getSafeSymbol();
1879 basestr=basestr+"->"+fd.getSafeSymbol();
1882 lasttype=fd.getType();
1884 IndexDescriptor id=(IndexDescriptor)desc;
1885 indexcheck="((tmpindex=";
1886 for(int j=0; j<id.tddesc.size(); j++) {
1887 indexcheck+=generateTemp(fm, id.getTempDescAt(j), lb)+"+";
1889 indexcheck+=id.offset+")>=0)&(tmpindex<((struct ArrayObject *)prefptr)->___length___)";
1891 if (!teststr.equals(""))
1893 teststr+="((prefptr="+basestr+")!= NULL) &&"+indexcheck;
1894 basestr="((void **)(((char *) &(((struct ArrayObject *)prefptr)->___length___))+sizeof(int)))[tmpindex]";
1896 lasttype=lasttype.dereference();
1901 if (teststr.equals("")) {
1902 oid="((unsigned int)"+basestr+")";
1904 oid="((unsigned int)(("+teststr+")?"+basestr+":NULL))";
1908 for(int i = breakindex; i < pp.desc.size(); i++) {
1909 String newfieldoffset;
1910 Object desc = pp.getDescAt(i);
1911 if(desc instanceof FieldDescriptor) {
1912 FieldDescriptor fd=(FieldDescriptor)desc;
1913 newfieldoffset = new String("(unsigned int)(&(((struct "+ lasttype.getSafeSymbol()+" *)0)->"+ fd.getSafeSymbol()+ "))");
1914 lasttype=fd.getType();
1916 newfieldoffset = "";
1917 IndexDescriptor id=(IndexDescriptor)desc;
1918 for(int j = 0; j < id.tddesc.size(); j++) {
1919 newfieldoffset += generateTemp(fm, id.getTempDescAt(j), lb) + "+";
1921 newfieldoffset += id.offset.toString();
1922 lasttype=lasttype.dereference();
1924 fieldoffset.add(newfieldoffset);
1927 int base=(tuplecount>0) ? ((Short)endoffset.get(tuplecount-1)).intValue() : 0;
1928 base+=pp.desc.size()-breakindex;
1929 endoffset.add(new Short((short)base));
1934 public void generateFlatGlobalConvNode(FlatMethod fm, LocalityBinding lb, FlatGlobalConvNode fgcn, PrintWriter output) {
1935 if (lb!=fgcn.getLocality())
1937 /* Have to generate flat globalconv */
1938 if (fgcn.getMakePtr()) {
1940 output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", (unsigned int) "+generateTemp(fm, fgcn.getSrc(),lb)+");");
1942 output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", "+generateTemp(fm, fgcn.getSrc(),lb)+", (void *)&("+localsprefix+"));");
1945 /* Need to convert to OID */
1946 if (fgcn.doConvert()) {
1947 output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)COMPOID("+generateTemp(fm, fgcn.getSrc(),lb)+");");
1949 output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=NULL;");
1954 public void generateFlatInstanceOfNode(FlatMethod fm, LocalityBinding lb, FlatInstanceOfNode fion, PrintWriter output) {
1956 if (fion.getType().isArray()) {
1957 type=state.getArrayNumber(fion.getType())+state.numClasses();
1959 type=fion.getType().getClassDesc().getId();
1962 if (fion.getType().getSymbol().equals(TypeUtil.ObjectClass))
1963 output.println(generateTemp(fm, fion.getDst(), lb)+"=1;");
1965 output.println(generateTemp(fm, fion.getDst(), lb)+"=instanceof("+generateTemp(fm,fion.getSrc(),lb)+","+type+");");
1968 public void generateFlatAtomicEnterNode(FlatMethod fm, LocalityBinding lb, FlatAtomicEnterNode faen, PrintWriter output) {
1969 /* Check to see if we need to generate code for this atomic */
1970 if (locality==null||locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
1972 /* Backup the temps. */
1973 for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator(); tmpit.hasNext();) {
1974 TempDescriptor tmp=tmpit.next();
1975 output.println(generateTemp(fm, backuptable.get(lb).get(tmp),lb)+"="+generateTemp(fm,tmp,lb)+";");
1978 output.println("goto transstart"+faen.getIdentifier()+";");
1980 /******* Print code to retry aborted transaction *******/
1981 output.println("transretry"+faen.getIdentifier()+":");
1984 for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator(); tmpit.hasNext();) {
1985 TempDescriptor tmp=tmpit.next();
1986 output.println(generateTemp(fm, tmp,lb)+"="+generateTemp(fm,backuptable.get(lb).get(tmp),lb)+";");
1990 /********* Need to revert local object store ********/
1991 String revertptr=generateTemp(fm, reverttable.get(lb),lb);
1993 output.println("while ("+revertptr+") {");
1994 output.println("struct ___Object___ * tmpptr;");
1995 output.println("tmpptr="+revertptr+"->"+nextobjstr+";");
1996 output.println("REVERT_OBJ("+revertptr+");");
1997 output.println(revertptr+"=tmpptr;");
1998 output.println("}");
2000 /******* Tell the runtime to start the transaction *******/
2002 output.println("transstart"+faen.getIdentifier()+":");
2003 output.println("transStart();");
2005 if (state.ABORTREADERS) {
2006 output.println("if (_setjmp(aborttrans)) {");
2007 output.println(" goto transretry"+faen.getIdentifier()+"; }");
2011 public void generateFlatAtomicExitNode(FlatMethod fm, LocalityBinding lb, FlatAtomicExitNode faen, PrintWriter output) {
2012 /* Check to see if we need to generate code for this atomic */
2013 if (locality==null||locality.getAtomic(lb).get(faen).intValue()>0)
2015 //store the revert list before we lose the transaction object
2016 String revertptr=null;
2018 revertptr=generateTemp(fm, reverttable.get(lb),lb);
2019 output.println(revertptr+"=revertlist;");
2021 output.println("if (transCommit()) {");
2022 /* Transaction aborts if it returns true */
2023 output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
2025 output.println("} else {");
2026 /* Need to commit local object store */
2027 output.println("while ("+revertptr+") {");
2028 output.println("struct ___Object___ * tmpptr;");
2029 output.println("tmpptr="+revertptr+"->"+nextobjstr+";");
2030 output.println("COMMIT_OBJ("+revertptr+");");
2031 output.println(revertptr+"=tmpptr;");
2032 output.println("}");
2034 output.println("}");
2038 public void generateSESE(FlatMethod fm, LocalityBinding lb, FlatSESEEnterNode faen, PrintWriter output) {
2043 public void generateFlatSESEEnterNode(FlatMethod fm, LocalityBinding lb, FlatSESEEnterNode faen, PrintWriter output) {
2046 public void generateFlatSESEExitNode(FlatMethod fm, LocalityBinding lb, FlatSESEExitNode faen, PrintWriter output) {
2047 //output.println("mlpNotifyExit( (struct SESE*)0 );");
2050 private void generateFlatCheckNode(FlatMethod fm, LocalityBinding lb, FlatCheckNode fcn, PrintWriter output) {
2051 if (state.CONSCHECK) {
2052 String specname=fcn.getSpec();
2053 String varname="repairstate___";
2054 output.println("{");
2055 output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
2057 TempDescriptor[] temps=fcn.getTemps();
2058 String[] vars=fcn.getVars();
2059 for(int i=0; i<temps.length; i++) {
2060 output.println(varname+"->"+vars[i]+"=(unsigned int)"+generateTemp(fm, temps[i],lb)+";");
2063 output.println("if (doanalysis"+specname+"("+varname+")) {");
2064 output.println("free"+specname+"_state("+varname+");");
2065 output.println("} else {");
2066 output.println("/* Bad invariant */");
2067 output.println("free"+specname+"_state("+varname+");");
2068 output.println("abort_task();");
2069 output.println("}");
2070 output.println("}");
2074 private void generateFlatCall(FlatMethod fm, LocalityBinding lb, FlatCall fc, PrintWriter output) {
2075 MethodDescriptor md=fc.getMethod();
2076 ParamsObject objectparams=(ParamsObject)paramstable.get(state.DSM||state.SINGLETM ? locality.getBinding(lb, fc) : md);
2077 ClassDescriptor cn=md.getClassDesc();
2078 output.println("{");
2079 if (GENERATEPRECISEGC) {
2080 if (state.DSM||state.SINGLETM) {
2081 LocalityBinding fclb=locality.getBinding(lb, fc);
2082 output.print(" struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
2084 output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
2086 output.print(objectparams.numPointers());
2087 output.print(", & "+localsprefix);
2088 if (md.getThis()!=null) {
2090 output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis(),lb));
2092 if (fc.getThis()!=null&&md.getThis()==null) {
2093 System.out.println("WARNING!!!!!!!!!!!!");
2094 System.out.println("Source code calls static method "+md+" on an object in "+fm.getMethod()+"!");
2098 for(int i=0; i<fc.numArgs(); i++) {
2099 Descriptor var=md.getParameter(i);
2100 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
2101 if (objectparams.isParamPtr(paramtemp)) {
2102 TempDescriptor targ=fc.getArg(i);
2104 TypeDescriptor td=md.getParamType(i);
2106 output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol() +" *)"+generateTemp(fm, targ,lb));
2108 output.print("(struct "+md.getParamType(i).getSafeSymbol() +" *)"+generateTemp(fm, targ,lb));
2111 output.println("};");
2116 if (fc.getReturnTemp()!=null)
2117 output.print(generateTemp(fm,fc.getReturnTemp(),lb)+"=");
2119 /* Do we need to do virtual dispatch? */
2120 if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
2122 if (state.DSM||state.SINGLETM) {
2123 LocalityBinding fclb=locality.getBinding(lb, fc);
2124 output.print(cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
2126 output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
2131 if (md.getReturnType().isClass()||md.getReturnType().isArray())
2132 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
2134 output.print(md.getReturnType().getSafeSymbol()+" ");
2135 output.print("(*)(");
2137 boolean printcomma=false;
2138 if (GENERATEPRECISEGC) {
2139 if (state.DSM||state.SINGLETM) {
2140 LocalityBinding fclb=locality.getBinding(lb, fc);
2141 output.print("struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
2143 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
2147 for(int i=0; i<objectparams.numPrimitives(); i++) {
2148 TempDescriptor temp=objectparams.getPrimitive(i);
2152 if (temp.getType().isClass()||temp.getType().isArray())
2153 output.print("struct " + temp.getType().getSafeSymbol()+" * ");
2155 output.print(temp.getType().getSafeSymbol());
2159 if (state.DSM||state.SINGLETM) {
2160 LocalityBinding fclb=locality.getBinding(lb, fc);
2161 output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getLocalityNumber(fclb)+"])");
2163 output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
2167 boolean needcomma=false;
2168 if (GENERATEPRECISEGC) {
2169 output.print("&__parameterlist__");
2173 if (!GENERATEPRECISEGC) {
2174 if (fc.getThis()!=null) {
2175 TypeDescriptor ptd=md.getThis().getType();
2178 if (ptd.isClass()&&!ptd.isArray())
2179 output.print("(struct "+ptd.getSafeSymbol()+" *) ");
2180 output.print(generateTemp(fm,fc.getThis(),lb));
2185 for(int i=0; i<fc.numArgs(); i++) {
2186 Descriptor var=md.getParameter(i);
2187 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
2188 if (objectparams.isParamPrim(paramtemp)) {
2189 TempDescriptor targ=fc.getArg(i);
2193 TypeDescriptor ptd=md.getParamType(i);
2194 if (ptd.isClass()&&!ptd.isArray())
2195 output.print("(struct "+ptd.getSafeSymbol()+" *) ");
2196 output.print(generateTemp(fm, targ,lb));
2200 output.println(");");
2201 output.println(" }");
2204 private boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
2205 Set subclasses=typeutil.getSubClasses(thiscd);
2206 if (subclasses==null)
2208 for(Iterator classit=subclasses.iterator(); classit.hasNext();) {
2209 ClassDescriptor cd=(ClassDescriptor)classit.next();
2210 Set possiblematches=cd.getMethodTable().getSet(md.getSymbol());
2211 for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) {
2212 MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
2213 if (md.matches(matchmd))
2220 private void generateFlatFieldNode(FlatMethod fm, LocalityBinding lb, FlatFieldNode ffn, PrintWriter output) {
2221 if (state.SINGLETM) {
2222 //single machine transactional memory case
2223 String field=ffn.getField().getSafeSymbol();
2224 String src=generateTemp(fm, ffn.getSrc(),lb);
2225 String dst=generateTemp(fm, ffn.getDst(),lb);
2227 output.println(dst+"="+ src +"->"+field+ ";");
2228 if (ffn.getField().getType().isPtr()&&locality.getAtomic(lb).get(ffn).intValue()>0&&
2229 ((dc==null)||dc.getNeedTrans(lb, ffn))&&
2230 locality.getNodePreTempInfo(lb, ffn).get(ffn.getSrc())!=LocalityAnalysis.SCRATCH) {
2231 output.println("TRANSREAD("+dst+", "+dst+", (void *) &(" + localsprefix + "));");
2233 } else if (state.DSM) {
2234 Integer status=locality.getNodePreTempInfo(lb,ffn).get(ffn.getSrc());
2235 if (status==LocalityAnalysis.GLOBAL) {
2236 String field=ffn.getField().getSafeSymbol();
2237 String src=generateTemp(fm, ffn.getSrc(),lb);
2238 String dst=generateTemp(fm, ffn.getDst(),lb);
2240 if (ffn.getField().getType().isPtr()) {
2242 //TODO: Uncomment this when we have runtime support
2243 //if (ffn.getSrc()==ffn.getDst()) {
2244 //output.println("{");
2245 //output.println("void * temp="+src+";");
2246 //output.println("if (temp&0x1) {");
2247 //output.println("temp=(void *) transRead(trans, (unsigned int) temp);");
2248 //output.println(src+"->"+field+"="+temp+";");
2249 //output.println("}");
2250 //output.println(dst+"=temp;");
2251 //output.println("}");
2253 output.println(dst+"="+ src +"->"+field+ ";");
2254 //output.println("if ("+dst+"&0x1) {");
2255 output.println("TRANSREAD("+dst+", (unsigned int) "+dst+");");
2256 //output.println(src+"->"+field+"="+src+"->"+field+";");
2257 //output.println("}");
2260 output.println(dst+"="+ src+"->"+field+";");
2262 } else if (status==LocalityAnalysis.LOCAL) {
2263 if (ffn.getField().getType().isPtr()&&
2264 ffn.getField().isGlobal()) {
2265 String field=ffn.getField().getSafeSymbol();
2266 String src=generateTemp(fm, ffn.getSrc(),lb);
2267 String dst=generateTemp(fm, ffn.getDst(),lb);
2268 output.println(dst+"="+ src +"->"+field+ ";");
2269 if (locality.getAtomic(lb).get(ffn).intValue()>0)
2270 output.println("TRANSREAD("+dst+", (unsigned int) "+dst+");");
2272 output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
2273 } else if (status==LocalityAnalysis.EITHER) {
2274 //Code is reading from a null pointer
2275 output.println("if ("+generateTemp(fm, ffn.getSrc(),lb)+") {");
2276 output.println("#ifndef RAW");
2277 output.println("printf(\"BIG ERROR\\n\");exit(-1);}");
2278 output.println("#endif");
2279 //This should throw a suitable null pointer error
2280 output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
2282 throw new Error("Read from non-global/non-local in:"+lb.getExplanation());
2284 output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
2288 private void generateFlatSetFieldNode(FlatMethod fm, LocalityBinding lb, FlatSetFieldNode fsfn, PrintWriter output) {
2289 if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
2290 throw new Error("Can't set array length");
2291 if (state.SINGLETM && locality.getAtomic(lb).get(fsfn).intValue()>0) {
2292 //Single Machine Transaction Case
2293 boolean srcptr=fsfn.getSrc().getType().isPtr();
2294 String src=generateTemp(fm,fsfn.getSrc(),lb);
2295 String dst=generateTemp(fm,fsfn.getDst(),lb);
2296 if (srcptr&&!fsfn.getSrc().getType().isNull()) {
2297 output.println("{");
2298 if ((dc==null)||dc.getNeedSrcTrans(lb, fsfn)&&
2299 locality.getNodePreTempInfo(lb, fsfn).get(fsfn.getSrc())!=LocalityAnalysis.SCRATCH) {
2300 output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
2302 output.println("INTPTR srcoid=(INTPTR)"+src+";");
2305 if (wb.needBarrier(fsfn)&&
2306 locality.getNodePreTempInfo(lb, fsfn).get(fsfn.getDst())!=LocalityAnalysis.SCRATCH) {
2307 output.println("*((unsigned int *)&("+dst+"->___objstatus___))|=DIRTY;");
2309 if (srcptr&!fsfn.getSrc().getType().isNull()) {
2310 output.println("*((unsigned INTPTR *)&("+dst+"->"+ fsfn.getField().getSafeSymbol()+"))=srcoid;");
2311 output.println("}");
2313 output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
2315 } else if (state.DSM && locality.getAtomic(lb).get(fsfn).intValue()>0) {
2316 Integer statussrc=locality.getNodePreTempInfo(lb,fsfn).get(fsfn.getSrc());
2317 Integer statusdst=locality.getNodeTempInfo(lb).get(fsfn).get(fsfn.getDst());
2318 boolean srcglobal=statussrc==LocalityAnalysis.GLOBAL;
2320 String src=generateTemp(fm,fsfn.getSrc(),lb);
2321 String dst=generateTemp(fm,fsfn.getDst(),lb);
2323 output.println("{");
2324 output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
2326 if (statusdst.equals(LocalityAnalysis.GLOBAL)) {
2329 if (wb.needBarrier(fsfn))
2330 output.println("*((unsigned int *)&("+dst+"->___localcopy___))|=DIRTY;");
2332 output.println("*((unsigned INTPTR *)&("+glbdst+"->"+ fsfn.getField().getSafeSymbol()+"))=srcoid;");
2334 output.println(glbdst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
2335 } else if (statusdst.equals(LocalityAnalysis.LOCAL)) {
2336 /** Check if we need to copy */
2337 output.println("if(!"+dst+"->"+localcopystr+") {");
2338 /* Link object into list */
2339 String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2340 output.println(revertptr+"=revertlist;");
2341 if (GENERATEPRECISEGC)
2342 output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
2344 output.println("COPY_OBJ("+dst+");");
2345 output.println(dst+"->"+nextobjstr+"="+revertptr+";");
2346 output.println("revertlist=(struct ___Object___ *)"+dst+";");
2347 output.println("}");
2349 output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=(void *) srcoid;");
2351 output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
2352 } else if (statusdst.equals(LocalityAnalysis.EITHER)) {
2353 //writing to a null...bad
2354 output.println("if ("+dst+") {");
2355 output.println("printf(\"BIG ERROR 2\\n\");exit(-1);}");
2357 output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=(void *) srcoid;");
2359 output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
2362 output.println("}");
2365 if (state.FASTCHECK) {
2366 String dst=generateTemp(fm, fsfn.getDst(),lb);
2367 output.println("if(!"+dst+"->"+localcopystr+") {");
2368 /* Link object into list */
2369 if (GENERATEPRECISEGC)
2370 output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
2372 output.println("COPY_OBJ("+dst+");");
2373 output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
2374 output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
2375 output.println("}");
2377 output.println(generateTemp(fm, fsfn.getDst(),lb)+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";");
2381 private void generateFlatElementNode(FlatMethod fm, LocalityBinding lb, FlatElementNode fen, PrintWriter output) {
2382 TypeDescriptor elementtype=fen.getSrc().getType().dereference();
2385 if (elementtype.isArray()||elementtype.isClass())
2388 type=elementtype.getSafeSymbol()+" ";
2390 if (this.state.ARRAYBOUNDARYCHECK && fen.needsBoundsCheck()) {
2391 output.println("if ("+generateTemp(fm, fen.getIndex(),lb)+"< 0 | "+generateTemp(fm, fen.getIndex(),lb)+" >= "+generateTemp(fm,fen.getSrc(),lb) + "->___length___)");
2392 output.println("failedboundschk();");
2394 if (state.SINGLETM) {
2395 //Single machine transaction case
2396 String dst=generateTemp(fm, fen.getDst(),lb);
2397 output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2399 if (elementtype.isPtr()&&locality.getAtomic(lb).get(fen).intValue()>0&&
2400 ((dc==null)||dc.getNeedTrans(lb, fen))&&
2401 locality.getNodePreTempInfo(lb, fen).get(fen.getSrc())!=LocalityAnalysis.SCRATCH) {
2402 output.println("TRANSREAD("+dst+", "+dst+", (void *)&(" + localsprefix+"));");
2404 } else if (state.DSM) {
2405 Integer status=locality.getNodePreTempInfo(lb,fen).get(fen.getSrc());
2406 if (status==LocalityAnalysis.GLOBAL) {
2407 String dst=generateTemp(fm, fen.getDst(),lb);
2409 if (elementtype.isPtr()) {
2410 output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2411 output.println("TRANSREAD("+dst+", "+dst+");");
2413 output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2415 } else if (status==LocalityAnalysis.LOCAL) {
2416 output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2417 } else if (status==LocalityAnalysis.EITHER) {
2418 //Code is reading from a null pointer
2419 output.println("if ("+generateTemp(fm, fen.getSrc(),lb)+") {");
2420 output.println("#ifndef RAW");
2421 output.println("printf(\"BIG ERROR\\n\");exit(-1);}");
2422 output.println("#endif");
2423 //This should throw a suitable null pointer error
2424 output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2426 throw new Error("Read from non-global/non-local in:"+lb.getExplanation());
2428 output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2432 private void generateFlatSetElementNode(FlatMethod fm, LocalityBinding lb, FlatSetElementNode fsen, PrintWriter output) {
2433 //TODO: need dynamic check to make sure this assignment is actually legal
2434 //Because Object[] could actually be something more specific...ie. Integer[]
2436 TypeDescriptor elementtype=fsen.getDst().getType().dereference();
2439 if (elementtype.isArray()||elementtype.isClass())
2442 type=elementtype.getSafeSymbol()+" ";
2444 if (this.state.ARRAYBOUNDARYCHECK && fsen.needsBoundsCheck()) {
2445 output.println("if ("+generateTemp(fm, fsen.getIndex(),lb)+"< 0 | "+generateTemp(fm, fsen.getIndex(),lb)+" >= "+generateTemp(fm,fsen.getDst(),lb) + "->___length___)");
2446 output.println("failedboundschk();");
2449 if (state.SINGLETM && locality.getAtomic(lb).get(fsen).intValue()>0) {
2450 //Transaction set element case
2451 if (wb.needBarrier(fsen)&&
2452 locality.getNodePreTempInfo(lb, fsen).get(fsen.getDst())!=LocalityAnalysis.SCRATCH) {
2453 output.println("*((unsigned int *)&("+generateTemp(fm,fsen.getDst(),lb)+"->___objstatus___))|=DIRTY;");
2455 if (fsen.getSrc().getType().isPtr()&&!fsen.getSrc().getType().isNull()) {
2456 output.println("{");
2457 String src=generateTemp(fm, fsen.getSrc(), lb);
2458 if ((dc==null)||dc.getNeedSrcTrans(lb, fsen)&&
2459 locality.getNodePreTempInfo(lb, fsen).get(fsen.getSrc())!=LocalityAnalysis.SCRATCH) {
2460 output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
2462 output.println("INTPTR srcoid=(INTPTR)"+src+";");
2464 output.println("((INTPTR*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]=srcoid;");
2465 output.println("}");
2467 output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
2469 } else if (state.DSM && locality.getAtomic(lb).get(fsen).intValue()>0) {
2470 Integer statussrc=locality.getNodePreTempInfo(lb,fsen).get(fsen.getSrc());
2471 Integer statusdst=locality.getNodePreTempInfo(lb,fsen).get(fsen.getDst());
2472 boolean srcglobal=statussrc==LocalityAnalysis.GLOBAL;
2473 boolean dstglobal=statusdst==LocalityAnalysis.GLOBAL;
2474 boolean dstlocal=statusdst==LocalityAnalysis.LOCAL;
2477 if (wb.needBarrier(fsen))
2478 output.println("*((unsigned int *)&("+generateTemp(fm,fsen.getDst(),lb)+"->___localcopy___))|=DIRTY;");
2479 } else if (dstlocal) {
2480 /** Check if we need to copy */
2481 String dst=generateTemp(fm, fsen.getDst(),lb);
2482 output.println("if(!"+dst+"->"+localcopystr+") {");
2483 /* Link object into list */
2484 String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2485 output.println(revertptr+"=revertlist;");
2486 if (GENERATEPRECISEGC)
2487 output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
2489 output.println("COPY_OBJ("+dst+");");
2490 output.println(dst+"->"+nextobjstr+"="+revertptr+";");
2491 output.println("revertlist=(struct ___Object___ *)"+dst+";");
2492 output.println("}");
2493 } else throw new Error("Unknown array type");
2495 output.println("{");
2496 String src=generateTemp(fm, fsen.getSrc(), lb);
2497 output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
2498 output.println("((INTPTR*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]=srcoid;");
2499 output.println("}");
2501 output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
2504 if (state.FASTCHECK) {
2505 String dst=generateTemp(fm, fsen.getDst(),lb);
2506 output.println("if(!"+dst+"->"+localcopystr+") {");
2507 /* Link object into list */
2508 if (GENERATEPRECISEGC)
2509 output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
2511 output.println("COPY_OBJ("+dst+");");
2512 output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
2513 output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
2514 output.println("}");
2516 output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
2520 protected void generateFlatNew(FlatMethod fm, LocalityBinding lb, FlatNew fn, PrintWriter output) {
2521 if (state.DSM && locality.getAtomic(lb).get(fn).intValue()>0&&!fn.isGlobal()) {
2522 //Stash pointer in case of GC
2523 String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2524 output.println(revertptr+"=revertlist;");
2526 if (state.SINGLETM) {
2527 if (fn.getType().isArray()) {
2528 int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
2529 if (locality.getAtomic(lb).get(fn).intValue()>0) {
2530 //inside transaction
2531 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarraytrans(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
2533 //outside transaction
2534 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
2537 if (locality.getAtomic(lb).get(fn).intValue()>0) {
2538 //inside transaction
2539 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newtrans(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
2541 //outside transaction
2542 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
2545 } else if (fn.getType().isArray()) {
2546 int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
2547 if (fn.isGlobal()&&(state.DSM||state.SINGLETM)) {
2548 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarrayglobal("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
2549 } else if (GENERATEPRECISEGC) {
2550 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
2552 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
2555 if (fn.isGlobal()) {
2556 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newglobal("+fn.getType().getClassDesc().getId()+");");
2557 } else if (GENERATEPRECISEGC) {
2558 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
2560 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
2563 if (state.DSM && locality.getAtomic(lb).get(fn).intValue()>0&&!fn.isGlobal()) {
2564 String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2565 String dst=generateTemp(fm,fn.getDst(),lb);
2566 output.println(dst+"->___localcopy___=(struct ___Object___*)1;");
2567 output.println(dst+"->"+nextobjstr+"="+revertptr+";");
2568 output.println("revertlist=(struct ___Object___ *)"+dst+";");
2570 if (state.FASTCHECK) {
2571 String dst=generateTemp(fm,fn.getDst(),lb);
2572 output.println(dst+"->___localcopy___=(struct ___Object___*)1;");
2573 output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
2574 output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
2578 private void generateFlatTagDeclaration(FlatMethod fm, LocalityBinding lb, FlatTagDeclaration fn, PrintWriter output) {
2579 if (GENERATEPRECISEGC) {
2580 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag(&"+localsprefix+", "+state.getTagId(fn.getType())+");");
2582 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag("+state.getTagId(fn.getType())+");");
2586 private void generateFlatOpNode(FlatMethod fm, LocalityBinding lb, FlatOpNode fon, PrintWriter output) {
2587 if (fon.getRight()!=null) {
2588 if (fon.getOp().getOp()==Operation.URIGHTSHIFT) {
2589 if (fon.getLeft().getType().isLong())
2590 output.println(generateTemp(fm, fon.getDest(),lb)+" = ((unsigned long long)"+generateTemp(fm, fon.getLeft(),lb)+")>>"+generateTemp(fm,fon.getRight(),lb)+";");
2592 output.println(generateTemp(fm, fon.getDest(),lb)+" = ((unsigned int)"+generateTemp(fm, fon.getLeft(),lb)+")>>"+generateTemp(fm,fon.getRight(),lb)+";");
2595 output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+fon.getOp().toString()+generateTemp(fm,fon.getRight(),lb)+";");
2596 } else if (fon.getOp().getOp()==Operation.ASSIGN)
2597 output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";");
2598 else if (fon.getOp().getOp()==Operation.UNARYPLUS)
2599 output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";");
2600 else if (fon.getOp().getOp()==Operation.UNARYMINUS)
2601 output.println(generateTemp(fm, fon.getDest(),lb)+" = -"+generateTemp(fm, fon.getLeft(),lb)+";");
2602 else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
2603 output.println(generateTemp(fm, fon.getDest(),lb)+" = !"+generateTemp(fm, fon.getLeft(),lb)+";");
2604 else if (fon.getOp().getOp()==Operation.COMP)
2605 output.println(generateTemp(fm, fon.getDest(),lb)+" = ~"+generateTemp(fm, fon.getLeft(),lb)+";");
2606 else if (fon.getOp().getOp()==Operation.ISAVAILABLE) {
2607 output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+"->fses==NULL;");
2609 output.println(generateTemp(fm, fon.getDest(),lb)+fon.getOp().toString()+generateTemp(fm, fon.getLeft(),lb)+";");
2612 private void generateFlatCastNode(FlatMethod fm, LocalityBinding lb, FlatCastNode fcn, PrintWriter output) {
2613 /* TODO: Do type check here */
2614 if (fcn.getType().isArray()) {
2616 } else if (fcn.getType().isClass())
2617 output.println(generateTemp(fm,fcn.getDst(),lb)+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc(),lb)+";");
2619 output.println(generateTemp(fm,fcn.getDst(),lb)+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc(),lb)+";");
2622 private void generateFlatLiteralNode(FlatMethod fm, LocalityBinding lb, FlatLiteralNode fln, PrintWriter output) {
2623 if (fln.getValue()==null)
2624 output.println(generateTemp(fm, fln.getDst(),lb)+"=0;");
2625 else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
2626 if (GENERATEPRECISEGC) {
2627 if (state.DSM && locality.getAtomic(lb).get(fln).intValue()>0) {
2628 //Stash pointer in case of GC
2629 String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2630 output.println(revertptr+"=revertlist;");
2632 output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString(&"+localsprefix+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
2633 if (state.DSM && locality.getAtomic(lb).get(fln).intValue()>0) {
2634 //Stash pointer in case of GC
2635 String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2636 output.println("revertlist="+revertptr+";");
2639 output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
2641 } else if (fln.getType().isBoolean()) {
2642 if (((Boolean)fln.getValue()).booleanValue())
2643 output.println(generateTemp(fm, fln.getDst(),lb)+"=1;");
2645 output.println(generateTemp(fm, fln.getDst(),lb)+"=0;");
2646 } else if (fln.getType().isChar()) {
2647 String st=FlatLiteralNode.escapeString(fln.getValue().toString());
2648 output.println(generateTemp(fm, fln.getDst(),lb)+"='"+st+"';");
2649 } else if (fln.getType().isLong()) {
2650 output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+"LL;");
2652 output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+";");
2655 protected void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
2656 if (frn.getReturnTemp()!=null) {
2657 if (frn.getReturnTemp().getType().isPtr())
2658 output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
2660 output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
2662 output.println("return;");
2666 protected void generateFlatCondBranch(FlatMethod fm, LocalityBinding lb, FlatCondBranch fcb, String label, PrintWriter output) {
2667 output.println("if (!"+generateTemp(fm, fcb.getTest(),lb)+") goto "+label+";");
2670 /** This method generates header information for the method or
2671 * task referenced by the Descriptor des. */
2673 private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) {
2675 ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : des);
2676 MethodDescriptor md=null;
2677 TaskDescriptor task=null;
2678 if (des instanceof MethodDescriptor)
2679 md=(MethodDescriptor) des;
2681 task=(TaskDescriptor) des;
2683 ClassDescriptor cn=md!=null ? md.getClassDesc() : null;
2685 if (md!=null&&md.getReturnType()!=null) {
2686 if (md.getReturnType().isClass()||md.getReturnType().isArray())
2687 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
2689 output.print(md.getReturnType().getSafeSymbol()+" ");
2691 //catch the constructor case
2692 output.print("void ");
2694 if (state.DSM||state.SINGLETM) {
2695 output.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
2697 output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
2699 output.print(task.getSafeSymbol()+"(");
2701 boolean printcomma=false;
2702 if (GENERATEPRECISEGC) {
2704 if (state.DSM||state.SINGLETM) {
2705 output.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
2707 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
2709 output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
2715 for(int i=0; i<objectparams.numPrimitives(); i++) {
2716 TempDescriptor temp=objectparams.getPrimitive(i);
2720 if (temp.getType().isClass()||temp.getType().isArray())
2721 output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
2723 output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
2725 output.println(") {");
2726 } else if (!GENERATEPRECISEGC) {
2727 /* Imprecise Task */
2728 output.println("void * parameterarray[]) {");
2729 /* Unpack variables */
2730 for(int i=0; i<objectparams.numPrimitives(); i++) {
2731 TempDescriptor temp=objectparams.getPrimitive(i);
2732 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
2734 for(int i=0; i<fm.numTags(); i++) {
2735 TempDescriptor temp=fm.getTag(i);
2736 int offset=i+objectparams.numPrimitives();
2737 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
2740 if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
2741 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
2742 } else output.println(") {");
2745 public void generateFlatFlagActionNode(FlatMethod fm, LocalityBinding lb, FlatFlagActionNode ffan, PrintWriter output) {
2746 output.println("/* FlatFlagActionNode */");
2749 /* Process tag changes */
2750 Relation tagsettable=new Relation();
2751 Relation tagcleartable=new Relation();
2753 Iterator tagsit=ffan.getTempTagPairs();
2754 while (tagsit.hasNext()) {
2755 TempTagPair ttp=(TempTagPair) tagsit.next();
2756 TempDescriptor objtmp=ttp.getTemp();
2757 TagDescriptor tag=ttp.getTag();
2758 TempDescriptor tagtmp=ttp.getTagTemp();
2759 boolean tagstatus=ffan.getTagChange(ttp);
2761 tagsettable.put(objtmp, tagtmp);
2763 tagcleartable.put(objtmp, tagtmp);
2768 Hashtable flagandtable=new Hashtable();
2769 Hashtable flagortable=new Hashtable();
2771 /* Process flag changes */
2772 Iterator flagsit=ffan.getTempFlagPairs();
2773 while(flagsit.hasNext()) {
2774 TempFlagPair tfp=(TempFlagPair)flagsit.next();
2775 TempDescriptor temp=tfp.getTemp();
2776 Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
2777 FlagDescriptor flag=tfp.getFlag();
2779 //Newly allocate objects that don't set any flags case
2780 if (flagortable.containsKey(temp)) {
2784 flagortable.put(temp,new Integer(mask));
2786 int flagid=1<<((Integer)flagtable.get(flag)).intValue();
2787 boolean flagstatus=ffan.getFlagChange(tfp);
2790 if (flagortable.containsKey(temp)) {
2791 mask=((Integer)flagortable.get(temp)).intValue();
2794 flagortable.put(temp,new Integer(mask));
2796 int mask=0xFFFFFFFF;
2797 if (flagandtable.containsKey(temp)) {
2798 mask=((Integer)flagandtable.get(temp)).intValue();
2800 mask&=(0xFFFFFFFF^flagid);
2801 flagandtable.put(temp,new Integer(mask));
2807 HashSet flagtagset=new HashSet();
2808 flagtagset.addAll(flagortable.keySet());
2809 flagtagset.addAll(flagandtable.keySet());
2810 flagtagset.addAll(tagsettable.keySet());
2811 flagtagset.addAll(tagcleartable.keySet());
2813 Iterator ftit=flagtagset.iterator();
2814 while(ftit.hasNext()) {
2815 TempDescriptor temp=(TempDescriptor)ftit.next();
2818 Set tagtmps=tagcleartable.get(temp);
2819 if (tagtmps!=null) {
2820 Iterator tagit=tagtmps.iterator();
2821 while(tagit.hasNext()) {
2822 TempDescriptor tagtmp=(TempDescriptor)tagit.next();
2823 if (GENERATEPRECISEGC)
2824 output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
2826 output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
2830 tagtmps=tagsettable.get(temp);
2831 if (tagtmps!=null) {
2832 Iterator tagit=tagtmps.iterator();
2833 while(tagit.hasNext()) {
2834 TempDescriptor tagtmp=(TempDescriptor)tagit.next();
2835 if (GENERATEPRECISEGC)
2836 output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
2838 output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp, lb)+", "+generateTemp(fm,tagtmp, lb)+");");
2843 int andmask=0xFFFFFFF;
2845 if (flagortable.containsKey(temp))
2846 ormask=((Integer)flagortable.get(temp)).intValue();
2847 if (flagandtable.containsKey(temp))
2848 andmask=((Integer)flagandtable.get(temp)).intValue();
2849 generateFlagOrAnd(ffan, fm, lb, temp, output, ormask, andmask);
2850 generateObjectDistribute(ffan, fm, lb, temp, output);
2854 protected void generateFlagOrAnd(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp,
2855 PrintWriter output, int ormask, int andmask) {
2856 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
2857 output.println("flagorandinit("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
2859 output.println("flagorand("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
2863 protected void generateObjectDistribute(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp, PrintWriter output) {
2864 output.println("enqueueObject("+generateTemp(fm, temp, lb)+");");
2867 void generateOptionalHeader(PrintWriter headers) {
2870 headers.println("#include \"task.h\"\n\n");
2871 headers.println("#ifndef _OPTIONAL_STRUCT_");
2872 headers.println("#define _OPTIONAL_STRUCT_");
2874 //STRUCT PREDICATEMEMBER
2875 headers.println("struct predicatemember{");
2876 headers.println("int type;");
2877 headers.println("int numdnfterms;");
2878 headers.println("int * flags;");
2879 headers.println("int numtags;");
2880 headers.println("int * tags;\n};\n\n");
2882 //STRUCT OPTIONALTASKDESCRIPTOR
2883 headers.println("struct optionaltaskdescriptor{");
2884 headers.println("struct taskdescriptor * task;");
2885 headers.println("int index;");
2886 headers.println("int numenterflags;");
2887 headers.println("int * enterflags;");
2888 headers.println("int numpredicatemembers;");
2889 headers.println("struct predicatemember ** predicatememberarray;");
2890 headers.println("};\n\n");
2892 //STRUCT TASKFAILURE
2893 headers.println("struct taskfailure {");
2894 headers.println("struct taskdescriptor * task;");
2895 headers.println("int index;");
2896 headers.println("int numoptionaltaskdescriptors;");
2897 headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
2899 //STRUCT FSANALYSISWRAPPER
2900 headers.println("struct fsanalysiswrapper{");
2901 headers.println("int flags;");
2902 headers.println("int numtags;");
2903 headers.println("int * tags;");
2904 headers.println("int numtaskfailures;");
2905 headers.println("struct taskfailure ** taskfailurearray;");
2906 headers.println("int numoptionaltaskdescriptors;");
2907 headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
2909 //STRUCT CLASSANALYSISWRAPPER
2910 headers.println("struct classanalysiswrapper{");
2911 headers.println("int type;");
2912 headers.println("int numotd;");
2913 headers.println("struct optionaltaskdescriptor ** otdarray;");
2914 headers.println("int numfsanalysiswrappers;");
2915 headers.println("struct fsanalysiswrapper ** fsanalysiswrapperarray;\n};");
2917 headers.println("extern struct classanalysiswrapper * classanalysiswrapperarray[];");
2919 Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
2920 while(taskit.hasNext()) {
2921 TaskDescriptor td=(TaskDescriptor)taskit.next();
2922 headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
2927 //CHECK OVER THIS -- THERE COULD BE SOME ERRORS HERE
2928 int generateOptionalPredicate(Predicate predicate, OptionalTaskDescriptor otd, ClassDescriptor cdtemp, PrintWriter output) {
2929 int predicateindex = 0;
2930 //iterate through the classes concerned by the predicate
2931 Set c_vard = predicate.vardescriptors;
2932 Hashtable<TempDescriptor, Integer> slotnumber=new Hashtable<TempDescriptor, Integer>();
2935 for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext();) {
2936 VarDescriptor vard = (VarDescriptor)vard_it.next();
2937 TypeDescriptor typed = vard.getType();
2939 //generate for flags
2940 HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
2941 output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2943 if (fen_hashset!=null) {
2944 for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext();) {
2945 FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
2947 DNFFlag dflag=fen.getDNF();
2948 numberterms+=dflag.size();
2950 Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
2952 for(int j=0; j<dflag.size(); j++) {
2954 output.println(",");
2955 Vector term=dflag.get(j);
2958 for(int k=0; k<term.size(); k++) {
2959 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
2960 FlagDescriptor fd=dfa.getFlag();
2961 boolean negated=dfa.getNegated();
2962 int flagid=1<<((Integer)flags.get(fd)).intValue();
2967 output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
2972 output.println("};\n");
2975 TagExpressionList tagel = predicate.tags.get(vard.getSymbol());
2976 output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2979 for(int j=0; j<tagel.numTags(); j++) {
2981 output.println(",");
2982 TempDescriptor tmp=tagel.getTemp(j);
2983 if (!slotnumber.containsKey(tmp)) {
2984 Integer slotint=new Integer(current_slot++);
2985 slotnumber.put(tmp,slotint);
2987 int slot=slotnumber.get(tmp).intValue();
2988 output.println("/* slot */"+ slot+", /*tagid*/"+state.getTagId(tmp.getTag()));
2990 numtags = tagel.numTags();
2992 output.println("};");
2994 //store the result into a predicatemember struct
2995 output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
2996 output.println("/*type*/"+typed.getClassDesc().getId()+",");
2997 output.println("/* number of dnf terms */"+numberterms+",");
2998 output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2999 output.println("/* number of tag */"+numtags+",");
3000 output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3001 output.println("};\n");
3006 //generate an array that stores the entire predicate
3007 output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
3008 for( int j = 0; j<predicateindex; j++) {
3009 if( j != predicateindex-1) output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3010 else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
3012 output.println("};\n");
3013 return predicateindex;
3017 void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, Set<OptionalTaskDescriptor>>> safeexecution, Hashtable optionaltaskdescriptors) {
3018 generateOptionalHeader(headers);
3020 output.println("#include \"optionalstruct.h\"\n\n");
3021 output.println("#include \"stdlib.h\"\n");
3023 HashSet processedcd = new HashSet();
3025 Enumeration e = safeexecution.keys();
3026 while (e.hasMoreElements()) {
3029 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
3030 Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp); //will be used several times
3032 //Generate the struct of optionals
3033 Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
3034 numotd = c_otd.size();
3035 if(maxotd<numotd) maxotd = numotd;
3036 if( !c_otd.isEmpty() ) {
3037 for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();) {
3038 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
3040 //generate the int arrays for the predicate
3041 Predicate predicate = otd.predicate;
3042 int predicateindex = generateOptionalPredicate(predicate, otd, cdtemp, output);
3043 TreeSet<Integer> fsset=new TreeSet<Integer>();
3044 //iterate through possible FSes corresponding to
3045 //the state when entering
3047 for(Iterator fses = otd.enterflagstates.iterator(); fses.hasNext();) {
3048 FlagState fs = (FlagState)fses.next();
3050 for(Iterator flags = fs.getFlags(); flags.hasNext();) {
3051 FlagDescriptor flagd = (FlagDescriptor)flags.next();
3052 int id=1<<((Integer)flaginfo.get(flagd)).intValue();
3055 fsset.add(new Integer(flagid));
3056 //tag information not needed because tag
3057 //changes are not tolerated.
3060 output.println("int enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
3061 boolean needcomma=false;
3062 for(Iterator<Integer> it=fsset.iterator(); it.hasNext();) {
3065 output.println(it.next());
3068 output.println("};\n");
3071 //generate optionaltaskdescriptor that actually
3072 //includes exit fses, predicate and the task
3074 output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
3075 output.println("&task_"+otd.td.getSafeSymbol()+",");
3076 output.println("/*index*/"+otd.getIndex()+",");
3077 output.println("/*number of enter flags*/"+fsset.size()+",");
3078 output.println("enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3079 output.println("/*number of members */"+predicateindex+",");
3080 output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3081 output.println("};\n");
3085 // if there are no optionals, there is no need to build the rest of the struct
3087 output.println("struct optionaltaskdescriptor * otdarray"+cdtemp.getSafeSymbol()+"[]={");
3088 c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
3089 if( !c_otd.isEmpty() ) {
3090 boolean needcomma=false;
3091 for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();) {
3092 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
3094 output.println(",");
3096 output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
3099 output.println("};\n");
3101 //get all the possible flagstates reachable by an object
3102 Hashtable hashtbtemp = safeexecution.get(cdtemp);
3104 TreeSet fsts=new TreeSet(new FlagComparator(flaginfo));
3105 fsts.addAll(hashtbtemp.keySet());
3106 for(Iterator fsit=fsts.iterator(); fsit.hasNext();) {
3107 FlagState fs = (FlagState)fsit.next();
3110 //get the set of OptionalTaskDescriptors corresponding
3111 HashSet<OptionalTaskDescriptor> availabletasks = (HashSet<OptionalTaskDescriptor>)hashtbtemp.get(fs);
3112 //iterate through the OptionalTaskDescriptors and
3113 //store the pointers to the optionals struct (see on
3114 //top) into an array
3116 output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
3117 for(Iterator<OptionalTaskDescriptor> mos = ordertd(availabletasks).iterator(); mos.hasNext();) {
3118 OptionalTaskDescriptor mm = mos.next();
3120 output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol());
3122 output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3125 output.println("};\n");
3127 //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose.
3130 for(Iterator flags = fs.getFlags(); flags.hasNext();) {
3131 FlagDescriptor flagd = (FlagDescriptor)flags.next();
3132 int id=1<<((Integer)flaginfo.get(flagd)).intValue();
3136 //process tag information
3139 boolean first = true;
3140 Enumeration tag_enum = fs.getTags();
3141 output.println("int tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
3142 while(tag_enum.hasMoreElements()) {
3144 TagDescriptor tagd = (TagDescriptor)tag_enum.nextElement();
3148 output.println(", ");
3149 output.println("/*tagid*/"+state.getTagId(tagd));
3151 output.println("};");
3153 Set<TaskIndex> tiset=sa.getTaskIndex(fs);
3154 for(Iterator<TaskIndex> itti=tiset.iterator(); itti.hasNext();) {
3155 TaskIndex ti=itti.next();
3159 Set<OptionalTaskDescriptor> otdset=sa.getOptions(fs, ti);
3161 output.print("struct optionaltaskdescriptor * optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array[] = {");
3162 boolean needcomma=false;
3163 for(Iterator<OptionalTaskDescriptor> otdit=ordertd(otdset).iterator(); otdit.hasNext();) {
3164 OptionalTaskDescriptor otd=otdit.next();
3168 output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
3170 output.println("};");
3172 output.print("struct taskfailure taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+" = {");
3173 output.print("&task_"+ti.getTask().getSafeSymbol()+", ");
3174 output.print(ti.getIndex()+", ");
3175 output.print(otdset.size()+", ");
3176 output.print("optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array");
3177 output.println("};");
3180 tiset=sa.getTaskIndex(fs);
3181 boolean needcomma=false;
3183 output.println("struct taskfailure * taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
3184 for(Iterator<TaskIndex> itti=tiset.iterator(); itti.hasNext();) {
3185 TaskIndex ti=itti.next();
3186 if (ti.isRuntime()) {
3193 output.print("&taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex());
3195 output.println("};\n");
3197 //Store the result in fsanalysiswrapper
3199 output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
3200 output.println("/*flag*/"+flagid+",");
3201 output.println("/* number of tags*/"+tagcounter+",");
3202 output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
3203 output.println("/* numtask failures */"+(tiset.size()-runtimeti)+",");
3204 output.println("taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
3205 output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
3206 output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
3207 output.println("};\n");
3211 //Build the array of fsanalysiswrappers
3212 output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
3213 boolean needcomma=false;
3214 for(int i = 0; i<fscounter; i++) {
3215 if (needcomma) output.print(",");
3216 output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol());
3219 output.println("};");
3221 //Build the classanalysiswrapper referring to the previous array
3222 output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
3223 output.println("/*type*/"+cdtemp.getId()+",");
3224 output.println("/*numotd*/"+numotd+",");
3225 output.println("otdarray"+cdtemp.getSafeSymbol()+",");
3226 output.println("/* number of fsanalysiswrappers */"+fscounter+",");
3227 output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
3228 processedcd.add(cdtemp);
3231 //build an array containing every classes for which code has been build
3232 output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
3233 for(int i=0; i<state.numClasses(); i++) {
3234 ClassDescriptor cn=cdarray[i];
3237 if (processedcd.contains(cn))
3238 output.print("&classanalysiswrapper_"+cn.getSafeSymbol());
3240 output.print("NULL");
3242 output.println("};");
3244 output.println("#define MAXOTD "+maxotd);
3245 headers.println("#endif");
3248 public List<OptionalTaskDescriptor> ordertd(Set<OptionalTaskDescriptor> otdset) {
3249 Relation r=new Relation();
3250 for(Iterator<OptionalTaskDescriptor>otdit=otdset.iterator(); otdit.hasNext();) {
3251 OptionalTaskDescriptor otd=otdit.next();
3252 TaskIndex ti=new TaskIndex(otd.td, otd.getIndex());
3256 LinkedList<OptionalTaskDescriptor> l=new LinkedList<OptionalTaskDescriptor>();
3257 for(Iterator it=r.keySet().iterator(); it.hasNext();) {
3258 Set s=r.get(it.next());
3259 for(Iterator it2=s.iterator(); it2.hasNext();) {
3260 OptionalTaskDescriptor otd=(OptionalTaskDescriptor)it2.next();
3268 protected void outputTransCode(PrintWriter output) {