2 import IR.Tree.FlagExpressionNode;
3 import IR.Tree.DNFFlag;
4 import IR.Tree.DNFFlagAtom;
5 import IR.Tree.TagExpressionList;
10 import Analysis.TaskStateAnalysis.FlagState;
11 import Analysis.TaskStateAnalysis.OptionalTaskDescriptor;
12 import Analysis.TaskStateAnalysis.Predicate;
13 import Analysis.Locality.LocalityAnalysis;
14 import Analysis.Locality.LocalityBinding;
16 public class BuildCode {
19 Hashtable paramstable;
24 String localsprefix="___locals___";
25 String paramsprefix="___params___";
26 String oidstr="___nextobject___";
27 String nextobjstr="___nextobject___";
28 String localcopystr="___localcopy___";
29 public static boolean GENERATEPRECISEGC=false;
30 public static String PREFIX="";
31 public static String arraytype="ArrayObject";
34 private int maxtaskparams=0;
35 private int maxcount=0;
36 ClassDescriptor[] cdarray;
37 TypeDescriptor[] arraytable;
38 LocalityAnalysis locality;
39 Hashtable<TempDescriptor, TempDescriptor> backuptable;
40 Hashtable<LocalityBinding, TempDescriptor> reverttable;
42 public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) {
43 this(st, temptovar, typeutil, null);
46 public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality) {
48 this.temptovar=temptovar;
49 paramstable=new Hashtable();
50 tempstable=new Hashtable();
51 fieldorder=new Hashtable();
52 flagorder=new Hashtable();
53 this.typeutil=typeutil;
54 virtualcalls=new Virtual(state,locality);
56 this.locality=locality;
57 this.backuptable=new Hashtable<TempDescriptor, TempDescriptor>();
58 this.reverttable=new Hashtable<LocalityBinding, TempDescriptor>();
62 /** The buildCode method outputs C code for all the methods. The Flat
63 * versions of the methods must already be generated and stored in
64 * the State object. */
66 public void buildCode() {
67 /* Create output streams to write to */
68 PrintWriter outclassdefs=null;
69 PrintWriter outstructs=null;
70 PrintWriter outrepairstructs=null;
71 PrintWriter outmethodheader=null;
72 PrintWriter outmethod=null;
73 PrintWriter outvirtual=null;
74 PrintWriter outtask=null;
75 PrintWriter outtaskdefs=null;
76 PrintWriter outoptionalarrays=null;
77 PrintWriter optionalheaders=null;
80 outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
81 outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
82 outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
83 outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
84 outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
86 outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
87 outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
89 outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
90 optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
93 if (state.structfile!=null) {
94 outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
96 } catch (Exception e) {
101 /* Build the virtual dispatch tables */
102 buildVirtualTables(outvirtual);
104 /* Output includes */
105 outmethodheader.println("#ifndef METHODHEADERS_H");
106 outmethodheader.println("#define METHODHEADERS_H");
107 outmethodheader.println("#include \"structdefs.h\"");
109 outmethodheader.println("#include \"dstm.h\"");
111 /* Output Structures */
112 outputStructs(outstructs);
114 // Output the C class declarations
115 // These could mutually reference each other
116 outputClassDeclarations(outclassdefs);
118 // Output function prototypes and structures for parameters
119 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
120 while(it.hasNext()) {
121 ClassDescriptor cn=(ClassDescriptor)it.next();
122 generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
124 outclassdefs.close();
127 /* Map flags to integers */
128 /* The runtime keeps track of flags using these integers */
129 it=state.getClassSymbolTable().getDescriptorsIterator();
130 while(it.hasNext()) {
131 ClassDescriptor cn=(ClassDescriptor)it.next();
135 generateTaskStructs(outstructs, outmethodheader);
137 /* Outputs generic task structures if this is a task
139 outputTaskTypes(outtask);
142 /* Build the actual methods */
143 outputMethods(outmethod);
146 /* Output code for tasks */
147 outputTaskCode(outtaskdefs, outmethod);
149 /* Record maximum number of task parameters */
150 outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
151 } else if (state.main!=null) {
152 /* Generate main method */
153 outputMainMethod(outmethod);
156 /* Generate information for task with optional parameters */
157 if (state.TASK&&state.OPTIONAL){
158 generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
159 outoptionalarrays.close();
162 /* Output structure definitions for repair tool */
163 if (state.structfile!=null) {
164 buildRepairStructs(outrepairstructs);
165 outrepairstructs.close();
169 outmethodheader.println("#endif");
170 outmethodheader.close();
172 outstructs.println("#endif");
176 /* This code just generates the main C method for java programs.
177 * The main C method packs up the arguments into a string array
178 * and passes it to the java main method. */
180 private void outputMainMethod(PrintWriter outmethod) {
181 outmethod.println("int main(int argc, const char *argv[]) {");
182 outmethod.println(" int i;");
184 outmethod.println("if (dstmStartup(argv[1])) {");
185 if (GENERATEPRECISEGC) {
186 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-2);");
188 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-2);");
191 if (GENERATEPRECISEGC) {
192 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
194 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
198 outmethod.println("initializethreads();");
201 outmethod.println(" for(i=2;i<argc;i++) {");
203 outmethod.println(" for(i=1;i<argc;i++) {");
204 outmethod.println(" int length=strlen(argv[i]);");
205 if (GENERATEPRECISEGC) {
206 outmethod.println(" struct ___String___ *newstring=NewString(NULL, argv[i], length);");
208 outmethod.println(" struct ___String___ *newstring=NewString(argv[i], length);");
211 outmethod.println(" ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-2]=newstring;");
213 outmethod.println(" ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
214 outmethod.println(" }");
217 MethodDescriptor md=typeutil.getMain();
218 ClassDescriptor cd=typeutil.getMainClass();
220 outmethod.println(" {");
221 if (GENERATEPRECISEGC) {
223 outmethod.print(" struct "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
225 outmethod.print(" struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
226 outmethod.println("1, NULL,"+"stringarray};");
228 outmethod.println(" "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
230 outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
233 outmethod.println(" "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
235 outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
237 outmethod.println(" }");
240 outmethod.println("}");
244 outmethod.println("pthread_mutex_lock(&gclistlock);");
245 outmethod.println("threadcount--;");
246 outmethod.println("pthread_cond_signal(&gccond);");
247 outmethod.println("pthread_mutex_unlock(&gclistlock);");
248 outmethod.println("pthread_exit(NULL);");
252 outmethod.println("}");
255 /* This method outputs code for each task. */
257 private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod) {
258 /* Compile task based program */
259 outtaskdefs.println("#include \"task.h\"");
260 outtaskdefs.println("#include \"methodheaders.h\"");
261 Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
262 while(taskit.hasNext()) {
263 TaskDescriptor td=(TaskDescriptor)taskit.next();
264 FlatMethod fm=state.getMethodFlat(td);
265 generateFlatMethod(fm, null, outmethod);
266 generateTaskDescriptor(outtaskdefs, fm, td);
269 //Output task descriptors
270 taskit=state.getTaskSymbolTable().getDescriptorsIterator();
271 outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
273 while(taskit.hasNext()) {
274 TaskDescriptor td=(TaskDescriptor)taskit.next();
278 outtaskdefs.println(",");
279 outtaskdefs.print("&task_"+td.getSafeSymbol());
281 outtaskdefs.println("};");
283 outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
286 /* This method outputs most of the methods.c file. This includes
287 * some standard includes and then an array with the sizes of
288 * objets and array that stores supertype and then the code for
289 * the Java methods.. */
291 private void outputMethods(PrintWriter outmethod) {
292 outmethod.println("#include \"methodheaders.h\"");
293 outmethod.println("#include \"virtualtable.h\"");
294 outmethod.println("#include <runtime.h>");
296 outmethod.println("#include \"localobjects.h\"");
299 outmethod.println("#include <thread.h>");
300 if (state.main!=null) {
301 outmethod.println("#include <string.h>");
303 if (state.CONSCHECK) {
304 outmethod.println("#include \"checkers.h\"");
306 //Store the sizes of classes & array elements
307 generateSizeArray(outmethod);
309 //Store table of supertypes
310 generateSuperTypeTable(outmethod);
312 //Store the layout of classes
313 generateLayoutStructs(outmethod);
315 /* Generate code for methods */
317 for(Iterator<LocalityBinding> lbit=locality.getLocalityBindings().iterator();lbit.hasNext();) {
318 LocalityBinding lb=lbit.next();
319 MethodDescriptor md=lb.getMethod();
320 FlatMethod fm=state.getMethodFlat(md);
321 if (!md.getModifiers().isNative()) {
322 generateFlatMethod(fm, lb, outmethod);
326 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
327 while(classit.hasNext()) {
328 ClassDescriptor cn=(ClassDescriptor)classit.next();
329 Iterator methodit=cn.getMethods();
330 while(methodit.hasNext()) {
331 /* Classify parameters */
332 MethodDescriptor md=(MethodDescriptor)methodit.next();
333 FlatMethod fm=state.getMethodFlat(md);
334 if (!md.getModifiers().isNative())
335 generateFlatMethod(fm, null, outmethod);
341 private void outputStructs(PrintWriter outstructs) {
342 outstructs.println("#ifndef STRUCTDEFS_H");
343 outstructs.println("#define STRUCTDEFS_H");
344 outstructs.println("#include \"classdefs.h\"");
346 /* Output #defines that the runtime uses to determine type
347 * numbers for various objects it needs */
348 outstructs.println("#define MAXCOUNT "+maxcount);
350 LocalityBinding lb=new LocalityBinding(typeutil.getRun(), false);
351 lb.setGlobalThis(LocalityAnalysis.GLOBAL);
352 outstructs.println("#define RUNMETHOD "+virtualcalls.getLocalityNumber(lb));
355 outstructs.println("#define STRINGARRAYTYPE "+
356 (state.getArrayNumber(
357 (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
359 outstructs.println("#define OBJECTARRAYTYPE "+
360 (state.getArrayNumber(
361 (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
364 outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
365 outstructs.println("#define CHARARRAYTYPE "+
366 (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
368 outstructs.println("#define BYTEARRAYTYPE "+
369 (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses()));
371 outstructs.println("#define BYTEARRAYARRAYTYPE "+
372 (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
374 outstructs.println("#define NUMCLASSES "+state.numClasses());
376 outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
377 outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
378 outstructs.println("#define TAGARRAYTYPE "+
379 (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses()));
383 private void outputClassDeclarations(PrintWriter outclassdefs) {
385 outclassdefs.println("#include <pthread.h>");
387 outclassdefs.println("#include \"optionalstruct.h\"");
388 outclassdefs.println("struct "+arraytype+";");
389 /* Start by declaring all structs */
390 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
391 while(it.hasNext()) {
392 ClassDescriptor cn=(ClassDescriptor)it.next();
393 outclassdefs.println("struct "+cn.getSafeSymbol()+";");
395 outclassdefs.println("");
396 //Print out definition for array type
397 outclassdefs.println("struct "+arraytype+" {");
398 outclassdefs.println(" int type;");
400 outclassdefs.println(" pthread_t tid;");
401 outclassdefs.println(" void * lockentry;");
402 outclassdefs.println(" int lockcount;");
405 outclassdefs.println(" int flag;");
406 outclassdefs.println(" void * flagptr;");
408 outclassdefs.println(" int numexitfses;");
409 outclassdefs.println(" int * exitfses;");
412 printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
414 outclassdefs.println(" int ___length___;");
415 outclassdefs.println("};\n");
416 outclassdefs.println("extern int classsize[];");
417 outclassdefs.println("extern int hasflags[];");
418 outclassdefs.println("extern unsigned int * pointerarray[];");
419 outclassdefs.println("extern int supertypes[];");
422 /** Prints out definitions for generic task structures */
424 private void outputTaskTypes(PrintWriter outtask) {
425 outtask.println("#ifndef _TASK_H");
426 outtask.println("#define _TASK_H");
427 outtask.println("struct parameterdescriptor {");
428 outtask.println("int type;");
429 outtask.println("int numberterms;");
430 outtask.println("int *intarray;");
431 outtask.println("void * queue;");
432 outtask.println("int numbertags;");
433 outtask.println("int *tagarray;");
434 outtask.println("};");
436 outtask.println("struct taskdescriptor {");
437 outtask.println("void * taskptr;");
438 outtask.println("int numParameters;");
439 outtask.println("int numTotal;");
440 outtask.println("struct parameterdescriptor **descriptorarray;");
441 outtask.println("char * name;");
442 outtask.println("};");
443 outtask.println("extern struct taskdescriptor * taskarray[];");
444 outtask.println("extern numtasks;");
445 outtask.println("#endif");
449 private void buildRepairStructs(PrintWriter outrepairstructs) {
450 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
451 while(classit.hasNext()) {
452 ClassDescriptor cn=(ClassDescriptor)classit.next();
453 outrepairstructs.println("structure "+cn.getSymbol()+" {");
454 outrepairstructs.println(" int __type__;");
456 outrepairstructs.println(" int __flag__;");
457 outrepairstructs.println(" int __flagptr__;");
459 printRepairStruct(cn, outrepairstructs);
460 outrepairstructs.println("}\n");
463 for(int i=0;i<state.numArrays();i++) {
464 TypeDescriptor tdarray=arraytable[i];
465 TypeDescriptor tdelement=tdarray.dereference();
466 outrepairstructs.println("structure "+arraytype+"_"+state.getArrayNumber(tdarray)+" {");
467 outrepairstructs.println(" int __type__;");
468 printRepairStruct(typeutil.getClass(TypeUtil.ObjectClass), outrepairstructs);
469 outrepairstructs.println(" int length;");
471 // Need to add support to repair tool for this
472 if (tdelement.isClass()||tdelement.isArray())
473 outrepairstructs.println(" "+tdelement.getRepairSymbol()+" * elem[this.length];");
475 outrepairstructs.println(" "+tdelement.getRepairSymbol()+" elem[this.length];");
477 outrepairstructs.println("}\n");
481 private void printRepairStruct(ClassDescriptor cn, PrintWriter output) {
482 ClassDescriptor sp=cn.getSuperDesc();
484 printRepairStruct(sp, output);
486 Vector fields=(Vector)fieldorder.get(cn);
488 for(int i=0;i<fields.size();i++) {
489 FieldDescriptor fd=(FieldDescriptor)fields.get(i);
490 if (fd.getType().isArray()) {
491 output.println(" "+arraytype+"_"+ state.getArrayNumber(fd.getType()) +" * "+fd.getSymbol()+";");
492 } else if (fd.getType().isClass())
493 output.println(" "+fd.getType().getRepairSymbol()+" * "+fd.getSymbol()+";");
494 else if (fd.getType().isFloat())
495 output.println(" int "+fd.getSymbol()+"; /* really float */");
497 output.println(" "+fd.getType().getRepairSymbol()+" "+fd.getSymbol()+";");
501 /** This method outputs TaskDescriptor information */
502 void generateTaskDescriptor(PrintWriter output, FlatMethod fm, TaskDescriptor task) {
503 for (int i=0;i<task.numParameters();i++) {
504 VarDescriptor param_var=task.getParameter(i);
505 TypeDescriptor param_type=task.getParamType(i);
506 FlagExpressionNode param_flag=task.getFlag(param_var);
507 TagExpressionList param_tag=task.getTag(param_var);
510 if (param_flag==null) {
511 output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
512 output.println("0x0, 0x0 };");
515 DNFFlag dflag=param_flag.getDNF();
516 dnfterms=dflag.size();
518 Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
519 output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
520 for(int j=0;j<dflag.size();j++) {
523 Vector term=dflag.get(j);
526 for(int k=0;k<term.size();k++) {
527 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
528 FlagDescriptor fd=dfa.getFlag();
529 boolean negated=dfa.getNegated();
530 int flagid=1<<((Integer)flags.get(fd)).intValue();
535 output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
537 output.println("};");
540 output.println("int parametertag_"+i+"_"+task.getSafeSymbol()+"[]={");
541 //BUG...added next line to fix, test with any task program
543 for(int j=0;j<param_tag.numTags();j++) {
546 /* for each tag we need */
547 /* which slot it is */
548 /* what type it is */
549 TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
550 TempDescriptor tmp=param_tag.getTemp(j);
551 int slot=fm.getTagInt(tmp);
552 output.println(slot+", "+state.getTagId(tvd.getTag()));
554 output.println("};");
556 output.println("struct parameterdescriptor parameter_"+i+"_"+task.getSafeSymbol()+"={");
557 output.println("/* type */"+param_type.getClassDesc().getId()+",");
558 output.println("/* number of DNF terms */"+dnfterms+",");
559 output.println("parameterdnf_"+i+"_"+task.getSafeSymbol()+",");
560 output.println("0,");
561 //BUG, added next line to fix and else statement...test
562 //with any task program
564 output.println("/* number of tags */"+param_tag.numTags()+",");
566 output.println("/* number of tags */ 0,");
567 output.println("parametertag_"+i+"_"+task.getSafeSymbol());
568 output.println("};");
572 output.println("struct parameterdescriptor * parameterdescriptors_"+task.getSafeSymbol()+"[] = {");
573 for (int i=0;i<task.numParameters();i++) {
576 output.print("¶meter_"+i+"_"+task.getSafeSymbol());
578 output.println("};");
580 output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={");
581 output.println("&"+task.getSafeSymbol()+",");
582 output.println("/* number of parameters */" +task.numParameters() + ",");
583 int numtotal=task.numParameters()+fm.numTags();
584 output.println("/* number total parameters */" +numtotal + ",");
585 output.println("parameterdescriptors_"+task.getSafeSymbol()+",");
586 output.println("\""+task.getSymbol()+"\"");
587 output.println("};");
591 /** The buildVirtualTables method outputs the virtual dispatch
592 * tables for methods. */
594 private void buildVirtualTables(PrintWriter outvirtual) {
595 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
596 while(classit.hasNext()) {
597 ClassDescriptor cd=(ClassDescriptor)classit.next();
598 if (virtualcalls.getMethodCount(cd)>maxcount)
599 maxcount=virtualcalls.getMethodCount(cd);
601 MethodDescriptor[][] virtualtable=null;
602 LocalityBinding[][] lbvirtualtable=null;
604 lbvirtualtable=new LocalityBinding[state.numClasses()+state.numArrays()][maxcount];
606 virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount];
608 /* Fill in virtual table */
609 classit=state.getClassSymbolTable().getDescriptorsIterator();
610 while(classit.hasNext()) {
611 ClassDescriptor cd=(ClassDescriptor)classit.next();
613 fillinRow(cd, lbvirtualtable, cd.getId());
615 fillinRow(cd, virtualtable, cd.getId());
618 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
619 Iterator arrayit=state.getArrayIterator();
620 while(arrayit.hasNext()) {
621 TypeDescriptor td=(TypeDescriptor)arrayit.next();
622 int id=state.getArrayNumber(td);
624 fillinRow(objectcd, lbvirtualtable, id+state.numClasses());
626 fillinRow(objectcd, virtualtable, id+state.numClasses());
629 outvirtual.print("void * virtualtable[]={");
630 boolean needcomma=false;
631 for(int i=0;i<state.numClasses()+state.numArrays();i++) {
632 for(int j=0;j<maxcount;j++) {
634 outvirtual.print(", ");
635 if (state.DSM&&lbvirtualtable[i][j]!=null) {
636 LocalityBinding lb=lbvirtualtable[i][j];
637 MethodDescriptor md=lb.getMethod();
638 outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
639 } else if (!state.DSM&&virtualtable[i][j]!=null) {
640 MethodDescriptor md=virtualtable[i][j];
641 outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
643 outvirtual.print("0");
647 outvirtual.println("");
649 outvirtual.println("};");
653 private void fillinRow(ClassDescriptor cd, MethodDescriptor[][] virtualtable, int rownum) {
654 /* Get inherited methods */
655 if (cd.getSuperDesc()!=null)
656 fillinRow(cd.getSuperDesc(), virtualtable, rownum);
657 /* Override them with our methods */
658 for(Iterator it=cd.getMethods();it.hasNext();) {
659 MethodDescriptor md=(MethodDescriptor)it.next();
660 if (md.isStatic()||md.getReturnType()==null)
662 int methodnum=virtualcalls.getMethodNumber(md);
663 virtualtable[rownum][methodnum]=md;
667 private void fillinRow(ClassDescriptor cd, LocalityBinding[][] virtualtable, int rownum) {
668 /* Get inherited methods */
669 if (cd.getSuperDesc()!=null)
670 fillinRow(cd.getSuperDesc(), virtualtable, rownum);
671 /* Override them with our methods */
672 if (locality.getClassBindings(cd)!=null)
673 for(Iterator<LocalityBinding> lbit=locality.getClassBindings(cd).iterator();lbit.hasNext();) {
674 LocalityBinding lb=lbit.next();
675 MethodDescriptor md=lb.getMethod();
676 //Is the method static or a constructor
677 if (md.isStatic()||md.getReturnType()==null)
679 int methodnum=virtualcalls.getLocalityNumber(lb);
680 virtualtable[rownum][methodnum]=lb;
685 /** Generate array that contains the sizes of class objects. The
686 * object allocation functions in the runtime use this
689 private void generateSizeArray(PrintWriter outclassdefs) {
690 outclassdefs.print("int classsize[]={");
691 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
692 cdarray=new ClassDescriptor[state.numClasses()];
693 while(it.hasNext()) {
694 ClassDescriptor cd=(ClassDescriptor)it.next();
695 cdarray[cd.getId()]=cd;
697 boolean needcomma=false;
698 for(int i=0;i<state.numClasses();i++) {
700 outclassdefs.print(", ");
701 outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");
705 arraytable=new TypeDescriptor[state.numArrays()];
707 Iterator arrayit=state.getArrayIterator();
708 while(arrayit.hasNext()) {
709 TypeDescriptor td=(TypeDescriptor)arrayit.next();
710 int id=state.getArrayNumber(td);
714 for(int i=0;i<state.numArrays();i++) {
716 outclassdefs.print(", ");
717 TypeDescriptor tdelement=arraytable[i].dereference();
718 if (tdelement.isArray()||tdelement.isClass())
719 outclassdefs.print("sizeof(void *)");
721 outclassdefs.print("sizeof("+tdelement.getSafeSymbol()+")");
725 outclassdefs.println("};");
728 /** Constructs params and temp objects for each method or task.
729 * These objects tell the compiler which temps need to be
732 private void generateTempStructs(FlatMethod fm, LocalityBinding lb) {
733 MethodDescriptor md=fm.getMethod();
734 TaskDescriptor task=fm.getTask();
735 Set<TempDescriptor> saveset=lb!=null?locality.getTempSet(lb):null;
736 ParamsObject objectparams=md!=null?new ParamsObject(md,tag++):new ParamsObject(task, tag++);
739 paramstable.put(lb, objectparams);
741 paramstable.put(md, objectparams);
743 paramstable.put(task, objectparams);
745 for(int i=0;i<fm.numParameters();i++) {
746 TempDescriptor temp=fm.getParameter(i);
747 TypeDescriptor type=temp.getType();
748 if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
749 objectparams.addPtr(temp);
751 objectparams.addPrim(temp);
752 if(lb!=null&&saveset.contains(temp)) {
753 backuptable.put(temp, temp.createNew());
757 for(int i=0;i<fm.numTags();i++) {
758 TempDescriptor temp=fm.getTag(i);
759 if (GENERATEPRECISEGC)
760 objectparams.addPtr(temp);
762 objectparams.addPrim(temp);
765 TempObject objecttemps=md!=null?new TempObject(objectparams,md,tag++):new TempObject(objectparams, task, tag++);
767 tempstable.put(lb, objecttemps);
769 tempstable.put(md, objecttemps);
771 tempstable.put(task, objecttemps);
773 for(Iterator nodeit=fm.getNodeSet().iterator();nodeit.hasNext();) {
774 FlatNode fn=(FlatNode)nodeit.next();
775 TempDescriptor[] writes=fn.writesTemps();
776 for(int i=0;i<writes.length;i++) {
777 TempDescriptor temp=writes[i];
778 TypeDescriptor type=temp.getType();
779 if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
780 objecttemps.addPtr(temp);
782 objecttemps.addPrim(temp);
783 if(lb!=null&&saveset.contains(temp)&&
784 !backuptable.containsKey(temp))
785 backuptable.put(temp, temp.createNew());
789 /* Create backup temps */
791 for(Iterator<TempDescriptor> tmpit=backuptable.values().iterator();tmpit.hasNext();) {
792 TempDescriptor tmp=tmpit.next();
793 TypeDescriptor type=tmp.getType();
794 if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
795 objecttemps.addPtr(tmp);
797 objecttemps.addPrim(tmp);
799 /* Create temp to hold revert table */
800 if (lb.getHasAtomic()) {
801 TempDescriptor reverttmp=new TempDescriptor("revertlist", typeutil.getClass(TypeUtil.ObjectClass));
802 if (GENERATEPRECISEGC)
803 objecttemps.addPtr(reverttmp);
805 objecttemps.addPrim(reverttmp);
806 reverttable.put(lb, reverttmp);
811 /** This method outputs the following information about classes
813 * (1) For classes, what are the locations of pointers.
814 * (2) For arrays, does the array contain pointers or primitives.
815 * (3) For classes, does the class contain flags.
818 private void generateLayoutStructs(PrintWriter output) {
819 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
820 while(it.hasNext()) {
821 ClassDescriptor cn=(ClassDescriptor)it.next();
822 output.println("unsigned int "+cn.getSafeSymbol()+"_pointers[]={");
823 Iterator allit=cn.getFieldTable().getAllDescriptorsIterator();
825 while(allit.hasNext()) {
826 FieldDescriptor fd=(FieldDescriptor)allit.next();
827 TypeDescriptor type=fd.getType();
828 if (state.DSM&&fd.isGlobal()) //Don't GC the global objects for now
830 if (type.isPtr()||type.isArray())
834 allit=cn.getFieldTable().getAllDescriptorsIterator();
835 while(allit.hasNext()) {
836 FieldDescriptor fd=(FieldDescriptor)allit.next();
837 TypeDescriptor type=fd.getType();
838 if (state.DSM&&fd.isGlobal()) //Don't GC the global objects for now
840 if (type.isPtr()||type.isArray()) {
842 output.print("((unsigned int)&(((struct "+cn.getSafeSymbol() +" *)0)->"+fd.getSafeSymbol()+"))");
845 output.println("};");
847 output.println("unsigned int * pointerarray[]={");
848 boolean needcomma=false;
849 for(int i=0;i<state.numClasses();i++) {
850 ClassDescriptor cn=cdarray[i];
854 output.print(cn.getSafeSymbol()+"_pointers");
857 for(int i=0;i<state.numArrays();i++) {
859 output.println(", ");
860 TypeDescriptor tdelement=arraytable[i].dereference();
861 if (tdelement.isArray()||tdelement.isClass())
862 output.print("((unsigned int *)1)");
868 output.println("};");
870 output.println("int hasflags[]={");
871 for(int i=0;i<state.numClasses();i++) {
872 ClassDescriptor cn=cdarray[i];
874 output.println(", ");
881 output.println("};");
884 /** Print out table to give us supertypes */
885 private void generateSuperTypeTable(PrintWriter output) {
886 output.println("int supertypes[]={");
887 boolean needcomma=false;
888 for(int i=0;i<state.numClasses();i++) {
889 ClassDescriptor cn=cdarray[i];
893 if (cn.getSuperDesc()!=null) {
894 ClassDescriptor cdsuper=cn.getSuperDesc();
895 output.print(cdsuper.getId());
899 output.println("};");
902 /** Force consistent field ordering between inherited classes. */
904 private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) {
906 ClassDescriptor sp=cn.getSuperDesc();
908 printClassStruct(sp, classdefout);
910 if (!fieldorder.containsKey(cn)) {
911 Vector fields=new Vector();
912 fieldorder.put(cn,fields);
913 Iterator fieldit=cn.getFields();
914 while(fieldit.hasNext()) {
915 FieldDescriptor fd=(FieldDescriptor)fieldit.next();
916 if (sp==null||!sp.getFieldTable().contains(fd.getSymbol()))
920 Vector fields=(Vector)fieldorder.get(cn);
922 for(int i=0;i<fields.size();i++) {
923 FieldDescriptor fd=(FieldDescriptor)fields.get(i);
924 if (fd.getType().isClass()||fd.getType().isArray())
925 classdefout.println(" struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
927 classdefout.println(" "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
932 /* Map flags to integers consistently between inherited
935 private void mapFlags(ClassDescriptor cn) {
936 ClassDescriptor sp=cn.getSuperDesc();
940 if (!flagorder.containsKey(cn)) {
941 Hashtable flags=new Hashtable();
942 flagorder.put(cn,flags);
944 Hashtable superflags=(Hashtable)flagorder.get(sp);
945 Iterator superflagit=superflags.keySet().iterator();
946 while(superflagit.hasNext()) {
947 FlagDescriptor fd=(FlagDescriptor)superflagit.next();
948 Integer number=(Integer)superflags.get(fd);
949 flags.put(fd, number);
950 if ((number.intValue()+1)>max)
951 max=number.intValue()+1;
955 Iterator flagit=cn.getFlags();
956 while(flagit.hasNext()) {
957 FlagDescriptor fd=(FlagDescriptor)flagit.next();
958 if (sp==null||!sp.getFlagTable().contains(fd.getSymbol()))
959 flags.put(fd, new Integer(max++));
965 /** This function outputs (1) structures that parameters are
966 * passed in (when PRECISE GC is enabled) and (2) function
967 * prototypes for the methods */
969 private void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) {
970 /* Output class structure */
971 classdefout.println("struct "+cn.getSafeSymbol()+" {");
972 classdefout.println(" int type;");
974 classdefout.println(" pthread_t tid;");
975 classdefout.println(" void * lockentry;");
976 classdefout.println(" int lockcount;");
980 classdefout.println(" int flag;");
981 classdefout.println(" void * flagptr;");
983 classdefout.println(" int failedstatus;");
984 classdefout.println(" int hashcode;");
985 classdefout.println(" int numexitfses;");
986 classdefout.println(" int * exitfses;");
987 classdefout.println(" int numotds;");
988 classdefout.println(" struct optionaltaskdescriptor ** otds;");
991 printClassStruct(cn, classdefout);
992 classdefout.println("};\n");
995 /* Cycle through LocalityBindings */
996 HashSet<MethodDescriptor> nativemethods=new HashSet<MethodDescriptor>();
997 Set<LocalityBinding> lbset=locality.getClassBindings(cn);
999 for(Iterator<LocalityBinding> lbit=lbset.iterator();lbit.hasNext();) {
1000 LocalityBinding lb=lbit.next();
1001 MethodDescriptor md=lb.getMethod();
1002 if (md.getModifiers().isNative()) {
1003 //make sure we only print a native method once
1004 if (nativemethods.contains(md)) {
1005 FlatMethod fm=state.getMethodFlat(md);
1006 generateTempStructs(fm, lb);
1009 nativemethods.add(md);
1011 generateMethod(cn, md, lb, headersout, output);
1014 for(Iterator methodit=cn.getMethods();methodit.hasNext();) {
1015 MethodDescriptor md=(MethodDescriptor)methodit.next();
1016 if (md.getModifiers().isNative()&&!nativemethods.contains(md)) {
1017 //Need to build param structure for library code
1018 FlatMethod fm=state.getMethodFlat(md);
1019 generateTempStructs(fm, null);
1020 generateMethodParam(cn, md, null, output);
1025 for(Iterator methodit=cn.getMethods();methodit.hasNext();) {
1026 MethodDescriptor md=(MethodDescriptor)methodit.next();
1027 generateMethod(cn, md, null, headersout, output);
1031 private void generateMethodParam(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter output) {
1032 /* Output parameter structure */
1033 if (GENERATEPRECISEGC) {
1034 ParamsObject objectparams=(ParamsObject) paramstable.get(lb!=null?lb:md);
1035 if (state.DSM&&lb!=null)
1036 output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
1038 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
1039 output.println(" int size;");
1040 output.println(" void * next;");
1041 for(int i=0;i<objectparams.numPointers();i++) {
1042 TempDescriptor temp=objectparams.getPointer(i);
1043 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1045 output.println("};\n");
1050 private void generateMethod(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter headersout, PrintWriter output) {
1051 FlatMethod fm=state.getMethodFlat(md);
1052 generateTempStructs(fm, lb);
1054 ParamsObject objectparams=(ParamsObject) paramstable.get(lb!=null?lb:md);
1055 TempObject objecttemps=(TempObject) tempstable.get(lb!=null?lb:md);
1057 generateMethodParam(cn, md, lb, output);
1059 /* Output temp structure */
1060 if (GENERATEPRECISEGC) {
1062 output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
1064 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
1065 output.println(" int size;");
1066 output.println(" void * next;");
1067 for(int i=0;i<objecttemps.numPointers();i++) {
1068 TempDescriptor temp=objecttemps.getPointer(i);
1069 if (temp.getType().isNull())
1070 output.println(" void * "+temp.getSafeSymbol()+";");
1072 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1074 output.println("};\n");
1077 /********* Output method declaration ***********/
1079 /* First the return type */
1080 if (md.getReturnType()!=null) {
1081 if (md.getReturnType().isClass()||md.getReturnType().isArray())
1082 headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1084 headersout.print(md.getReturnType().getSafeSymbol()+" ");
1086 //catch the constructor case
1087 headersout.print("void ");
1089 /* Next the method name */
1091 headersout.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1093 headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1095 boolean printcomma=false;
1096 if (GENERATEPRECISEGC) {
1098 headersout.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1100 headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1104 if (state.DSM&&lb.isAtomic()) {
1106 headersout.print(", ");
1107 headersout.print("transrecord_t * trans");
1111 /* Output parameter list*/
1112 for(int i=0;i<objectparams.numPrimitives();i++) {
1113 TempDescriptor temp=objectparams.getPrimitive(i);
1115 headersout.print(", ");
1117 if (temp.getType().isClass()||temp.getType().isArray())
1118 headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1120 headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1122 headersout.println(");\n");
1126 /** This function outputs (1) structures that parameters are
1127 * passed in (when PRECISE GC is enabled) and (2) function
1128 * prototypes for the tasks */
1130 private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
1131 /* Cycle through tasks */
1132 Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
1134 while(taskit.hasNext()) {
1135 /* Classify parameters */
1136 TaskDescriptor task=(TaskDescriptor)taskit.next();
1137 FlatMethod fm=state.getMethodFlat(task);
1138 generateTempStructs(fm, null);
1140 ParamsObject objectparams=(ParamsObject) paramstable.get(task);
1141 TempObject objecttemps=(TempObject) tempstable.get(task);
1143 /* Output parameter structure */
1144 if (GENERATEPRECISEGC) {
1145 output.println("struct "+task.getSafeSymbol()+"_params {");
1147 output.println(" int size;");
1148 output.println(" void * next;");
1149 for(int i=0;i<objectparams.numPointers();i++) {
1150 TempDescriptor temp=objectparams.getPointer(i);
1151 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1154 output.println("};\n");
1155 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
1156 maxtaskparams=objectparams.numPointers()+fm.numTags();
1160 /* Output temp structure */
1161 if (GENERATEPRECISEGC) {
1162 output.println("struct "+task.getSafeSymbol()+"_locals {");
1163 output.println(" int size;");
1164 output.println(" void * next;");
1165 for(int i=0;i<objecttemps.numPointers();i++) {
1166 TempDescriptor temp=objecttemps.getPointer(i);
1167 if (temp.getType().isNull())
1168 output.println(" void * "+temp.getSafeSymbol()+";");
1169 else if(temp.getType().isTag())
1170 output.println(" struct "+
1171 (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1173 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1175 output.println("};\n");
1178 /* Output task declaration */
1179 headersout.print("void " + task.getSafeSymbol()+"(");
1181 boolean printcomma=false;
1182 if (GENERATEPRECISEGC) {
1183 headersout.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1185 headersout.print("void * parameterarray[]");
1186 headersout.println(");\n");
1190 /***** Generate code for FlatMethod fm. *****/
1192 private void generateFlatMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
1193 MethodDescriptor md=fm.getMethod();
1195 TaskDescriptor task=fm.getTask();
1197 ClassDescriptor cn=md!=null?md.getClassDesc():null;
1199 ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null?lb:md!=null?md:task);
1200 generateHeader(fm, lb, md!=null?md:task,output);
1201 TempObject objecttemp=(TempObject) tempstable.get(lb!=null?lb:md!=null?md:task);
1202 if (state.DSM&&lb.getHasAtomic()) {
1203 output.println("transrecord_t * trans;");
1206 if (GENERATEPRECISEGC) {
1207 if (md!=null&&state.DSM)
1208 output.print(" struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1209 else if (md!=null&&!state.DSM)
1210 output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1212 output.print(" struct "+task.getSafeSymbol()+"_locals "+localsprefix+"={");
1214 output.print(objecttemp.numPointers()+",");
1215 output.print(paramsprefix);
1216 for(int j=0;j<objecttemp.numPointers();j++)
1217 output.print(", NULL");
1218 output.println("};");
1221 for(int i=0;i<objecttemp.numPrimitives();i++) {
1222 TempDescriptor td=objecttemp.getPrimitive(i);
1223 TypeDescriptor type=td.getType();
1225 output.println(" void * "+td.getSafeSymbol()+";");
1226 else if (type.isClass()||type.isArray())
1227 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
1229 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
1232 /* Assign labels to FlatNode's if necessary.*/
1234 Hashtable<FlatNode, Integer> nodetolabel=assignLabels(fm);
1236 /* Check to see if we need to do a GC if this is a
1237 * multi-threaded program...*/
1239 if (state.THREAD&&GENERATEPRECISEGC) {
1240 output.println("checkcollect(&"+localsprefix+");");
1243 /* Do the actual code generation */
1244 FlatNode current_node=null;
1245 HashSet tovisit=new HashSet();
1246 HashSet visited=new HashSet();
1247 tovisit.add(fm.getNext(0));
1248 while(current_node!=null||!tovisit.isEmpty()) {
1249 if (current_node==null) {
1250 current_node=(FlatNode)tovisit.iterator().next();
1251 tovisit.remove(current_node);
1253 visited.add(current_node);
1254 if (nodetolabel.containsKey(current_node))
1255 output.println("L"+nodetolabel.get(current_node)+":");
1256 if (state.INSTRUCTIONFAILURE) {
1258 output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
1261 output.println("if ((--instructioncount)==0) injectinstructionfailure();");
1263 if (current_node.numNext()==0) {
1265 generateFlatNode(fm, lb, current_node, output);
1266 if (current_node.kind()!=FKind.FlatReturnNode) {
1267 output.println(" return;");
1270 } else if(current_node.numNext()==1) {
1272 generateFlatNode(fm, lb, current_node, output);
1273 FlatNode nextnode=current_node.getNext(0);
1274 if (visited.contains(nextnode)) {
1275 output.println("goto L"+nodetolabel.get(nextnode)+";");
1278 current_node=nextnode;
1279 } else if (current_node.numNext()==2) {
1282 generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
1283 if (!visited.contains(current_node.getNext(1)))
1284 tovisit.add(current_node.getNext(1));
1285 if (visited.contains(current_node.getNext(0))) {
1286 output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
1289 current_node=current_node.getNext(0);
1290 } else throw new Error();
1293 output.println("}\n\n");
1296 /** This method assigns labels to FlatNodes */
1298 private Hashtable<FlatNode, Integer> assignLabels(FlatMethod fm) {
1299 HashSet tovisit=new HashSet();
1300 HashSet visited=new HashSet();
1302 Hashtable<FlatNode, Integer> nodetolabel=new Hashtable<FlatNode, Integer>();
1303 tovisit.add(fm.getNext(0));
1305 /*Assign labels first. A node needs a label if the previous
1306 * node has two exits or this node is a join point. */
1308 while(!tovisit.isEmpty()) {
1309 FlatNode fn=(FlatNode)tovisit.iterator().next();
1312 for(int i=0;i<fn.numNext();i++) {
1313 FlatNode nn=fn.getNext(i);
1315 //1) Edge >1 of node
1316 nodetolabel.put(nn,new Integer(labelindex++));
1318 if (!visited.contains(nn)&&!tovisit.contains(nn)) {
1322 nodetolabel.put(nn,new Integer(labelindex++));
1330 /** Generate text string that corresponds to the TempDescriptor td. */
1331 private String generateTemp(FlatMethod fm, TempDescriptor td, LocalityBinding lb) {
1332 MethodDescriptor md=fm.getMethod();
1333 TaskDescriptor task=fm.getTask();
1334 TempObject objecttemps=(TempObject) tempstable.get(lb!=null?lb:md!=null?md:task);
1336 if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1337 return td.getSafeSymbol();
1340 if (objecttemps.isLocalPtr(td)) {
1341 return localsprefix+"."+td.getSafeSymbol();
1344 if (objecttemps.isParamPtr(td)) {
1345 return paramsprefix+"->"+td.getSafeSymbol();
1350 private void generateFlatNode(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output) {
1352 case FKind.FlatAtomicEnterNode:
1353 generateFlatAtomicEnterNode(fm, lb, (FlatAtomicEnterNode) fn, output);
1355 case FKind.FlatAtomicExitNode:
1356 generateFlatAtomicExitNode(fm, lb, (FlatAtomicExitNode) fn, output);
1358 case FKind.FlatGlobalConvNode:
1359 generateFlatGlobalConvNode(fm, lb, (FlatGlobalConvNode) fn, output);
1361 case FKind.FlatTagDeclaration:
1362 generateFlatTagDeclaration(fm, lb, (FlatTagDeclaration) fn,output);
1364 case FKind.FlatCall:
1365 generateFlatCall(fm, lb, (FlatCall) fn,output);
1367 case FKind.FlatFieldNode:
1368 generateFlatFieldNode(fm, lb, (FlatFieldNode) fn,output);
1370 case FKind.FlatElementNode:
1371 generateFlatElementNode(fm, lb, (FlatElementNode) fn,output);
1373 case FKind.FlatSetElementNode:
1374 generateFlatSetElementNode(fm, lb, (FlatSetElementNode) fn,output);
1376 case FKind.FlatSetFieldNode:
1377 generateFlatSetFieldNode(fm, lb, (FlatSetFieldNode) fn,output);
1380 generateFlatNew(fm, lb, (FlatNew) fn,output);
1382 case FKind.FlatOpNode:
1383 generateFlatOpNode(fm, lb, (FlatOpNode) fn,output);
1385 case FKind.FlatCastNode:
1386 generateFlatCastNode(fm, lb, (FlatCastNode) fn,output);
1388 case FKind.FlatLiteralNode:
1389 generateFlatLiteralNode(fm, lb, (FlatLiteralNode) fn,output);
1391 case FKind.FlatReturnNode:
1392 generateFlatReturnNode(fm, lb, (FlatReturnNode) fn,output);
1395 output.println("/* nop */");
1397 case FKind.FlatBackEdge:
1398 if ((state.THREAD||state.DSM)&&GENERATEPRECISEGC) {
1399 output.println("checkcollect(&"+localsprefix+");");
1401 output.println("/* nop */");
1403 case FKind.FlatCheckNode:
1404 generateFlatCheckNode(fm, lb, (FlatCheckNode) fn, output);
1406 case FKind.FlatFlagActionNode:
1407 generateFlatFlagActionNode(fm, lb, (FlatFlagActionNode) fn, output);
1414 public void generateFlatGlobalConvNode(FlatMethod fm, LocalityBinding lb, FlatGlobalConvNode fgcn, PrintWriter output) {
1415 if (lb!=fgcn.getLocality())
1417 /* Have to generate flat globalconv */
1418 if (fgcn.getMakePtr()) {
1419 output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)transRead(trans, (unsigned int) "+generateTemp(fm, fgcn.getSrc(),lb)+");");
1421 /* Need to convert to OID */
1422 output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)COMPOID("+generateTemp(fm, fgcn.getSrc(),lb)+");");
1426 public void generateFlatAtomicEnterNode(FlatMethod fm, LocalityBinding lb, FlatAtomicEnterNode faen, PrintWriter output) {
1427 /* Check to see if we need to generate code for this atomic */
1428 if (locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
1430 /* Backup the temps. */
1431 for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator();tmpit.hasNext();) {
1432 TempDescriptor tmp=tmpit.next();
1433 output.println(generateTemp(fm, backuptable.get(tmp),lb)+"="+generateTemp(fm,tmp,lb)+";");
1435 output.println("goto transstart"+faen.getIdentifier()+";");
1437 /******* Print code to retry aborted transaction *******/
1438 output.println("transretry"+faen.getIdentifier()+":");
1441 for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator();tmpit.hasNext();) {
1442 TempDescriptor tmp=tmpit.next();
1443 output.println(generateTemp(fm, tmp,lb)+"="+generateTemp(fm,backuptable.get(tmp),lb)+";");
1446 /********* Need to revert local object store ********/
1447 String revertptr=generateTemp(fm, reverttable.get(lb),lb);
1449 output.println("while ("+revertptr+") {");
1450 output.println("struct ___Object___ * tmpptr;");
1451 output.println("tmpptr="+revertptr+"->"+nextobjstr+";");
1452 output.println("REVERT_OBJ("+revertptr+");");
1453 output.println(revertptr+"=tmpptr;");
1454 output.println("}");
1456 /******* Tell the runtime to start the transaction *******/
1458 output.println("transstart"+faen.getIdentifier()+":");
1459 output.println("trans=transStart();");
1462 public void generateFlatAtomicExitNode(FlatMethod fm, LocalityBinding lb, FlatAtomicExitNode faen, PrintWriter output) {
1463 /* Check to see if we need to generate code for this atomic */
1464 if (locality.getAtomic(lb).get(faen).intValue()>0)
1466 //store the revert list before we lose the transaction object
1467 String revertptr=generateTemp(fm, reverttable.get(lb),lb);
1468 output.println(revertptr+"=trans->revertlist;");
1469 output.println("if (transCommit(trans)) {");
1470 /* Transaction aborts if it returns true */
1471 output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
1472 output.println("} else {");
1473 /* Need to commit local object store */
1474 output.println("while ("+revertptr+") {");
1475 output.println("struct ___Object___ * tmpptr;");
1476 output.println("tmpptr="+revertptr+"->"+nextobjstr+";");
1477 output.println("COMMIT_OBJ("+revertptr+");");
1478 output.println(revertptr+"=tmpptr;");
1479 output.println("}");
1480 output.println("}");
1483 private void generateFlatCheckNode(FlatMethod fm, LocalityBinding lb, FlatCheckNode fcn, PrintWriter output) {
1484 if (state.CONSCHECK) {
1485 String specname=fcn.getSpec();
1486 String varname="repairstate___";
1487 output.println("{");
1488 output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
1490 TempDescriptor[] temps=fcn.getTemps();
1491 String[] vars=fcn.getVars();
1492 for(int i=0;i<temps.length;i++) {
1493 output.println(varname+"->"+vars[i]+"=(unsigned int)"+generateTemp(fm, temps[i],lb)+";");
1496 output.println("if (doanalysis"+specname+"("+varname+")) {");
1497 output.println("free"+specname+"_state("+varname+");");
1498 output.println("} else {");
1499 output.println("/* Bad invariant */");
1500 output.println("free"+specname+"_state("+varname+");");
1501 output.println("abort_task();");
1502 output.println("}");
1503 output.println("}");
1507 private void generateFlatCall(FlatMethod fm, LocalityBinding lb, FlatCall fc, PrintWriter output) {
1508 MethodDescriptor md=fc.getMethod();
1509 ParamsObject objectparams=(ParamsObject)paramstable.get(state.DSM?locality.getBinding(lb, fc):md);
1510 ClassDescriptor cn=md.getClassDesc();
1511 output.println("{");
1512 if (GENERATEPRECISEGC) {
1514 LocalityBinding fclb=locality.getBinding(lb, fc);
1515 output.print(" struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
1517 output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
1519 output.print(objectparams.numPointers());
1520 output.print(", & "+localsprefix);
1521 if (fc.getThis()!=null) {
1523 output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis(),lb));
1525 for(int i=0;i<fc.numArgs();i++) {
1526 Descriptor var=md.getParameter(i);
1527 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
1528 if (objectparams.isParamPtr(paramtemp)) {
1529 TempDescriptor targ=fc.getArg(i);
1531 TypeDescriptor td=md.getParamType(i);
1533 output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol() +" *)"+generateTemp(fm, targ,lb));
1535 output.print("(struct "+md.getParamType(i).getSafeSymbol() +" *)"+generateTemp(fm, targ,lb));
1538 output.println("};");
1543 if (fc.getReturnTemp()!=null)
1544 output.print(generateTemp(fm,fc.getReturnTemp(),lb)+"=");
1546 /* Do we need to do virtual dispatch? */
1547 if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
1550 LocalityBinding fclb=locality.getBinding(lb, fc);
1551 output.print(cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
1553 output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
1558 if (md.getReturnType().isClass()||md.getReturnType().isArray())
1559 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1561 output.print(md.getReturnType().getSafeSymbol()+" ");
1562 output.print("(*)(");
1564 boolean printcomma=false;
1565 if (GENERATEPRECISEGC) {
1567 LocalityBinding fclb=locality.getBinding(lb, fc);
1568 output.print("struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
1570 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
1574 for(int i=0;i<objectparams.numPrimitives();i++) {
1575 TempDescriptor temp=objectparams.getPrimitive(i);
1579 if (temp.getType().isClass()||temp.getType().isArray())
1580 output.print("struct " + temp.getType().getSafeSymbol()+" * ");
1582 output.print(temp.getType().getSafeSymbol());
1586 LocalityBinding fclb=locality.getBinding(lb, fc);
1587 output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getLocalityNumber(fclb)+"])");
1589 output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
1593 boolean needcomma=false;
1594 if (GENERATEPRECISEGC) {
1595 output.print("&__parameterlist__");
1599 if (state.DSM&&locality.getBinding(lb,fc).isAtomic()) {
1602 output.print("trans");
1606 if (!GENERATEPRECISEGC) {
1607 if (fc.getThis()!=null) {
1608 TypeDescriptor ptd=md.getThis().getType();
1611 if (ptd.isClass()&&!ptd.isArray())
1612 output.print("(struct "+ptd.getSafeSymbol()+" *) ");
1613 output.print(generateTemp(fm,fc.getThis(),lb));
1618 for(int i=0;i<fc.numArgs();i++) {
1619 Descriptor var=md.getParameter(i);
1620 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
1621 if (objectparams.isParamPrim(paramtemp)) {
1622 TempDescriptor targ=fc.getArg(i);
1626 TypeDescriptor ptd=md.getParamType(i);
1627 if (ptd.isClass()&&!ptd.isArray())
1628 output.print("(struct "+ptd.getSafeSymbol()+" *) ");
1629 output.print(generateTemp(fm, targ,lb));
1633 output.println(");");
1634 output.println(" }");
1637 private boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
1638 Set subclasses=typeutil.getSubClasses(thiscd);
1639 if (subclasses==null)
1641 for(Iterator classit=subclasses.iterator();classit.hasNext();) {
1642 ClassDescriptor cd=(ClassDescriptor)classit.next();
1643 Set possiblematches=cd.getMethodTable().getSet(md.getSymbol());
1644 for(Iterator matchit=possiblematches.iterator();matchit.hasNext();) {
1645 MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
1646 if (md.matches(matchmd))
1653 private void generateFlatFieldNode(FlatMethod fm, LocalityBinding lb, FlatFieldNode ffn, PrintWriter output) {
1655 Integer status=locality.getNodePreTempInfo(lb,ffn).get(ffn.getSrc());
1656 if (status==LocalityAnalysis.GLOBAL) {
1657 String field=ffn.getField().getSafeSymbol();
1658 String src=generateTemp(fm, ffn.getSrc(),lb);
1659 String dst=generateTemp(fm, ffn.getDst(),lb);
1661 if (ffn.getField().getType().isPtr()||
1662 ffn.getField().getType().isArray()) {
1664 //TODO: Uncomment this when we have runtime support
1665 //if (ffn.getSrc()==ffn.getDst()) {
1666 //output.println("{");
1667 //output.println("void * temp="+src+";");
1668 //output.println("if (temp&0x1) {");
1669 //output.println("temp=(void *) transRead(trans, (unsigned int) temp);");
1670 //output.println(src+"->"+field+"="+temp+";");
1671 //output.println("}");
1672 //output.println(dst+"=temp;");
1673 //output.println("}");
1675 output.println(dst+"="+ src +"->"+field+ ";");
1676 //output.println("if ("+dst+"&0x1) {");
1677 output.println(dst+"=(void *) transRead(trans, (unsigned int) "+dst+");");
1678 //output.println(src+"->"+field+"="+src+"->"+field+";");
1679 //output.println("}");
1682 output.println(dst+"="+ src+"->"+field+";");
1684 } else if (status==LocalityAnalysis.LOCAL) {
1685 output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
1686 } else if (status==LocalityAnalysis.EITHER) {
1687 //Code is reading from a null pointer
1688 output.println("if ("+generateTemp(fm, ffn.getSrc(),lb)+") {");
1689 output.println("printf(\"BIG ERROR\n\");exit(-1);}");
1690 //This should throw a suitable null pointer error
1691 output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
1693 throw new Error("Read from non-global/non-local in:"+lb.getExplanation());
1695 output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
1698 private void generateFlatSetFieldNode(FlatMethod fm, LocalityBinding lb, FlatSetFieldNode fsfn, PrintWriter output) {
1699 if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
1700 throw new Error("Can't set array length");
1701 if (state.DSM && locality.getAtomic(lb).get(fsfn).intValue()>0) {
1702 Integer statussrc=locality.getNodePreTempInfo(lb,fsfn).get(fsfn.getSrc());
1703 Integer statusdst=locality.getNodeTempInfo(lb).get(fsfn).get(fsfn.getDst());
1704 boolean srcglobal=statussrc==LocalityAnalysis.GLOBAL;
1706 String src=generateTemp(fm,fsfn.getSrc(),lb);
1707 String dst=generateTemp(fm,fsfn.getDst(),lb);
1709 output.println("{");
1710 output.println("int srcoid="+src+"->"+oidstr+";");
1712 if (statusdst.equals(LocalityAnalysis.GLOBAL)) {
1715 output.println("*((unsigned int *)&("+dst+"->___localcopy___))|=DIRTY;");
1717 output.println("*((unsigned int *)&("+glbdst+"->"+ fsfn.getField().getSafeSymbol()+"))=srcoid;");
1718 output.println("}");
1720 output.println(glbdst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
1721 } else if (statusdst.equals(LocalityAnalysis.LOCAL)) {
1722 /** Check if we need to copy */
1723 output.println("if(!"+dst+"->"+localcopystr+") {");
1724 /* Link object into list */
1725 output.println(dst+"->"+nextobjstr+"=trans->localtrans;");
1726 output.println("trans->localtrans="+dst+";");
1727 if (GENERATEPRECISEGC)
1728 output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
1730 output.println("COPY_OBJ("+dst+");");
1731 output.println("}");
1733 output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=srcoid;");
1735 output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
1736 } else if (statusdst.equals(LocalityAnalysis.EITHER)) {
1737 //writing to a null...bad
1738 output.println("if ("+dst+") {");
1739 output.println("printf(\"BIG ERROR 2\n\");exit(-1);}");
1741 output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=srcoid;");
1743 output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
1746 output.println("}");
1749 output.println(generateTemp(fm, fsfn.getDst(),lb)+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";");
1753 private void generateFlatElementNode(FlatMethod fm, LocalityBinding lb, FlatElementNode fen, PrintWriter output) {
1754 TypeDescriptor elementtype=fen.getSrc().getType().dereference();
1757 if (elementtype.isArray()||elementtype.isClass())
1760 type=elementtype.getSafeSymbol()+" ";
1762 if (fen.needsBoundsCheck()) {
1763 output.println("if ("+generateTemp(fm, fen.getIndex(),lb)+"< 0 || "+generateTemp(fm, fen.getIndex(),lb)+" >= "+generateTemp(fm,fen.getSrc(),lb) + "->___length___)");
1764 output.println("failedboundschk();");
1767 output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
1770 private void generateFlatSetElementNode(FlatMethod fm, LocalityBinding lb, FlatSetElementNode fsen, PrintWriter output) {
1771 //TODO: need dynamic check to make sure this assignment is actually legal
1772 //Because Object[] could actually be something more specific...ie. Integer[]
1774 TypeDescriptor elementtype=fsen.getDst().getType().dereference();
1777 if (elementtype.isArray()||elementtype.isClass())
1780 type=elementtype.getSafeSymbol()+" ";
1782 if (fsen.needsBoundsCheck()) {
1783 output.println("if ("+generateTemp(fm, fsen.getIndex(),lb)+"< 0 || "+generateTemp(fm, fsen.getIndex(),lb)+" >= "+generateTemp(fm,fsen.getDst(),lb) + "->___length___)");
1784 output.println("failedboundschk();");
1787 output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
1790 private void generateFlatNew(FlatMethod fm, LocalityBinding lb, FlatNew fn, PrintWriter output) {
1791 if (fn.getType().isArray()) {
1792 int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
1793 if (fn.isGlobal()) {
1794 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarrayglobal(trans, "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
1795 } else if (GENERATEPRECISEGC) {
1796 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
1798 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
1801 if (fn.isGlobal()) {
1802 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newglobal(trans, "+fn.getType().getClassDesc().getId()+");");
1803 } else if (GENERATEPRECISEGC) {
1804 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
1806 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
1811 private void generateFlatTagDeclaration(FlatMethod fm, LocalityBinding lb, FlatTagDeclaration fn, PrintWriter output) {
1812 if (GENERATEPRECISEGC) {
1813 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag(&"+localsprefix+", "+state.getTagId(fn.getType())+");");
1815 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag("+state.getTagId(fn.getType())+");");
1819 private void generateFlatOpNode(FlatMethod fm, LocalityBinding lb, FlatOpNode fon, PrintWriter output) {
1820 if (fon.getRight()!=null)
1821 output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+fon.getOp().toString()+generateTemp(fm,fon.getRight(),lb)+";");
1822 else if (fon.getOp().getOp()==Operation.ASSIGN)
1823 output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";");
1824 else if (fon.getOp().getOp()==Operation.UNARYPLUS)
1825 output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";");
1826 else if (fon.getOp().getOp()==Operation.UNARYMINUS)
1827 output.println(generateTemp(fm, fon.getDest(),lb)+" = -"+generateTemp(fm, fon.getLeft(),lb)+";");
1828 else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
1829 output.println(generateTemp(fm, fon.getDest(),lb)+" = !"+generateTemp(fm, fon.getLeft(),lb)+";");
1831 output.println(generateTemp(fm, fon.getDest(),lb)+fon.getOp().toString()+generateTemp(fm, fon.getLeft(),lb)+";");
1834 private void generateFlatCastNode(FlatMethod fm, LocalityBinding lb, FlatCastNode fcn, PrintWriter output) {
1835 /* TODO: Do type check here */
1836 if (fcn.getType().isArray()) {
1838 } else if (fcn.getType().isClass())
1839 output.println(generateTemp(fm,fcn.getDst(),lb)+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc(),lb)+";");
1841 output.println(generateTemp(fm,fcn.getDst(),lb)+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc(),lb)+";");
1844 private void generateFlatLiteralNode(FlatMethod fm, LocalityBinding lb, FlatLiteralNode fln, PrintWriter output) {
1845 if (fln.getValue()==null)
1846 output.println(generateTemp(fm, fln.getDst(),lb)+"=0;");
1847 else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
1848 if (GENERATEPRECISEGC) {
1849 output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString(&"+localsprefix+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
1851 output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
1853 } else if (fln.getType().isBoolean()) {
1854 if (((Boolean)fln.getValue()).booleanValue())
1855 output.println(generateTemp(fm, fln.getDst(),lb)+"=1;");
1857 output.println(generateTemp(fm, fln.getDst(),lb)+"=0;");
1858 } else if (fln.getType().isChar()) {
1859 String st=FlatLiteralNode.escapeString(fln.getValue().toString());
1860 output.println(generateTemp(fm, fln.getDst(),lb)+"='"+st+"';");
1862 output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+";");
1865 private void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
1866 if (frn.getReturnTemp()!=null)
1867 output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1869 output.println("return;");
1872 private void generateFlatCondBranch(FlatMethod fm, LocalityBinding lb, FlatCondBranch fcb, String label, PrintWriter output) {
1873 output.println("if (!"+generateTemp(fm, fcb.getTest(),lb)+") goto "+label+";");
1876 /** This method generates header information for the method or
1877 * task referenced by the Descriptor des. */
1879 private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) {
1881 ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null?lb:des);
1882 MethodDescriptor md=null;
1883 TaskDescriptor task=null;
1884 if (des instanceof MethodDescriptor)
1885 md=(MethodDescriptor) des;
1887 task=(TaskDescriptor) des;
1889 ClassDescriptor cn=md!=null?md.getClassDesc():null;
1891 if (md!=null&&md.getReturnType()!=null) {
1892 if (md.getReturnType().isClass()||md.getReturnType().isArray())
1893 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1895 output.print(md.getReturnType().getSafeSymbol()+" ");
1897 //catch the constructor case
1898 output.print("void ");
1901 output.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1903 output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1905 output.print(task.getSafeSymbol()+"(");
1907 boolean printcomma=false;
1908 if (GENERATEPRECISEGC) {
1911 output.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1913 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1915 output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1919 if (state.DSM&&lb.isAtomic()) {
1922 output.print("transrecord_t * trans");
1928 for(int i=0;i<objectparams.numPrimitives();i++) {
1929 TempDescriptor temp=objectparams.getPrimitive(i);
1933 if (temp.getType().isClass()||temp.getType().isArray())
1934 output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1936 output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1938 output.println(") {");
1939 } else if (!GENERATEPRECISEGC) {
1940 /* Imprecise Task */
1941 output.println("void * parameterarray[]) {");
1942 /* Unpack variables */
1943 for(int i=0;i<objectparams.numPrimitives();i++) {
1944 TempDescriptor temp=objectparams.getPrimitive(i);
1945 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
1947 for(int i=0;i<fm.numTags();i++) {
1948 TempDescriptor temp=fm.getTag(i);
1949 int offset=i+objectparams.numPrimitives();
1950 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
1953 if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
1954 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
1955 } else output.println(") {");
1958 public void generateFlatFlagActionNode(FlatMethod fm, LocalityBinding lb, FlatFlagActionNode ffan, PrintWriter output) {
1959 output.println("/* FlatFlagActionNode */");
1962 /* Process tag changes */
1963 Relation tagsettable=new Relation();
1964 Relation tagcleartable=new Relation();
1966 Iterator tagsit=ffan.getTempTagPairs();
1967 while (tagsit.hasNext()) {
1968 TempTagPair ttp=(TempTagPair) tagsit.next();
1969 TempDescriptor objtmp=ttp.getTemp();
1970 TagDescriptor tag=ttp.getTag();
1971 TempDescriptor tagtmp=ttp.getTagTemp();
1972 boolean tagstatus=ffan.getTagChange(ttp);
1974 tagsettable.put(objtmp, tagtmp);
1976 tagcleartable.put(objtmp, tagtmp);
1981 Hashtable flagandtable=new Hashtable();
1982 Hashtable flagortable=new Hashtable();
1984 /* Process flag changes */
1985 Iterator flagsit=ffan.getTempFlagPairs();
1986 while(flagsit.hasNext()) {
1987 TempFlagPair tfp=(TempFlagPair)flagsit.next();
1988 TempDescriptor temp=tfp.getTemp();
1989 Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
1990 FlagDescriptor flag=tfp.getFlag();
1992 //Newly allocate objects that don't set any flags case
1993 if (flagortable.containsKey(temp)) {
1997 flagortable.put(temp,new Integer(mask));
1999 int flagid=1<<((Integer)flagtable.get(flag)).intValue();
2000 boolean flagstatus=ffan.getFlagChange(tfp);
2003 if (flagortable.containsKey(temp)) {
2004 mask=((Integer)flagortable.get(temp)).intValue();
2007 flagortable.put(temp,new Integer(mask));
2009 int mask=0xFFFFFFFF;
2010 if (flagandtable.containsKey(temp)) {
2011 mask=((Integer)flagandtable.get(temp)).intValue();
2013 mask&=(0xFFFFFFFF^flagid);
2014 flagandtable.put(temp,new Integer(mask));
2020 HashSet flagtagset=new HashSet();
2021 flagtagset.addAll(flagortable.keySet());
2022 flagtagset.addAll(flagandtable.keySet());
2023 flagtagset.addAll(tagsettable.keySet());
2024 flagtagset.addAll(tagcleartable.keySet());
2026 Iterator ftit=flagtagset.iterator();
2027 while(ftit.hasNext()) {
2028 TempDescriptor temp=(TempDescriptor)ftit.next();
2031 Set tagtmps=tagcleartable.get(temp);
2032 if (tagtmps!=null) {
2033 Iterator tagit=tagtmps.iterator();
2034 while(tagit.hasNext()) {
2035 TempDescriptor tagtmp=(TempDescriptor)tagit.next();
2036 if (GENERATEPRECISEGC)
2037 output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
2039 output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
2043 tagtmps=tagsettable.get(temp);
2044 if (tagtmps!=null) {
2045 Iterator tagit=tagtmps.iterator();
2046 while(tagit.hasNext()) {
2047 TempDescriptor tagtmp=(TempDescriptor)tagit.next();
2048 if (GENERATEPRECISEGC)
2049 output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
2051 output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp, lb)+", "+generateTemp(fm,tagtmp, lb)+");");
2056 int andmask=0xFFFFFFF;
2058 if (flagortable.containsKey(temp))
2059 ormask=((Integer)flagortable.get(temp)).intValue();
2060 if (flagandtable.containsKey(temp))
2061 andmask=((Integer)flagandtable.get(temp)).intValue();
2062 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
2063 output.println("flagorandinit("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
2065 output.println("flagorand("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
2070 void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> safeexecution, Hashtable optionaltaskdescriptors) {
2073 headers.println("#include \"task.h\"\n\n");
2074 headers.println("#ifndef _OPTIONAL_STRUCT_");
2075 headers.println("#define _OPTIONAL_STRUCT_");
2080 //STRUCT PREDICATEMEMBER
2081 headers.println("struct predicatemember{");
2082 headers.println("int type;");
2083 headers.println("int numdnfterms;");
2084 headers.println("int * flags;");
2085 headers.println("int numtags;");
2086 headers.println("int * tags;\n};\n\n");
2088 /*//STRUCT EXITSTATES
2089 headers.println("struct exitstates{");
2090 headers.println("int numflagstates;");
2091 headers.println("int * flagstatearray;\n};\n\n");*///appeared to be useless
2093 //STRUCT OPTIONALTASKDESCRIPTOR
2094 headers.println("struct optionaltaskdescriptor{");
2095 headers.println("struct taskdescriptor * task;");
2096 headers.println("int numenterflags;");
2097 headers.println("int * enterflags;");
2098 headers.println("int numpredicatemembers;");
2099 headers.println("struct predicatemember ** predicatememberarray;");
2100 //headers.println("int numexitstates;");
2101 //headers.println("int numTotal;");
2102 //headers.println("struct exitstates ** exitstatesarray;\n};\n\n");
2103 headers.println("\n};\n\n");
2105 //STRUCT FSANALYSISWRAPPER
2106 headers.println("struct fsanalysiswrapper{");
2107 headers.println("int flags;");
2108 headers.println("int numtags;");
2109 headers.println("int * tags;");
2110 headers.println("int numoptionaltaskdescriptors;");
2111 headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
2113 //STRUCT CLASSANALYSISWRAPPER
2114 headers.println("struct classanalysiswrapper{");
2115 headers.println("int type;");
2116 headers.println("int numotd;");
2117 headers.println("struct optionaltaskdescriptor ** otdarray;");
2118 headers.println("int numfsanalysiswrappers;");
2119 headers.println("struct fsanalysiswrapper ** fsanalysiswrapperarray;\n};");
2121 headers.println("extern struct classanalysiswrapper * classanalysiswrapperarray[];");
2123 Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
2124 while(taskit.hasNext()) {
2125 TaskDescriptor td=(TaskDescriptor)taskit.next();
2126 headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
2132 output.println("#include \"optionalstruct.h\"\n\n");
2133 HashSet processedcd = new HashSet();
2136 Enumeration e = safeexecution.keys();
2137 while (e.hasMoreElements()) {
2140 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
2141 Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp);//will be used several times
2143 //////////////////////////DEBUG
2144 System.out.println(cdtemp.getSymbol()+" "+cdtemp.getId());
2145 for(Iterator flags = cdtemp.getFlags(); flags.hasNext();){
2146 FlagDescriptor flagd = (FlagDescriptor)flags.next();
2147 int flagid=1<<((Integer)flaginfo.get(flagd)).intValue();
2148 System.out.println(" Flag "+flagd.getSymbol()+" 0x"+Integer.toHexString(flagid)+" int "+flagid);
2150 ///////////////////////////
2152 //Generate the struct of optionals
2153 if((Hashtable)optionaltaskdescriptors.get(cdtemp)==null) System.out.println("Was in cd :"+cdtemp.getSymbol());
2154 Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
2155 numotd = c_otd.size();
2156 if(maxotd<numotd) maxotd = numotd;
2157 if( !c_otd.isEmpty() ){
2158 for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
2159 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
2161 //generate the int arrays for the predicate
2162 Predicate predicate = otd.predicate;
2163 int predicateindex = 0;
2164 //iterate through the classes concerned by the predicate
2165 Collection c_vard = predicate.vardescriptors;
2166 for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext();){
2167 VarDescriptor vard = (VarDescriptor)vard_it.next();
2168 TypeDescriptor typed = vard.getType();
2170 //generate for flags
2171 HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
2172 output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2174 if (fen_hashset!=null){
2175 for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext();){
2176 FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
2181 DNFFlag dflag=fen.getDNF();
2182 numberterms+=dflag.size();
2184 Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
2186 for(int j=0;j<dflag.size();j++) {
2188 output.println(",");
2189 Vector term=dflag.get(j);
2192 for(int k=0;k<term.size();k++) {
2193 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
2194 FlagDescriptor fd=dfa.getFlag();
2195 boolean negated=dfa.getNegated();
2196 int flagid=1<<((Integer)flags.get(fd)).intValue();
2201 output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
2206 output.println("};\n");
2209 TagExpressionList tagel = predicate.tags.get(vard.getSymbol());
2210 output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2211 //BUG...added next line to fix, test with any task program
2214 for(int j=0;j<tagel.numTags();j++) {
2216 output.println(",");
2217 TempDescriptor tmp=tagel.getTemp(j);
2218 //got rid of slot, maybe some improvments to do ???
2219 output.println("/*tagid*/"+state.getTagId(tmp.getTag()));
2221 numtags = tagel.numTags();
2223 output.println("};");
2225 //store the result into a predicatemember struct
2226 output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
2227 output.println("/*type*/"+typed.getClassDesc().getId()+",");
2228 output.println("/* number of dnf terms */"+numberterms+",");
2229 output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2230 output.println("/* number of tag */"+numtags+",");
2231 output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2232 output.println("};\n");
2237 //generate an array that stores the entire predicate
2238 output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2239 for( int j = 0; j<predicateindex; j++){
2240 if( j != predicateindex-1)output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2241 else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
2243 output.println("};\n");
2246 output.println("int enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2247 //iterate through possible FSes corresponding to the state when entering
2248 for(Iterator fses = otd.enterflagstates.iterator(); fses.hasNext();){
2249 FlagState fs = (FlagState)fses.next();
2252 for(Iterator flags = fs.getFlags(); flags.hasNext();){
2253 FlagDescriptor flagd = (FlagDescriptor)flags.next();
2254 int id=1<<((Integer)flaginfo.get(flagd)).intValue();
2257 if(fsnumber!=1) output.print(",");
2258 output.print(flagid);
2259 //tag information not needed because tag changes are not tolerated.
2261 output.println("};\n");
2264 //generate optionaltaskdescriptor that actually includes exit fses, predicate and the task concerned
2265 output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
2266 output.println("&task_"+otd.td.getSafeSymbol()+",");
2267 output.println("/*number of enter flags*/"+fsnumber+",");
2268 output.println("enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2269 output.println("/*number of members */"+predicateindex+",");
2270 output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2271 output.println("};\n");
2274 else continue; // if there is no optionals, there is no need to build the rest of the struct
2276 output.println("struct optionaltaskdescriptor * otdarray"+cdtemp.getSafeSymbol()+"[]={");
2277 c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
2279 if( !c_otd.isEmpty() ){
2280 for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
2281 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
2282 if(x!=0) output.println(",");
2284 output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
2287 output.println("};\n");
2289 //get all the possible falgstates reachable by an object
2290 Hashtable hashtbtemp = safeexecution.get(cdtemp);
2291 Enumeration fses = hashtbtemp.keys();
2293 while(fses.hasMoreElements()){
2294 FlagState fs = (FlagState)fses.nextElement();
2297 //get the set of OptionalTaskDescriptors corresponding
2298 HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
2299 //iterate through the OptionalTaskDescriptors and store the pointers to the optionals struct (see on top) into an array
2301 output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
2302 for(Iterator mos = availabletasks.iterator(); mos.hasNext();){
2303 OptionalTaskDescriptor mm = (OptionalTaskDescriptor)mos.next();
2304 if(!mos.hasNext()) output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol());
2306 else output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2309 output.println("};\n");
2311 //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose.
2314 for(Iterator flags = fs.getFlags(); flags.hasNext();){
2315 FlagDescriptor flagd = (FlagDescriptor)flags.next();
2316 int id=1<<((Integer)flaginfo.get(flagd)).intValue();
2321 //process tag information
2324 boolean first = true;
2325 Enumeration tag_enum = fs.getTags();
2326 output.println("int tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
2327 while(tag_enum.hasMoreElements()){
2329 TagDescriptor tagd = (TagDescriptor)tag_enum.nextElement();
2333 output.println(", ");
2334 output.println("/*tagid*/"+state.getTagId(tagd));
2336 output.println("};");
2339 //Store the result in fsanalysiswrapper
2341 output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
2342 output.println("/*flag*/"+flagid+",");
2343 output.println("/* number of tags*/"+tagcounter+",");
2344 output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
2345 output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
2346 output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
2347 output.println("};\n");
2351 //Build the array of fsanalysiswrappers
2352 output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
2353 for(int i = 0; i<fscounter; i++){
2354 if(i==fscounter-1) output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+"};\n");
2356 else output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+",");
2359 //Build the classanalysiswrapper referring to the previous array
2360 output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
2361 output.println("/*type*/"+cdtemp.getId()+",");
2362 output.println("/*numotd*/"+numotd+",");
2363 output.println("otdarray"+cdtemp.getSafeSymbol()+",");
2364 output.println("/* number of fsanalysiswrappers */"+fscounter+",");
2365 output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
2367 processedcd.add(cdtemp);
2370 //build an array containing every classes for which code has been build
2371 output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
2372 boolean needcomma=false;
2373 for(Iterator classit = processedcd.iterator(); classit.hasNext();){
2374 ClassDescriptor cdtemp=(ClassDescriptor)classit.next();
2376 output.println(", ");
2378 output.println("&classanalysiswrapper_"+cdtemp.getSafeSymbol());
2380 output.println("};");
2382 output.println("int numclasses="+processedcd.size()+";");
2383 headers.println("extern numclasses;");
2384 output.println("int maxotd="+maxotd+";");
2385 headers.println("extern maxotd;");
2386 headers.println("#endif");