2 import IR.Tree.Modifiers;
3 import IR.Tree.FlagExpressionNode;
4 import IR.Tree.DNFFlag;
5 import IR.Tree.DNFFlagAtom;
6 import IR.Tree.TagExpressionList;
7 import IR.Tree.OffsetNode;
14 import Analysis.TaskStateAnalysis.FlagState;
15 import Analysis.TaskStateAnalysis.FlagComparator;
16 import Analysis.TaskStateAnalysis.OptionalTaskDescriptor;
17 import Analysis.TaskStateAnalysis.Predicate;
18 import Analysis.TaskStateAnalysis.SafetyAnalysis;
19 import Analysis.TaskStateAnalysis.TaskIndex;
20 import Analysis.CallGraph.CallGraph;
21 import Analysis.Loops.GlobalFieldType;
22 import Util.CodePrinter;
24 public class BuildCode {
27 Hashtable paramstable;
32 String localsprefix="___locals___";
33 String localsprefixaddr="&"+localsprefix;
34 String localsprefixderef=localsprefix+".";
35 String fcrevert="___fcrevert___";
36 String paramsprefix="___params___";
37 String nextobjstr="___nextobject___";
38 String localcopystr="___localcopy___";
39 public static boolean GENERATEPRECISEGC=false;
40 public static String PREFIX="";
41 public static String arraytype="ArrayObject";
42 public static int flagcount = 0;
45 protected int maxtaskparams=0;
46 protected int maxcount=0;
47 ClassDescriptor[] cdarray;
48 TypeDescriptor[] arraytable;
51 Hashtable<String, ClassDescriptor> printedfieldstbl;
53 public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) {
54 this(st, temptovar, typeutil, null);
57 public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa) {
60 callgraph=new CallGraph(state);
61 this.temptovar=temptovar;
62 paramstable=new Hashtable();
63 tempstable=new Hashtable();
64 fieldorder=new Hashtable();
65 flagorder=new Hashtable();
66 this.typeutil=typeutil;
67 virtualcalls=new Virtual(state, null);
68 printedfieldstbl = new Hashtable<String, ClassDescriptor>();
71 /** The buildCode method outputs C code for all the methods. The Flat
72 * versions of the methods must already be generated and stored in
73 * the State object. */
76 public void buildCode() {
77 /* Create output streams to write to */
78 PrintWriter outclassdefs=null;
79 PrintWriter outstructs=null;
80 PrintWriter outrepairstructs=null;
81 PrintWriter outmethodheader=null;
82 PrintWriter outmethod=null;
83 PrintWriter outvirtual=null;
84 PrintWriter outtask=null;
85 PrintWriter outtaskdefs=null;
86 PrintWriter outoptionalarrays=null;
87 PrintWriter optionalheaders=null;
88 PrintWriter outglobaldefs=null;
91 buildCodeSetup(); //EXTENSION POINT
92 outstructs=new CodePrinter(new FileOutputStream(PREFIX+"structdefs.h"), true);
93 outmethodheader=new CodePrinter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
94 outclassdefs=new CodePrinter(new FileOutputStream(PREFIX+"classdefs.h"), true);
96 // TODO add version for normal Java later
97 outglobaldefs=new CodePrinter(new FileOutputStream(PREFIX+"globaldefs.h"), true);
99 outmethod=new CodePrinter(new FileOutputStream(PREFIX+"methods.c"), true);
100 outvirtual=new CodePrinter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
102 outtask=new CodePrinter(new FileOutputStream(PREFIX+"task.h"), true);
103 outtaskdefs=new CodePrinter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
104 if (state.OPTIONAL) {
105 outoptionalarrays=new CodePrinter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
106 optionalheaders=new CodePrinter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
109 if (state.structfile!=null) {
110 outrepairstructs=new CodePrinter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
112 } catch (Exception e) {
117 /* Fix field safe symbols due to shadowing */
118 FieldShadow.handleFieldShadow(state);
120 /* Build the virtual dispatch tables */
121 buildVirtualTables(outvirtual);
123 /* Tag the methods that are invoked by static blocks */
124 tagMethodInvokedByStaticBlock();
126 /* Output includes */
127 outmethodheader.println("#ifndef METHODHEADERS_H");
128 outmethodheader.println("#define METHODHEADERS_H");
129 outmethodheader.println("#include \"structdefs.h\"");
131 if (state.EVENTMONITOR) {
132 outmethodheader.println("#include \"monitor.h\"");
135 additionalIncludesMethodsHeader(outmethodheader);
137 /* Output Structures */
138 outputStructs(outstructs);
140 // Output the C class declarations
141 // These could mutually reference each other
144 // TODO add version for normal Java later
145 outglobaldefs.println("#ifndef __GLOBALDEF_H_");
146 outglobaldefs.println("#define __GLOBALDEF_H_");
147 outglobaldefs.println("");
148 outglobaldefs.println("struct global_defs_t {");
151 outclassdefs.println("#ifndef __CLASSDEF_H_");
152 outclassdefs.println("#define __CLASSDEF_H_");
153 outputClassDeclarations(outclassdefs, outglobaldefs);
155 // Output function prototypes and structures for parameters
156 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
157 while(it.hasNext()) {
158 ClassDescriptor cn=(ClassDescriptor)it.next();
159 generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs);
161 outclassdefs.println("#endif");
162 outclassdefs.close();
164 // TODO add version for normal Java later
165 outglobaldefs.println("};");
166 outglobaldefs.println("");
167 outglobaldefs.println("extern struct global_defs_t * global_defs_p;");
168 outglobaldefs.println("#endif");
169 outglobaldefs.flush();
170 outglobaldefs.close();
174 /* Map flags to integers */
175 /* The runtime keeps track of flags using these integers */
176 it=state.getClassSymbolTable().getDescriptorsIterator();
177 while(it.hasNext()) {
178 ClassDescriptor cn=(ClassDescriptor)it.next();
182 generateTaskStructs(outstructs, outmethodheader);
184 /* Outputs generic task structures if this is a task
186 outputTaskTypes(outtask);
190 // an opportunity for subclasses to do extra
192 preCodeGenInitialization();
195 /* Build the actual methods */
196 outputMethods(outmethod);
199 // opportunity for subclasses to gen extra code
200 additionalCodeGen(outmethodheader,
206 /* Output code for tasks */
207 outputTaskCode(outtaskdefs, outmethod);
209 /* Record maximum number of task parameters */
210 outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
211 } else if (state.main!=null) {
212 /* Generate main method */
213 outputMainMethod(outmethod);
216 /* Generate information for task with optional parameters */
217 if (state.TASK&&state.OPTIONAL) {
218 generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
219 outoptionalarrays.close();
222 /* Output structure definitions for repair tool */
223 if (state.structfile!=null) {
224 buildRepairStructs(outrepairstructs);
225 outrepairstructs.close();
229 outmethodheader.println("#endif");
230 outmethodheader.close();
232 outstructs.println("#endif");
237 postCodeGenCleanUp();
242 /* This method goes though the call graph and tag those methods that are
243 * invoked inside static blocks
245 protected void tagMethodInvokedByStaticBlock() {
247 Iterator it_sclasses = this.state.getSClassSymbolTable().getDescriptorsIterator();
248 MethodDescriptor current_md=null;
249 HashSet tovisit=new HashSet();
250 HashSet visited=new HashSet();
252 while(it_sclasses.hasNext()) {
253 ClassDescriptor cd = (ClassDescriptor)it_sclasses.next();
254 MethodDescriptor md = (MethodDescriptor)cd.getMethodTable().get("staticblocks");
260 while(!tovisit.isEmpty()) {
261 current_md=(MethodDescriptor)tovisit.iterator().next();
262 tovisit.remove(current_md);
263 visited.add(current_md);
264 Iterator it_callee = this.callgraph.getCalleeSet(current_md).iterator();
265 while(it_callee.hasNext()) {
266 Descriptor d = (Descriptor)it_callee.next();
267 if(d instanceof MethodDescriptor) {
268 if(!visited.contains(d)) {
269 ((MethodDescriptor)d).setIsInvokedByStatic(true);
275 } // TODO for normal Java version
278 /* This code generates code for each static block and static field
280 protected void outputStaticBlocks(PrintWriter outmethod) {
281 // execute all the static blocks and all the static field initializations
285 /* This code generates code to create a Class object for each class for
288 protected void outputClassObjects(PrintWriter outmethod) {
289 // for each class, initialize its Class object
293 /* This code just generates the main C method for java programs.
294 * The main C method packs up the arguments into a string array
295 * and passes it to the java main method. */
297 protected void outputMainMethod(PrintWriter outmethod) {
298 outmethod.println("int main(int argc, const char *argv[]) {");
299 outmethod.println(" int i;");
301 outputStaticBlocks(outmethod);
302 outputClassObjects(outmethod);
305 additionalCodeAtTopOfMain(outmethod);
308 outmethod.println("initializethreads();");
311 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
312 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
314 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
316 outmethod.println(" for(i=1;i<argc;i++) {");
317 outmethod.println(" int length=strlen(argv[i]);");
319 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
320 outmethod.println(" struct ___String___ *newstring=NewString(NULL, argv[i], length);");
322 outmethod.println(" struct ___String___ *newstring=NewString(argv[i], length);");
324 outmethod.println(" ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
325 outmethod.println(" }");
327 MethodDescriptor md=typeutil.getMain();
328 ClassDescriptor cd=typeutil.getMainClass();
330 outmethod.println(" {");
331 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
332 outmethod.print(" struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
333 outmethod.println("1, NULL,"+"stringarray};");
334 outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
336 outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
338 outmethod.println(" }");
341 outmethod.println("pthread_mutex_lock(&gclistlock);");
342 outmethod.println("threadcount--;");
343 outmethod.println("pthread_cond_signal(&gccond);");
344 outmethod.println("pthread_mutex_unlock(&gclistlock);");
347 if (state.EVENTMONITOR) {
348 outmethod.println("dumpdata();");
352 outmethod.println("pthread_exit(NULL);");
355 additionalCodeAtBottomOfMain(outmethod);
357 outmethod.println("}");
360 /* This method outputs code for each task. */
362 protected void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod) {
363 /* Compile task based program */
364 outtaskdefs.println("#include \"task.h\"");
365 outtaskdefs.println("#include \"methodheaders.h\"");
366 Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
367 while(taskit.hasNext()) {
368 TaskDescriptor td=(TaskDescriptor)taskit.next();
369 FlatMethod fm=state.getMethodFlat(td);
370 generateFlatMethod(fm, outmethod);
371 generateTaskDescriptor(outtaskdefs, fm, td);
374 //Output task descriptors
375 taskit=state.getTaskSymbolTable().getDescriptorsIterator();
376 outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
378 while(taskit.hasNext()) {
379 TaskDescriptor td=(TaskDescriptor)taskit.next();
383 outtaskdefs.println(",");
384 outtaskdefs.print("&task_"+td.getSafeSymbol());
386 outtaskdefs.println("};");
388 outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
392 /* This method outputs most of the methods.c file. This includes
393 * some standard includes and then an array with the sizes of
394 * objets and array that stores supertype and then the code for
395 * the Java methods.. */
396 protected void outputMethods(PrintWriter outmethod) {
397 outmethod.println("#include \"methodheaders.h\"");
398 outmethod.println("#include \"virtualtable.h\"");
399 outmethod.println("#include \"runtime.h\"");
401 // always include: compiler directives will leave out
402 // instrumentation when option is not set
403 outmethod.println("#include \"coreprof/coreprof.h\"");
405 if (state.FASTCHECK) {
406 outmethod.println("#include \"localobjects.h\"");
408 if(state.MULTICORE) {
410 outmethod.println("#include \"task.h\"");
412 outmethod.println("#include \"multicoreruntime.h\"");
413 outmethod.println("#include \"runtime_arch.h\"");
415 if (state.THREAD||state.DSM||state.SINGLETM) {
416 outmethod.println("#include <thread.h>");
419 outmethod.println("#include \"thread.h\"");
421 if (state.main!=null) {
422 outmethod.println("#include <string.h>");
424 if (state.CONSCHECK) {
425 outmethod.println("#include \"checkers.h\"");
429 additionalIncludesMethodsImplementation(outmethod);
433 // TODO add version for normal Java later
434 outmethod.println("struct global_defs_t * global_defs_p;");
436 //Store the sizes of classes & array elements
437 generateSizeArray(outmethod);
439 //Store table of supertypes
440 generateSuperTypeTable(outmethod);
442 //Store the layout of classes
443 generateLayoutStructs(outmethod);
446 additionalCodeAtTopMethodsImplementation(outmethod);
448 generateMethods(outmethod);
451 protected void generateMethods(PrintWriter outmethod) {
452 /* Generate code for methods */
453 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
454 while(classit.hasNext()) {
455 ClassDescriptor cn=(ClassDescriptor)classit.next();
456 Iterator methodit=cn.getMethods();
457 while(methodit.hasNext()) {
458 /* Classify parameters */
459 MethodDescriptor md=(MethodDescriptor)methodit.next();
460 FlatMethod fm=state.getMethodFlat(md);
461 if (!md.getModifiers().isNative()) {
462 generateFlatMethod(fm, outmethod);
468 protected void outputStructs(PrintWriter outstructs) {
469 outstructs.println("#ifndef STRUCTDEFS_H");
470 outstructs.println("#define STRUCTDEFS_H");
471 outstructs.println("#include \"classdefs.h\"");
472 outstructs.println("#ifndef INTPTR");
473 outstructs.println("#ifdef BIT64");
474 outstructs.println("#define INTPTR long");
475 outstructs.println("#else");
476 outstructs.println("#define INTPTR int");
477 outstructs.println("#endif");
478 outstructs.println("#endif");
481 additionalIncludesStructsHeader(outstructs);
484 /* Output #defines that the runtime uses to determine type
485 * numbers for various objects it needs */
486 outstructs.println("#define MAXCOUNT "+maxcount);
488 outstructs.println("#define STRINGARRAYTYPE "+
489 (state.getArrayNumber(
490 (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
492 outstructs.println("#define OBJECTARRAYTYPE "+
493 (state.getArrayNumber(
494 (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
497 outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
498 outstructs.println("#define CHARARRAYTYPE "+
499 (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
501 outstructs.println("#define BYTEARRAYTYPE "+
502 (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses()));
504 outstructs.println("#define BYTEARRAYARRAYTYPE "+
505 (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
507 outstructs.println("#define NUMCLASSES "+state.numClasses());
508 int totalClassSize = state.numClasses() + state.numArrays();
509 outstructs.println("#define TOTALNUMCLASSANDARRAY "+ totalClassSize);
511 outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
512 outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
513 outstructs.println("#define TAGARRAYTYPE "+
514 (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses()));
518 protected void outputClassDeclarations(PrintWriter outclassdefs, PrintWriter outglobaldefs) {
519 if (state.THREAD||state.DSM||state.SINGLETM)
520 outclassdefs.println("#include <pthread.h>");
521 outclassdefs.println("#ifndef INTPTR");
522 outclassdefs.println("#ifdef BIT64");
523 outclassdefs.println("#define INTPTR long");
524 outclassdefs.println("#else");
525 outclassdefs.println("#define INTPTR int");
526 outclassdefs.println("#endif");
527 outclassdefs.println("#endif");
529 outclassdefs.println("#include \"optionalstruct.h\"");
530 outclassdefs.println("struct "+arraytype+";");
531 /* Start by declaring all structs */
532 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
533 while(it.hasNext()) {
534 ClassDescriptor cn=(ClassDescriptor)it.next();
535 outclassdefs.println("struct "+cn.getSafeSymbol()+";");
538 // TODO add version for normal Java later
539 if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) {
540 // this class has static fields/blocks, need to add a global flag to
541 // indicate if its static fields have been initialized and/or if its
542 // static blocks have been executed
543 outglobaldefs.println(" int "+cn.getSafeSymbol()+"static_block_exe_flag;");
546 // for each class, create a global object
547 outglobaldefs.println(" struct ___Object___ *"+cn.getSafeSymbol()+"classobj;");
550 outclassdefs.println("");
551 //Print out definition for array type
552 outclassdefs.println("struct "+arraytype+" {");
553 outclassdefs.println(" int type;");
556 additionalClassObjectFields(outclassdefs);
559 if (state.EVENTMONITOR) {
560 outclassdefs.println(" int objuid;");
563 outclassdefs.println(" pthread_t tid;");
564 outclassdefs.println(" void * lockentry;");
565 outclassdefs.println(" int lockcount;");
568 outclassdefs.println(" int mutex;");
569 outclassdefs.println(" int objlock;");
570 if(state.MULTICOREGC) {
571 outclassdefs.println(" int marked;");
575 outclassdefs.println(" int flag;");
576 if(!state.MULTICORE) {
577 outclassdefs.println(" void * flagptr;");
579 outclassdefs.println(" int version;");
580 outclassdefs.println(" int * lock;"); // lock entry for this obj
581 outclassdefs.println(" int mutex;");
582 outclassdefs.println(" int lockcount;");
583 if(state.MULTICOREGC) {
584 outclassdefs.println(" int marked;");
588 outclassdefs.println(" int numfses;");
589 outclassdefs.println(" int * fses;");
593 printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs, outglobaldefs);
594 printedfieldstbl.clear();
595 printExtraArrayFields(outclassdefs);
596 if (state.ARRAYPAD) {
597 outclassdefs.println(" int paddingforarray;");
600 outclassdefs.println(" int ___length___;");
601 outclassdefs.println("};\n");
604 // TODO add version for normal Java later
605 outclassdefs.println("");
606 //Print out definition for Class type
607 outclassdefs.println("struct Class {");
608 outclassdefs.println(" int type;");
611 additionalClassObjectFields(outclassdefs);
614 if (state.EVENTMONITOR) {
615 outclassdefs.println(" int objuid;");
618 outclassdefs.println(" pthread_t tid;");
619 outclassdefs.println(" void * lockentry;");
620 outclassdefs.println(" int lockcount;");
623 outclassdefs.println(" int mutex;");
624 outclassdefs.println(" int objlock;");
625 if(state.MULTICOREGC) {
626 outclassdefs.println(" int marked;");
630 outclassdefs.println(" int flag;");
631 if(!state.MULTICORE) {
632 outclassdefs.println(" void * flagptr;");
634 outclassdefs.println(" int version;");
635 outclassdefs.println(" int * lock;"); // lock entry for this obj
636 outclassdefs.println(" int mutex;");
637 outclassdefs.println(" int lockcount;");
638 if(state.MULTICOREGC) {
639 outclassdefs.println(" int marked;");
643 outclassdefs.println(" int numfses;");
644 outclassdefs.println(" int * fses;");
647 printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs, outglobaldefs);
648 printedfieldstbl.clear();
649 outclassdefs.println("};\n");
652 outclassdefs.println("");
653 outclassdefs.println("extern int classsize[];");
654 outclassdefs.println("extern int hasflags[];");
655 outclassdefs.println("extern unsigned INTPTR * pointerarray[];");
656 outclassdefs.println("extern int* supertypes[];");
657 outclassdefs.println("");
660 /** Prints out definitions for generic task structures */
662 protected void outputTaskTypes(PrintWriter outtask) {
663 outtask.println("#ifndef _TASK_H");
664 outtask.println("#define _TASK_H");
665 outtask.println("struct parameterdescriptor {");
666 outtask.println("int type;");
667 outtask.println("int numberterms;");
668 outtask.println("int *intarray;");
669 outtask.println("void * queue;");
670 outtask.println("int numbertags;");
671 outtask.println("int *tagarray;");
672 outtask.println("};");
674 outtask.println("struct taskdescriptor {");
675 outtask.println("void * taskptr;");
676 outtask.println("int numParameters;");
677 outtask.println(" int numTotal;");
678 outtask.println("struct parameterdescriptor **descriptorarray;");
679 outtask.println("char * name;");
680 outtask.println("};");
681 outtask.println("extern struct taskdescriptor * taskarray[];");
682 outtask.println("extern numtasks;");
683 outtask.println("#endif");
687 protected void buildRepairStructs(PrintWriter outrepairstructs) {
688 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
689 while(classit.hasNext()) {
690 ClassDescriptor cn=(ClassDescriptor)classit.next();
691 outrepairstructs.println("structure "+cn.getSymbol()+" {");
692 outrepairstructs.println(" int __type__;");
694 outrepairstructs.println(" int __flag__;");
695 if(!state.MULTICORE) {
696 outrepairstructs.println(" int __flagptr__;");
699 printRepairStruct(cn, outrepairstructs);
700 outrepairstructs.println("}\n");
703 for(int i=0; i<state.numArrays(); i++) {
704 TypeDescriptor tdarray=arraytable[i];
705 TypeDescriptor tdelement=tdarray.dereference();
706 outrepairstructs.println("structure "+arraytype+"_"+state.getArrayNumber(tdarray)+" {");
707 outrepairstructs.println(" int __type__;");
708 printRepairStruct(typeutil.getClass(TypeUtil.ObjectClass), outrepairstructs);
709 outrepairstructs.println(" int length;");
710 outrepairstructs.println("}\n");
714 protected void printRepairStruct(ClassDescriptor cn, PrintWriter output) {
715 ClassDescriptor sp=cn.getSuperDesc();
717 printRepairStruct(sp, output);
719 Vector fields=(Vector)fieldorder.get(cn);
721 for(int i=0; i<fields.size(); i++) {
722 FieldDescriptor fd=(FieldDescriptor)fields.get(i);
723 if (fd.getType().isArray()) {
724 output.println(" "+arraytype+"_"+ state.getArrayNumber(fd.getType()) +" * "+fd.getSymbol()+";");
725 } else if (fd.getType().isClass())
726 output.println(" "+fd.getType().getRepairSymbol()+" * "+fd.getSymbol()+";");
727 else if (fd.getType().isFloat())
728 output.println(" int "+fd.getSymbol()+"; /* really float */");
730 output.println(" "+fd.getType().getRepairSymbol()+" "+fd.getSymbol()+";");
734 /** This method outputs TaskDescriptor information */
735 protected void generateTaskDescriptor(PrintWriter output, FlatMethod fm, TaskDescriptor task) {
736 for (int i=0; i<task.numParameters(); i++) {
737 VarDescriptor param_var=task.getParameter(i);
738 TypeDescriptor param_type=task.getParamType(i);
739 FlagExpressionNode param_flag=task.getFlag(param_var);
740 TagExpressionList param_tag=task.getTag(param_var);
743 if (param_flag==null) {
744 output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
745 output.println("0x0, 0x0 };");
748 DNFFlag dflag=param_flag.getDNF();
749 dnfterms=dflag.size();
751 Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
752 output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
753 for(int j=0; j<dflag.size(); j++) {
756 Vector term=dflag.get(j);
759 for(int k=0; k<term.size(); k++) {
760 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
761 FlagDescriptor fd=dfa.getFlag();
762 boolean negated=dfa.getNegated();
763 int flagid=1<<((Integer)flags.get(fd)).intValue();
768 output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
770 output.println("};");
773 output.println("int parametertag_"+i+"_"+task.getSafeSymbol()+"[]={");
775 for(int j=0; j<param_tag.numTags(); j++) {
778 /* for each tag we need */
779 /* which slot it is */
780 /* what type it is */
781 TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
782 TempDescriptor tmp=param_tag.getTemp(j);
783 int slot=fm.getTagInt(tmp);
784 output.println(slot+", "+state.getTagId(tvd.getTag()));
786 output.println("};");
788 output.println("struct parameterdescriptor parameter_"+i+"_"+task.getSafeSymbol()+"={");
789 output.println("/* type */"+param_type.getClassDesc().getId()+",");
790 output.println("/* number of DNF terms */"+dnfterms+",");
791 output.println("parameterdnf_"+i+"_"+task.getSafeSymbol()+",");
792 output.println("0,");
794 output.println("/* number of tags */"+param_tag.numTags()+",");
796 output.println("/* number of tags */ 0,");
797 output.println("parametertag_"+i+"_"+task.getSafeSymbol());
798 output.println("};");
802 output.println("struct parameterdescriptor * parameterdescriptors_"+task.getSafeSymbol()+"[] = {");
803 for (int i=0; i<task.numParameters(); i++) {
806 output.print("¶meter_"+i+"_"+task.getSafeSymbol());
808 output.println("};");
810 output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={");
811 output.println("&"+task.getSafeSymbol()+",");
812 output.println("/* number of parameters */" +task.numParameters() + ",");
813 int numtotal=task.numParameters()+fm.numTags();
814 output.println("/* number total parameters */" +numtotal + ",");
815 output.println("parameterdescriptors_"+task.getSafeSymbol()+",");
816 output.println("\""+task.getSymbol()+"\"");
817 output.println("};");
821 /** The buildVirtualTables method outputs the virtual dispatch
822 * tables for methods. */
824 protected void buildVirtualTables(PrintWriter outvirtual) {
825 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
826 while(classit.hasNext()) {
827 ClassDescriptor cd=(ClassDescriptor)classit.next();
828 if (virtualcalls.getMethodCount(cd)>maxcount)
829 maxcount=virtualcalls.getMethodCount(cd);
831 MethodDescriptor[][] virtualtable=null;
832 virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount];
834 /* Fill in virtual table */
835 classit=state.getClassSymbolTable().getDescriptorsIterator();
836 while(classit.hasNext()) {
837 ClassDescriptor cd=(ClassDescriptor)classit.next();
838 fillinRow(cd, virtualtable, cd.getId());
841 ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
842 Iterator arrayit=state.getArrayIterator();
843 while(arrayit.hasNext()) {
844 TypeDescriptor td=(TypeDescriptor)arrayit.next();
845 int id=state.getArrayNumber(td);
846 fillinRow(objectcd, virtualtable, id+state.numClasses());
849 outvirtual.print("void * virtualtable[]={");
850 boolean needcomma=false;
851 for(int i=0; i<state.numClasses()+state.numArrays(); i++) {
852 for(int j=0; j<maxcount; j++) {
854 outvirtual.print(", ");
855 if (virtualtable[i][j]!=null) {
856 MethodDescriptor md=virtualtable[i][j];
857 outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
859 outvirtual.print("0");
863 outvirtual.println("");
865 outvirtual.println("};");
869 protected void fillinRow(ClassDescriptor cd, MethodDescriptor[][] virtualtable, int rownum) {
870 /* Get inherited methods */
871 if (cd.getSuperDesc()!=null)
872 fillinRow(cd.getSuperDesc(), virtualtable, rownum);
874 // TODO add version for normal Java later
875 Iterator it_sifs = cd.getSuperInterfaces();
876 while(it_sifs.hasNext()) {
877 ClassDescriptor superif = (ClassDescriptor)it_sifs.next();
878 fillinRow(superif, virtualtable, rownum);
881 /* Override them with our methods */
882 for(Iterator it=cd.getMethods(); it.hasNext(); ) {
883 MethodDescriptor md=(MethodDescriptor)it.next();
884 if (md.isStatic()||md.getReturnType()==null)
886 int methodnum=virtualcalls.getMethodNumber(md);
887 virtualtable[rownum][methodnum]=md;
891 /** Generate array that contains the sizes of class objects. The
892 * object allocation functions in the runtime use this
895 protected void generateSizeArray(PrintWriter outclassdefs) {
896 outclassdefs.print("extern struct prefetchCountStats * evalPrefetch;\n");
897 generateSizeArrayExtensions(outclassdefs);
899 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
900 cdarray=new ClassDescriptor[state.numClasses()];
903 while(it.hasNext()) {
904 ClassDescriptor cd=(ClassDescriptor)it.next();
905 cdarray[cd.getId()] = cd;
908 arraytable=new TypeDescriptor[state.numArrays()];
910 Iterator arrayit=state.getArrayIterator();
911 while(arrayit.hasNext()) {
912 TypeDescriptor td=(TypeDescriptor)arrayit.next();
913 int id=state.getArrayNumber(td);
917 /* Print out types */
918 outclassdefs.println("/* ");
919 for(int i=0; i<state.numClasses(); i++) {
920 ClassDescriptor cd=cdarray[i];
922 outclassdefs.println("NULL " + i);
924 outclassdefs.println(cd +" "+i);
928 for(int i=0; i<state.numArrays(); i++) {
929 TypeDescriptor arraytd=arraytable[i];
930 outclassdefs.println(arraytd.toPrettyString() +" "+(i+state.numClasses()));
933 outclassdefs.println("*/");
936 outclassdefs.print("int classsize[]={");
938 boolean needcomma=false;
939 for(int i=0; i<state.numClasses(); i++) {
941 outclassdefs.print(", ");
943 outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");
945 outclassdefs.print("0");
951 for(int i=0; i<state.numArrays(); i++) {
953 outclassdefs.print(", ");
954 TypeDescriptor tdelement=arraytable[i].dereference();
955 if (tdelement.isArray()||tdelement.isClass()||tdelement.isNull())
956 outclassdefs.print("sizeof(void *)");
958 outclassdefs.print("sizeof("+tdelement.getSafeSymbol()+")");
962 outclassdefs.println("};");
964 ClassDescriptor objectclass=typeutil.getClass(TypeUtil.ObjectClass);
966 outclassdefs.print("int typearray[]={");
967 for(int i=0; i<state.numClasses(); i++) {
968 ClassDescriptor cd=cdarray[i];
969 ClassDescriptor supercd=i>0 ? cd.getSuperDesc() : null;
971 outclassdefs.print(", ");
973 outclassdefs.print("-1");
975 outclassdefs.print(supercd.getId());
979 for(int i=0; i<state.numArrays(); i++) {
980 TypeDescriptor arraytd=arraytable[i];
981 ClassDescriptor arraycd=arraytd.getClassDesc();
984 outclassdefs.print(", ");
985 outclassdefs.print(objectclass.getId());
989 ClassDescriptor cd=arraycd.getSuperDesc();
992 TypeDescriptor supertd=new TypeDescriptor(cd);
993 supertd.setArrayCount(arraytd.getArrayCount());
994 type=state.getArrayNumber(supertd);
996 type+=state.numClasses();
999 cd=cd.getSuperDesc();
1002 outclassdefs.print(", ");
1003 outclassdefs.print(type);
1007 outclassdefs.println("};");
1012 outclassdefs.print("int typearray2[]={");
1013 for(int i=0; i<state.numArrays(); i++) {
1014 TypeDescriptor arraytd=arraytable[i];
1015 ClassDescriptor arraycd=arraytd.getClassDesc();
1016 if (arraycd==null) {
1018 outclassdefs.print(", ");
1019 outclassdefs.print("-1");
1023 ClassDescriptor cd=arraycd.getSuperDesc();
1024 int level=arraytd.getArrayCount()-1;
1026 for(; level>0; level--) {
1027 TypeDescriptor supertd=new TypeDescriptor(objectclass);
1028 supertd.setArrayCount(level);
1029 type=state.getArrayNumber(supertd);
1031 type+=state.numClasses();
1036 outclassdefs.print(", ");
1037 outclassdefs.print(type);
1041 outclassdefs.println("};");
1044 /** Constructs params and temp objects for each method or task.
1045 * These objects tell the compiler which temps need to be
1048 protected void generateTempStructs(FlatMethod fm) {
1049 MethodDescriptor md=fm.getMethod();
1050 TaskDescriptor task=fm.getTask();
1051 ParamsObject objectparams=md!=null ? new ParamsObject(md,tag++) : new ParamsObject(task, tag++);
1053 paramstable.put(md, objectparams);
1055 paramstable.put(task, objectparams);
1057 for(int i=0; i<fm.numParameters(); i++) {
1058 TempDescriptor temp=fm.getParameter(i);
1059 TypeDescriptor type=temp.getType();
1060 if (type.isPtr()&&((GENERATEPRECISEGC) || (this.state.MULTICOREGC)))
1061 objectparams.addPtr(temp);
1063 objectparams.addPrim(temp);
1066 for(int i=0; i<fm.numTags(); i++) {
1067 TempDescriptor temp=fm.getTag(i);
1068 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
1069 objectparams.addPtr(temp);
1071 objectparams.addPrim(temp);
1074 TempObject objecttemps=md!=null ? new TempObject(objectparams,md,tag++) : new TempObject(objectparams, task, tag++);
1076 tempstable.put(md, objecttemps);
1078 tempstable.put(task, objecttemps);
1080 for(Iterator nodeit=fm.getNodeSet().iterator(); nodeit.hasNext(); ) {
1081 FlatNode fn=(FlatNode)nodeit.next();
1082 TempDescriptor[] writes=fn.writesTemps();
1083 for(int i=0; i<writes.length; i++) {
1084 TempDescriptor temp=writes[i];
1085 TypeDescriptor type=temp.getType();
1086 if (type.isPtr()&&((GENERATEPRECISEGC) || (this.state.MULTICOREGC)))
1087 objecttemps.addPtr(temp);
1089 objecttemps.addPrim(temp);
1094 /** This method outputs the following information about classes
1096 * (1) For classes, what are the locations of pointers.
1097 * (2) For arrays, does the array contain pointers or primitives.
1098 * (3) For classes, does the class contain flags.
1101 protected void generateLayoutStructs(PrintWriter output) {
1102 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
1103 while(it.hasNext()) {
1104 ClassDescriptor cn=(ClassDescriptor)it.next();
1105 output.println("unsigned INTPTR "+cn.getSafeSymbol()+"_pointers[]={");
1106 Iterator allit=cn.getFieldTable().getAllDescriptorsIterator();
1108 while(allit.hasNext()) {
1109 FieldDescriptor fd=(FieldDescriptor)allit.next();
1110 TypeDescriptor type=fd.getType();
1114 output.print(count);
1115 allit=cn.getFieldTable().getAllDescriptorsIterator();
1116 while(allit.hasNext()) {
1117 FieldDescriptor fd=(FieldDescriptor)allit.next();
1118 if(fd.isStatic() || fd.isVolatile()) {
1121 TypeDescriptor type=fd.getType();
1123 output.println(",");
1124 output.print("((unsigned INTPTR)&(((struct "+cn.getSafeSymbol() +" *)0)->"+
1125 fd.getSafeSymbol()+"))");
1128 output.println("};");
1130 output.println("unsigned INTPTR * pointerarray[]={");
1131 boolean needcomma=false;
1132 for(int i=0; i<state.numClasses(); i++) {
1133 ClassDescriptor cn=cdarray[i];
1135 output.println(",");
1138 output.print(cn.getSafeSymbol()+"_pointers");
1140 output.print("NULL");
1144 for(int i=0; i<state.numArrays(); i++) {
1146 output.println(", ");
1147 TypeDescriptor tdelement=arraytable[i].dereference();
1148 if (tdelement.isArray()||tdelement.isClass())
1149 output.print("((unsigned INTPTR *)1)");
1155 output.println("};");
1157 output.println("int hasflags[]={");
1158 for(int i=0; i<state.numClasses(); i++) {
1159 ClassDescriptor cn=cdarray[i];
1161 output.println(", ");
1163 if ((cn != null) && (cn.hasFlags()))
1168 output.println("};");
1172 /** Print out table to give us supertypes */
1173 protected void generateSuperTypeTable(PrintWriter output) {
1174 for(int i=0; i<state.numClasses(); i++) {
1175 ClassDescriptor cn=cdarray[i];
1179 output.print("int supertypes" + cn.getSafeSymbol() + "[] = {");
1180 boolean ncomma = false;
1182 if((cn != null) && (cn.getSuperDesc() != null)) {
1185 Iterator it_sifs = cn != null? cn.getSuperInterfaces() : null;
1186 while(it_sifs != null && it_sifs.hasNext()) {
1192 if ((cn != null) && (cn.getSuperDesc()!=null)) {
1196 ClassDescriptor cdsuper=cn.getSuperDesc();
1197 output.print(cdsuper.getId());
1199 it_sifs = cn != null? cn.getSuperInterfaces() : null;
1200 while(it_sifs != null && it_sifs.hasNext()) {
1204 output.print(((ClassDescriptor)it_sifs.next()).getId());
1207 output.println("};");
1209 output.println("int* supertypes[]={");
1210 boolean needcomma=false;
1211 for(int i=0; i<state.numClasses(); i++) {
1212 ClassDescriptor cn=cdarray[i];
1214 output.println(",");
1217 output.print("supertypes" + cn.getSafeSymbol());
1222 output.println("};");
1225 /** Force consistent field ordering between inherited classes. */
1227 protected void printClassStruct(ClassDescriptor cn, PrintWriter classdefout, PrintWriter globaldefout) {
1229 ClassDescriptor sp=cn.getSuperDesc();
1231 printClassStruct(sp, classdefout, /*globaldefout*/ null);
1233 SymbolTable sitbl = cn.getSuperInterfaceTable();
1234 Iterator it_sifs = sitbl.getDescriptorsIterator();
1236 while(it_sifs.hasNext()) {
1237 ClassDescriptor si = (ClassDescriptor)it_sifs.next();
1238 printClassStruct(si, classdefout, /*globaldefout*/ null);
1242 if (!fieldorder.containsKey(cn)) {
1243 Vector fields=new Vector();
1244 fieldorder.put(cn,fields);
1246 Vector fieldvec=cn.getFieldVec();
1247 for(int i=0; i<fieldvec.size(); i++) {
1248 FieldDescriptor fd=(FieldDescriptor)fieldvec.get(i);
1250 if((sp != null) && sp.getFieldTable().contains(fd.getSymbol())) {
1253 it_sifs = sitbl.getDescriptorsIterator();
1254 boolean hasprinted = false;
1255 while(it_sifs.hasNext()) {
1256 ClassDescriptor si = (ClassDescriptor)it_sifs.next();
1257 if(si.getFieldTable().contains(fd.getSymbol())) {
1263 // this field has been defined in the super class
1269 if ((sp==null) || (!sp.getFieldTable().contains(fd.getSymbol())))
1274 //Vector fields=(Vector)fieldorder.get(cn);
1276 Vector fields = cn.getFieldVec();
1278 for(int i=0; i<fields.size(); i++) {
1279 FieldDescriptor fd=(FieldDescriptor)fields.get(i);
1280 String fstring = fd.getSafeSymbol();
1281 if(printedfieldstbl.containsKey(fstring)) {
1282 printedfieldstbl.put(fstring, cn);
1285 printedfieldstbl.put(fstring, cn);
1287 if (state.MGC && fd.getType().isClass()
1288 && fd.getType().getClassDesc().isEnum()) {
1289 classdefout.println(" int " + fd.getSafeSymbol() + ";");
1290 } else if (fd.getType().isClass()||fd.getType().isArray()) {
1291 if ((state.MGC) && (fd.isStatic())) {
1292 // TODO add version for normal Java later
1294 if(globaldefout != null) {
1295 if(fd.isVolatile()) {
1296 globaldefout.println(" volatile struct "+fd.getType().getSafeSymbol()+ " * "+fd.getSafeSymbol()+";");
1298 globaldefout.println(" struct "+fd.getType().getSafeSymbol()+ " * "+fd.getSafeSymbol()+";");
1301 } else if ((state.MGC) && (fd.isVolatile())) {
1302 // TODO add version for normal Java later
1304 if(globaldefout != null) {
1305 globaldefout.println(" volatile struct "+fd.getType().getSafeSymbol()+ " * "+fd.getSafeSymbol()+";");
1308 classdefout.println(" struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
1310 } else if ((state.MGC) && (fd.isStatic())) {
1311 // TODO add version for normal Java later
1313 if(globaldefout != null) {
1314 if(fd.isVolatile()) {
1315 globaldefout.println(" volatile "+fd.getType().getSafeSymbol()+ " "+fd.getSafeSymbol()+";");
1317 globaldefout.println(" "+fd.getType().getSafeSymbol()+ " "+fd.getSafeSymbol()+";");
1320 } else if ((state.MGC) && (fd.isVolatile())) {
1321 // TODO add version for normal Java later
1323 if(globaldefout != null) {
1324 globaldefout.println(" volatile "+fd.getType().getSafeSymbol()+ " "+fd.getSafeSymbol()+";");
1327 classdefout.println(" "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
1332 /* Map flags to integers consistently between inherited
1335 protected void mapFlags(ClassDescriptor cn) {
1336 ClassDescriptor sp=cn.getSuperDesc();
1340 if (!flagorder.containsKey(cn)) {
1341 Hashtable flags=new Hashtable();
1342 flagorder.put(cn,flags);
1344 Hashtable superflags=(Hashtable)flagorder.get(sp);
1345 Iterator superflagit=superflags.keySet().iterator();
1346 while(superflagit.hasNext()) {
1347 FlagDescriptor fd=(FlagDescriptor)superflagit.next();
1348 Integer number=(Integer)superflags.get(fd);
1349 flags.put(fd, number);
1350 if ((number.intValue()+1)>max)
1351 max=number.intValue()+1;
1355 Iterator flagit=cn.getFlags();
1356 while(flagit.hasNext()) {
1357 FlagDescriptor fd=(FlagDescriptor)flagit.next();
1358 if (sp==null||!sp.getFlagTable().contains(fd.getSymbol()))
1359 flags.put(fd, new Integer(max++));
1365 /** This function outputs (1) structures that parameters are
1366 * passed in (when PRECISE GC is enabled) and (2) function
1367 * prototypes for the methods */
1369 protected void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout, PrintWriter globaldefout) {
1370 /* Output class structure */
1371 classdefout.println("struct "+cn.getSafeSymbol()+" {");
1372 classdefout.println(" int type;");
1375 additionalClassObjectFields(classdefout);
1378 if (state.EVENTMONITOR) {
1379 classdefout.println(" int objuid;");
1382 classdefout.println(" pthread_t tid;");
1383 classdefout.println(" void * lockentry;");
1384 classdefout.println(" int lockcount;");
1387 classdefout.println(" int mutex;");
1388 classdefout.println(" int objlock;");
1389 if(state.MULTICOREGC) {
1390 classdefout.println(" int marked;");
1394 classdefout.println(" int flag;");
1395 if((!state.MULTICORE) || (cn.getSymbol().equals("TagDescriptor"))) {
1396 classdefout.println(" void * flagptr;");
1397 } else if (state.MULTICORE) {
1398 classdefout.println(" int version;");
1399 classdefout.println(" int * lock;"); // lock entry for this obj
1400 classdefout.println(" int mutex;");
1401 classdefout.println(" int lockcount;");
1402 if(state.MULTICOREGC) {
1403 classdefout.println(" int marked;");
1406 if (state.OPTIONAL) {
1407 classdefout.println(" int numfses;");
1408 classdefout.println(" int * fses;");
1411 printClassStruct(cn, classdefout, globaldefout);
1412 printedfieldstbl.clear(); // = new Hashtable<String, ClassDescriptor>();
1413 classdefout.println("};\n");
1414 generateCallStructsMethods(cn, output, headersout);
1418 protected void generateCallStructsMethods(ClassDescriptor cn, PrintWriter output, PrintWriter headersout) {
1419 for(Iterator methodit=cn.getMethods(); methodit.hasNext(); ) {
1420 MethodDescriptor md=(MethodDescriptor)methodit.next();
1421 generateMethod(cn, md, headersout, output);
1425 protected void generateMethodParam(ClassDescriptor cn, MethodDescriptor md, PrintWriter output) {
1426 /* Output parameter structure */
1427 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1428 ParamsObject objectparams=(ParamsObject) paramstable.get(md);
1429 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
1430 output.println(" int size;");
1431 output.println(" void * next;");
1432 for(int i=0; i<objectparams.numPointers(); i++) {
1433 TempDescriptor temp=objectparams.getPointer(i);
1434 if(state.MGC && temp.getType().isClass() && temp.getType().getClassDesc().isEnum()) {
1435 output.println(" int " + temp.getSafeSymbol() + ";");
1437 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1440 output.println("};\n");
1444 protected void generateMethod(ClassDescriptor cn, MethodDescriptor md, PrintWriter headersout, PrintWriter output) {
1445 FlatMethod fm=state.getMethodFlat(md);
1446 generateTempStructs(fm);
1448 ParamsObject objectparams=(ParamsObject) paramstable.get(md);
1449 TempObject objecttemps=(TempObject) tempstable.get(md);
1451 generateMethodParam(cn, md, output);
1453 /* Output temp structure */
1454 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1455 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
1456 output.println(" int size;");
1457 output.println(" void * next;");
1458 for(int i=0; i<objecttemps.numPointers(); i++) {
1459 TempDescriptor temp=objecttemps.getPointer(i);
1460 if (temp.getType().isNull())
1461 output.println(" void * "+temp.getSafeSymbol()+";");
1463 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1465 output.println("};\n");
1468 /********* Output method declaration ***********/
1469 headersout.println("#define D"+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+" 1");
1470 /* First the return type */
1471 if (md.getReturnType()!=null) {
1472 if(state.MGC && md.getReturnType().isClass() && md.getReturnType().getClassDesc().isEnum()) {
1473 headersout.println(" int ");
1474 } else if (md.getReturnType().isClass()||md.getReturnType().isArray())
1475 headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1477 headersout.print(md.getReturnType().getSafeSymbol()+" ");
1479 //catch the constructor case
1480 headersout.print("void ");
1482 /* Next the method name */
1483 headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1484 boolean printcomma=false;
1485 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1486 headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1490 /* Output parameter list*/
1491 for(int i=0; i<objectparams.numPrimitives(); i++) {
1492 TempDescriptor temp=objectparams.getPrimitive(i);
1494 headersout.print(", ");
1496 if(state.MGC && temp.getType().isClass() && temp.getType().getClassDesc().isEnum()) {
1497 headersout.print("int " + temp.getSafeSymbol());
1498 } else if (temp.getType().isClass()||temp.getType().isArray())
1499 headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1501 headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1503 headersout.println(");\n");
1507 /** This function outputs (1) structures that parameters are
1508 * passed in (when PRECISE GC is enabled) and (2) function
1509 * prototypes for the tasks */
1511 protected void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
1512 /* Cycle through tasks */
1513 Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
1515 while(taskit.hasNext()) {
1516 /* Classify parameters */
1517 TaskDescriptor task=(TaskDescriptor)taskit.next();
1518 FlatMethod fm=state.getMethodFlat(task);
1519 generateTempStructs(fm);
1521 ParamsObject objectparams=(ParamsObject) paramstable.get(task);
1522 TempObject objecttemps=(TempObject) tempstable.get(task);
1524 /* Output parameter structure */
1525 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1526 output.println("struct "+task.getSafeSymbol()+"_params {");
1527 output.println(" int size;");
1528 output.println(" void * next;");
1529 for(int i=0; i<objectparams.numPointers(); i++) {
1530 TempDescriptor temp=objectparams.getPointer(i);
1531 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1534 output.println("};\n");
1535 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
1536 maxtaskparams=objectparams.numPointers()+fm.numTags();
1540 /* Output temp structure */
1541 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1542 output.println("struct "+task.getSafeSymbol()+"_locals {");
1543 output.println(" int size;");
1544 output.println(" void * next;");
1545 for(int i=0; i<objecttemps.numPointers(); i++) {
1546 TempDescriptor temp=objecttemps.getPointer(i);
1547 if (temp.getType().isNull())
1548 output.println(" void * "+temp.getSafeSymbol()+";");
1549 else if(temp.getType().isTag())
1550 output.println(" struct "+
1551 (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1553 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1555 output.println("};\n");
1558 /* Output task declaration */
1559 headersout.print("void " + task.getSafeSymbol()+"(");
1561 boolean printcomma=false;
1562 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1563 headersout.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1565 headersout.print("void * parameterarray[]");
1566 headersout.println(");\n");
1570 protected void generateFlatMethod(FlatMethod fm, PrintWriter output) {
1571 if (State.PRINTFLAT)
1572 System.out.println(fm.printMethod());
1573 MethodDescriptor md=fm.getMethod();
1574 TaskDescriptor task=fm.getTask();
1575 ClassDescriptor cn=md!=null ? md.getClassDesc() : null;
1576 ParamsObject objectparams=(ParamsObject)paramstable.get(md!=null ? md : task);
1577 generateHeader(fm, md!=null ? md : task,output);
1578 TempObject objecttemp=(TempObject) tempstable.get(md!=null ? md : task);
1580 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1582 output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1584 output.print(" struct "+task.getSafeSymbol()+"_locals "+localsprefix+"={");
1585 output.print(objecttemp.numPointers()+",");
1586 output.print(paramsprefix);
1587 for(int j=0; j<objecttemp.numPointers(); j++)
1588 output.print(", NULL");
1589 output.println("};");
1592 for(int i=0; i<objecttemp.numPrimitives(); i++) {
1593 TempDescriptor td=objecttemp.getPrimitive(i);
1594 TypeDescriptor type=td.getType();
1595 if (type.isNull() && !type.isArray())
1596 output.println(" void * "+td.getSafeSymbol()+";");
1597 else if (state.MGC && type.isClass() && type.getClassDesc().isEnum()) {
1598 output.println(" int " + td.getSafeSymbol() + ";");
1599 } else if (type.isClass()||type.isArray())
1600 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
1602 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
1605 additionalCodeAtTopFlatMethodBody(output, fm);
1607 /* Check to see if we need to do a GC if this is a
1608 * multi-threaded program...*/
1610 if (((state.OOOJAVA||state.THREAD)&&GENERATEPRECISEGC)
1611 || this.state.MULTICOREGC) {
1612 //Don't bother if we aren't in recursive methods...The loops case will catch it
1613 if (callgraph.getAllMethods(md).contains(md)) {
1614 if (this.state.MULTICOREGC) {
1615 output.println("if(gcflag) gc("+localsprefixaddr+");");
1617 output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
1623 // TODO add version for normal Java later
1624 if(fm.getMethod().isStaticBlock()) {
1625 // a static block, check if it has been executed
1626 output.println(" if(global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag != 0) {");
1627 output.println(" return;");
1628 output.println(" }");
1633 generateCode(fm.getNext(0), fm, null, output);
1635 output.println("}\n\n");
1638 protected void generateCode(FlatNode first,
1640 Set<FlatNode> stopset,
1641 PrintWriter output) {
1643 /* Assign labels to FlatNode's if necessary.*/
1645 Hashtable<FlatNode, Integer> nodetolabel;
1647 nodetolabel=assignLabels(first, stopset);
1649 Set<FlatNode> storeset=null;
1650 HashSet<FlatNode> genset=null;
1651 HashSet<FlatNode> refset=null;
1652 Set<FlatNode> unionset=null;
1654 /* Do the actual code generation */
1655 FlatNode current_node=null;
1656 HashSet tovisit=new HashSet();
1657 HashSet visited=new HashSet();
1659 while(current_node!=null||!tovisit.isEmpty()) {
1660 if (current_node==null) {
1661 current_node=(FlatNode)tovisit.iterator().next();
1662 tovisit.remove(current_node);
1663 } else if (tovisit.contains(current_node)) {
1664 tovisit.remove(current_node);
1666 visited.add(current_node);
1667 if (nodetolabel.containsKey(current_node)) {
1668 output.println("L"+nodetolabel.get(current_node)+":");
1670 if (state.INSTRUCTIONFAILURE) {
1672 output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
1674 output.println("if ((--instructioncount)==0) injectinstructionfailure();");
1676 if (current_node.numNext()==0||stopset!=null&&stopset.contains(current_node)) {
1678 generateFlatNode(fm, current_node, output);
1680 if (state.OOOJAVA && stopset!=null) {
1681 assert first.getPrev(0) instanceof FlatSESEEnterNode;
1682 assert current_node instanceof FlatSESEExitNode;
1683 FlatSESEEnterNode fsen = (FlatSESEEnterNode) first.getPrev(0);
1684 FlatSESEExitNode fsxn = (FlatSESEExitNode) current_node;
1685 assert fsen.getFlatExit().equals(fsxn);
1686 assert fsxn.getFlatEnter().equals(fsen);
1688 if (current_node.kind()!=FKind.FlatReturnNode) {
1690 // TODO add version for normal Java later
1691 if((fm.getMethod() != null) && (fm.getMethod().isStaticBlock())) {
1692 // a static block, check if it has been executed
1693 output.println(" global_defs_p->" + fm.getMethod().getClassDesc().getSafeSymbol()+"static_block_exe_flag = 1;");
1697 output.println(" return;");
1700 } else if(current_node.numNext()==1) {
1702 if (state.OOOJAVA &&
1703 current_node.kind()==FKind.FlatSESEEnterNode) {
1704 FlatSESEEnterNode fsen = (FlatSESEEnterNode)current_node;
1705 generateFlatNode(fm, current_node, output);
1706 nextnode=fsen.getFlatExit().getNext(0);
1709 generateFlatNode(fm, current_node, output);
1710 nextnode=current_node.getNext(0);
1712 if (visited.contains(nextnode)) {
1713 output.println("goto L"+nodetolabel.get(nextnode)+";");
1716 current_node=nextnode;
1717 } else if (current_node.numNext()==2) {
1720 generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
1721 if (!visited.contains(current_node.getNext(1)))
1722 tovisit.add(current_node.getNext(1));
1723 if (visited.contains(current_node.getNext(0))) {
1724 output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
1727 current_node=current_node.getNext(0);
1728 } else throw new Error();
1732 protected Hashtable<FlatNode, Integer> assignLabels(FlatNode first, Set<FlatNode> lastset) {
1733 HashSet tovisit=new HashSet();
1734 HashSet visited=new HashSet();
1736 Hashtable<FlatNode, Integer> nodetolabel=new Hashtable<FlatNode, Integer>();
1739 /*Assign labels first. A node needs a label if the previous
1740 * node has two exits or this node is a join point. */
1742 while(!tovisit.isEmpty()) {
1743 FlatNode fn=(FlatNode)tovisit.iterator().next();
1748 if(lastset!=null&&lastset.contains(fn)) {
1749 // if last is not null and matches, don't go
1750 // any further for assigning labels
1754 for(int i=0; i<fn.numNext(); i++) {
1755 FlatNode nn=fn.getNext(i);
1758 //1) Edge >1 of node
1759 nodetolabel.put(nn,new Integer(labelindex++));
1761 if (!visited.contains(nn)&&!tovisit.contains(nn)) {
1765 nodetolabel.put(nn,new Integer(labelindex++));
1772 /** Generate text string that corresponds to the TempDescriptor td. */
1773 protected String generateTemp(FlatMethod fm, TempDescriptor td) {
1774 MethodDescriptor md=fm.getMethod();
1775 TaskDescriptor task=fm.getTask();
1776 TempObject objecttemps=(TempObject) tempstable.get(md!=null ? md : task);
1778 if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1779 return td.getSafeSymbol();
1782 if (objecttemps.isLocalPtr(td)) {
1783 return localsprefixderef+td.getSafeSymbol();
1786 if (objecttemps.isParamPtr(td)) {
1787 return paramsprefix+"->"+td.getSafeSymbol();
1795 protected void generateFlatNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
1796 additionalCodePreNode(fm, fn, output);
1800 case FKind.FlatAtomicEnterNode:
1801 generateFlatAtomicEnterNode(fm, (FlatAtomicEnterNode) fn, output);
1804 case FKind.FlatAtomicExitNode:
1805 generateFlatAtomicExitNode(fm, (FlatAtomicExitNode) fn, output);
1808 case FKind.FlatInstanceOfNode:
1809 generateFlatInstanceOfNode(fm, (FlatInstanceOfNode)fn, output);
1812 case FKind.FlatSESEEnterNode:
1813 generateFlatSESEEnterNode(fm, (FlatSESEEnterNode)fn, output);
1816 case FKind.FlatSESEExitNode:
1817 generateFlatSESEExitNode(fm, (FlatSESEExitNode)fn, output);
1820 case FKind.FlatWriteDynamicVarNode:
1821 generateFlatWriteDynamicVarNode(fm, (FlatWriteDynamicVarNode)fn, output);
1824 case FKind.FlatGlobalConvNode:
1825 generateFlatGlobalConvNode(fm, (FlatGlobalConvNode) fn, output);
1828 case FKind.FlatTagDeclaration:
1829 generateFlatTagDeclaration(fm, (FlatTagDeclaration) fn,output);
1832 case FKind.FlatCall:
1833 generateFlatCall(fm, (FlatCall) fn,output);
1836 case FKind.FlatFieldNode:
1837 generateFlatFieldNode(fm, (FlatFieldNode) fn,output);
1840 case FKind.FlatElementNode:
1841 generateFlatElementNode(fm, (FlatElementNode) fn,output);
1844 case FKind.FlatSetElementNode:
1845 generateFlatSetElementNode(fm, (FlatSetElementNode) fn,output);
1848 case FKind.FlatSetFieldNode:
1849 generateFlatSetFieldNode(fm, (FlatSetFieldNode) fn,output);
1853 generateFlatNew(fm, (FlatNew) fn,output);
1856 case FKind.FlatOpNode:
1857 generateFlatOpNode(fm, (FlatOpNode) fn,output);
1860 case FKind.FlatCastNode:
1861 generateFlatCastNode(fm, (FlatCastNode) fn,output);
1864 case FKind.FlatLiteralNode:
1865 generateFlatLiteralNode(fm, (FlatLiteralNode) fn,output);
1868 case FKind.FlatReturnNode:
1869 generateFlatReturnNode(fm, (FlatReturnNode) fn,output);
1873 output.println("/* nop */");
1876 case FKind.FlatGenReachNode:
1877 // this node is just for generating a reach graph
1878 // in disjointness analysis at a particular program point
1881 case FKind.FlatExit:
1882 output.println("/* exit */");
1885 case FKind.FlatBackEdge:
1886 generateFlatBackEdge(fm, (FlatBackEdge)fn, output);
1889 case FKind.FlatCheckNode:
1890 generateFlatCheckNode(fm, (FlatCheckNode) fn, output);
1893 case FKind.FlatFlagActionNode:
1894 generateFlatFlagActionNode(fm, (FlatFlagActionNode) fn, output);
1897 case FKind.FlatPrefetchNode:
1898 generateFlatPrefetchNode(fm, (FlatPrefetchNode) fn, output);
1901 case FKind.FlatOffsetNode:
1902 generateFlatOffsetNode(fm, (FlatOffsetNode)fn, output);
1909 additionalCodePostNode(fm, fn, output);
1912 public void generateFlatBackEdge(FlatMethod fm, FlatBackEdge fn, PrintWriter output) {
1913 if (((state.OOOJAVA||state.THREAD)&&GENERATEPRECISEGC)
1914 || (this.state.MULTICOREGC)) {
1915 if(this.state.MULTICOREGC) {
1916 output.println("if (gcflag) gc("+localsprefixaddr+");");
1918 output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
1921 output.println("/* nop */");
1924 public void generateFlatOffsetNode(FlatMethod fm, FlatOffsetNode fofn, PrintWriter output) {
1925 output.println("/* FlatOffsetNode */");
1926 FieldDescriptor fd=fofn.getField();
1927 if(!fd.isStatic() && !fd.isVolatile()) {
1928 output.println(generateTemp(fm, fofn.getDst())+ " = (short)(int) (&((struct "+fofn.getClassType().getSafeSymbol() +" *)0)->"+
1929 fd.getSafeSymbol()+");");
1931 output.println("/* offset */");
1934 public void generateFlatPrefetchNode(FlatMethod fm, FlatPrefetchNode fpn, PrintWriter output) {
1937 public void generateFlatGlobalConvNode(FlatMethod fm, FlatGlobalConvNode fgcn, PrintWriter output) {
1940 public void generateFlatInstanceOfNode(FlatMethod fm, FlatInstanceOfNode fion, PrintWriter output) {
1942 if (fion.getType().isArray()) {
1943 type=state.getArrayNumber(fion.getType())+state.numClasses();
1945 type=fion.getType().getClassDesc().getId();
1948 if (fion.getType().getSymbol().equals(TypeUtil.ObjectClass))
1949 output.println(generateTemp(fm, fion.getDst())+"=1;");
1951 output.println(generateTemp(fm, fion.getDst())+"=instanceof("+generateTemp(fm,fion.getSrc())+","+type+");");
1954 public void generateFlatAtomicEnterNode(FlatMethod fm, FlatAtomicEnterNode faen, PrintWriter output) {
1957 public void generateFlatAtomicExitNode(FlatMethod fm, FlatAtomicExitNode faen, PrintWriter output) {
1960 public void generateFlatSESEEnterNode(FlatMethod fm,
1961 FlatSESEEnterNode fsen,
1962 PrintWriter output) {
1963 // if OOOJAVA flag is off, okay that SESE nodes are in IR graph,
1964 // just skip over them and code generates exactly the same
1967 public void generateFlatSESEExitNode(FlatMethod fm,
1968 FlatSESEExitNode fsexn,
1969 PrintWriter output) {
1970 // if OOOJAVA flag is off, okay that SESE nodes are in IR graph,
1971 // just skip over them and code generates exactly the same
1974 public void generateFlatWriteDynamicVarNode(FlatMethod fm,
1975 FlatWriteDynamicVarNode fwdvn,
1976 PrintWriter output) {
1980 protected void generateFlatCheckNode(FlatMethod fm, FlatCheckNode fcn, PrintWriter output) {
1981 if (state.CONSCHECK) {
1982 String specname=fcn.getSpec();
1983 String varname="repairstate___";
1984 output.println("{");
1985 output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
1987 TempDescriptor[] temps=fcn.getTemps();
1988 String[] vars=fcn.getVars();
1989 for(int i=0; i<temps.length; i++) {
1990 output.println(varname+"->"+vars[i]+"=(unsigned int)"+generateTemp(fm, temps[i])+";");
1993 output.println("if (doanalysis"+specname+"("+varname+")) {");
1994 output.println("free"+specname+"_state("+varname+");");
1995 output.println("} else {");
1996 output.println("/* Bad invariant */");
1997 output.println("free"+specname+"_state("+varname+");");
1998 output.println("abort_task();");
1999 output.println("}");
2000 output.println("}");
2004 protected void generateFlatCall(FlatMethod fm, FlatCall fc, PrintWriter output) {
2005 MethodDescriptor md=fc.getMethod();
2006 ParamsObject objectparams=(ParamsObject)paramstable.get(md);
2007 ClassDescriptor cn=md.getClassDesc();
2009 // if the called method is a static block or a static method or a constructor
2010 // need to check if it can be invoked inside some static block
2012 // TODO add version for normal Java later
2013 if((md.isStatic() || md.isStaticBlock() || md.isConstructor()) &&
2014 ((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic()))) {
2015 if(!md.isInvokedByStatic()) {
2016 System.err.println("Error: a method that is invoked inside a static block is not tagged!");
2018 // is a static block or is invoked in some static block
2019 ClassDescriptor cd = fm.getMethod().getClassDesc();
2021 // the same class, do nothing
2022 // TODO may want to invoke static field initialization here
2024 if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) {
2025 // need to check if the class' static fields have been initialized and/or
2026 // its static blocks have been executed
2027 output.println("#ifdef MGC_STATIC_INIT_CHECK");
2028 output.println("if(global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {");
2029 if(cn.getNumStaticBlocks() != 0) {
2030 MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks");
2031 output.println(" "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
2033 output.println(" global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;");
2035 output.println("}");
2036 output.println("#endif // MGC_STATIC_INIT_CHECK");
2040 if((md.getSymbol().equals("MonitorEnter") || md.getSymbol().equals("MonitorExit")) && fc.getThis().getSymbol().equals("classobj")) {
2041 // call MonitorEnter/MonitorExit on a class obj
2042 output.println(" " + cn.getSafeSymbol()+md.getSafeSymbol()+"_"
2043 +md.getSafeMethodDescriptor() + "((struct ___Object___*)(global_defs_p->"
2044 + fc.getThis().getType().getClassDesc().getSafeSymbol() +"classobj));");
2049 output.println("{");
2050 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2051 output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
2052 output.print(objectparams.numPointers());
2053 output.print(", "+localsprefixaddr);
2054 if (md.getThis()!=null) {
2056 output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis()));
2058 if (fc.getThis()!=null&&md.getThis()==null) {
2059 System.out.println("WARNING!!!!!!!!!!!!");
2060 System.out.println("Source code calls static method "+md+" on an object in "+fm.getMethod()+"!");
2064 for(int i=0; i<fc.numArgs(); i++) {
2065 Descriptor var=md.getParameter(i);
2066 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
2067 if (objectparams.isParamPtr(paramtemp)) {
2068 TempDescriptor targ=fc.getArg(i);
2070 TypeDescriptor td=md.getParamType(i);
2072 output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol() +" *)"+generateTemp(fm, targ));
2074 output.print("(struct "+md.getParamType(i).getSafeSymbol() +" *)"+generateTemp(fm, targ));
2077 output.println("};");
2082 if (fc.getReturnTemp()!=null)
2083 output.print(generateTemp(fm,fc.getReturnTemp())+"=");
2085 /* Do we need to do virtual dispatch? */
2086 if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
2088 output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
2092 if (state.MGC && md.getReturnType().isClass() && md.getReturnType().getClassDesc().isEnum()) {
2093 output.print("int ");
2094 } else if (md.getReturnType().isClass()||md.getReturnType().isArray())
2095 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
2097 output.print(md.getReturnType().getSafeSymbol()+" ");
2098 output.print("(*)(");
2100 boolean printcomma=false;
2101 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2102 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
2106 for(int i=0; i<objectparams.numPrimitives(); i++) {
2107 TempDescriptor temp=objectparams.getPrimitive(i);
2111 if (state.MGC && temp.getType().isClass() && temp.getType().getClassDesc().isEnum()) {
2112 output.print("int ");
2113 } else if (temp.getType().isClass()||temp.getType().isArray())
2114 output.print("struct " + temp.getType().getSafeSymbol()+" * ");
2116 output.print(temp.getType().getSafeSymbol());
2120 output.print("))virtualtable["+generateTemp(fm,fc.getThis())+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
2124 boolean needcomma=false;
2125 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2126 output.print("&__parameterlist__");
2130 if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
2131 if (fc.getThis()!=null) {
2132 TypeDescriptor ptd=null;
2133 if(md.getThis() != null) {
2134 ptd = md.getThis().getType();
2136 ptd = fc.getThis().getType();
2140 if(state.MGC && ptd.isClass() && ptd.getClassDesc().isEnum()) {
2142 } else if (ptd.isClass()&&!ptd.isArray())
2143 output.print("(struct "+ptd.getSafeSymbol()+" *) ");
2144 output.print(generateTemp(fm,fc.getThis()));
2149 for(int i=0; i<fc.numArgs(); i++) {
2150 Descriptor var=md.getParameter(i);
2151 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
2152 if (objectparams.isParamPrim(paramtemp)) {
2153 TempDescriptor targ=fc.getArg(i);
2157 TypeDescriptor ptd=md.getParamType(i);
2158 if (state.MGC && ptd.isClass() && ptd.getClassDesc().isEnum()) {
2160 } else if (ptd.isClass()&&!ptd.isArray())
2161 output.print("(struct "+ptd.getSafeSymbol()+" *) ");
2162 output.print(generateTemp(fm, targ));
2166 output.println(");");
2167 output.println(" }");
2170 protected boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
2171 Set subclasses=typeutil.getSubClasses(thiscd);
2172 if (subclasses==null)
2174 for(Iterator classit=subclasses.iterator(); classit.hasNext(); ) {
2175 ClassDescriptor cd=(ClassDescriptor)classit.next();
2176 Set possiblematches=cd.getMethodTable().getSetFromSameScope(md.getSymbol());
2177 for(Iterator matchit=possiblematches.iterator(); matchit.hasNext(); ) {
2178 MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
2179 if (md.matches(matchmd))
2186 protected void generateFlatFieldNode(FlatMethod fm, FlatFieldNode ffn, PrintWriter output) {
2188 // TODO add version for normal Java later
2189 if(ffn.getField().isStatic() || ffn.getField().isVolatile()) {
2191 if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) {
2192 // is a static block or is invoked in some static block
2193 ClassDescriptor cd = fm.getMethod().getClassDesc();
2194 ClassDescriptor cn = ffn.getSrc().getType().getClassDesc();
2196 // the same class, do nothing
2197 // TODO may want to invoke static field initialization here
2199 if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) {
2200 // need to check if the class' static fields have been initialized and/or
2201 // its static blocks have been executed
2202 output.println("#ifdef MGC_STATIC_INIT_CHECK");
2203 output.println("if(global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {");
2204 if(cn.getNumStaticBlocks() != 0) {
2205 MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks");
2206 output.println(" "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
2208 output.println(" global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;");
2210 output.println("}");
2211 output.println("#endif // MGC_STATIC_INIT_CHECK");
2215 // redirect to the global_defs_p structure
2216 if((ffn.getField().isStatic()) || (ffn.getField().isVolatile()) || (ffn.getSrc().getType().isClassNameRef())) {
2217 // reference to the static field with Class name
2218 output.println(generateTemp(fm, ffn.getDst())+"=global_defs_p->"+ffn.getField().getSafeSymbol()+";");
2220 output.println(generateTemp(fm, ffn.getDst())+"=*"+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
2222 } else if (ffn.getField().isEnum()) {
2223 // an Enum value, directly replace the field access as int
2224 output.println(generateTemp(fm, ffn.getDst()) + "=" + ffn.getField().enumValue() + ";");
2226 output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
2229 output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
2234 protected void generateFlatSetFieldNode(FlatMethod fm, FlatSetFieldNode fsfn, PrintWriter output) {
2235 if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
2236 throw new Error("Can't set array length");
2237 if (state.FASTCHECK) {
2238 String dst=generateTemp(fm, fsfn.getDst());
2239 output.println("if(!"+dst+"->"+localcopystr+") {");
2240 /* Link object into list */
2241 if (GENERATEPRECISEGC || this.state.MULTICOREGC)
2242 output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
2244 output.println("COPY_OBJ("+dst+");");
2245 output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
2246 output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
2247 output.println("}");
2250 // TODO add version for normal Java later
2251 if(fsfn.getField().isStatic()) {
2253 if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) {
2254 // is a static block or is invoked in some static block
2255 ClassDescriptor cd = fm.getMethod().getClassDesc();
2256 ClassDescriptor cn = fsfn.getDst().getType().getClassDesc();
2258 // the same class, do nothing
2259 // TODO may want to invoke static field initialization here
2261 if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) {
2262 // need to check if the class' static fields have been initialized and/or
2263 // its static blocks have been executed
2264 output.println("#ifdef MGC_STATIC_INIT_CHECK");
2265 output.println("if(global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {");
2266 if(cn.getNumStaticFields() != 0) {
2267 // TODO add static field initialization here
2269 if(cn.getNumStaticBlocks() != 0) {
2270 MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks");
2271 output.println(" "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
2273 output.println(" global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;");
2275 output.println("}");
2276 output.println("#endif // MGC_STATIC_INIT_CHECK");
2280 // redirect to the global_defs_p structure
2281 if((fsfn.getDst().getType().isClassNameRef()) || (fsfn.getField().isStatic()) || (fsfn.getField().isVolatile())) {
2282 // reference to the static field with Class name
2283 output.println("global_defs_p->" +
2284 fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
2286 output.println("*"+generateTemp(fm, fsfn.getDst())+"->"+
2287 fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
2290 output.println(generateTemp(fm, fsfn.getDst())+"->"+
2291 fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
2294 output.println(generateTemp(fm, fsfn.getDst())+"->"+
2295 fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
2299 protected void generateFlatElementNode(FlatMethod fm, FlatElementNode fen, PrintWriter output) {
2300 TypeDescriptor elementtype=fen.getSrc().getType().dereference();
2303 if (state.MGC && elementtype.isClass() && elementtype.getClassDesc().isEnum()) {
2305 } else if (elementtype.isArray()||elementtype.isClass())
2308 type=elementtype.getSafeSymbol()+" ";
2310 if (this.state.ARRAYBOUNDARYCHECK && fen.needsBoundsCheck()) {
2311 output.println("if (unlikely(((unsigned int)"+generateTemp(fm, fen.getIndex())+") >= "+generateTemp(fm,fen.getSrc()) + "->___length___))");
2312 output.println("failedboundschk();");
2314 output.println(generateTemp(fm, fen.getDst())+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc())+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex())+"];");
2317 protected void generateFlatSetElementNode(FlatMethod fm, FlatSetElementNode fsen, PrintWriter output) {
2318 //TODO: need dynamic check to make sure this assignment is actually legal
2319 //Because Object[] could actually be something more specific...ie. Integer[]
2321 TypeDescriptor elementtype=fsen.getDst().getType().dereference();
2324 if (state.MGC && elementtype.isClass() && elementtype.getClassDesc().isEnum()) {
2326 } else if (elementtype.isArray()||elementtype.isClass() || (state.MGC && elementtype.isNull()))
2329 type=elementtype.getSafeSymbol()+" ";
2331 if (this.state.ARRAYBOUNDARYCHECK && fsen.needsBoundsCheck()) {
2332 output.println("if (unlikely(((unsigned int)"+generateTemp(fm, fsen.getIndex())+") >= "+generateTemp(fm,fsen.getDst()) + "->___length___))");
2333 output.println("failedboundschk();");
2335 if (state.FASTCHECK) {
2336 String dst=generateTemp(fm, fsen.getDst());
2337 output.println("if(!"+dst+"->"+localcopystr+") {");
2338 /* Link object into list */
2339 if (GENERATEPRECISEGC || this.state.MULTICOREGC)
2340 output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
2342 output.println("COPY_OBJ("+dst+");");
2343 output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
2344 output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
2345 output.println("}");
2347 output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst())+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex())+"]="+generateTemp(fm,fsen.getSrc())+";");
2351 protected void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
2352 if (fn.getType().isArray()) {
2353 int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
2354 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2355 output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize())+");");
2357 output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");");
2360 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2361 output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");");
2363 output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
2366 if (state.FASTCHECK) {
2367 String dst=generateTemp(fm,fn.getDst());
2368 output.println(dst+"->___localcopy___=(struct ___Object___*)1;");
2369 output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
2370 output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
2374 protected void generateFlatTagDeclaration(FlatMethod fm, FlatTagDeclaration fn, PrintWriter output) {
2375 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2376 output.println(generateTemp(fm,fn.getDst())+"=allocate_tag("+localsprefixaddr+", "+state.getTagId(fn.getType())+");");
2378 output.println(generateTemp(fm,fn.getDst())+"=allocate_tag("+state.getTagId(fn.getType())+");");
2382 protected void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) {
2383 if (fon.getRight()!=null) {
2384 if (fon.getOp().getOp()==Operation.URIGHTSHIFT) {
2385 if (fon.getLeft().getType().isLong())
2386 output.println(generateTemp(fm, fon.getDest())+" = ((unsigned long long)"+generateTemp(fm, fon.getLeft())+")>>"+generateTemp(fm,fon.getRight())+";");
2388 output.println(generateTemp(fm, fon.getDest())+" = ((unsigned int)"+generateTemp(fm, fon.getLeft())+")>>"+generateTemp(fm,fon.getRight())+";");
2391 output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";");
2392 } else if (fon.getOp().getOp()==Operation.ASSIGN)
2393 output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
2394 else if (fon.getOp().getOp()==Operation.UNARYPLUS)
2395 output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
2396 else if (fon.getOp().getOp()==Operation.UNARYMINUS)
2397 output.println(generateTemp(fm, fon.getDest())+" = -"+generateTemp(fm, fon.getLeft())+";");
2398 else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
2399 output.println(generateTemp(fm, fon.getDest())+" = !"+generateTemp(fm, fon.getLeft())+";");
2400 else if (fon.getOp().getOp()==Operation.COMP)
2401 output.println(generateTemp(fm, fon.getDest())+" = ~"+generateTemp(fm, fon.getLeft())+";");
2402 else if (fon.getOp().getOp()==Operation.ISAVAILABLE) {
2403 output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+"->fses==NULL;");
2405 output.println(generateTemp(fm, fon.getDest())+fon.getOp().toString()+generateTemp(fm, fon.getLeft())+";");
2408 protected void generateFlatCastNode(FlatMethod fm, FlatCastNode fcn, PrintWriter output) {
2409 /* TODO: Do type check here */
2410 if (fcn.getType().isArray()) {
2411 output.println(generateTemp(fm,fcn.getDst())+"=(struct ArrayObject *)"+generateTemp(fm,fcn.getSrc())+";");
2412 } else if (state.MGC && fcn.getType().isClass() && fcn.getType().getClassDesc().isEnum()) {
2413 output.println(generateTemp(fm,fcn.getDst())+"=(int)"+generateTemp(fm,fcn.getSrc())+";");
2414 } else if (fcn.getType().isClass())
2415 output.println(generateTemp(fm,fcn.getDst())+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc())+";");
2417 output.println(generateTemp(fm,fcn.getDst())+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc())+";");
2420 protected void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) {
2421 if (fln.getValue()==null)
2422 output.println(generateTemp(fm, fln.getDst())+"=0;");
2423 else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
2424 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2425 output.println(generateTemp(fm, fln.getDst())+"=NewString("+localsprefixaddr+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
2427 output.println(generateTemp(fm, fln.getDst())+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
2429 } else if (fln.getType().isBoolean()) {
2430 if (((Boolean)fln.getValue()).booleanValue())
2431 output.println(generateTemp(fm, fln.getDst())+"=1;");
2433 output.println(generateTemp(fm, fln.getDst())+"=0;");
2434 } else if (fln.getType().isChar()) {
2435 String st=FlatLiteralNode.escapeString(fln.getValue().toString());
2436 output.println(generateTemp(fm, fln.getDst())+"='"+st+"';");
2437 } else if (fln.getType().isLong()) {
2438 output.println(generateTemp(fm, fln.getDst())+"="+fln.getValue()+"LL;");
2440 output.println(generateTemp(fm, fln.getDst())+"="+fln.getValue()+";");
2443 protected void generateFlatReturnNode(FlatMethod fm, FlatReturnNode frn, PrintWriter output) {
2445 // TODO add version for normal Java later
2446 if((fm.getMethod() != null) && (fm.getMethod().isStaticBlock())) {
2447 // a static block, check if it has been executed
2448 output.println(" global_defs_p->" + fm.getMethod().getClassDesc().getSafeSymbol()+"static_block_exe_flag = 1;");
2452 if (frn.getReturnTemp()!=null) {
2453 if (frn.getReturnTemp().getType().isPtr())
2454 output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp())+";");
2456 output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
2458 output.println("return;");
2462 protected void generateFlatCondBranch(FlatMethod fm, FlatCondBranch fcb, String label, PrintWriter output) {
2463 output.println("if (!"+generateTemp(fm, fcb.getTest())+") goto "+label+";");
2466 /** This method generates header information for the method or
2467 * task referenced by the Descriptor des. */
2468 protected void generateHeader(FlatMethod fm, Descriptor des, PrintWriter output) {
2469 generateHeader(fm, des, output, false);
2472 protected void generateHeader(FlatMethod fm, Descriptor des, PrintWriter output, boolean addSESErecord) {
2474 ParamsObject objectparams=(ParamsObject)paramstable.get(des);
2475 MethodDescriptor md=null;
2476 TaskDescriptor task=null;
2477 if (des instanceof MethodDescriptor)
2478 md=(MethodDescriptor) des;
2480 task=(TaskDescriptor) des;
2482 ClassDescriptor cn=md!=null ? md.getClassDesc() : null;
2484 if (md!=null&&md.getReturnType()!=null) {
2485 if (state.MGC && md.getReturnType().isClass() && md.getReturnType().getClassDesc().isEnum()) {
2486 output.print("int ");
2487 } else if (md.getReturnType().isClass()||md.getReturnType().isArray())
2488 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
2490 output.print(md.getReturnType().getSafeSymbol()+" ");
2492 //catch the constructor case
2493 output.print("void ");
2495 output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
2497 output.print(task.getSafeSymbol()+"(");
2499 boolean printcomma=false;
2500 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2502 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
2504 output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
2510 for(int i=0; i<objectparams.numPrimitives(); i++) {
2511 TempDescriptor temp=objectparams.getPrimitive(i);
2515 if(state.MGC && temp.getType().isClass() && temp.getType().getClassDesc().isEnum()) {
2516 output.print("int " + temp.getSafeSymbol());
2517 } else if (temp.getType().isClass()||temp.getType().isArray())
2518 output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
2520 output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
2522 output.println(") {");
2523 } else if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
2524 /* Imprecise Task */
2525 output.println("void * parameterarray[]) {");
2526 /* Unpack variables */
2527 for(int i=0; i<objectparams.numPrimitives(); i++) {
2528 TempDescriptor temp=objectparams.getPrimitive(i);
2529 if(state.MGC && temp.getType().isClass() && temp.getType().getClassDesc().isEnum()) {
2530 output.print("int " + temp.getSafeSymbol() + "=parameterarray["+i+"];");
2532 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
2535 for(int i=0; i<fm.numTags(); i++) {
2536 TempDescriptor temp=fm.getTag(i);
2537 int offset=i+objectparams.numPrimitives();
2538 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
2541 if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
2542 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
2543 } else output.println(") {");
2546 public void generateFlatFlagActionNode(FlatMethod fm, FlatFlagActionNode ffan, PrintWriter output) {
2547 output.println("/* FlatFlagActionNode */");
2550 /* Process tag changes */
2551 Relation tagsettable=new Relation();
2552 Relation tagcleartable=new Relation();
2554 Iterator tagsit=ffan.getTempTagPairs();
2555 while (tagsit.hasNext()) {
2556 TempTagPair ttp=(TempTagPair) tagsit.next();
2557 TempDescriptor objtmp=ttp.getTemp();
2558 TagDescriptor tag=ttp.getTag();
2559 TempDescriptor tagtmp=ttp.getTagTemp();
2560 boolean tagstatus=ffan.getTagChange(ttp);
2562 tagsettable.put(objtmp, tagtmp);
2564 tagcleartable.put(objtmp, tagtmp);
2569 Hashtable flagandtable=new Hashtable();
2570 Hashtable flagortable=new Hashtable();
2572 /* Process flag changes */
2573 Iterator flagsit=ffan.getTempFlagPairs();
2574 while(flagsit.hasNext()) {
2575 TempFlagPair tfp=(TempFlagPair)flagsit.next();
2576 TempDescriptor temp=tfp.getTemp();
2577 Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
2578 FlagDescriptor flag=tfp.getFlag();
2580 //Newly allocate objects that don't set any flags case
2581 if (flagortable.containsKey(temp)) {
2585 flagortable.put(temp,new Integer(mask));
2587 int flagid=1<<((Integer)flagtable.get(flag)).intValue();
2588 boolean flagstatus=ffan.getFlagChange(tfp);
2591 if (flagortable.containsKey(temp)) {
2592 mask=((Integer)flagortable.get(temp)).intValue();
2595 flagortable.put(temp,new Integer(mask));
2597 int mask=0xFFFFFFFF;
2598 if (flagandtable.containsKey(temp)) {
2599 mask=((Integer)flagandtable.get(temp)).intValue();
2601 mask&=(0xFFFFFFFF^flagid);
2602 flagandtable.put(temp,new Integer(mask));
2608 HashSet flagtagset=new HashSet();
2609 flagtagset.addAll(flagortable.keySet());
2610 flagtagset.addAll(flagandtable.keySet());
2611 flagtagset.addAll(tagsettable.keySet());
2612 flagtagset.addAll(tagcleartable.keySet());
2614 Iterator ftit=flagtagset.iterator();
2615 while(ftit.hasNext()) {
2616 TempDescriptor temp=(TempDescriptor)ftit.next();
2619 Set tagtmps=tagcleartable.get(temp);
2620 if (tagtmps!=null) {
2621 Iterator tagit=tagtmps.iterator();
2622 while(tagit.hasNext()) {
2623 TempDescriptor tagtmp=(TempDescriptor)tagit.next();
2624 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
2625 output.println("tagclear("+localsprefixaddr+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
2627 output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
2631 tagtmps=tagsettable.get(temp);
2632 if (tagtmps!=null) {
2633 Iterator tagit=tagtmps.iterator();
2634 while(tagit.hasNext()) {
2635 TempDescriptor tagtmp=(TempDescriptor)tagit.next();
2636 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
2637 output.println("tagset("+localsprefixaddr+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
2639 output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
2644 int andmask=0xFFFFFFF;
2646 if (flagortable.containsKey(temp))
2647 ormask=((Integer)flagortable.get(temp)).intValue();
2648 if (flagandtable.containsKey(temp))
2649 andmask=((Integer)flagandtable.get(temp)).intValue();
2650 generateFlagOrAnd(ffan, fm, temp, output, ormask, andmask);
2651 generateObjectDistribute(ffan, fm, temp, output);
2655 protected void generateFlagOrAnd(FlatFlagActionNode ffan, FlatMethod fm, TempDescriptor temp,
2656 PrintWriter output, int ormask, int andmask) {
2657 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
2658 output.println("flagorandinit("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
2660 output.println("flagorand("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
2664 protected void generateObjectDistribute(FlatFlagActionNode ffan, FlatMethod fm, TempDescriptor temp, PrintWriter output) {
2665 output.println("enqueueObject("+generateTemp(fm, temp)+");");
2668 void generateOptionalHeader(PrintWriter headers) {
2671 headers.println("#include \"task.h\"\n\n");
2672 headers.println("#ifndef _OPTIONAL_STRUCT_");
2673 headers.println("#define _OPTIONAL_STRUCT_");
2675 //STRUCT PREDICATEMEMBER
2676 headers.println("struct predicatemember{");
2677 headers.println("int type;");
2678 headers.println("int numdnfterms;");
2679 headers.println("int * flags;");
2680 headers.println("int numtags;");
2681 headers.println("int * tags;\n};\n\n");
2683 //STRUCT OPTIONALTASKDESCRIPTOR
2684 headers.println("struct optionaltaskdescriptor{");
2685 headers.println("struct taskdescriptor * task;");
2686 headers.println("int index;");
2687 headers.println("int numenterflags;");
2688 headers.println("int * enterflags;");
2689 headers.println("int numpredicatemembers;");
2690 headers.println("struct predicatemember ** predicatememberarray;");
2691 headers.println("};\n\n");
2693 //STRUCT TASKFAILURE
2694 headers.println("struct taskfailure {");
2695 headers.println("struct taskdescriptor * task;");
2696 headers.println("int index;");
2697 headers.println("int numoptionaltaskdescriptors;");
2698 headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
2700 //STRUCT FSANALYSISWRAPPER
2701 headers.println("struct fsanalysiswrapper{");
2702 headers.println("int flags;");
2703 headers.println("int numtags;");
2704 headers.println("int * tags;");
2705 headers.println("int numtaskfailures;");
2706 headers.println("struct taskfailure ** taskfailurearray;");
2707 headers.println("int numoptionaltaskdescriptors;");
2708 headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
2710 //STRUCT CLASSANALYSISWRAPPER
2711 headers.println("struct classanalysiswrapper{");
2712 headers.println("int type;");
2713 headers.println("int numotd;");
2714 headers.println("struct optionaltaskdescriptor ** otdarray;");
2715 headers.println("int numfsanalysiswrappers;");
2716 headers.println("struct fsanalysiswrapper ** fsanalysiswrapperarray;\n};");
2718 headers.println("extern struct classanalysiswrapper * classanalysiswrapperarray[];");
2720 Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
2721 while(taskit.hasNext()) {
2722 TaskDescriptor td=(TaskDescriptor)taskit.next();
2723 headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
2728 //CHECK OVER THIS -- THERE COULD BE SOME ERRORS HERE
2729 int generateOptionalPredicate(Predicate predicate, OptionalTaskDescriptor otd, ClassDescriptor cdtemp, PrintWriter output) {
2730 int predicateindex = 0;
2731 //iterate through the classes concerned by the predicate
2732 Set c_vard = predicate.vardescriptors;
2733 Hashtable<TempDescriptor, Integer> slotnumber=new Hashtable<TempDescriptor, Integer>();
2736 for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext(); ) {
2737 VarDescriptor vard = (VarDescriptor)vard_it.next();
2738 TypeDescriptor typed = vard.getType();
2740 //generate for flags
2741 HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
2742 output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2744 if (fen_hashset!=null) {
2745 for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext(); ) {
2746 FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
2748 DNFFlag dflag=fen.getDNF();
2749 numberterms+=dflag.size();
2751 Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
2753 for(int j=0; j<dflag.size(); j++) {
2755 output.println(",");
2756 Vector term=dflag.get(j);
2759 for(int k=0; k<term.size(); k++) {
2760 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
2761 FlagDescriptor fd=dfa.getFlag();
2762 boolean negated=dfa.getNegated();
2763 int flagid=1<<((Integer)flags.get(fd)).intValue();
2768 output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
2773 output.println("};\n");
2776 TagExpressionList tagel = predicate.tags.get(vard.getSymbol());
2777 output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2780 for(int j=0; j<tagel.numTags(); j++) {
2782 output.println(",");
2783 TempDescriptor tmp=tagel.getTemp(j);
2784 if (!slotnumber.containsKey(tmp)) {
2785 Integer slotint=new Integer(current_slot++);
2786 slotnumber.put(tmp,slotint);
2788 int slot=slotnumber.get(tmp).intValue();
2789 output.println("/* slot */"+ slot+", /*tagid*/"+state.getTagId(tmp.getTag()));
2791 numtags = tagel.numTags();
2793 output.println("};");
2795 //store the result into a predicatemember struct
2796 output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
2797 output.println("/*type*/"+typed.getClassDesc().getId()+",");
2798 output.println("/* number of dnf terms */"+numberterms+",");
2799 output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2800 output.println("/* number of tag */"+numtags+",");
2801 output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2802 output.println("};\n");
2807 //generate an array that stores the entire predicate
2808 output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2809 for( int j = 0; j<predicateindex; j++) {
2810 if( j != predicateindex-1) output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2811 else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
2813 output.println("};\n");
2814 return predicateindex;
2818 void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, Set<OptionalTaskDescriptor>>> safeexecution, Hashtable optionaltaskdescriptors) {
2819 generateOptionalHeader(headers);
2821 output.println("#include \"optionalstruct.h\"\n\n");
2822 output.println("#include \"stdlib.h\"\n");
2824 HashSet processedcd = new HashSet();
2826 Enumeration e = safeexecution.keys();
2827 while (e.hasMoreElements()) {
2830 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
2831 Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp); //will be used several times
2833 //Generate the struct of optionals
2834 Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
2835 numotd = c_otd.size();
2836 if(maxotd<numotd) maxotd = numotd;
2837 if( !c_otd.isEmpty() ) {
2838 for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext(); ) {
2839 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
2841 //generate the int arrays for the predicate
2842 Predicate predicate = otd.predicate;
2843 int predicateindex = generateOptionalPredicate(predicate, otd, cdtemp, output);
2844 TreeSet<Integer> fsset=new TreeSet<Integer>();
2845 //iterate through possible FSes corresponding to
2846 //the state when entering
2848 for(Iterator fses = otd.enterflagstates.iterator(); fses.hasNext(); ) {
2849 FlagState fs = (FlagState)fses.next();
2851 for(Iterator flags = fs.getFlags(); flags.hasNext(); ) {
2852 FlagDescriptor flagd = (FlagDescriptor)flags.next();
2853 int id=1<<((Integer)flaginfo.get(flagd)).intValue();
2856 fsset.add(new Integer(flagid));
2857 //tag information not needed because tag
2858 //changes are not tolerated.
2861 output.println("int enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2862 boolean needcomma=false;
2863 for(Iterator<Integer> it=fsset.iterator(); it.hasNext(); ) {
2866 output.println(it.next());
2869 output.println("};\n");
2872 //generate optionaltaskdescriptor that actually
2873 //includes exit fses, predicate and the task
2875 output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
2876 output.println("&task_"+otd.td.getSafeSymbol()+",");
2877 output.println("/*index*/"+otd.getIndex()+",");
2878 output.println("/*number of enter flags*/"+fsset.size()+",");
2879 output.println("enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2880 output.println("/*number of members */"+predicateindex+",");
2881 output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2882 output.println("};\n");
2886 // if there are no optionals, there is no need to build the rest of the struct
2888 output.println("struct optionaltaskdescriptor * otdarray"+cdtemp.getSafeSymbol()+"[]={");
2889 c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
2890 if( !c_otd.isEmpty() ) {
2891 boolean needcomma=false;
2892 for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext(); ) {
2893 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
2895 output.println(",");
2897 output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
2900 output.println("};\n");
2902 //get all the possible flagstates reachable by an object
2903 Hashtable hashtbtemp = safeexecution.get(cdtemp);
2905 TreeSet fsts=new TreeSet(new FlagComparator(flaginfo));
2906 fsts.addAll(hashtbtemp.keySet());
2907 for(Iterator fsit=fsts.iterator(); fsit.hasNext(); ) {
2908 FlagState fs = (FlagState)fsit.next();
2911 //get the set of OptionalTaskDescriptors corresponding
2912 HashSet<OptionalTaskDescriptor> availabletasks = (HashSet<OptionalTaskDescriptor>)hashtbtemp.get(fs);
2913 //iterate through the OptionalTaskDescriptors and
2914 //store the pointers to the optionals struct (see on
2915 //top) into an array
2917 output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
2918 for(Iterator<OptionalTaskDescriptor> mos = ordertd(availabletasks).iterator(); mos.hasNext(); ) {
2919 OptionalTaskDescriptor mm = mos.next();
2921 output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol());
2923 output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2926 output.println("};\n");
2928 //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose.
2931 for(Iterator flags = fs.getFlags(); flags.hasNext(); ) {
2932 FlagDescriptor flagd = (FlagDescriptor)flags.next();
2933 int id=1<<((Integer)flaginfo.get(flagd)).intValue();
2937 //process tag information
2940 boolean first = true;
2941 Enumeration tag_enum = fs.getTags();
2942 output.println("int tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
2943 while(tag_enum.hasMoreElements()) {
2945 TagDescriptor tagd = (TagDescriptor)tag_enum.nextElement();
2949 output.println(", ");
2950 output.println("/*tagid*/"+state.getTagId(tagd));
2952 output.println("};");
2954 Set<TaskIndex> tiset=sa.getTaskIndex(fs);
2955 for(Iterator<TaskIndex> itti=tiset.iterator(); itti.hasNext(); ) {
2956 TaskIndex ti=itti.next();
2960 Set<OptionalTaskDescriptor> otdset=sa.getOptions(fs, ti);
2962 output.print("struct optionaltaskdescriptor * optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array[] = {");
2963 boolean needcomma=false;
2964 for(Iterator<OptionalTaskDescriptor> otdit=ordertd(otdset).iterator(); otdit.hasNext(); ) {
2965 OptionalTaskDescriptor otd=otdit.next();
2969 output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
2971 output.println("};");
2973 output.print("struct taskfailure taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+" = {");
2974 output.print("&task_"+ti.getTask().getSafeSymbol()+", ");
2975 output.print(ti.getIndex()+", ");
2976 output.print(otdset.size()+", ");
2977 output.print("optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array");
2978 output.println("};");
2981 tiset=sa.getTaskIndex(fs);
2982 boolean needcomma=false;
2984 output.println("struct taskfailure * taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
2985 for(Iterator<TaskIndex> itti=tiset.iterator(); itti.hasNext(); ) {
2986 TaskIndex ti=itti.next();
2987 if (ti.isRuntime()) {
2994 output.print("&taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex());
2996 output.println("};\n");
2998 //Store the result in fsanalysiswrapper
3000 output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
3001 output.println("/*flag*/"+flagid+",");
3002 output.println("/* number of tags*/"+tagcounter+",");
3003 output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
3004 output.println("/* numtask failures */"+(tiset.size()-runtimeti)+",");
3005 output.println("taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
3006 output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
3007 output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
3008 output.println("};\n");
3012 //Build the array of fsanalysiswrappers
3013 output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
3014 boolean needcomma=false;
3015 for(int i = 0; i<fscounter; i++) {
3016 if (needcomma) output.print(",");
3017 output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol());
3020 output.println("};");
3022 //Build the classanalysiswrapper referring to the previous array
3023 output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
3024 output.println("/*type*/"+cdtemp.getId()+",");
3025 output.println("/*numotd*/"+numotd+",");
3026 output.println("otdarray"+cdtemp.getSafeSymbol()+",");
3027 output.println("/* number of fsanalysiswrappers */"+fscounter+",");
3028 output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
3029 processedcd.add(cdtemp);
3032 //build an array containing every classes for which code has been build
3033 output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
3034 for(int i=0; i<state.numClasses(); i++) {
3035 ClassDescriptor cn=cdarray[i];
3038 if ((cn != null) && (processedcd.contains(cn)))
3039 output.print("&classanalysiswrapper_"+cn.getSafeSymbol());
3041 output.print("NULL");
3043 output.println("};");
3045 output.println("#define MAXOTD "+maxotd);
3046 headers.println("#endif");
3049 public List<OptionalTaskDescriptor> ordertd(Set<OptionalTaskDescriptor> otdset) {
3050 Relation r=new Relation();
3051 for(Iterator<OptionalTaskDescriptor>otdit=otdset.iterator(); otdit.hasNext(); ) {
3052 OptionalTaskDescriptor otd=otdit.next();
3053 TaskIndex ti=new TaskIndex(otd.td, otd.getIndex());
3057 LinkedList<OptionalTaskDescriptor> l=new LinkedList<OptionalTaskDescriptor>();
3058 for(Iterator it=r.keySet().iterator(); it.hasNext(); ) {
3059 Set s=r.get(it.next());
3060 for(Iterator it2=s.iterator(); it2.hasNext(); ) {
3061 OptionalTaskDescriptor otd=(OptionalTaskDescriptor)it2.next();
3069 // override these methods in a subclass of BuildCode
3070 // to generate code for additional systems
3071 protected void printExtraArrayFields(PrintWriter outclassdefs) {
3073 protected void outputTransCode(PrintWriter output) {
3075 protected void buildCodeSetup() {
3077 protected void generateSizeArrayExtensions(PrintWriter outclassdefs) {
3079 protected void additionalIncludesMethodsHeader(PrintWriter outmethodheader) {
3081 protected void preCodeGenInitialization() {
3083 protected void postCodeGenCleanUp() {
3085 protected void additionalCodeGen(PrintWriter outmethodheader,
3086 PrintWriter outstructs,
3087 PrintWriter outmethod) {
3089 protected void additionalCodeAtTopOfMain(PrintWriter outmethod) {
3091 protected void additionalCodeAtBottomOfMain(PrintWriter outmethod) {
3093 protected void additionalIncludesMethodsImplementation(PrintWriter outmethod) {
3095 protected void additionalIncludesStructsHeader(PrintWriter outstructs) {
3097 protected void additionalClassObjectFields(PrintWriter outclassdefs) {
3099 protected void additionalCodeAtTopMethodsImplementation(PrintWriter outmethod) {
3101 protected void additionalCodeAtTopFlatMethodBody(PrintWriter output, FlatMethod fm) {
3103 protected void additionalCodePreNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
3105 protected void additionalCodePostNode(FlatMethod fm, FlatNode fn, PrintWriter output) {