86e7db56cc4db6ae04f642328f0fd079b9def0b3
[IRC.git] / Robust / src / IR / Flat / BuildCodeMGC.java
1 package IR.Flat;
2
3 import java.io.FileOutputStream;
4 import java.io.PrintWriter;
5 import java.util.Hashtable;
6 import java.util.Iterator;
7
8 import Analysis.TaskStateAnalysis.SafetyAnalysis;
9 import Analysis.CallGraph.CallGraph;
10 import IR.ClassDescriptor;
11 import IR.MethodDescriptor;
12 import IR.State;
13 import IR.SymbolTable;
14 import IR.TypeUtil;
15
16 public class BuildCodeMGC extends BuildCode {
17   int coreNum;
18   int tcoreNum;
19   int gcoreNum;
20   int startupcorenum;    // record the core containing startup task, s
21   // uppose only one core can have startup object
22
23   public BuildCodeMGC(State st, 
24                       Hashtable temptovar, 
25                       TypeUtil typeutil, 
26                       SafetyAnalysis sa,
27                       int coreNum, 
28                       int tcoreNum,
29                       int gcoreNum, CallGraph callgraph) {
30     super(st, temptovar, typeutil, sa, callgraph);
31     this.coreNum = coreNum; // # of the active cores
32     this.tcoreNum = tcoreNum; // # of the total number of cores
33     this.gcoreNum = gcoreNum; // # of the cores for gc if any
34     this.startupcorenum = 0;
35   }
36
37   public void buildCode() {
38     /* Create output streams to write to */
39     PrintWriter outclassdefs=null;
40     PrintWriter outglobaldefs=null;
41     PrintWriter outglobaldefsprim=null;
42     PrintWriter outstructs=null;
43     PrintWriter outmethodheader=null;
44     PrintWriter outmethod=null;
45     PrintWriter outvirtual=null;
46
47     try {
48       outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
49       outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
50       outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
51       outglobaldefs=new PrintWriter(new FileOutputStream(PREFIX+"globaldefs.h"), true);
52       outglobaldefsprim=new PrintWriter(new FileOutputStream(PREFIX+"globaldefsprim.h"), true);
53       outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
54       outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
55     } catch (Exception e) {
56       e.printStackTrace();
57       System.exit(-1);
58     }
59     
60     /* Fix field safe symbols due to shadowing */
61     FieldShadow.handleFieldShadow(state);
62
63     /* Build the virtual dispatch tables */
64     super.buildVirtualTables(outvirtual);
65     
66     /* Tag the methods that are invoked by static blocks */
67     super.tagMethodInvokedByStaticBlock();
68
69     /* Output includes */
70     outmethodheader.println("#ifndef METHODHEADERS_H");
71     outmethodheader.println("#define METHODHEADERS_H");
72     outmethodheader.println("#include \"structdefs.h\"");
73
74     /* Output Structures */
75     super.outputStructs(outstructs);
76
77     outglobaldefs.println("#ifndef __GLOBALDEF_H_");
78     outglobaldefs.println("#define __GLOBALDEF_H_");
79     outglobaldefs.println("");
80     outglobaldefs.println("struct global_defs_t {");
81     outglobaldefs.println("  int size;");
82     outglobaldefs.println("  void * next;");
83
84     outglobaldefsprim.println("#ifndef __GLOBALDEFPRIM_H_");
85     outglobaldefsprim.println("#define __GLOBALDEFPRIM_H_");
86     outglobaldefsprim.println("");
87     outglobaldefsprim.println("struct global_defsprim_t {");
88     
89     // Output the C class declarations
90     // These could mutually reference each other    
91     outclassdefs.println("#ifndef __CLASSDEF_H_");
92     outclassdefs.println("#define __CLASSDEF_H_");
93     super.outputClassDeclarations(outclassdefs, outglobaldefs, outglobaldefsprim);
94
95     // Output function prototypes and structures for parameters
96     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
97     while(it.hasNext()) {
98       ClassDescriptor cn=(ClassDescriptor)it.next();
99       super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs, outglobaldefsprim);
100     }
101     // TODO add version for normal Java later
102     outclassdefs.println("#include \"globaldefs.h\"");
103     outclassdefs.println("#include \"globaldefsprim.h\"");
104     outclassdefs.println("#endif");
105     outclassdefs.close();
106     outglobaldefs.println("};");
107     outglobaldefs.println("");
108     outglobaldefs.println("extern struct global_defs_t * global_defs_p;");
109     outglobaldefs.println("#endif");
110     outglobaldefs.flush();
111     outglobaldefs.close();
112
113     outglobaldefsprim.println("};");
114     outglobaldefsprim.println("");
115     outglobaldefsprim.println("extern struct global_defsprim_t * global_defsprim_p;");
116     outglobaldefsprim.println("#endif");
117     outglobaldefsprim.flush();
118     outglobaldefsprim.close();
119
120     /* Build the actual methods */
121     super.outputMethods(outmethod);
122
123     /* Record maximum number of task parameters */
124     //outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
125     /* Record maximum number of all types, i.e. length of classsize[] */
126     outstructs.println("#define NUMTYPES "+(state.numClasses() + state.numArrays() + state.numInterfaces()));
127     /* Record number of total cores */
128     outstructs.println("#define NUMCORES "+this.tcoreNum);
129     /* Record number of active cores */
130     outstructs.println("#define NUMCORESACTIVE "+this.coreNum); // this.coreNum 
131                                     // can be reset by the scheduling analysis
132     /* Record number of garbage collection cores */
133     outstructs.println("#ifdef MULTICORE_GC");
134     outstructs.println("#define NUMCORES4GC "+this.gcoreNum);
135     outstructs.println("#endif");
136     /* Record number of core containing startup task */
137     outstructs.println("#define STARTUPCORE "+this.startupcorenum);
138     
139     if (state.main!=null) {
140     /* Generate main method */
141       outputMainMethod(outmethod);
142     }
143
144     /* Close files */
145     outmethodheader.println("#endif");
146     outmethodheader.close();
147     outmethod.close();
148     outstructs.println("#endif");
149     outstructs.close();
150   }
151   
152   protected void outputMainMethod(PrintWriter outmethod) {
153     outmethod.println("int mgc_main(int argc, const char *argv[]) {");
154     outmethod.println("  int i;");
155     
156     if (state.MULTICOREGC) {
157       outmethod.println("  global_defs_p->size="+globaldefscount+";");
158       outmethod.println("  global_defs_p->next=NULL;");
159       outmethod.println("  for(i=0;i<"+globaldefscount+";i++) {");
160       outmethod.println("    ((struct garbagelist *)global_defs_p)->array[i]=NULL;");
161       outmethod.println("  }");
162     }
163     
164     outputStaticBlocks(outmethod);
165     outputClassObjects(outmethod);
166     
167     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
168       outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
169     } else {
170       outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
171     }
172     outmethod.println("  for(i=1;i<argc;i++) {");
173     outmethod.println("    int length=strlen(argv[i]);");
174     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
175       outmethod.println("    struct ___String___ *newstring=NewString(NULL, argv[i], length);");
176     } else {
177       outmethod.println("    struct ___String___ *newstring=NewString(argv[i], length);");
178     }
179     outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
180     outmethod.println("  }");    
181
182     MethodDescriptor md=typeutil.getMain();
183     ClassDescriptor cd=typeutil.getMainClass();
184
185     outmethod.println("   {");
186     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
187       outmethod.print("       struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
188       outmethod.println("1, NULL,"+"stringarray};");
189       outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
190     } else {
191       outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
192     }
193     outmethod.println("   }");
194
195     outmethod.println("}");
196   }
197 }