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.MyOptional;
13 public class BuildCode {
16 Hashtable paramstable;
21 String localsprefix="___locals___";
22 String paramsprefix="___params___";
23 public static boolean GENERATEPRECISEGC=false;
24 public static String PREFIX="";
25 public static String arraytype="ArrayObject";
28 private int maxtaskparams=0;
29 ClassDescriptor[] cdarray;
30 TypeDescriptor[] arraytable;
32 public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) {
34 this.temptovar=temptovar;
35 paramstable=new Hashtable();
36 tempstable=new Hashtable();
37 fieldorder=new Hashtable();
38 flagorder=new Hashtable();
39 this.typeutil=typeutil;
40 virtualcalls=new Virtual(state);
43 /** The buildCode method outputs C code for all the methods. The Flat
44 * versions of the methods must already be generated and stored in
45 * the State object. */
47 public void buildCode() {
48 /* Create output streams to write to */
49 PrintWriter outclassdefs=null;
50 PrintWriter outstructs=null;
51 PrintWriter outrepairstructs=null;
52 PrintWriter outmethodheader=null;
53 PrintWriter outmethod=null;
54 PrintWriter outvirtual=null;
55 PrintWriter outtask=null;
56 PrintWriter outtaskdefs=null;
57 PrintWriter outoptionalarrays=null;
60 OutputStream str=new FileOutputStream(PREFIX+"structdefs.h");
61 outstructs=new java.io.PrintWriter(str, true);
62 str=new FileOutputStream(PREFIX+"methodheaders.h");
63 outmethodheader=new java.io.PrintWriter(str, true);
64 str=new FileOutputStream(PREFIX+"classdefs.h");
65 outclassdefs=new java.io.PrintWriter(str, true);
66 str=new FileOutputStream(PREFIX+"methods.c");
67 outmethod=new java.io.PrintWriter(str, true);
68 str=new FileOutputStream(PREFIX+"virtualtable.h");
69 outvirtual=new java.io.PrintWriter(str, true);
71 str=new FileOutputStream(PREFIX+"task.h");
72 outtask=new java.io.PrintWriter(str, true);
73 str=new FileOutputStream(PREFIX+"taskdefs.c");
74 outtaskdefs=new java.io.PrintWriter(str, true);
76 str=new FileOutputStream(PREFIX+"optionnalarrays.c");
77 outoptionalarrays=new java.io.PrintWriter(str, true);
80 if (state.structfile!=null) {
81 str=new FileOutputStream(PREFIX+state.structfile+".struct");
82 outrepairstructs=new java.io.PrintWriter(str, true);
84 } catch (Exception e) {
89 /* Build the virtual dispatch tables */
90 buildVirtualTables(outvirtual);
95 outmethodheader.println("#ifndef METHODHEADERS_H");
96 outmethodheader.println("#define METHODHEADERS_H");
97 outmethodheader.println("#include \"structdefs.h\"");
99 outstructs.println("#ifndef STRUCTDEFS_H");
100 outstructs.println("#define STRUCTDEFS_H");
101 outstructs.println("#include \"classdefs.h\"");
105 /* Output types for short array and string */
106 outstructs.println("#define STRINGARRAYTYPE "+
107 (state.getArrayNumber(
108 (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
110 outstructs.println("#define OBJECTARRAYTYPE "+
111 (state.getArrayNumber(
112 (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
115 outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
116 outstructs.println("#define CHARARRAYTYPE "+
117 (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
119 outstructs.println("#define BYTEARRAYTYPE "+
120 (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses()));
122 outstructs.println("#define BYTEARRAYARRAYTYPE "+
123 (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
125 outstructs.println("#define NUMCLASSES "+state.numClasses());
127 outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
128 outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
129 outstructs.println("#define TAGARRAYTYPE "+
130 (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses()));
133 // Output the C class declarations
134 // These could mutually reference each other
136 outclassdefs.println("#include <pthread.h>");
138 outclassdefs.println("struct "+arraytype+";");
140 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
141 while(it.hasNext()) {
142 ClassDescriptor cn=(ClassDescriptor)it.next();
143 outclassdefs.println("struct "+cn.getSafeSymbol()+";");
145 outclassdefs.println("");
147 //Print out definition for array type
148 outclassdefs.println("struct "+arraytype+" {");
149 outclassdefs.println(" int type;");
151 outclassdefs.println(" pthread_t tid;");
152 outclassdefs.println(" void * lockentry;");
153 outclassdefs.println(" int lockcount;");
157 outclassdefs.println(" int flag;");
158 outclassdefs.println(" void * flagptr;");
159 outclassdefs.println(" int failedstatus;");
160 outclassdefs.println(" int * flagset;");
162 printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
163 outclassdefs.println(" int ___length___;");
164 outclassdefs.println("};\n");
167 //Print out definitions for task types
168 outtask.println("struct parameterdescriptor {");
169 outtask.println("int type;");
170 outtask.println("int numberterms;");
171 outtask.println("int *intarray;");
172 outtask.println("void * queue;");
173 outtask.println("int numbertags;");
174 outtask.println("int *tagarray;");
175 outtask.println("};");
177 outtask.println("struct taskdescriptor {");
178 outtask.println("void * taskptr;");
179 outtask.println("int numParameters;");
180 outtask.println("int numTotal;");
181 outtask.println("struct parameterdescriptor **descriptorarray;");
182 outtask.println("char * name;");
183 outtask.println("};");
184 outtask.println("extern struct taskdescriptor * taskarray[];");
185 outtask.println("extern numtasks;");
189 // Output function prototypes and structures for parameters
190 it=state.getClassSymbolTable().getDescriptorsIterator();
191 while(it.hasNext()) {
192 ClassDescriptor cn=(ClassDescriptor)it.next();
193 generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
197 /* Map flags to integers */
198 it=state.getClassSymbolTable().getDescriptorsIterator();
199 while(it.hasNext()) {
200 ClassDescriptor cn=(ClassDescriptor)it.next();
204 generateTaskStructs(outstructs, outmethodheader);
207 outmethodheader.println("#endif");
209 outmethodheader.close();
211 /* Build the actual methods */
212 outmethod.println("#include \"methodheaders.h\"");
213 outmethod.println("#include \"virtualtable.h\"");
214 outmethod.println("#include <runtime.h>");
216 outmethod.println("#include <thread.h>");
217 if (state.main!=null) {
218 outmethod.println("#include <string.h>");
221 if (state.CONSCHECK) {
222 outmethod.println("#include \"checkers.h\"");
224 outclassdefs.println("extern int classsize[];");
225 outclassdefs.println("extern int hasflags[];");
226 outclassdefs.println("extern int * pointerarray[];");
227 outclassdefs.println("extern int supertypes[];");
229 //Store the sizes of classes & array elements
230 generateSizeArray(outmethod);
232 //Store table of supertypes
233 generateSuperTypeTable(outmethod);
235 //Store the layout of classes
236 generateLayoutStructs(outmethod);
238 /* Generate code for methods */
239 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
240 while(classit.hasNext()) {
241 ClassDescriptor cn=(ClassDescriptor)classit.next();
242 Iterator methodit=cn.getMethods();
243 while(methodit.hasNext()) {
244 /* Classify parameters */
245 MethodDescriptor md=(MethodDescriptor)methodit.next();
246 FlatMethod fm=state.getMethodFlat(md);
247 if (!md.getModifiers().isNative())
248 generateFlatMethod(fm,outmethod);
253 /* Compile task based program */
254 outtaskdefs.println("#include \"task.h\"");
255 outtaskdefs.println("#include \"methodheaders.h\"");
256 Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
257 while(taskit.hasNext()) {
258 TaskDescriptor td=(TaskDescriptor)taskit.next();
259 FlatMethod fm=state.getMethodFlat(td);
260 generateFlatMethod(fm, outmethod);
261 generateTaskDescriptor(outtaskdefs, fm, td);
265 //Output task descriptors
266 taskit=state.getTaskSymbolTable().getDescriptorsIterator();
267 outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
269 while(taskit.hasNext()) {
270 TaskDescriptor td=(TaskDescriptor)taskit.next();
274 outtaskdefs.println(",");
275 outtaskdefs.print("&task_"+td.getSafeSymbol());
277 outtaskdefs.println("};");
280 outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
282 } else if (state.main!=null) {
283 /* Generate main method */
284 outmethod.println("int main(int argc, const char *argv[]) {");
285 outmethod.println(" int i;");
286 if (GENERATEPRECISEGC) {
287 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
289 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
292 outmethod.println("initializethreads();");
294 outmethod.println(" for(i=1;i<argc;i++) {");
295 outmethod.println(" int length=strlen(argv[i]);");
296 if (GENERATEPRECISEGC) {
297 outmethod.println(" struct ___String___ *newstring=NewString(NULL, argv[i], length);");
299 outmethod.println(" struct ___String___ *newstring=NewString(argv[i], length);");
301 outmethod.println(" ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
302 outmethod.println(" }");
305 MethodDescriptor md=typeutil.getMain();
306 ClassDescriptor cd=typeutil.getMainClass();
308 outmethod.println(" {");
309 if (GENERATEPRECISEGC) {
310 outmethod.print(" struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
311 outmethod.println("1, NULL,"+"stringarray};");
312 outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
314 outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
315 outmethod.println(" }");
318 outmethod.println("pthread_mutex_lock(&gclistlock);");
319 outmethod.println("threadcount--;");
320 outmethod.println("pthread_cond_signal(&gccond);");
321 outmethod.println("pthread_mutex_unlock(&gclistlock);");
322 outmethod.println("pthread_exit(NULL);");
324 outmethod.println("}");
327 outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
329 if (state.TASK&&state.OPTIONAL){
330 generateOptionalArrays(outoptionalarrays, state.getAnalysisResult(), state.getMyOptionals());
331 outoptionalarrays.close();
335 /* Output structure definitions for repair tool */
336 if (state.structfile!=null) {
337 buildRepairStructs(outrepairstructs);
338 outrepairstructs.close();
340 outstructs.println("#endif");
348 private int maxcount=0;
350 private void buildRepairStructs(PrintWriter outrepairstructs) {
351 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
352 while(classit.hasNext()) {
353 ClassDescriptor cn=(ClassDescriptor)classit.next();
354 outrepairstructs.println("structure "+cn.getSymbol()+" {");
355 outrepairstructs.println(" int __type__;");
357 outrepairstructs.println(" int __flag__;");
358 outrepairstructs.println(" int __flagptr__;");
360 printRepairStruct(cn, outrepairstructs);
361 outrepairstructs.println("}\n");
364 for(int i=0;i<state.numArrays();i++) {
365 TypeDescriptor tdarray=arraytable[i];
366 TypeDescriptor tdelement=tdarray.dereference();
367 outrepairstructs.println("structure "+arraytype+"_"+state.getArrayNumber(tdarray)+" {");
368 outrepairstructs.println(" int __type__;");
369 printRepairStruct(typeutil.getClass(TypeUtil.ObjectClass), outrepairstructs);
370 outrepairstructs.println(" int length;");
372 // Need to add support to repair tool for this
373 if (tdelement.isClass()||tdelement.isArray())
374 outrepairstructs.println(" "+tdelement.getRepairSymbol()+" * elem[this.length];");
376 outrepairstructs.println(" "+tdelement.getRepairSymbol()+" elem[this.length];");
378 outrepairstructs.println("}\n");
383 private void printRepairStruct(ClassDescriptor cn, PrintWriter output) {
384 ClassDescriptor sp=cn.getSuperDesc();
386 printRepairStruct(sp, output);
388 Vector fields=(Vector)fieldorder.get(cn);
390 for(int i=0;i<fields.size();i++) {
391 FieldDescriptor fd=(FieldDescriptor)fields.get(i);
392 if (fd.getType().isArray()) {
393 output.println(" "+arraytype+"_"+ state.getArrayNumber(fd.getType()) +" * "+fd.getSymbol()+";");
394 } else if (fd.getType().isClass())
395 output.println(" "+fd.getType().getRepairSymbol()+" * "+fd.getSymbol()+";");
396 else if (fd.getType().isFloat())
397 output.println(" int "+fd.getSymbol()+"; /* really float */");
399 output.println(" "+fd.getType().getRepairSymbol()+" "+fd.getSymbol()+";");
403 /** This method outputs TaskDescriptor information */
404 void generateTaskDescriptor(PrintWriter output, FlatMethod fm, TaskDescriptor task) {
405 for (int i=0;i<task.numParameters();i++) {
406 VarDescriptor param_var=task.getParameter(i);
407 TypeDescriptor param_type=task.getParamType(i);
408 FlagExpressionNode param_flag=task.getFlag(param_var);
409 TagExpressionList param_tag=task.getTag(param_var);
412 if (param_flag==null) {
413 output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
414 output.println("0x0, 0x0 };");
418 DNFFlag dflag=param_flag.getDNF();
419 dnfterms=dflag.size();
421 Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
422 output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
423 for(int j=0;j<dflag.size();j++) {
426 Vector term=dflag.get(j);
429 for(int k=0;k<term.size();k++) {
430 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
431 FlagDescriptor fd=dfa.getFlag();
432 boolean negated=dfa.getNegated();
433 int flagid=1<<((Integer)flags.get(fd)).intValue();
438 output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
440 output.println("};");
443 output.println("int parametertag_"+i+"_"+task.getSafeSymbol()+"[]={");
444 //BUG...added next line to fix, test with any task program
446 for(int j=0;j<param_tag.numTags();j++) {
449 /* for each tag we need */
450 /* which slot it is */
451 /* what type it is */
452 TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
453 TempDescriptor tmp=param_tag.getTemp(j);
454 int slot=fm.getTagInt(tmp);
455 output.println(slot+", "+state.getTagId(tvd.getTag()));
457 output.println("};");
459 output.println("struct parameterdescriptor parameter_"+i+"_"+task.getSafeSymbol()+"={");
460 output.println("/* type */"+param_type.getClassDesc().getId()+",");
461 output.println("/* number of DNF terms */"+dnfterms+",");
462 output.println("parameterdnf_"+i+"_"+task.getSafeSymbol()+",");
463 output.println("0,");
464 //BUG, added next line to fix and else statement...test
465 //with any task program
467 output.println("/* number of tags */"+param_tag.numTags()+",");
469 output.println("/* number of tags */ 0,");
470 output.println("parametertag_"+i+"_"+task.getSafeSymbol());
471 output.println("};");
475 output.println("struct parameterdescriptor * parameterdescriptors_"+task.getSafeSymbol()+"[] = {");
476 for (int i=0;i<task.numParameters();i++) {
479 output.print("¶meter_"+i+"_"+task.getSafeSymbol());
481 output.println("};");
483 output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={");
484 output.println("&"+task.getSafeSymbol()+",");
485 output.println("/* number of parameters */" +task.numParameters() + ",");
486 int numtotal=task.numParameters()+fm.numTags();
487 output.println("/* number total parameters */" +numtotal + ",");
488 output.println("parameterdescriptors_"+task.getSafeSymbol()+",");
489 output.println("\""+task.getSymbol()+"\"");
490 output.println("};");
494 /** The buildVirtualTables method outputs the virtual dispatch
495 * tables for methods. */
497 private void buildVirtualTables(PrintWriter outvirtual) {
498 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
499 while(classit.hasNext()) {
500 ClassDescriptor cd=(ClassDescriptor)classit.next();
501 if (virtualcalls.getMethodCount(cd)>maxcount)
502 maxcount=virtualcalls.getMethodCount(cd);
504 MethodDescriptor[][] virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount];
506 /* Fill in virtual table */
507 classit=state.getClassSymbolTable().getDescriptorsIterator();
508 while(classit.hasNext()) {
509 ClassDescriptor cd=(ClassDescriptor)classit.next();
510 fillinRow(cd, virtualtable, cd.getId());
513 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
514 Iterator arrayit=state.getArrayIterator();
515 while(arrayit.hasNext()) {
516 TypeDescriptor td=(TypeDescriptor)arrayit.next();
517 int id=state.getArrayNumber(td);
518 fillinRow(objectcd, virtualtable, id+state.numClasses());
521 outvirtual.print("void * virtualtable[]={");
522 boolean needcomma=false;
523 for(int i=0;i<state.numClasses()+state.numArrays();i++) {
524 for(int j=0;j<maxcount;j++) {
526 outvirtual.print(", ");
527 if (virtualtable[i][j]!=null) {
528 MethodDescriptor md=virtualtable[i][j];
529 outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
531 outvirtual.print("0");
535 outvirtual.println("");
537 outvirtual.println("};");
541 private void fillinRow(ClassDescriptor cd, MethodDescriptor[][] virtualtable, int rownum) {
542 /* Get inherited methods */
543 if (cd.getSuperDesc()!=null)
544 fillinRow(cd.getSuperDesc(), virtualtable, rownum);
545 /* Override them with our methods */
546 for(Iterator it=cd.getMethods();it.hasNext();) {
547 MethodDescriptor md=(MethodDescriptor)it.next();
548 if (md.isStatic()||md.getReturnType()==null)
550 int methodnum=virtualcalls.getMethodNumber(md);
551 virtualtable[rownum][methodnum]=md;
555 /** Generate array that contains the sizes of class objects. The
556 * object allocation functions in the runtime use this
559 private void generateSizeArray(PrintWriter outclassdefs) {
560 outclassdefs.print("int classsize[]={");
561 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
562 cdarray=new ClassDescriptor[state.numClasses()];
563 while(it.hasNext()) {
564 ClassDescriptor cd=(ClassDescriptor)it.next();
565 cdarray[cd.getId()]=cd;
567 boolean needcomma=false;
568 for(int i=0;i<state.numClasses();i++) {
570 outclassdefs.print(", ");
571 outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");
575 arraytable=new TypeDescriptor[state.numArrays()];
577 Iterator arrayit=state.getArrayIterator();
578 while(arrayit.hasNext()) {
579 TypeDescriptor td=(TypeDescriptor)arrayit.next();
580 int id=state.getArrayNumber(td);
584 for(int i=0;i<state.numArrays();i++) {
586 outclassdefs.print(", ");
587 TypeDescriptor tdelement=arraytable[i].dereference();
588 if (tdelement.isArray()||tdelement.isClass())
589 outclassdefs.print("sizeof(void *)");
591 outclassdefs.print("sizeof("+tdelement.getSafeSymbol()+")");
595 outclassdefs.println("};");
598 /** Constructs params and temp objects for each method or task.
599 * These objects tell the compiler which temps need to be
602 private void generateTempStructs(FlatMethod fm) {
603 MethodDescriptor md=fm.getMethod();
604 TaskDescriptor task=fm.getTask();
606 ParamsObject objectparams=md!=null?new ParamsObject(md,tag++):new ParamsObject(task, tag++);
608 paramstable.put(md, objectparams);
610 paramstable.put(task, objectparams);
612 for(int i=0;i<fm.numParameters();i++) {
613 TempDescriptor temp=fm.getParameter(i);
614 TypeDescriptor type=temp.getType();
615 if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
616 objectparams.addPtr(temp);
618 objectparams.addPrim(temp);
621 for(int i=0;i<fm.numTags();i++) {
622 TempDescriptor temp=fm.getTag(i);
623 if (GENERATEPRECISEGC)
624 objectparams.addPtr(temp);
626 objectparams.addPrim(temp);
629 TempObject objecttemps=md!=null?new TempObject(objectparams,md,tag++):new TempObject(objectparams, task, tag++);
631 tempstable.put(md, objecttemps);
633 tempstable.put(task, objecttemps);
635 for(Iterator nodeit=fm.getNodeSet().iterator();nodeit.hasNext();) {
636 FlatNode fn=(FlatNode)nodeit.next();
637 TempDescriptor[] writes=fn.writesTemps();
638 for(int i=0;i<writes.length;i++) {
639 TempDescriptor temp=writes[i];
640 TypeDescriptor type=temp.getType();
641 if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
642 objecttemps.addPtr(temp);
644 objecttemps.addPrim(temp);
649 private void generateLayoutStructs(PrintWriter output) {
650 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
651 while(it.hasNext()) {
652 ClassDescriptor cn=(ClassDescriptor)it.next();
653 output.println("int "+cn.getSafeSymbol()+"_pointers[]={");
654 Iterator allit=cn.getFieldTable().getAllDescriptorsIterator();
656 while(allit.hasNext()) {
657 FieldDescriptor fd=(FieldDescriptor)allit.next();
658 TypeDescriptor type=fd.getType();
659 if (type.isPtr()||type.isArray())
663 allit=cn.getFieldTable().getAllDescriptorsIterator();
664 while(allit.hasNext()) {
665 FieldDescriptor fd=(FieldDescriptor)allit.next();
666 TypeDescriptor type=fd.getType();
667 if (type.isPtr()||type.isArray()) {
669 output.print("((int)&(((struct "+cn.getSafeSymbol() +" *)0)->"+fd.getSafeSymbol()+"))");
672 output.println("};");
674 output.println("int * pointerarray[]={");
675 boolean needcomma=false;
676 for(int i=0;i<state.numClasses();i++) {
677 ClassDescriptor cn=cdarray[i];
681 output.print(cn.getSafeSymbol()+"_pointers");
684 for(int i=0;i<state.numArrays();i++) {
686 output.println(", ");
687 TypeDescriptor tdelement=arraytable[i].dereference();
688 if (tdelement.isArray()||tdelement.isClass())
689 output.print("((int *)1)");
695 output.println("};");
697 output.println("int hasflags[]={");
698 for(int i=0;i<state.numClasses();i++) {
699 ClassDescriptor cn=cdarray[i];
701 output.println(", ");
708 output.println("};");
711 /** Print out table to give us supertypes */
712 private void generateSuperTypeTable(PrintWriter output) {
713 output.println("int supertypes[]={");
714 boolean needcomma=false;
715 for(int i=0;i<state.numClasses();i++) {
716 ClassDescriptor cn=cdarray[i];
720 if (cn.getSuperDesc()!=null) {
721 ClassDescriptor cdsuper=cn.getSuperDesc();
722 output.print(cdsuper.getId());
726 output.println("};");
729 /** Force consistent field ordering between inherited classes. */
731 private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) {
732 ClassDescriptor sp=cn.getSuperDesc();
734 printClassStruct(sp, classdefout);
736 if (!fieldorder.containsKey(cn)) {
737 Vector fields=new Vector();
738 fieldorder.put(cn,fields);
739 Iterator fieldit=cn.getFields();
740 while(fieldit.hasNext()) {
741 FieldDescriptor fd=(FieldDescriptor)fieldit.next();
742 if (sp==null||!sp.getFieldTable().contains(fd.getSymbol()))
746 Vector fields=(Vector)fieldorder.get(cn);
748 for(int i=0;i<fields.size();i++) {
749 FieldDescriptor fd=(FieldDescriptor)fields.get(i);
750 if (fd.getType().isClass()||fd.getType().isArray())
751 classdefout.println(" struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
753 classdefout.println(" "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
758 /* Map flags to integers consistently between inherited
761 private void mapFlags(ClassDescriptor cn) {
762 ClassDescriptor sp=cn.getSuperDesc();
766 if (!flagorder.containsKey(cn)) {
767 Hashtable flags=new Hashtable();
768 flagorder.put(cn,flags);
770 Hashtable superflags=(Hashtable)flagorder.get(sp);
771 Iterator superflagit=superflags.keySet().iterator();
772 while(superflagit.hasNext()) {
773 FlagDescriptor fd=(FlagDescriptor)superflagit.next();
774 Integer number=(Integer)superflags.get(fd);
775 flags.put(fd, number);
776 if ((number.intValue()+1)>max)
777 max=number.intValue()+1;
781 Iterator flagit=cn.getFlags();
782 while(flagit.hasNext()) {
783 FlagDescriptor fd=(FlagDescriptor)flagit.next();
784 if (sp==null||!sp.getFlagTable().contains(fd.getSymbol()))
785 flags.put(fd, new Integer(max++));
791 /** This function outputs (1) structures that parameters are
792 * passed in (when PRECISE GC is enabled) and (2) function
793 * prototypes for the methods */
795 private void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) {
796 /* Output class structure */
797 classdefout.println("struct "+cn.getSafeSymbol()+" {");
798 classdefout.println(" int type;");
800 classdefout.println(" pthread_t tid;");
801 classdefout.println(" void * lockentry;");
802 classdefout.println(" int lockcount;");
806 classdefout.println(" int flag;");
807 classdefout.println(" void * flagptr;");
808 classdefout.println(" int failedstatus;");
809 classdefout.println(" int * flagset;");
811 printClassStruct(cn, classdefout);
812 classdefout.println("};\n");
814 /* Cycle through methods */
815 Iterator methodit=cn.getMethods();
816 while(methodit.hasNext()) {
817 /* Classify parameters */
818 MethodDescriptor md=(MethodDescriptor)methodit.next();
819 FlatMethod fm=state.getMethodFlat(md);
820 generateTempStructs(fm);
822 ParamsObject objectparams=(ParamsObject) paramstable.get(md);
823 TempObject objecttemps=(TempObject) tempstable.get(md);
825 /* Output parameter structure */
826 if (GENERATEPRECISEGC) {
827 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
828 output.println(" int size;");
829 output.println(" void * next;");
830 for(int i=0;i<objectparams.numPointers();i++) {
831 TempDescriptor temp=objectparams.getPointer(i);
832 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
834 output.println("};\n");
837 /* Output temp structure */
838 if (GENERATEPRECISEGC) {
839 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
840 output.println(" int size;");
841 output.println(" void * next;");
842 for(int i=0;i<objecttemps.numPointers();i++) {
843 TempDescriptor temp=objecttemps.getPointer(i);
844 if (temp.getType().isNull())
845 output.println(" void * "+temp.getSafeSymbol()+";");
847 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
849 output.println("};\n");
852 /* Output method declaration */
853 if (md.getReturnType()!=null) {
854 if (md.getReturnType().isClass()||md.getReturnType().isArray())
855 headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
857 headersout.print(md.getReturnType().getSafeSymbol()+" ");
859 //catch the constructor case
860 headersout.print("void ");
861 headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
863 boolean printcomma=false;
864 if (GENERATEPRECISEGC) {
865 headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
869 //output parameter list
870 for(int i=0;i<objectparams.numPrimitives();i++) {
871 TempDescriptor temp=objectparams.getPrimitive(i);
873 headersout.print(", ");
875 if (temp.getType().isClass()||temp.getType().isArray())
876 headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
878 headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
880 headersout.println(");\n");
885 /** This function outputs (1) structures that parameters are
886 * passed in (when PRECISE GC is enabled) and (2) function
887 * prototypes for the tasks */
889 private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
890 /* Cycle through tasks */
891 Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
893 while(taskit.hasNext()) {
894 /* Classify parameters */
895 TaskDescriptor task=(TaskDescriptor)taskit.next();
896 FlatMethod fm=state.getMethodFlat(task);
897 generateTempStructs(fm);
899 ParamsObject objectparams=(ParamsObject) paramstable.get(task);
900 TempObject objecttemps=(TempObject) tempstable.get(task);
902 /* Output parameter structure */
903 if (GENERATEPRECISEGC) {
904 output.println("struct "+task.getSafeSymbol()+"_params {");
906 output.println(" int size;");
907 output.println(" void * next;");
908 for(int i=0;i<objectparams.numPointers();i++) {
909 TempDescriptor temp=objectparams.getPointer(i);
910 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
913 output.println("};\n");
914 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
915 maxtaskparams=objectparams.numPointers()+fm.numTags();
919 /* Output temp structure */
920 if (GENERATEPRECISEGC) {
921 output.println("struct "+task.getSafeSymbol()+"_locals {");
922 output.println(" int size;");
923 output.println(" void * next;");
924 for(int i=0;i<objecttemps.numPointers();i++) {
925 TempDescriptor temp=objecttemps.getPointer(i);
926 if (temp.getType().isNull())
927 output.println(" void * "+temp.getSafeSymbol()+";");
928 else if(temp.getType().isTag())
929 output.println(" struct "+
930 (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
932 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
934 output.println("};\n");
937 /* Output task declaration */
938 headersout.print("void " + task.getSafeSymbol()+"(");
940 boolean printcomma=false;
941 if (GENERATEPRECISEGC) {
942 headersout.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
944 headersout.print("void * parameterarray[]");
945 headersout.println(");\n");
949 /** Generate code for flatmethod fm. */
951 private void generateFlatMethod(FlatMethod fm, PrintWriter output) {
952 MethodDescriptor md=fm.getMethod();
953 TaskDescriptor task=fm.getTask();
955 ClassDescriptor cn=md!=null?md.getClassDesc():null;
957 ParamsObject objectparams=(ParamsObject)paramstable.get(md!=null?md:task);
959 generateHeader(fm, md!=null?md:task,output);
961 TempObject objecttemp=(TempObject) tempstable.get(md!=null?md:task);
964 if (GENERATEPRECISEGC) {
966 output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
968 output.print(" struct "+task.getSafeSymbol()+"_locals "+localsprefix+"={");
970 output.print(objecttemp.numPointers()+",");
971 output.print(paramsprefix);
972 for(int j=0;j<objecttemp.numPointers();j++)
973 output.print(", NULL");
974 output.println("};");
977 for(int i=0;i<objecttemp.numPrimitives();i++) {
978 TempDescriptor td=objecttemp.getPrimitive(i);
979 TypeDescriptor type=td.getType();
981 output.println(" void * "+td.getSafeSymbol()+";");
982 else if (type.isClass()||type.isArray())
983 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
985 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
988 /* Generate labels first */
989 HashSet tovisit=new HashSet();
990 HashSet visited=new HashSet();
992 Hashtable nodetolabel=new Hashtable();
993 tovisit.add(fm.getNext(0));
994 FlatNode current_node=null;
997 //Node needs a label if it is
998 while(!tovisit.isEmpty()) {
999 FlatNode fn=(FlatNode)tovisit.iterator().next();
1002 for(int i=0;i<fn.numNext();i++) {
1003 FlatNode nn=fn.getNext(i);
1005 //1) Edge >1 of node
1006 nodetolabel.put(nn,new Integer(labelindex++));
1008 if (!visited.contains(nn)&&!tovisit.contains(nn)) {
1012 nodetolabel.put(nn,new Integer(labelindex++));
1017 if (state.THREAD&&GENERATEPRECISEGC) {
1018 output.println("checkcollect(&"+localsprefix+");");
1021 //Do the actual code generation
1022 tovisit=new HashSet();
1023 visited=new HashSet();
1024 tovisit.add(fm.getNext(0));
1025 while(current_node!=null||!tovisit.isEmpty()) {
1026 if (current_node==null) {
1027 current_node=(FlatNode)tovisit.iterator().next();
1028 tovisit.remove(current_node);
1030 visited.add(current_node);
1031 if (nodetolabel.containsKey(current_node))
1032 output.println("L"+nodetolabel.get(current_node)+":");
1033 if (state.INSTRUCTIONFAILURE) {
1035 output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
1038 output.println("if ((--instructioncount)==0) injectinstructionfailure();");
1040 if (current_node.numNext()==0) {
1042 generateFlatNode(fm, current_node, output);
1043 if (current_node.kind()!=FKind.FlatReturnNode) {
1044 output.println(" return;");
1047 } else if(current_node.numNext()==1) {
1049 generateFlatNode(fm, current_node, output);
1050 FlatNode nextnode=current_node.getNext(0);
1051 if (visited.contains(nextnode)) {
1052 output.println("goto L"+nodetolabel.get(nextnode)+";");
1055 current_node=nextnode;
1056 } else if (current_node.numNext()==2) {
1059 generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
1060 if (!visited.contains(current_node.getNext(1)))
1061 tovisit.add(current_node.getNext(1));
1062 if (visited.contains(current_node.getNext(0))) {
1063 output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
1066 current_node=current_node.getNext(0);
1067 } else throw new Error();
1071 output.println("}\n\n");
1074 /** Generate text string that corresponds to the Temp td. */
1075 private String generateTemp(FlatMethod fm, TempDescriptor td) {
1076 MethodDescriptor md=fm.getMethod();
1077 TaskDescriptor task=fm.getTask();
1078 TempObject objecttemps=(TempObject) tempstable.get(md!=null?md:task);
1080 if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1081 return td.getSafeSymbol();
1084 if (objecttemps.isLocalPtr(td)) {
1085 return localsprefix+"."+td.getSafeSymbol();
1088 if (objecttemps.isParamPtr(td)) {
1089 return paramsprefix+"->"+td.getSafeSymbol();
1094 private void generateFlatNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
1096 case FKind.FlatAtomicEnterNode:
1097 generateFlatAtomicEnterNode(fm, (FlatAtomicEnterNode) fn, output);
1099 case FKind.FlatAtomicExitNode:
1100 generateFlatAtomicExitNode(fm, (FlatAtomicExitNode) fn, output);
1102 case FKind.FlatTagDeclaration:
1103 generateFlatTagDeclaration(fm, (FlatTagDeclaration) fn,output);
1105 case FKind.FlatCall:
1106 generateFlatCall(fm, (FlatCall) fn,output);
1108 case FKind.FlatFieldNode:
1109 generateFlatFieldNode(fm, (FlatFieldNode) fn,output);
1111 case FKind.FlatElementNode:
1112 generateFlatElementNode(fm, (FlatElementNode) fn,output);
1114 case FKind.FlatSetElementNode:
1115 generateFlatSetElementNode(fm, (FlatSetElementNode) fn,output);
1117 case FKind.FlatSetFieldNode:
1118 generateFlatSetFieldNode(fm, (FlatSetFieldNode) fn,output);
1121 generateFlatNew(fm, (FlatNew) fn,output);
1123 case FKind.FlatOpNode:
1124 generateFlatOpNode(fm, (FlatOpNode) fn,output);
1126 case FKind.FlatCastNode:
1127 generateFlatCastNode(fm, (FlatCastNode) fn,output);
1129 case FKind.FlatLiteralNode:
1130 generateFlatLiteralNode(fm, (FlatLiteralNode) fn,output);
1132 case FKind.FlatReturnNode:
1133 generateFlatReturnNode(fm, (FlatReturnNode) fn,output);
1136 output.println("/* nop */");
1138 case FKind.FlatBackEdge:
1139 if (state.THREAD&&GENERATEPRECISEGC) {
1140 output.println("checkcollect(&"+localsprefix+");");
1142 output.println("/* nop */");
1144 case FKind.FlatCheckNode:
1145 generateFlatCheckNode(fm, (FlatCheckNode) fn, output);
1147 case FKind.FlatFlagActionNode:
1148 generateFlatFlagActionNode(fm, (FlatFlagActionNode) fn, output);
1156 public void generateFlatAtomicEnterNode(FlatMethod fm, FlatAtomicEnterNode faen, PrintWriter output) {
1159 public void generateFlatAtomicExitNode(FlatMethod fm, FlatAtomicExitNode faen, PrintWriter output) {
1162 private void generateFlatCheckNode(FlatMethod fm, FlatCheckNode fcn, PrintWriter output) {
1164 if (state.CONSCHECK) {
1165 String specname=fcn.getSpec();
1166 String varname="repairstate___";
1167 output.println("{");
1168 output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
1170 TempDescriptor[] temps=fcn.getTemps();
1171 String[] vars=fcn.getVars();
1172 for(int i=0;i<temps.length;i++) {
1173 output.println(varname+"->"+vars[i]+"=(int)"+generateTemp(fm, temps[i])+";");
1176 output.println("if (doanalysis"+specname+"("+varname+")) {");
1177 output.println("free"+specname+"_state("+varname+");");
1178 output.println("} else {");
1179 output.println("/* Bad invariant */");
1180 output.println("free"+specname+"_state("+varname+");");
1181 output.println("abort_task();");
1182 output.println("}");
1184 output.println("}");
1188 private void generateFlatCall(FlatMethod fm, FlatCall fc, PrintWriter output) {
1189 MethodDescriptor md=fc.getMethod();
1190 ParamsObject objectparams=(ParamsObject) paramstable.get(md);
1191 ClassDescriptor cn=md.getClassDesc();
1192 output.println("{");
1193 if (GENERATEPRECISEGC) {
1194 output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
1196 output.print(objectparams.numPointers());
1197 // output.print(objectparams.getUID());
1198 output.print(", & "+localsprefix);
1199 if (fc.getThis()!=null) {
1201 output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis()));
1203 for(int i=0;i<fc.numArgs();i++) {
1204 Descriptor var=md.getParameter(i);
1205 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
1206 if (objectparams.isParamPtr(paramtemp)) {
1207 TempDescriptor targ=fc.getArg(i);
1209 TypeDescriptor td=md.getParamType(i);
1211 output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol() +" *)"+generateTemp(fm, targ));
1213 output.print("(struct "+md.getParamType(i).getSafeSymbol() +" *)"+generateTemp(fm, targ));
1216 output.println("};");
1221 if (fc.getReturnTemp()!=null)
1222 output.print(generateTemp(fm,fc.getReturnTemp())+"=");
1224 /* Do we need to do virtual dispatch? */
1225 if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
1226 output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
1230 if (md.getReturnType().isClass()||md.getReturnType().isArray())
1231 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1233 output.print(md.getReturnType().getSafeSymbol()+" ");
1234 output.print("(*)(");
1236 boolean printcomma=false;
1237 if (GENERATEPRECISEGC) {
1238 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
1243 for(int i=0;i<objectparams.numPrimitives();i++) {
1244 TempDescriptor temp=objectparams.getPrimitive(i);
1248 if (temp.getType().isClass()||temp.getType().isArray())
1249 output.print("struct " + temp.getType().getSafeSymbol()+" * ");
1251 output.print(temp.getType().getSafeSymbol());
1254 output.print("))virtualtable["+generateTemp(fm,fc.getThis())+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
1258 boolean needcomma=false;
1259 if (GENERATEPRECISEGC) {
1260 output.print("&__parameterlist__");
1263 if (fc.getThis()!=null) {
1264 TypeDescriptor ptd=md.getThis().getType();
1265 if (ptd.isClass()&&!ptd.isArray())
1266 output.print("(struct "+ptd.getSafeSymbol()+" *) ");
1267 output.print(generateTemp(fm,fc.getThis()));
1271 for(int i=0;i<fc.numArgs();i++) {
1272 Descriptor var=md.getParameter(i);
1273 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
1274 if (objectparams.isParamPrim(paramtemp)) {
1275 TempDescriptor targ=fc.getArg(i);
1279 TypeDescriptor ptd=md.getParamType(i);
1280 if (ptd.isClass()&&!ptd.isArray())
1281 output.print("(struct "+ptd.getSafeSymbol()+" *) ");
1282 output.print(generateTemp(fm, targ));
1286 output.println(");");
1287 output.println(" }");
1290 private boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
1291 Set subclasses=typeutil.getSubClasses(thiscd);
1292 if (subclasses==null)
1294 for(Iterator classit=subclasses.iterator();classit.hasNext();) {
1295 ClassDescriptor cd=(ClassDescriptor)classit.next();
1296 Set possiblematches=cd.getMethodTable().getSet(md.getSymbol());
1297 for(Iterator matchit=possiblematches.iterator();matchit.hasNext();) {
1298 MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
1299 if (md.matches(matchmd))
1306 private void generateFlatFieldNode(FlatMethod fm, FlatFieldNode ffn, PrintWriter output) {
1307 output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
1310 private void generateFlatSetFieldNode(FlatMethod fm, FlatSetFieldNode fsfn, PrintWriter output) {
1311 if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
1312 throw new Error("Can't set array length");
1313 output.println(generateTemp(fm, fsfn.getDst())+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
1316 private void generateFlatElementNode(FlatMethod fm, FlatElementNode fen, PrintWriter output) {
1317 TypeDescriptor elementtype=fen.getSrc().getType().dereference();
1320 if (elementtype.isArray()||elementtype.isClass())
1323 type=elementtype.getSafeSymbol()+" ";
1325 if (fen.needsBoundsCheck()) {
1326 output.println("if ("+generateTemp(fm, fen.getIndex())+"< 0 || "+generateTemp(fm, fen.getIndex())+" >= "+generateTemp(fm,fen.getSrc()) + "->___length___)");
1327 output.println("failedboundschk();");
1330 output.println(generateTemp(fm, fen.getDst())+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc())+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex())+"];");
1333 private void generateFlatSetElementNode(FlatMethod fm, FlatSetElementNode fsen, PrintWriter output) {
1334 //TODO: need dynamic check to make sure this assignment is actually legal
1335 //Because Object[] could actually be something more specific...ie. Integer[]
1337 TypeDescriptor elementtype=fsen.getDst().getType().dereference();
1340 if (elementtype.isArray()||elementtype.isClass())
1343 type=elementtype.getSafeSymbol()+" ";
1345 if (fsen.needsBoundsCheck()) {
1346 output.println("if ("+generateTemp(fm, fsen.getIndex())+"< 0 || "+generateTemp(fm, fsen.getIndex())+" >= "+generateTemp(fm,fsen.getDst()) + "->___length___)");
1347 output.println("failedboundschk();");
1350 output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst())+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex())+"]="+generateTemp(fm,fsen.getSrc())+";");
1353 private void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
1354 if (fn.getType().isArray()) {
1355 int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
1356 if (GENERATEPRECISEGC) {
1357 output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize())+");");
1359 output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");");
1362 if (GENERATEPRECISEGC) {
1363 output.println(generateTemp(fm,fn.getDst())+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
1365 output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
1371 private void generateFlatTagDeclaration(FlatMethod fm, FlatTagDeclaration fn, PrintWriter output) {
1372 if (GENERATEPRECISEGC) {
1373 output.println(generateTemp(fm,fn.getDst())+"=allocate_tag(&"+localsprefix+", "+state.getTagId(fn.getType())+");");
1375 output.println(generateTemp(fm,fn.getDst())+"=allocate_tag("+state.getTagId(fn.getType())+");");
1379 private void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) {
1381 if (fon.getRight()!=null)
1382 output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";");
1383 else if (fon.getOp().getOp()==Operation.ASSIGN)
1384 output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
1385 else if (fon.getOp().getOp()==Operation.UNARYPLUS)
1386 output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
1387 else if (fon.getOp().getOp()==Operation.UNARYMINUS)
1388 output.println(generateTemp(fm, fon.getDest())+" = -"+generateTemp(fm, fon.getLeft())+";");
1389 else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
1390 output.println(generateTemp(fm, fon.getDest())+" = !"+generateTemp(fm, fon.getLeft())+";");
1392 output.println(generateTemp(fm, fon.getDest())+fon.getOp().toString()+generateTemp(fm, fon.getLeft())+";");
1395 private void generateFlatCastNode(FlatMethod fm, FlatCastNode fcn, PrintWriter output) {
1396 /* TODO: Do type check here */
1397 if (fcn.getType().isArray()) {
1399 } else if (fcn.getType().isClass())
1400 output.println(generateTemp(fm,fcn.getDst())+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc())+";");
1402 output.println(generateTemp(fm,fcn.getDst())+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc())+";");
1405 private void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) {
1406 if (fln.getValue()==null)
1407 output.println(generateTemp(fm, fln.getDst())+"=0;");
1408 else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
1409 if (GENERATEPRECISEGC) {
1410 output.println(generateTemp(fm, fln.getDst())+"=NewString(&"+localsprefix+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
1412 output.println(generateTemp(fm, fln.getDst())+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
1414 } else if (fln.getType().isBoolean()) {
1415 if (((Boolean)fln.getValue()).booleanValue())
1416 output.println(generateTemp(fm, fln.getDst())+"=1;");
1418 output.println(generateTemp(fm, fln.getDst())+"=0;");
1419 } else if (fln.getType().isChar()) {
1420 String st=FlatLiteralNode.escapeString(fln.getValue().toString());
1421 output.println(generateTemp(fm, fln.getDst())+"='"+st+"';");
1423 output.println(generateTemp(fm, fln.getDst())+"="+fln.getValue()+";");
1426 private void generateFlatReturnNode(FlatMethod fm, FlatReturnNode frn, PrintWriter output) {
1428 if (frn.getReturnTemp()!=null)
1429 output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
1431 output.println("return;");
1434 private void generateFlatCondBranch(FlatMethod fm, FlatCondBranch fcb, String label, PrintWriter output) {
1435 output.println("if (!"+generateTemp(fm, fcb.getTest())+") goto "+label+";");
1438 private void generateHeader(FlatMethod fm, Descriptor des, PrintWriter output) {
1440 ParamsObject objectparams=(ParamsObject)paramstable.get(des);
1441 MethodDescriptor md=null;
1442 TaskDescriptor task=null;
1443 if (des instanceof MethodDescriptor)
1444 md=(MethodDescriptor) des;
1446 task=(TaskDescriptor) des;
1448 ClassDescriptor cn=md!=null?md.getClassDesc():null;
1450 if (md!=null&&md.getReturnType()!=null) {
1451 if (md.getReturnType().isClass()||md.getReturnType().isArray())
1452 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1454 output.print(md.getReturnType().getSafeSymbol()+" ");
1456 //catch the constructor case
1457 output.print("void ");
1459 output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1461 output.print(task.getSafeSymbol()+"(");
1463 boolean printcomma=false;
1464 if (GENERATEPRECISEGC) {
1466 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1468 output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1474 for(int i=0;i<objectparams.numPrimitives();i++) {
1475 TempDescriptor temp=objectparams.getPrimitive(i);
1479 if (temp.getType().isClass()||temp.getType().isArray())
1480 output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1482 output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1484 output.println(") {");
1485 } else if (!GENERATEPRECISEGC) {
1486 /* Imprecise Task */
1487 output.println("void * parameterarray[]) {");
1488 /* Unpack variables */
1489 for(int i=0;i<objectparams.numPrimitives();i++) {
1490 TempDescriptor temp=objectparams.getPrimitive(i);
1491 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
1493 for(int i=0;i<fm.numTags();i++) {
1494 TempDescriptor temp=fm.getTag(i);
1495 int offset=i+objectparams.numPrimitives();
1496 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
1499 if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
1500 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
1501 } else output.println(") {");
1504 public void generateFlatFlagActionNode(FlatMethod fm, FlatFlagActionNode ffan, PrintWriter output) {
1505 output.println("/* FlatFlagActionNode */");
1508 /* Process tag changes */
1509 Relation tagsettable=new Relation();
1510 Relation tagcleartable=new Relation();
1512 Iterator tagsit=ffan.getTempTagPairs();
1513 while (tagsit.hasNext()) {
1514 TempTagPair ttp=(TempTagPair) tagsit.next();
1515 TempDescriptor objtmp=ttp.getTemp();
1516 TagDescriptor tag=ttp.getTag();
1517 TempDescriptor tagtmp=ttp.getTagTemp();
1518 boolean tagstatus=ffan.getTagChange(ttp);
1520 tagsettable.put(objtmp, tagtmp);
1522 tagcleartable.put(objtmp, tagtmp);
1527 Hashtable flagandtable=new Hashtable();
1528 Hashtable flagortable=new Hashtable();
1530 /* Process flag changes */
1531 Iterator flagsit=ffan.getTempFlagPairs();
1532 while(flagsit.hasNext()) {
1533 TempFlagPair tfp=(TempFlagPair)flagsit.next();
1534 TempDescriptor temp=tfp.getTemp();
1535 Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
1536 FlagDescriptor flag=tfp.getFlag();
1538 //Newly allocate objects that don't set any flags case
1539 if (flagortable.containsKey(temp)) {
1543 flagortable.put(temp,new Integer(mask));
1545 int flagid=1<<((Integer)flagtable.get(flag)).intValue();
1546 boolean flagstatus=ffan.getFlagChange(tfp);
1549 if (flagortable.containsKey(temp)) {
1550 mask=((Integer)flagortable.get(temp)).intValue();
1553 flagortable.put(temp,new Integer(mask));
1555 int mask=0xFFFFFFFF;
1556 if (flagandtable.containsKey(temp)) {
1557 mask=((Integer)flagandtable.get(temp)).intValue();
1559 mask&=(0xFFFFFFFF^flagid);
1560 flagandtable.put(temp,new Integer(mask));
1566 HashSet flagtagset=new HashSet();
1567 flagtagset.addAll(flagortable.keySet());
1568 flagtagset.addAll(flagandtable.keySet());
1569 flagtagset.addAll(tagsettable.keySet());
1570 flagtagset.addAll(tagcleartable.keySet());
1572 Iterator ftit=flagtagset.iterator();
1573 while(ftit.hasNext()) {
1574 TempDescriptor temp=(TempDescriptor)ftit.next();
1577 Set tagtmps=tagcleartable.get(temp);
1578 if (tagtmps!=null) {
1579 Iterator tagit=tagtmps.iterator();
1580 while(tagit.hasNext()) {
1581 TempDescriptor tagtmp=(TempDescriptor)tagit.next();
1582 if (GENERATEPRECISEGC)
1583 output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1585 output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1589 tagtmps=tagsettable.get(temp);
1590 if (tagtmps!=null) {
1591 Iterator tagit=tagtmps.iterator();
1592 while(tagit.hasNext()) {
1593 TempDescriptor tagtmp=(TempDescriptor)tagit.next();
1594 if (GENERATEPRECISEGC)
1595 output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1597 output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1602 int andmask=0xFFFFFFF;
1604 if (flagortable.containsKey(temp))
1605 ormask=((Integer)flagortable.get(temp)).intValue();
1606 if (flagandtable.containsKey(temp))
1607 andmask=((Integer)flagandtable.get(temp)).intValue();
1608 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
1609 output.println("flagorandinit("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
1611 output.println("flagorand("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
1616 void generateOptionalArrays(PrintWriter output, Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> safeexecution, Hashtable myoptionals) {
1618 /* SymbolTable classes = state.getClassSymbolTable();
1619 for( Iterator it = classes.getAllDescriptorsIterator(); it.hasNext();){
1620 ClassDescriptor cd = (ClassDescriptor)it.next();
1621 output.println("Class "+cd.getSymbol());
1622 Hashtable flags=(Hashtable)flagorder.get(cd);
1623 for (Iterator fit = cd.getFlags(); fit.hasNext();){
1624 FlagDescriptor fd = (FlagDescriptor)fit.next();
1625 int flagid=1<<((Integer)flags.get(fd)).intValue();
1626 output.println("\tFlag associated with "+fd.getSymbol()+" : 0x"+Integer.toHexString(flagid)+" bx"+Integer.toBinaryString(flagid));
1634 int classescounter = 0;
1635 Enumeration e = safeexecution.keys();
1636 while (e.hasMoreElements()) {
1638 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
1639 for(Iterator myoit = ((HashSet)myoptionals.get(cdtemp)).iterator(); myoit.hasNext();){
1640 MyOptional myo = (MyOptional)myoit.next();
1641 output.println("struct myoptional myoptional_"+"/*ID to determine*/"+"_"+"cdtemp.getsafeSymbol()"+"={");
1642 //insert code to generate the myoptional
1643 output.println("};");
1646 Hashtable hashtbtemp = safeexecution.get(cdtemp);
1647 Enumeration fses = hashtbtemp.keys();
1648 while(fses.hasMoreElements()){
1649 //get all the possible falgstates reachable by an object
1650 FlagState fs = (FlagState)fses.nextElement();
1652 //get the set of MyOptionnals
1653 HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
1654 //iterate through the MyOptionals
1655 for(Iterator mos = availabletasks.iterator(); mos.hasNext();){
1656 MyOptional mm = (MyOptional)mos.next();
1659 output.println("struct myoptional * myoptionals_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
1660 for(int i=0; i<myocounter; i++){
1661 if(i==myocounter-1) output.println("&myoptional_"+"/*ID to determine*/"+"_"+cdtemp.getSafeSymbol()+"};");
1663 else output.println("&myoptional_"+"/*ID to determine*/"+"_"+cdtemp.getSafeSymbol()+",");
1666 output.println("int flagstatednf_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
1667 for(Iterator flags = fs.getFlags(); flags.hasNext();){
1668 FlagDescriptor flagd = (FlagDescriptor)flags.next();
1669 //process the fs, maybe add int tagstate[]
1671 output.println("};");
1672 output.println("struct structB structB_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
1673 output.println("/* number of dnf terms (to add)*/,");
1674 output.println("flagstatednf_"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
1675 output.println("/* number of tags (to add)*/,");
1676 output.println("tags_"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
1677 output.println("/* number of myoptionals */,");
1678 output.println("myoptionals_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
1679 output.println("};");
1681 output.println("struct structB * structBs_"+cdtemp.getSafeSymbol()+"[] = {");
1682 for(int i = 0; i<fscounter; i++){
1683 if(i==fscounter-1) output.println("&structB_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"};");
1685 else output.println("&structB_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
1688 output.println("struct structA structA_"+cdtemp.getSafeSymbol()+"={");
1689 output.println("/* class identifier */,");
1690 output.println("structBs_"+cdtemp.getSafeSymbol()+"};");
1692 output.println("struct structA * classesarray[]={");
1693 e = safeexecution.keys();
1695 while (e.hasMoreElements()) {
1696 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
1698 if(j==classescounter) output.println("&structA_"+cdtemp.getSafeSymbol()+"};");
1699 else output.println("&structA_"+cdtemp.getSafeSymbol()+",");
1701 output.println("int numclasses = "+classescounter+";");