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 public static boolean GENERATEPRECISEGC=false;
27 public static String PREFIX="";
28 public static String arraytype="ArrayObject";
31 private int maxtaskparams=0;
32 private int maxcount=0;
33 ClassDescriptor[] cdarray;
34 TypeDescriptor[] arraytable;
35 LocalityAnalysis locality;
36 Hashtable<TempDescriptor, TempDescriptor> backuptable;
38 public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) {
40 this.temptovar=temptovar;
41 paramstable=new Hashtable();
42 tempstable=new Hashtable();
43 fieldorder=new Hashtable();
44 flagorder=new Hashtable();
45 this.typeutil=typeutil;
46 virtualcalls=new Virtual(state);
49 public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality) {
50 this(st, temptovar, typeutil);
51 this.locality=locality;
52 this.backuptable=new Hashtable<TempDescriptor, TempDescriptor>();
55 /** The buildCode method outputs C code for all the methods. The Flat
56 * versions of the methods must already be generated and stored in
57 * the State object. */
59 public void buildCode() {
60 /* Create output streams to write to */
61 PrintWriter outclassdefs=null;
62 PrintWriter outstructs=null;
63 PrintWriter outrepairstructs=null;
64 PrintWriter outmethodheader=null;
65 PrintWriter outmethod=null;
66 PrintWriter outvirtual=null;
67 PrintWriter outtask=null;
68 PrintWriter outtaskdefs=null;
69 PrintWriter outoptionalarrays=null;
70 PrintWriter optionalheaders=null;
73 outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
74 outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
75 outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
76 outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
77 outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
79 outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
80 outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
82 outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
83 optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
86 if (state.structfile!=null) {
87 outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
89 } catch (Exception e) {
94 /* Build the virtual dispatch tables */
95 buildVirtualTables(outvirtual);
98 outmethodheader.println("#ifndef METHODHEADERS_H");
99 outmethodheader.println("#define METHODHEADERS_H");
100 outmethodheader.println("#include \"structdefs.h\"");
102 /* Output Structures */
103 outputStructs(outstructs);
105 // Output the C class declarations
106 // These could mutually reference each other
107 outputClassDeclarations(outclassdefs);
109 // Output function prototypes and structures for parameters
110 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
111 while(it.hasNext()) {
112 ClassDescriptor cn=(ClassDescriptor)it.next();
113 generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
115 outclassdefs.close();
118 /* Map flags to integers */
119 /* The runtime keeps track of flags using these integers */
120 it=state.getClassSymbolTable().getDescriptorsIterator();
121 while(it.hasNext()) {
122 ClassDescriptor cn=(ClassDescriptor)it.next();
126 generateTaskStructs(outstructs, outmethodheader);
128 /* Outputs generic task structures if this is a task
130 outputTaskTypes(outtask);
133 /* Build the actual methods */
134 outputMethods(outmethod);
137 /* Output code for tasks */
138 outputTaskCode(outtaskdefs, outmethod);
140 /* Record maximum number of task parameters */
141 outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
142 } else if (state.main!=null) {
143 /* Generate main method */
144 outputMainMethod(outmethod);
147 /* Generate information for task with optional parameters */
148 if (state.TASK&&state.OPTIONAL){
149 generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
150 outoptionalarrays.close();
153 /* Output structure definitions for repair tool */
154 if (state.structfile!=null) {
155 buildRepairStructs(outrepairstructs);
156 outrepairstructs.close();
160 outmethodheader.println("#endif");
161 outmethodheader.close();
163 outstructs.println("#endif");
167 /* This code just generates the main C method for java programs.
168 * The main C method packs up the arguments into a string array
169 * and passes it to the java main method. */
171 private void outputMainMethod(PrintWriter outmethod) {
172 outmethod.println("int main(int argc, const char *argv[]) {");
173 outmethod.println(" int i;");
174 if (GENERATEPRECISEGC) {
175 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
177 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
180 outmethod.println("initializethreads();");
182 outmethod.println(" for(i=1;i<argc;i++) {");
183 outmethod.println(" int length=strlen(argv[i]);");
184 if (GENERATEPRECISEGC) {
185 outmethod.println(" struct ___String___ *newstring=NewString(NULL, argv[i], length);");
187 outmethod.println(" struct ___String___ *newstring=NewString(argv[i], length);");
189 outmethod.println(" ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
190 outmethod.println(" }");
193 MethodDescriptor md=typeutil.getMain();
194 ClassDescriptor cd=typeutil.getMainClass();
196 outmethod.println(" {");
197 if (GENERATEPRECISEGC) {
198 outmethod.print(" struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
199 outmethod.println("1, NULL,"+"stringarray};");
200 outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
202 outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
203 outmethod.println(" }");
206 outmethod.println("pthread_mutex_lock(&gclistlock);");
207 outmethod.println("threadcount--;");
208 outmethod.println("pthread_cond_signal(&gccond);");
209 outmethod.println("pthread_mutex_unlock(&gclistlock);");
210 outmethod.println("pthread_exit(NULL);");
212 outmethod.println("}");
215 /* This method outputs code for each task. */
217 private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod) {
218 /* Compile task based program */
219 outtaskdefs.println("#include \"task.h\"");
220 outtaskdefs.println("#include \"methodheaders.h\"");
221 Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
222 while(taskit.hasNext()) {
223 TaskDescriptor td=(TaskDescriptor)taskit.next();
224 FlatMethod fm=state.getMethodFlat(td);
225 generateFlatMethod(fm, null, outmethod);
226 generateTaskDescriptor(outtaskdefs, fm, td);
229 //Output task descriptors
230 taskit=state.getTaskSymbolTable().getDescriptorsIterator();
231 outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
233 while(taskit.hasNext()) {
234 TaskDescriptor td=(TaskDescriptor)taskit.next();
238 outtaskdefs.println(",");
239 outtaskdefs.print("&task_"+td.getSafeSymbol());
241 outtaskdefs.println("};");
243 outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
246 /* This method outputs most of the methods.c file. This includes
247 * some standard includes and then an array with the sizes of
248 * objets and array that stores supertype and then the code for
249 * the Java methods.. */
251 private void outputMethods(PrintWriter outmethod) {
252 outmethod.println("#include \"methodheaders.h\"");
253 outmethod.println("#include \"virtualtable.h\"");
254 outmethod.println("#include <runtime.h>");
256 outmethod.println("#include <thread.h>");
257 if (state.main!=null) {
258 outmethod.println("#include <string.h>");
260 if (state.CONSCHECK) {
261 outmethod.println("#include \"checkers.h\"");
263 //Store the sizes of classes & array elements
264 generateSizeArray(outmethod);
266 //Store table of supertypes
267 generateSuperTypeTable(outmethod);
269 //Store the layout of classes
270 generateLayoutStructs(outmethod);
272 /* Generate code for methods */
274 for(Iterator<LocalityBinding> lbit=locality.getLocalityBindings().iterator();lbit.hasNext();) {
275 LocalityBinding lb=lbit.next();
276 MethodDescriptor md=lb.getMethod();
277 FlatMethod fm=state.getMethodFlat(md);
278 if (!md.getModifiers().isNative()) {
279 generateFlatMethod(fm, lb, outmethod);
283 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
284 while(classit.hasNext()) {
285 ClassDescriptor cn=(ClassDescriptor)classit.next();
286 Iterator methodit=cn.getMethods();
287 while(methodit.hasNext()) {
288 /* Classify parameters */
289 MethodDescriptor md=(MethodDescriptor)methodit.next();
290 FlatMethod fm=state.getMethodFlat(md);
291 if (!md.getModifiers().isNative())
292 generateFlatMethod(fm, null, outmethod);
298 private void outputStructs(PrintWriter outstructs) {
299 outstructs.println("#ifndef STRUCTDEFS_H");
300 outstructs.println("#define STRUCTDEFS_H");
301 outstructs.println("#include \"classdefs.h\"");
303 /* Output #defines that the runtime uses to determine type
304 * numbers for various objects it needs */
306 outstructs.println("#define STRINGARRAYTYPE "+
307 (state.getArrayNumber(
308 (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
310 outstructs.println("#define OBJECTARRAYTYPE "+
311 (state.getArrayNumber(
312 (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
315 outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
316 outstructs.println("#define CHARARRAYTYPE "+
317 (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
319 outstructs.println("#define BYTEARRAYTYPE "+
320 (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses()));
322 outstructs.println("#define BYTEARRAYARRAYTYPE "+
323 (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
325 outstructs.println("#define NUMCLASSES "+state.numClasses());
327 outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
328 outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
329 outstructs.println("#define TAGARRAYTYPE "+
330 (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses()));
334 private void outputClassDeclarations(PrintWriter outclassdefs) {
336 outclassdefs.println("#include <pthread.h>");
337 outclassdefs.println("struct "+arraytype+";");
338 /* Start by declaring all structs */
339 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
340 while(it.hasNext()) {
341 ClassDescriptor cn=(ClassDescriptor)it.next();
342 outclassdefs.println("struct "+cn.getSafeSymbol()+";");
344 outclassdefs.println("");
345 //Print out definition for array type
346 outclassdefs.println("struct "+arraytype+" {");
347 outclassdefs.println(" int type;");
349 outclassdefs.println(" pthread_t tid;");
350 outclassdefs.println(" void * lockentry;");
351 outclassdefs.println(" int lockcount;");
354 outclassdefs.println(" int flag;");
355 outclassdefs.println(" void * flagptr;");
357 outclassdefs.println(" int failedstatus;");
359 printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
361 outclassdefs.println(" int ___length___;");
362 outclassdefs.println("};\n");
363 outclassdefs.println("extern int classsize[];");
364 outclassdefs.println("extern int hasflags[];");
365 outclassdefs.println("extern int * pointerarray[];");
366 outclassdefs.println("extern int supertypes[];");
369 /** Prints out definitions for generic task structures */
371 private void outputTaskTypes(PrintWriter outtask) {
372 outtask.println("#ifndef _TASK_H");
373 outtask.println("#define _TASK_H");
374 outtask.println("struct parameterdescriptor {");
375 outtask.println("int type;");
376 outtask.println("int numberterms;");
377 outtask.println("int *intarray;");
378 outtask.println("void * queue;");
379 outtask.println("int numbertags;");
380 outtask.println("int *tagarray;");
381 outtask.println("};");
383 outtask.println("struct taskdescriptor {");
384 outtask.println("void * taskptr;");
385 outtask.println("int numParameters;");
386 outtask.println("int numTotal;");
387 outtask.println("struct parameterdescriptor **descriptorarray;");
388 outtask.println("char * name;");
389 outtask.println("};");
390 outtask.println("extern struct taskdescriptor * taskarray[];");
391 outtask.println("extern numtasks;");
392 outtask.println("#endif");
396 private void buildRepairStructs(PrintWriter outrepairstructs) {
397 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
398 while(classit.hasNext()) {
399 ClassDescriptor cn=(ClassDescriptor)classit.next();
400 outrepairstructs.println("structure "+cn.getSymbol()+" {");
401 outrepairstructs.println(" int __type__;");
403 outrepairstructs.println(" int __flag__;");
404 outrepairstructs.println(" int __flagptr__;");
406 printRepairStruct(cn, outrepairstructs);
407 outrepairstructs.println("}\n");
410 for(int i=0;i<state.numArrays();i++) {
411 TypeDescriptor tdarray=arraytable[i];
412 TypeDescriptor tdelement=tdarray.dereference();
413 outrepairstructs.println("structure "+arraytype+"_"+state.getArrayNumber(tdarray)+" {");
414 outrepairstructs.println(" int __type__;");
415 printRepairStruct(typeutil.getClass(TypeUtil.ObjectClass), outrepairstructs);
416 outrepairstructs.println(" int length;");
418 // Need to add support to repair tool for this
419 if (tdelement.isClass()||tdelement.isArray())
420 outrepairstructs.println(" "+tdelement.getRepairSymbol()+" * elem[this.length];");
422 outrepairstructs.println(" "+tdelement.getRepairSymbol()+" elem[this.length];");
424 outrepairstructs.println("}\n");
428 private void printRepairStruct(ClassDescriptor cn, PrintWriter output) {
429 ClassDescriptor sp=cn.getSuperDesc();
431 printRepairStruct(sp, output);
433 Vector fields=(Vector)fieldorder.get(cn);
435 for(int i=0;i<fields.size();i++) {
436 FieldDescriptor fd=(FieldDescriptor)fields.get(i);
437 if (fd.getType().isArray()) {
438 output.println(" "+arraytype+"_"+ state.getArrayNumber(fd.getType()) +" * "+fd.getSymbol()+";");
439 } else if (fd.getType().isClass())
440 output.println(" "+fd.getType().getRepairSymbol()+" * "+fd.getSymbol()+";");
441 else if (fd.getType().isFloat())
442 output.println(" int "+fd.getSymbol()+"; /* really float */");
444 output.println(" "+fd.getType().getRepairSymbol()+" "+fd.getSymbol()+";");
448 /** This method outputs TaskDescriptor information */
449 void generateTaskDescriptor(PrintWriter output, FlatMethod fm, TaskDescriptor task) {
450 for (int i=0;i<task.numParameters();i++) {
451 VarDescriptor param_var=task.getParameter(i);
452 TypeDescriptor param_type=task.getParamType(i);
453 FlagExpressionNode param_flag=task.getFlag(param_var);
454 TagExpressionList param_tag=task.getTag(param_var);
457 if (param_flag==null) {
458 output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
459 output.println("0x0, 0x0 };");
462 DNFFlag dflag=param_flag.getDNF();
463 dnfterms=dflag.size();
465 Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
466 output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
467 for(int j=0;j<dflag.size();j++) {
470 Vector term=dflag.get(j);
473 for(int k=0;k<term.size();k++) {
474 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
475 FlagDescriptor fd=dfa.getFlag();
476 boolean negated=dfa.getNegated();
477 int flagid=1<<((Integer)flags.get(fd)).intValue();
482 output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
484 output.println("};");
487 output.println("int parametertag_"+i+"_"+task.getSafeSymbol()+"[]={");
488 //BUG...added next line to fix, test with any task program
490 for(int j=0;j<param_tag.numTags();j++) {
493 /* for each tag we need */
494 /* which slot it is */
495 /* what type it is */
496 TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
497 TempDescriptor tmp=param_tag.getTemp(j);
498 int slot=fm.getTagInt(tmp);
499 output.println(slot+", "+state.getTagId(tvd.getTag()));
501 output.println("};");
503 output.println("struct parameterdescriptor parameter_"+i+"_"+task.getSafeSymbol()+"={");
504 output.println("/* type */"+param_type.getClassDesc().getId()+",");
505 output.println("/* number of DNF terms */"+dnfterms+",");
506 output.println("parameterdnf_"+i+"_"+task.getSafeSymbol()+",");
507 output.println("0,");
508 //BUG, added next line to fix and else statement...test
509 //with any task program
511 output.println("/* number of tags */"+param_tag.numTags()+",");
513 output.println("/* number of tags */ 0,");
514 output.println("parametertag_"+i+"_"+task.getSafeSymbol());
515 output.println("};");
519 output.println("struct parameterdescriptor * parameterdescriptors_"+task.getSafeSymbol()+"[] = {");
520 for (int i=0;i<task.numParameters();i++) {
523 output.print("¶meter_"+i+"_"+task.getSafeSymbol());
525 output.println("};");
527 output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={");
528 output.println("&"+task.getSafeSymbol()+",");
529 output.println("/* number of parameters */" +task.numParameters() + ",");
530 int numtotal=task.numParameters()+fm.numTags();
531 output.println("/* number total parameters */" +numtotal + ",");
532 output.println("parameterdescriptors_"+task.getSafeSymbol()+",");
533 output.println("\""+task.getSymbol()+"\"");
534 output.println("};");
538 /** The buildVirtualTables method outputs the virtual dispatch
539 * tables for methods. */
541 private void buildVirtualTables(PrintWriter outvirtual) {
542 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
543 while(classit.hasNext()) {
544 ClassDescriptor cd=(ClassDescriptor)classit.next();
545 if (virtualcalls.getMethodCount(cd)>maxcount)
546 maxcount=virtualcalls.getMethodCount(cd);
548 MethodDescriptor[][] virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount];
550 /* Fill in virtual table */
551 classit=state.getClassSymbolTable().getDescriptorsIterator();
552 while(classit.hasNext()) {
553 ClassDescriptor cd=(ClassDescriptor)classit.next();
554 fillinRow(cd, virtualtable, cd.getId());
557 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
558 Iterator arrayit=state.getArrayIterator();
559 while(arrayit.hasNext()) {
560 TypeDescriptor td=(TypeDescriptor)arrayit.next();
561 int id=state.getArrayNumber(td);
562 fillinRow(objectcd, virtualtable, id+state.numClasses());
565 outvirtual.print("void * virtualtable[]={");
566 boolean needcomma=false;
567 for(int i=0;i<state.numClasses()+state.numArrays();i++) {
568 for(int j=0;j<maxcount;j++) {
570 outvirtual.print(", ");
571 if (virtualtable[i][j]!=null) {
572 MethodDescriptor md=virtualtable[i][j];
573 outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
575 outvirtual.print("0");
579 outvirtual.println("");
581 outvirtual.println("};");
585 private void fillinRow(ClassDescriptor cd, MethodDescriptor[][] virtualtable, int rownum) {
586 /* Get inherited methods */
587 if (cd.getSuperDesc()!=null)
588 fillinRow(cd.getSuperDesc(), virtualtable, rownum);
589 /* Override them with our methods */
590 for(Iterator it=cd.getMethods();it.hasNext();) {
591 MethodDescriptor md=(MethodDescriptor)it.next();
592 if (md.isStatic()||md.getReturnType()==null)
594 int methodnum=virtualcalls.getMethodNumber(md);
595 virtualtable[rownum][methodnum]=md;
599 /** Generate array that contains the sizes of class objects. The
600 * object allocation functions in the runtime use this
603 private void generateSizeArray(PrintWriter outclassdefs) {
604 outclassdefs.print("int classsize[]={");
605 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
606 cdarray=new ClassDescriptor[state.numClasses()];
607 while(it.hasNext()) {
608 ClassDescriptor cd=(ClassDescriptor)it.next();
609 cdarray[cd.getId()]=cd;
611 boolean needcomma=false;
612 for(int i=0;i<state.numClasses();i++) {
614 outclassdefs.print(", ");
615 outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");
619 arraytable=new TypeDescriptor[state.numArrays()];
621 Iterator arrayit=state.getArrayIterator();
622 while(arrayit.hasNext()) {
623 TypeDescriptor td=(TypeDescriptor)arrayit.next();
624 int id=state.getArrayNumber(td);
628 for(int i=0;i<state.numArrays();i++) {
630 outclassdefs.print(", ");
631 TypeDescriptor tdelement=arraytable[i].dereference();
632 if (tdelement.isArray()||tdelement.isClass())
633 outclassdefs.print("sizeof(void *)");
635 outclassdefs.print("sizeof("+tdelement.getSafeSymbol()+")");
639 outclassdefs.println("};");
642 /** Constructs params and temp objects for each method or task.
643 * These objects tell the compiler which temps need to be
646 private void generateTempStructs(FlatMethod fm, LocalityBinding lb) {
647 MethodDescriptor md=fm.getMethod();
648 TaskDescriptor task=fm.getTask();
649 Set<TempDescriptor> saveset=state.DSM?locality.getTempSet(lb):null;
650 ParamsObject objectparams=md!=null?new ParamsObject(md,tag++):new ParamsObject(task, tag++);
653 paramstable.put(md, objectparams);
655 paramstable.put(task, objectparams);
657 for(int i=0;i<fm.numParameters();i++) {
658 TempDescriptor temp=fm.getParameter(i);
659 TypeDescriptor type=temp.getType();
660 if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
661 objectparams.addPtr(temp);
663 objectparams.addPrim(temp);
664 if(state.DSM&&saveset.contains(temp)) {
665 backuptable.put(temp, temp.createNew());
669 for(int i=0;i<fm.numTags();i++) {
670 TempDescriptor temp=fm.getTag(i);
671 if (GENERATEPRECISEGC)
672 objectparams.addPtr(temp);
674 objectparams.addPrim(temp);
677 TempObject objecttemps=md!=null?new TempObject(objectparams,md,tag++):new TempObject(objectparams, task, tag++);
679 tempstable.put(md, objecttemps);
681 tempstable.put(task, objecttemps);
683 for(Iterator nodeit=fm.getNodeSet().iterator();nodeit.hasNext();) {
684 FlatNode fn=(FlatNode)nodeit.next();
685 TempDescriptor[] writes=fn.writesTemps();
686 for(int i=0;i<writes.length;i++) {
687 TempDescriptor temp=writes[i];
688 TypeDescriptor type=temp.getType();
689 if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
690 objecttemps.addPtr(temp);
692 objecttemps.addPrim(temp);
693 if(state.DSM&&saveset.contains(temp)&&
694 !backuptable.containsKey(temp))
695 backuptable.put(temp, temp.createNew());
699 /* Create backup temps */
701 for(Iterator<TempDescriptor> tmpit=backuptable.values().iterator();tmpit.hasNext();) {
702 TempDescriptor tmp=tmpit.next();
703 TypeDescriptor type=tmp.getType();
704 if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
705 objecttemps.addPtr(tmp);
707 objecttemps.addPrim(tmp);
711 /** This method outputs the following information about classes
713 * (1) For classes, what are the locations of pointers.
714 * (2) For arrays, does the array contain pointers or primitives.
715 * (3) For classes, does the class contain flags.
718 private void generateLayoutStructs(PrintWriter output) {
719 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
720 while(it.hasNext()) {
721 ClassDescriptor cn=(ClassDescriptor)it.next();
722 output.println("int "+cn.getSafeSymbol()+"_pointers[]={");
723 Iterator allit=cn.getFieldTable().getAllDescriptorsIterator();
725 while(allit.hasNext()) {
726 FieldDescriptor fd=(FieldDescriptor)allit.next();
727 TypeDescriptor type=fd.getType();
728 if (type.isPtr()||type.isArray())
732 allit=cn.getFieldTable().getAllDescriptorsIterator();
733 while(allit.hasNext()) {
734 FieldDescriptor fd=(FieldDescriptor)allit.next();
735 TypeDescriptor type=fd.getType();
736 if (type.isPtr()||type.isArray()) {
738 output.print("((int)&(((struct "+cn.getSafeSymbol() +" *)0)->"+fd.getSafeSymbol()+"))");
741 output.println("};");
743 output.println("int * pointerarray[]={");
744 boolean needcomma=false;
745 for(int i=0;i<state.numClasses();i++) {
746 ClassDescriptor cn=cdarray[i];
750 output.print(cn.getSafeSymbol()+"_pointers");
753 for(int i=0;i<state.numArrays();i++) {
755 output.println(", ");
756 TypeDescriptor tdelement=arraytable[i].dereference();
757 if (tdelement.isArray()||tdelement.isClass())
758 output.print("((int *)1)");
764 output.println("};");
766 output.println("int hasflags[]={");
767 for(int i=0;i<state.numClasses();i++) {
768 ClassDescriptor cn=cdarray[i];
770 output.println(", ");
777 output.println("};");
780 /** Print out table to give us supertypes */
781 private void generateSuperTypeTable(PrintWriter output) {
782 output.println("int supertypes[]={");
783 boolean needcomma=false;
784 for(int i=0;i<state.numClasses();i++) {
785 ClassDescriptor cn=cdarray[i];
789 if (cn.getSuperDesc()!=null) {
790 ClassDescriptor cdsuper=cn.getSuperDesc();
791 output.print(cdsuper.getId());
795 output.println("};");
798 /** Force consistent field ordering between inherited classes. */
800 private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) {
801 ClassDescriptor sp=cn.getSuperDesc();
803 printClassStruct(sp, classdefout);
805 if (!fieldorder.containsKey(cn)) {
806 Vector fields=new Vector();
807 fieldorder.put(cn,fields);
808 Iterator fieldit=cn.getFields();
809 while(fieldit.hasNext()) {
810 FieldDescriptor fd=(FieldDescriptor)fieldit.next();
811 if (sp==null||!sp.getFieldTable().contains(fd.getSymbol()))
815 Vector fields=(Vector)fieldorder.get(cn);
817 for(int i=0;i<fields.size();i++) {
818 FieldDescriptor fd=(FieldDescriptor)fields.get(i);
819 if (fd.getType().isClass()||fd.getType().isArray())
820 classdefout.println(" struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
822 classdefout.println(" "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
827 /* Map flags to integers consistently between inherited
830 private void mapFlags(ClassDescriptor cn) {
831 ClassDescriptor sp=cn.getSuperDesc();
835 if (!flagorder.containsKey(cn)) {
836 Hashtable flags=new Hashtable();
837 flagorder.put(cn,flags);
839 Hashtable superflags=(Hashtable)flagorder.get(sp);
840 Iterator superflagit=superflags.keySet().iterator();
841 while(superflagit.hasNext()) {
842 FlagDescriptor fd=(FlagDescriptor)superflagit.next();
843 Integer number=(Integer)superflags.get(fd);
844 flags.put(fd, number);
845 if ((number.intValue()+1)>max)
846 max=number.intValue()+1;
850 Iterator flagit=cn.getFlags();
851 while(flagit.hasNext()) {
852 FlagDescriptor fd=(FlagDescriptor)flagit.next();
853 if (sp==null||!sp.getFlagTable().contains(fd.getSymbol()))
854 flags.put(fd, new Integer(max++));
860 /** This function outputs (1) structures that parameters are
861 * passed in (when PRECISE GC is enabled) and (2) function
862 * prototypes for the methods */
864 private void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) {
865 /* Output class structure */
866 classdefout.println("struct "+cn.getSafeSymbol()+" {");
867 classdefout.println(" int type;");
869 classdefout.println(" pthread_t tid;");
870 classdefout.println(" void * lockentry;");
871 classdefout.println(" int lockcount;");
875 classdefout.println(" int flag;");
876 classdefout.println(" void * flagptr;");
877 if (state.OPTIONAL) classdefout.println(" int failedstatus;");
879 printClassStruct(cn, classdefout);
880 classdefout.println("};\n");
883 /* Cycle through LocalityBindings */
884 for(Iterator<LocalityBinding> lbit=locality.getClassBindings(cn).iterator();lbit.hasNext();) {
885 LocalityBinding lb=lbit.next();
886 MethodDescriptor md=lb.getMethod();
887 generateMethod(cn, md, lb, headersout, output);
890 /* Cycle through methods */
891 for(Iterator methodit=cn.getMethods();methodit.hasNext();) {
892 /* Classify parameters */
893 MethodDescriptor md=(MethodDescriptor)methodit.next();
894 generateMethod(cn, md, null, headersout, output);
899 private void generateMethod(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter headersout, PrintWriter output) {
900 FlatMethod fm=state.getMethodFlat(md);
901 generateTempStructs(fm, null);
903 ParamsObject objectparams=(ParamsObject) paramstable.get(md);
904 TempObject objecttemps=(TempObject) tempstable.get(md);
906 /* Output parameter structure */
907 if (GENERATEPRECISEGC) {
908 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
909 output.println(" int size;");
910 output.println(" void * next;");
911 for(int i=0;i<objectparams.numPointers();i++) {
912 TempDescriptor temp=objectparams.getPointer(i);
913 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
915 output.println("};\n");
918 /* Output temp structure */
919 if (GENERATEPRECISEGC) {
920 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
921 output.println(" int size;");
922 output.println(" void * next;");
923 for(int i=0;i<objecttemps.numPointers();i++) {
924 TempDescriptor temp=objecttemps.getPointer(i);
925 if (temp.getType().isNull())
926 output.println(" void * "+temp.getSafeSymbol()+";");
928 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
930 output.println("};\n");
933 /********* Output method declaration ***********/
935 /* First the return type */
936 if (md.getReturnType()!=null) {
937 if (md.getReturnType().isClass()||md.getReturnType().isArray())
938 headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
940 headersout.print(md.getReturnType().getSafeSymbol()+" ");
942 //catch the constructor case
943 headersout.print("void ");
945 /* Next the method name */
947 headersout.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
949 headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
951 boolean printcomma=false;
952 if (GENERATEPRECISEGC) {
953 headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
957 if (state.DSM&&lb.isAtomic()) {
959 headersout.print(", ");
960 headersout.print("transrecord_t * trans");
964 /* Output parameter list*/
965 for(int i=0;i<objectparams.numPrimitives();i++) {
966 TempDescriptor temp=objectparams.getPrimitive(i);
968 headersout.print(", ");
970 if (temp.getType().isClass()||temp.getType().isArray())
971 headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
973 headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
975 headersout.println(");\n");
979 /** This function outputs (1) structures that parameters are
980 * passed in (when PRECISE GC is enabled) and (2) function
981 * prototypes for the tasks */
983 private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
984 /* Cycle through tasks */
985 Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
987 while(taskit.hasNext()) {
988 /* Classify parameters */
989 TaskDescriptor task=(TaskDescriptor)taskit.next();
990 FlatMethod fm=state.getMethodFlat(task);
991 generateTempStructs(fm, null);
993 ParamsObject objectparams=(ParamsObject) paramstable.get(task);
994 TempObject objecttemps=(TempObject) tempstable.get(task);
996 /* Output parameter structure */
997 if (GENERATEPRECISEGC) {
998 output.println("struct "+task.getSafeSymbol()+"_params {");
1000 output.println(" int size;");
1001 output.println(" void * next;");
1002 for(int i=0;i<objectparams.numPointers();i++) {
1003 TempDescriptor temp=objectparams.getPointer(i);
1004 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1007 output.println("};\n");
1008 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
1009 maxtaskparams=objectparams.numPointers()+fm.numTags();
1013 /* Output temp structure */
1014 if (GENERATEPRECISEGC) {
1015 output.println("struct "+task.getSafeSymbol()+"_locals {");
1016 output.println(" int size;");
1017 output.println(" void * next;");
1018 for(int i=0;i<objecttemps.numPointers();i++) {
1019 TempDescriptor temp=objecttemps.getPointer(i);
1020 if (temp.getType().isNull())
1021 output.println(" void * "+temp.getSafeSymbol()+";");
1022 else if(temp.getType().isTag())
1023 output.println(" struct "+
1024 (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1026 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1028 output.println("};\n");
1031 /* Output task declaration */
1032 headersout.print("void " + task.getSafeSymbol()+"(");
1034 boolean printcomma=false;
1035 if (GENERATEPRECISEGC) {
1036 headersout.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1038 headersout.print("void * parameterarray[]");
1039 headersout.println(");\n");
1043 /** Generate code for FlatMethod fm. */
1045 private void generateFlatMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
1046 MethodDescriptor md=fm.getMethod();
1047 TaskDescriptor task=fm.getTask();
1049 ClassDescriptor cn=md!=null?md.getClassDesc():null;
1051 ParamsObject objectparams=(ParamsObject)paramstable.get(md!=null?md:task);
1052 generateHeader(fm, lb, md!=null?md:task,output);
1053 TempObject objecttemp=(TempObject) tempstable.get(md!=null?md:task);
1054 if (state.DSM&&lb.getHasAtomic()) {
1055 output.println("transrecord_t * trans;");
1058 if (GENERATEPRECISEGC) {
1060 output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1062 output.print(" struct "+task.getSafeSymbol()+"_locals "+localsprefix+"={");
1064 output.print(objecttemp.numPointers()+",");
1065 output.print(paramsprefix);
1066 for(int j=0;j<objecttemp.numPointers();j++)
1067 output.print(", NULL");
1068 output.println("};");
1071 for(int i=0;i<objecttemp.numPrimitives();i++) {
1072 TempDescriptor td=objecttemp.getPrimitive(i);
1073 TypeDescriptor type=td.getType();
1075 output.println(" void * "+td.getSafeSymbol()+";");
1076 else if (type.isClass()||type.isArray())
1077 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
1079 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
1082 /* Assign labels to FlatNode's if necessary.*/
1084 Hashtable<FlatNode, Integer> nodetolabel=assignLabels(fm);
1086 /* Check to see if we need to do a GC if this is a
1087 * multi-threaded program...*/
1089 if (state.THREAD&&GENERATEPRECISEGC) {
1090 output.println("checkcollect(&"+localsprefix+");");
1093 /* Do the actual code generation */
1094 FlatNode current_node=null;
1095 HashSet tovisit=new HashSet();
1096 HashSet visited=new HashSet();
1097 tovisit.add(fm.getNext(0));
1098 while(current_node!=null||!tovisit.isEmpty()) {
1099 if (current_node==null) {
1100 current_node=(FlatNode)tovisit.iterator().next();
1101 tovisit.remove(current_node);
1103 visited.add(current_node);
1104 if (nodetolabel.containsKey(current_node))
1105 output.println("L"+nodetolabel.get(current_node)+":");
1106 if (state.INSTRUCTIONFAILURE) {
1108 output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
1111 output.println("if ((--instructioncount)==0) injectinstructionfailure();");
1113 if (current_node.numNext()==0) {
1115 generateFlatNode(fm, lb, current_node, output);
1116 if (current_node.kind()!=FKind.FlatReturnNode) {
1117 output.println(" return;");
1120 } else if(current_node.numNext()==1) {
1122 generateFlatNode(fm, lb, current_node, output);
1123 FlatNode nextnode=current_node.getNext(0);
1124 if (visited.contains(nextnode)) {
1125 output.println("goto L"+nodetolabel.get(nextnode)+";");
1128 current_node=nextnode;
1129 } else if (current_node.numNext()==2) {
1132 generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
1133 if (!visited.contains(current_node.getNext(1)))
1134 tovisit.add(current_node.getNext(1));
1135 if (visited.contains(current_node.getNext(0))) {
1136 output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
1139 current_node=current_node.getNext(0);
1140 } else throw new Error();
1143 output.println("}\n\n");
1146 /** This method assigns labels to FlatNodes */
1148 private Hashtable<FlatNode, Integer> assignLabels(FlatMethod fm) {
1149 HashSet tovisit=new HashSet();
1150 HashSet visited=new HashSet();
1152 Hashtable<FlatNode, Integer> nodetolabel=new Hashtable<FlatNode, Integer>();
1153 tovisit.add(fm.getNext(0));
1155 /*Assign labels first. A node needs a label if the previous
1156 * node has two exits or this node is a join point. */
1158 while(!tovisit.isEmpty()) {
1159 FlatNode fn=(FlatNode)tovisit.iterator().next();
1162 for(int i=0;i<fn.numNext();i++) {
1163 FlatNode nn=fn.getNext(i);
1165 //1) Edge >1 of node
1166 nodetolabel.put(nn,new Integer(labelindex++));
1168 if (!visited.contains(nn)&&!tovisit.contains(nn)) {
1172 nodetolabel.put(nn,new Integer(labelindex++));
1180 /** Generate text string that corresponds to the TempDescriptor td. */
1181 private String generateTemp(FlatMethod fm, TempDescriptor td) {
1182 MethodDescriptor md=fm.getMethod();
1183 TaskDescriptor task=fm.getTask();
1184 TempObject objecttemps=(TempObject) tempstable.get(md!=null?md:task);
1186 if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1187 return td.getSafeSymbol();
1190 if (objecttemps.isLocalPtr(td)) {
1191 return localsprefix+"."+td.getSafeSymbol();
1194 if (objecttemps.isParamPtr(td)) {
1195 return paramsprefix+"->"+td.getSafeSymbol();
1200 private void generateFlatNode(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output) {
1202 case FKind.FlatAtomicEnterNode:
1203 generateFlatAtomicEnterNode(fm, lb, (FlatAtomicEnterNode) fn, output);
1205 case FKind.FlatAtomicExitNode:
1206 generateFlatAtomicExitNode(fm, lb, (FlatAtomicExitNode) fn, output);
1208 case FKind.FlatTagDeclaration:
1209 generateFlatTagDeclaration(fm, (FlatTagDeclaration) fn,output);
1211 case FKind.FlatCall:
1212 generateFlatCall(fm, (FlatCall) fn,output);
1214 case FKind.FlatFieldNode:
1215 generateFlatFieldNode(fm, (FlatFieldNode) fn,output);
1217 case FKind.FlatElementNode:
1218 generateFlatElementNode(fm, (FlatElementNode) fn,output);
1220 case FKind.FlatSetElementNode:
1221 generateFlatSetElementNode(fm, (FlatSetElementNode) fn,output);
1223 case FKind.FlatSetFieldNode:
1224 generateFlatSetFieldNode(fm, (FlatSetFieldNode) fn,output);
1227 generateFlatNew(fm, (FlatNew) fn,output);
1229 case FKind.FlatOpNode:
1230 generateFlatOpNode(fm, (FlatOpNode) fn,output);
1232 case FKind.FlatCastNode:
1233 generateFlatCastNode(fm, (FlatCastNode) fn,output);
1235 case FKind.FlatLiteralNode:
1236 generateFlatLiteralNode(fm, (FlatLiteralNode) fn,output);
1238 case FKind.FlatReturnNode:
1239 generateFlatReturnNode(fm, (FlatReturnNode) fn,output);
1242 output.println("/* nop */");
1244 case FKind.FlatBackEdge:
1245 if (state.THREAD&&GENERATEPRECISEGC) {
1246 output.println("checkcollect(&"+localsprefix+");");
1248 output.println("/* nop */");
1250 case FKind.FlatCheckNode:
1251 generateFlatCheckNode(fm, (FlatCheckNode) fn, output);
1253 case FKind.FlatFlagActionNode:
1254 generateFlatFlagActionNode(fm, (FlatFlagActionNode) fn, output);
1261 public void generateFlatAtomicEnterNode(FlatMethod fm, LocalityBinding lb, FlatAtomicEnterNode faen, PrintWriter output) {
1262 /* Check to see if we need to generate code for this atomic */
1263 if (locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
1265 /* Backup the temps. */
1266 for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator();tmpit.hasNext();) {
1267 TempDescriptor tmp=tmpit.next();
1268 output.println(generateTemp(fm, backuptable.get(tmp))+"="+generateTemp(fm,tmp)+";");
1270 output.println("goto transstart"+faen.getIdentifier()+";");
1272 /******* Print code to abort transaction *******/
1273 output.println("transabort"+faen.getIdentifier()+":");
1276 for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator();tmpit.hasNext();) {
1277 TempDescriptor tmp=tmpit.next();
1278 output.println(generateTemp(fm, tmp)+"="+generateTemp(fm,backuptable.get(tmp))+";");
1281 /******* Tell the runtime to start the transaction *******/
1283 output.println("transstart"+faen.getIdentifier()+":");
1284 output.println("trans=transStart();");
1287 public void generateFlatAtomicExitNode(FlatMethod fm, LocalityBinding lb, FlatAtomicExitNode faen, PrintWriter output) {
1288 /* Check to see if we need to generate code for this atomic */
1289 if (locality.getAtomic(lb).get(faen).intValue()>0)
1294 private void generateFlatCheckNode(FlatMethod fm, FlatCheckNode fcn, PrintWriter output) {
1295 if (state.CONSCHECK) {
1296 String specname=fcn.getSpec();
1297 String varname="repairstate___";
1298 output.println("{");
1299 output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
1301 TempDescriptor[] temps=fcn.getTemps();
1302 String[] vars=fcn.getVars();
1303 for(int i=0;i<temps.length;i++) {
1304 output.println(varname+"->"+vars[i]+"=(int)"+generateTemp(fm, temps[i])+";");
1307 output.println("if (doanalysis"+specname+"("+varname+")) {");
1308 output.println("free"+specname+"_state("+varname+");");
1309 output.println("} else {");
1310 output.println("/* Bad invariant */");
1311 output.println("free"+specname+"_state("+varname+");");
1312 output.println("abort_task();");
1313 output.println("}");
1314 output.println("}");
1318 private void generateFlatCall(FlatMethod fm, FlatCall fc, PrintWriter output) {
1319 MethodDescriptor md=fc.getMethod();
1320 ParamsObject objectparams=(ParamsObject) paramstable.get(md);
1321 ClassDescriptor cn=md.getClassDesc();
1322 output.println("{");
1323 if (GENERATEPRECISEGC) {
1324 output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
1326 output.print(objectparams.numPointers());
1327 // output.print(objectparams.getUID());
1328 output.print(", & "+localsprefix);
1329 if (fc.getThis()!=null) {
1331 output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis()));
1333 for(int i=0;i<fc.numArgs();i++) {
1334 Descriptor var=md.getParameter(i);
1335 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
1336 if (objectparams.isParamPtr(paramtemp)) {
1337 TempDescriptor targ=fc.getArg(i);
1339 TypeDescriptor td=md.getParamType(i);
1341 output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol() +" *)"+generateTemp(fm, targ));
1343 output.print("(struct "+md.getParamType(i).getSafeSymbol() +" *)"+generateTemp(fm, targ));
1346 output.println("};");
1351 if (fc.getReturnTemp()!=null)
1352 output.print(generateTemp(fm,fc.getReturnTemp())+"=");
1354 /* Do we need to do virtual dispatch? */
1355 if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
1356 output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
1359 if (md.getReturnType().isClass()||md.getReturnType().isArray())
1360 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1362 output.print(md.getReturnType().getSafeSymbol()+" ");
1363 output.print("(*)(");
1365 boolean printcomma=false;
1366 if (GENERATEPRECISEGC) {
1367 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
1372 for(int i=0;i<objectparams.numPrimitives();i++) {
1373 TempDescriptor temp=objectparams.getPrimitive(i);
1377 if (temp.getType().isClass()||temp.getType().isArray())
1378 output.print("struct " + temp.getType().getSafeSymbol()+" * ");
1380 output.print(temp.getType().getSafeSymbol());
1383 output.print("))virtualtable["+generateTemp(fm,fc.getThis())+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
1387 boolean needcomma=false;
1388 if (GENERATEPRECISEGC) {
1389 output.print("&__parameterlist__");
1392 if (fc.getThis()!=null) {
1393 TypeDescriptor ptd=md.getThis().getType();
1394 if (ptd.isClass()&&!ptd.isArray())
1395 output.print("(struct "+ptd.getSafeSymbol()+" *) ");
1396 output.print(generateTemp(fm,fc.getThis()));
1400 for(int i=0;i<fc.numArgs();i++) {
1401 Descriptor var=md.getParameter(i);
1402 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
1403 if (objectparams.isParamPrim(paramtemp)) {
1404 TempDescriptor targ=fc.getArg(i);
1408 TypeDescriptor ptd=md.getParamType(i);
1409 if (ptd.isClass()&&!ptd.isArray())
1410 output.print("(struct "+ptd.getSafeSymbol()+" *) ");
1411 output.print(generateTemp(fm, targ));
1415 output.println(");");
1416 output.println(" }");
1419 private boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
1420 Set subclasses=typeutil.getSubClasses(thiscd);
1421 if (subclasses==null)
1423 for(Iterator classit=subclasses.iterator();classit.hasNext();) {
1424 ClassDescriptor cd=(ClassDescriptor)classit.next();
1425 Set possiblematches=cd.getMethodTable().getSet(md.getSymbol());
1426 for(Iterator matchit=possiblematches.iterator();matchit.hasNext();) {
1427 MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
1428 if (md.matches(matchmd))
1435 private void generateFlatFieldNode(FlatMethod fm, FlatFieldNode ffn, PrintWriter output) {
1436 output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
1439 private void generateFlatSetFieldNode(FlatMethod fm, FlatSetFieldNode fsfn, PrintWriter output) {
1440 if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
1441 throw new Error("Can't set array length");
1442 output.println(generateTemp(fm, fsfn.getDst())+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
1445 private void generateFlatElementNode(FlatMethod fm, FlatElementNode fen, PrintWriter output) {
1446 TypeDescriptor elementtype=fen.getSrc().getType().dereference();
1449 if (elementtype.isArray()||elementtype.isClass())
1452 type=elementtype.getSafeSymbol()+" ";
1454 if (fen.needsBoundsCheck()) {
1455 output.println("if ("+generateTemp(fm, fen.getIndex())+"< 0 || "+generateTemp(fm, fen.getIndex())+" >= "+generateTemp(fm,fen.getSrc()) + "->___length___)");
1456 output.println("failedboundschk();");
1459 output.println(generateTemp(fm, fen.getDst())+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc())+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex())+"];");
1462 private void generateFlatSetElementNode(FlatMethod fm, FlatSetElementNode fsen, PrintWriter output) {
1463 //TODO: need dynamic check to make sure this assignment is actually legal
1464 //Because Object[] could actually be something more specific...ie. Integer[]
1466 TypeDescriptor elementtype=fsen.getDst().getType().dereference();
1469 if (elementtype.isArray()||elementtype.isClass())
1472 type=elementtype.getSafeSymbol()+" ";
1474 if (fsen.needsBoundsCheck()) {
1475 output.println("if ("+generateTemp(fm, fsen.getIndex())+"< 0 || "+generateTemp(fm, fsen.getIndex())+" >= "+generateTemp(fm,fsen.getDst()) + "->___length___)");
1476 output.println("failedboundschk();");
1479 output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst())+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex())+"]="+generateTemp(fm,fsen.getSrc())+";");
1482 private void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
1483 if (fn.getType().isArray()) {
1484 int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
1485 if (GENERATEPRECISEGC) {
1486 output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize())+");");
1488 output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");");
1491 if (GENERATEPRECISEGC) {
1492 output.println(generateTemp(fm,fn.getDst())+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
1494 output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
1500 private void generateFlatTagDeclaration(FlatMethod fm, FlatTagDeclaration fn, PrintWriter output) {
1501 if (GENERATEPRECISEGC) {
1502 output.println(generateTemp(fm,fn.getDst())+"=allocate_tag(&"+localsprefix+", "+state.getTagId(fn.getType())+");");
1504 output.println(generateTemp(fm,fn.getDst())+"=allocate_tag("+state.getTagId(fn.getType())+");");
1508 private void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) {
1510 if (fon.getRight()!=null)
1511 output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";");
1512 else if (fon.getOp().getOp()==Operation.ASSIGN)
1513 output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
1514 else if (fon.getOp().getOp()==Operation.UNARYPLUS)
1515 output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
1516 else if (fon.getOp().getOp()==Operation.UNARYMINUS)
1517 output.println(generateTemp(fm, fon.getDest())+" = -"+generateTemp(fm, fon.getLeft())+";");
1518 else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
1519 output.println(generateTemp(fm, fon.getDest())+" = !"+generateTemp(fm, fon.getLeft())+";");
1521 output.println(generateTemp(fm, fon.getDest())+fon.getOp().toString()+generateTemp(fm, fon.getLeft())+";");
1524 private void generateFlatCastNode(FlatMethod fm, FlatCastNode fcn, PrintWriter output) {
1525 /* TODO: Do type check here */
1526 if (fcn.getType().isArray()) {
1528 } else if (fcn.getType().isClass())
1529 output.println(generateTemp(fm,fcn.getDst())+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc())+";");
1531 output.println(generateTemp(fm,fcn.getDst())+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc())+";");
1534 private void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) {
1535 if (fln.getValue()==null)
1536 output.println(generateTemp(fm, fln.getDst())+"=0;");
1537 else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
1538 if (GENERATEPRECISEGC) {
1539 output.println(generateTemp(fm, fln.getDst())+"=NewString(&"+localsprefix+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
1541 output.println(generateTemp(fm, fln.getDst())+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
1543 } else if (fln.getType().isBoolean()) {
1544 if (((Boolean)fln.getValue()).booleanValue())
1545 output.println(generateTemp(fm, fln.getDst())+"=1;");
1547 output.println(generateTemp(fm, fln.getDst())+"=0;");
1548 } else if (fln.getType().isChar()) {
1549 String st=FlatLiteralNode.escapeString(fln.getValue().toString());
1550 output.println(generateTemp(fm, fln.getDst())+"='"+st+"';");
1552 output.println(generateTemp(fm, fln.getDst())+"="+fln.getValue()+";");
1555 private void generateFlatReturnNode(FlatMethod fm, FlatReturnNode frn, PrintWriter output) {
1556 if (frn.getReturnTemp()!=null)
1557 output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
1559 output.println("return;");
1562 private void generateFlatCondBranch(FlatMethod fm, FlatCondBranch fcb, String label, PrintWriter output) {
1563 output.println("if (!"+generateTemp(fm, fcb.getTest())+") goto "+label+";");
1566 /** This method generates header information for the method or
1567 * task referenced by the Descriptor des. */
1569 private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) {
1571 ParamsObject objectparams=(ParamsObject)paramstable.get(des);
1572 MethodDescriptor md=null;
1573 TaskDescriptor task=null;
1574 if (des instanceof MethodDescriptor)
1575 md=(MethodDescriptor) des;
1577 task=(TaskDescriptor) des;
1579 ClassDescriptor cn=md!=null?md.getClassDesc():null;
1581 if (md!=null&&md.getReturnType()!=null) {
1582 if (md.getReturnType().isClass()||md.getReturnType().isArray())
1583 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1585 output.print(md.getReturnType().getSafeSymbol()+" ");
1587 //catch the constructor case
1588 output.print("void ");
1591 output.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1593 output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1595 output.print(task.getSafeSymbol()+"(");
1597 boolean printcomma=false;
1598 if (GENERATEPRECISEGC) {
1600 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1602 output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1606 if (state.DSM&&lb.isAtomic()) {
1609 output.print("transrecord_t * trans");
1615 for(int i=0;i<objectparams.numPrimitives();i++) {
1616 TempDescriptor temp=objectparams.getPrimitive(i);
1620 if (temp.getType().isClass()||temp.getType().isArray())
1621 output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1623 output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1625 output.println(") {");
1626 } else if (!GENERATEPRECISEGC) {
1627 /* Imprecise Task */
1628 output.println("void * parameterarray[]) {");
1629 /* Unpack variables */
1630 for(int i=0;i<objectparams.numPrimitives();i++) {
1631 TempDescriptor temp=objectparams.getPrimitive(i);
1632 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
1634 for(int i=0;i<fm.numTags();i++) {
1635 TempDescriptor temp=fm.getTag(i);
1636 int offset=i+objectparams.numPrimitives();
1637 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
1640 if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
1641 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
1642 } else output.println(") {");
1645 public void generateFlatFlagActionNode(FlatMethod fm, FlatFlagActionNode ffan, PrintWriter output) {
1646 output.println("/* FlatFlagActionNode */");
1649 /* Process tag changes */
1650 Relation tagsettable=new Relation();
1651 Relation tagcleartable=new Relation();
1653 Iterator tagsit=ffan.getTempTagPairs();
1654 while (tagsit.hasNext()) {
1655 TempTagPair ttp=(TempTagPair) tagsit.next();
1656 TempDescriptor objtmp=ttp.getTemp();
1657 TagDescriptor tag=ttp.getTag();
1658 TempDescriptor tagtmp=ttp.getTagTemp();
1659 boolean tagstatus=ffan.getTagChange(ttp);
1661 tagsettable.put(objtmp, tagtmp);
1663 tagcleartable.put(objtmp, tagtmp);
1668 Hashtable flagandtable=new Hashtable();
1669 Hashtable flagortable=new Hashtable();
1671 /* Process flag changes */
1672 Iterator flagsit=ffan.getTempFlagPairs();
1673 while(flagsit.hasNext()) {
1674 TempFlagPair tfp=(TempFlagPair)flagsit.next();
1675 TempDescriptor temp=tfp.getTemp();
1676 Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
1677 FlagDescriptor flag=tfp.getFlag();
1679 //Newly allocate objects that don't set any flags case
1680 if (flagortable.containsKey(temp)) {
1684 flagortable.put(temp,new Integer(mask));
1686 int flagid=1<<((Integer)flagtable.get(flag)).intValue();
1687 boolean flagstatus=ffan.getFlagChange(tfp);
1690 if (flagortable.containsKey(temp)) {
1691 mask=((Integer)flagortable.get(temp)).intValue();
1694 flagortable.put(temp,new Integer(mask));
1696 int mask=0xFFFFFFFF;
1697 if (flagandtable.containsKey(temp)) {
1698 mask=((Integer)flagandtable.get(temp)).intValue();
1700 mask&=(0xFFFFFFFF^flagid);
1701 flagandtable.put(temp,new Integer(mask));
1707 HashSet flagtagset=new HashSet();
1708 flagtagset.addAll(flagortable.keySet());
1709 flagtagset.addAll(flagandtable.keySet());
1710 flagtagset.addAll(tagsettable.keySet());
1711 flagtagset.addAll(tagcleartable.keySet());
1713 Iterator ftit=flagtagset.iterator();
1714 while(ftit.hasNext()) {
1715 TempDescriptor temp=(TempDescriptor)ftit.next();
1718 Set tagtmps=tagcleartable.get(temp);
1719 if (tagtmps!=null) {
1720 Iterator tagit=tagtmps.iterator();
1721 while(tagit.hasNext()) {
1722 TempDescriptor tagtmp=(TempDescriptor)tagit.next();
1723 if (GENERATEPRECISEGC)
1724 output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1726 output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1730 tagtmps=tagsettable.get(temp);
1731 if (tagtmps!=null) {
1732 Iterator tagit=tagtmps.iterator();
1733 while(tagit.hasNext()) {
1734 TempDescriptor tagtmp=(TempDescriptor)tagit.next();
1735 if (GENERATEPRECISEGC)
1736 output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1738 output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1743 int andmask=0xFFFFFFF;
1745 if (flagortable.containsKey(temp))
1746 ormask=((Integer)flagortable.get(temp)).intValue();
1747 if (flagandtable.containsKey(temp))
1748 andmask=((Integer)flagandtable.get(temp)).intValue();
1749 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
1750 output.println("flagorandinit("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
1752 output.println("flagorand("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
1757 void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> safeexecution, Hashtable optionaltaskdescriptors) {
1760 headers.println("#include \"task.h\"\n\n");
1763 //STRUCT PREDICATEMEMBER
1764 headers.println("struct predicatemember{");
1765 headers.println("int type;");
1766 headers.println("int numdnfterms;");
1767 headers.println("int * flags;");
1768 headers.println("int numtags;");
1769 headers.println("int * tags;\n};\n\n");
1771 //STRUCT EXITFLAGSTATE
1772 headers.println("struct exitflagstate{");
1773 headers.println("int numflags;");
1774 headers.println("int * flags;");
1776 headers.println("int numtags;");
1777 headers.println("int * tags;");
1779 headers.println("\n};\n\n");
1782 headers.println("struct exitstates{");
1783 headers.println("int numexitflagstates;");
1784 headers.println("struct exitflagstate * exitflagstatearray;\n};\n\n");
1786 //STRUCT OPTIONALTASKDESCRIPTOR
1787 headers.println("struct optionaltaskdescriptor{");
1788 headers.println("struct taskdescriptor * task;");
1789 headers.println("int numpredicatemembers;");
1790 headers.println("struct predicatemember * predicatememberarray;");
1791 headers.println("int numexitstates;");
1792 headers.println("struct existates * exitstatesarray;\n};\n\n");
1794 //STRUCT FSANALYSISWRAPPER
1795 headers.println("struct fsanalysiswrapper{");
1796 headers.println("int numflags;");
1797 headers.println("int * flags;");
1798 headers.println("int numtags;");
1799 headers.println("int * tags;");
1800 headers.println("int numoptionaltaskdescriptors;");
1801 headers.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray;\n};\n\n");
1803 //STRUCT CLASSANALYSISWRAPPER
1804 headers.println("struct classanalyiswrapper{");
1805 headers.println("int type;");
1806 headers.println("int numfsanalysiswrappers;");
1807 headers.println("struct fsanalysiswrapper * fsanalysiswrapperarray;\n};\n\n");
1809 Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
1810 while(taskit.hasNext()) {
1811 TaskDescriptor td=(TaskDescriptor)taskit.next();
1812 headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
1818 output.println("#include \"optionalstruct.h\"\n\n");
1819 HashSet processedcd = new HashSet();
1822 Enumeration e = safeexecution.keys();
1823 while (e.hasMoreElements()) {
1826 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
1827 Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp);//will be used several times
1829 //Generate the struct of optionals
1830 if((Hashtable)optionaltaskdescriptors.get(cdtemp)==null) System.out.println("Was in cd :"+cdtemp.getSymbol());
1831 Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
1832 if( !c_otd.isEmpty() ){
1833 for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
1834 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
1836 //generate the int arrays for the predicate
1837 Predicate predicate = otd.predicate;
1838 int predicateindex = 0;
1839 //iterate through the classes concerned by the predicate
1840 Collection c_vard = predicate.vardescriptors.values();
1841 for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext();){
1842 VarDescriptor vard = (VarDescriptor)vard_it.next();
1843 TypeDescriptor typed = vard.getType();
1845 //generate for flags
1846 HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
1847 output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1849 if (fen_hashset!=null){
1850 for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext();){
1851 FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
1853 //output.println("0x0, 0x0 };");
1858 DNFFlag dflag=fen.getDNF();
1859 numberterms+=dflag.size();
1861 Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
1863 for(int j=0;j<dflag.size();j++) {
1865 output.println(",");
1866 Vector term=dflag.get(j);
1869 for(int k=0;k<term.size();k++) {
1870 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
1871 FlagDescriptor fd=dfa.getFlag();
1872 boolean negated=dfa.getNegated();
1873 int flagid=1<<((Integer)flags.get(fd)).intValue();
1878 output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
1883 output.println("};\n");
1886 TagExpressionList tagel = predicate.tags.get(vard.getSymbol());
1887 output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1888 //BUG...added next line to fix, test with any task program
1891 for(int j=0;j<tagel.numTags();j++) {
1893 output.println(",");
1894 /* for each tag we need */
1895 /* which slot it is */
1896 /* what type it is */
1897 //TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(tagel.getName(j));
1898 TempDescriptor tmp=tagel.getTemp(j);
1900 output.println("/*tagid*/"+state.getTagId(tmp.getTag()));
1902 numtags = tagel.numTags();
1904 output.println("};");
1906 //store the result into a predicatemember struct
1907 output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
1908 output.println("/*type*/"+typed.getClassDesc().getId()+",");
1909 output.println("/* number of dnf terms */"+numberterms+",");
1910 output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
1911 output.println("/* number of tag */"+numtags+",");
1912 output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
1913 output.println("};\n");
1918 //generate an array that stores the entire predicate
1919 output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1920 for( int j = 0; j<predicateindex; j++){
1921 if( j != predicateindex-1)output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
1922 else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
1925 //generate the struct for possible exitfses
1926 HashSet<HashSet> exitfses = otd.exitfses;
1928 int nbexit = exitfses.size();
1931 //iterate through possible exits
1932 for(Iterator exitfseshash = exitfses.iterator(); exitfseshash.hasNext();){
1933 HashSet temp_hashset = (HashSet)exitfseshash.next();
1936 //iterate through possible FSes corresponding to the exit
1937 for(Iterator exfses = temp_hashset.iterator(); exfses.hasNext();){
1938 FlagState fs = (FlagState)exfses.next();
1940 output.println("int flags"+fsnumber+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1941 int counterflag = 0;
1942 for(Iterator flags = fs.getFlags(); flags.hasNext();){
1943 FlagDescriptor flagd = (FlagDescriptor)flags.next();
1944 int flagid=1<<((Integer)flaginfo.get(flagd)).intValue();
1945 if( flags.hasNext() ) output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/,");
1946 else output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/");
1949 output.println("};\n");
1950 //do the same for tags;
1951 //maybe not needed because no tag changes tolerated.
1953 //store the information into a struct
1954 output.println("struct exitflagstate exitflagstate"+fsnumber+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
1955 output.println("/*number of flags*/"+counterflag+",");
1956 output.println("flags"+fsnumber+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
1957 output.println("};\n");
1960 //store fses corresponding to this exit into an array
1961 output.println("struct exitflagstate * exitflagstatearray"+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+" [] = {");
1962 for( int j = 0; j<fsnumber; j++){
1963 if( j != fsnumber-1)output.println("&exitflagstate"+(j+1)+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"'");
1964 else output.println("&exitflagstate"+(j+1)+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
1967 //store that information in a struct
1968 output.println("struct exitstates exitstates"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
1969 output.println("/*number of exitflagstate*/"+fsnumber+",");
1970 output.println("exitflagstatearray"+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
1971 output.println("};\n");
1976 //store the information concerning all exits into an array
1977 output.println("struct exitstates * exitstatesarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1978 for( int j = 0; j<nbexit; j++){
1979 if( j != nbexit-1)output.println("&exitstates"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
1980 else output.println("&exitstates"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
1984 //generate optionaltaskdescriptor that actually includes exit fses, predicate and the task concerned
1985 output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
1986 output.println("task_"+otd.td.getSafeSymbol()+",");
1987 output.println("/*number of members */"+predicateindex+",");
1988 output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
1989 output.println("/*number of exit fses */"+nbexit+",");
1990 output.println("exitstatearray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
1991 output.println("};\n");
1994 else continue; // if there is no optionals, there is no need to build the rest of the struct
1996 //get all the possible falgstates reachable by an object
1997 Hashtable hashtbtemp = safeexecution.get(cdtemp);
1998 Enumeration fses = hashtbtemp.keys();
2000 while(fses.hasMoreElements()){
2001 FlagState fs = (FlagState)fses.nextElement();
2004 //get the set of OptionalTaskDescriptors corresponding
2005 HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
2006 //iterate through the OptionalTaskDescriptors and store the pointers to the optionals struct (see on top) into an array
2008 output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
2009 for(Iterator mos = availabletasks.iterator(); mos.hasNext();){
2010 OptionalTaskDescriptor mm = (OptionalTaskDescriptor)mos.next();
2011 if(!mos.hasNext()) output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
2013 else output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2016 //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose.
2018 output.println("int flags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
2019 for(Iterator flags = fs.getFlags(); flags.hasNext();){
2020 FlagDescriptor flagd = (FlagDescriptor)flags.next();
2021 int flagid=1<<((Integer)flaginfo.get(flagd)).intValue();
2022 if( flags.hasNext() ) output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/,");
2023 else output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/");
2026 //process tag information
2029 //TagExpressionList tagel = fs.getTags();
2030 //output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2031 //BUG...added next line to fix, test with any task program
2034 // for(int j=0;j<tagel.numTags();j++) {
2036 // output.println(",");
2037 // TempDescriptor tmp=tagel.getTemp(j);
2038 // output.println("/*tagid*/"+state.getTagId(tmp.getTag()));
2040 // numtags = tagel.numTags();
2042 //output.println("};");
2045 //Store the result in fsanalysiswrapper
2046 output.println("};\n");
2047 output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
2048 output.println("/* number of flags*/"+fs.numFlags()+",");
2049 output.println("flags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
2050 output.println("/* number of tags*/"+tagcounter+",");
2051 output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
2052 output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
2053 output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
2054 output.println("};\n");
2058 //Build the array of fsanalysiswrappers
2059 output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
2060 for(int i = 0; i<fscounter; i++){
2061 if(i==fscounter-1) output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+"};\n");
2063 else output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+",");
2066 //Build the classanalysiswrapper referring to the previous array
2067 output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
2068 output.println("/*type*/"+cdtemp.getId()+",");
2069 output.println("/* number of fsanalysiswrappers */"+fscounter+",");
2070 output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
2072 processedcd.add(cdtemp);
2075 //build an array containing every classes for which code has been build
2076 output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
2077 for(Iterator classit = processedcd.iterator(); classit.hasNext();){
2078 ClassDescriptor cdtemp=(ClassDescriptor)classit.next();
2079 if(!classit.hasNext()) output.println("&classanalysiswrapper_"+cdtemp.getSafeSymbol()+"};\n");
2080 else output.println("&classanalysiswrapper_"+cdtemp.getSafeSymbol()+",");
2082 output.println("int numclasses = "+processedcd.size()+";");