big code reorg...get TM out of buildcode
[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 IR.ClassDescriptor;
10 import IR.MethodDescriptor;
11 import IR.State;
12 import IR.SymbolTable;
13 import IR.TypeUtil;
14
15 public class BuildCodeMGC extends BuildCode {
16   int coreNum;
17   int tcoreNum;
18   int gcoreNum;
19   int startupcorenum;    // record the core containing startup task, s
20   // uppose only one core can have startup object
21
22   public BuildCodeMGC(State st, 
23                       Hashtable temptovar, 
24                       TypeUtil typeutil, 
25                       SafetyAnalysis sa,
26                       int coreNum, 
27                       int tcoreNum,
28                       int gcoreNum) {
29     super(st, temptovar, typeutil, sa);
30     this.coreNum = coreNum; // # of the active cores
31     this.tcoreNum = tcoreNum; // # of the total number of cores
32     this.gcoreNum = gcoreNum; // # of the cores for gc if any
33     this.startupcorenum = 0;
34   }
35
36   public void buildCode() {
37     /* Create output streams to write to */
38     PrintWriter outclassdefs=null;
39     PrintWriter outglobaldefs=null;
40     PrintWriter outstructs=null;
41     PrintWriter outmethodheader=null;
42     PrintWriter outmethod=null;
43     PrintWriter outvirtual=null;
44
45     try {
46       outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
47       outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
48       outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
49       outglobaldefs=new PrintWriter(new FileOutputStream(PREFIX+"globaldefs.h"), true);
50       outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
51       outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
52     } catch (Exception e) {
53       e.printStackTrace();
54       System.exit(-1);
55     }
56     
57     /* Fix field safe symbols due to shadowing */
58     FieldShadow.handleFieldShadow(state);
59
60     /* Build the virtual dispatch tables */
61     super.buildVirtualTables(outvirtual);
62     
63     /* Tag the methods that are invoked by static blocks */
64     super.tagMethodInvokedByStaticBlock();
65
66     /* Output includes */
67     outmethodheader.println("#ifndef METHODHEADERS_H");
68     outmethodheader.println("#define METHODHEADERS_H");
69     outmethodheader.println("#include \"structdefs.h\"");
70
71     /* Output Structures */
72     super.outputStructs(outstructs);
73
74     outglobaldefs.println("#ifndef __GLOBALDEF_H_");
75     outglobaldefs.println("#define __GLOBALDEF_H_");
76     outglobaldefs.println("");
77     outglobaldefs.println("struct global_defs_t {");
78     
79     // Output the C class declarations
80     // These could mutually reference each other    
81     outclassdefs.println("#ifndef __CLASSDEF_H_");
82     outclassdefs.println("#define __CLASSDEF_H_");
83     super.outputClassDeclarations(outclassdefs, outglobaldefs);
84
85     // Output function prototypes and structures for parameters
86     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
87     int numclasses = this.state.numClasses();
88     while(it.hasNext()) {
89       ClassDescriptor cn=(ClassDescriptor)it.next();
90       super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs);
91     }
92     // TODO add version for normal Java later
93     outclassdefs.println("#include \"globaldefs.h\"");
94     outclassdefs.println("#endif");
95     outclassdefs.close();
96     outglobaldefs.println("};");
97     outglobaldefs.println("");
98     outglobaldefs.println("extern struct global_defs_t * global_defs_p;");
99     outglobaldefs.println("#endif");
100     outglobaldefs.flush();
101     outglobaldefs.close();
102
103     /* Build the actual methods */
104     super.outputMethods(outmethod);
105
106     /* Record maximum number of task parameters */
107     //outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
108     /* Record maximum number of all types, i.e. length of classsize[] */
109     outstructs.println("#define NUMTYPES "+(state.numClasses() + state.numArrays()));
110     /* Record number of total cores */
111     outstructs.println("#define NUMCORES "+this.tcoreNum);
112     /* Record number of active cores */
113     outstructs.println("#define NUMCORESACTIVE "+this.coreNum); // this.coreNum 
114                                     // can be reset by the scheduling analysis
115     /* Record number of garbage collection cores */
116     outstructs.println("#ifdef MULTICORE_GC");
117     outstructs.println("#define NUMCORES4GC "+this.gcoreNum);
118     outstructs.println("#endif");
119     /* Record number of core containing startup task */
120     outstructs.println("#define STARTUPCORE "+this.startupcorenum);
121     
122     if (state.main!=null) {
123     /* Generate main method */
124       outputMainMethod(outmethod);
125     }
126
127     /* Close files */
128     outmethodheader.println("#endif");
129     outmethodheader.close();
130     outmethod.close();
131     outstructs.println("#endif");
132     outstructs.close();
133   }
134   
135   protected void outputMainMethod(PrintWriter outmethod) {
136     outmethod.println("int mgc_main(int argc, const char *argv[]) {");
137     outmethod.println("  int i;");
138     
139     outputStaticBlocks(outmethod);
140     outputClassObjects(outmethod);
141     
142     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
143       outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
144     } else {
145       outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
146     }
147     outmethod.println("  for(i=1;i<argc;i++) {");
148     outmethod.println("    int length=strlen(argv[i]);");
149     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
150       outmethod.println("    struct ___String___ *newstring=NewString(NULL, argv[i], length);");
151     } else {
152       outmethod.println("    struct ___String___ *newstring=NewString(argv[i], length);");
153     }
154     outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
155     outmethod.println("  }");    
156
157     MethodDescriptor md=typeutil.getMain();
158     ClassDescriptor cd=typeutil.getMainClass();
159
160     outmethod.println("   {");
161     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
162       outmethod.print("       struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
163       outmethod.println("1, NULL,"+"stringarray};");
164       outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
165     } else {
166       outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
167     }
168     outmethod.println("   }");
169
170     outmethod.println("}");
171   }
172   
173   protected void outputStaticBlocks(PrintWriter outmethod) {
174     // execute all the static blocks and all the static field initializations
175     SymbolTable sctbl = this.state.getSClassSymbolTable();
176     Iterator it_sclasses = sctbl.getDescriptorsIterator();
177     if(it_sclasses.hasNext()) {
178       outmethod.println("#define MGC_STATIC_INIT_CHECK");
179       while(it_sclasses.hasNext()) {
180         ClassDescriptor t_cd = (ClassDescriptor)it_sclasses.next();
181         MethodDescriptor t_md = (MethodDescriptor)t_cd.getMethodTable().get("staticblocks");
182         if(t_md != null) {
183           outmethod.println("   {");
184           if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
185             outmethod.print("       struct "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"_params __parameterlist__={");
186             outmethod.println("1, NULL};");
187             outmethod.println("     "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"(& __parameterlist__);");
188           } else {
189             outmethod.println("     "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
190           }
191           outmethod.println("   }");
192         }
193       }
194       outmethod.println("#undef MGC_STATIC_INIT_CHECK");
195     }
196   }
197   
198   protected void outputClassObjects(PrintWriter outmethod) {
199     // for each class, initialize its Class object
200     if(state.MGC) {
201       SymbolTable ctbl = this.state.getClassSymbolTable();
202       Iterator it_classes = ctbl.getDescriptorsIterator();
203
204       /*TypeDescriptor[] tdarray=new TypeDescriptor[1];
205       tdarray[0] = new TypeDescriptor(((ClassDescriptor)this.state.getClassSymbolTable().get("Object")));
206       
207       TypeDescriptor typetolookin=new TypeDescriptor(((ClassDescriptor)this.state.getClassSymbolTable().get("Class")));;
208
209       //find the constructor for 'Class' class
210       ClassDescriptor classtolookin=typetolookin.getClassDesc();
211
212       Set methoddescriptorset=classtolookin.getMethodTable().getSet(typetolookin.getSymbol());
213       MethodDescriptor bestmd=null;
214 NextMethod:
215       for(Iterator methodit=methoddescriptorset.iterator(); methodit.hasNext();) {
216         MethodDescriptor currmd=(MethodDescriptor)methodit.next();
217         // Need correct number of parameters 
218         if (1!=currmd.numParameters())
219           continue;
220         for(int i=0; i<1; i++) {
221           if (!typeutil.isSuperorType(currmd.getParamType(i),tdarray[i]))
222             continue NextMethod;
223         }
224         // Local allocations can't call global allocator 
225         if (currmd.isGlobal())
226           continue;
227
228         // Method okay so far 
229         if (bestmd==null)
230           bestmd=currmd;
231         else {
232           if (typeutil.isMoreSpecific(currmd,bestmd)) {
233             bestmd=currmd;
234           } else if (!typeutil.isMoreSpecific(bestmd, currmd)) {
235             throw new Error("No method is most specific");
236           }
237
238           // Is this more specific than bestmd 
239         }
240       }
241       if (bestmd==null)
242         throw new Error("No constructor found for Class in ");
243       */
244       while(it_classes.hasNext()) {
245         ClassDescriptor t_cd = (ClassDescriptor)it_classes.next();
246         /*if(t_cd.getSymbol().equals("Class") || t_cd.getSymbol().equals("VMClass")) {
247           continue;
248         }*/
249         // TODO initialize the Class object for this class  ++
250         outmethod.println(" {");
251         /*
252         // create the vmdata object that record the class's type
253         if(this.state.MULTICOREGC) {
254           outmethod.println("    void * " + t_cd.getSafeSymbol() + "vmdata=allocate_new("+localsprefixaddr+", "+t_cd.getId()+");");              
255         } else {
256           outmethod.println("    void * " + t_cd.getSafeSymbol() + "vmdata=allocate_new("+t_cd.getId()+");");
257         }
258         // invoke the Class.constructor
259         ParamsObject objectparams=(ParamsObject)paramstable.get(bestmd);
260         if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
261           outmethod.print("    struct "+classtolookin.getSafeSymbol()+bestmd.getSafeSymbol()+"_"+bestmd.getSafeMethodDescriptor()+"_params __parameterlist__={");
262           outmethod.print(objectparams.numPointers());
263           outmethod.print(", "+localsprefixaddr);
264           if (bestmd.getThis()!=null) {
265             outmethod.print(", ");
266             outmethod.print("(struct "+bestmd.getThis().getType().getSafeSymbol() +" *)&(global_defs_p->"+t_cd.getSafeSymbol()+"classobj)");
267           }
268
269           Descriptor var=bestmd.getParameter(0);
270           TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
271           if (objectparams.isParamPtr(paramtemp)) {
272             outmethod.print(", ");
273             TypeDescriptor td=bestmd.getParamType(0);
274             outmethod.print("(struct "+bestmd.getParamType(0).getSafeSymbol()  +" *)" + t_cd.getSafeSymbol() + "vmdata");
275           }
276           outmethod.println("};");
277         }
278         outmethod.print("    ");
279
280         outmethod.print(classtolookin.getSafeSymbol()+bestmd.getSafeSymbol()+"_"+bestmd.getSafeMethodDescriptor());
281
282         outmethod.print("(");
283         boolean needcomma=false;
284         if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
285           outmethod.print("&__parameterlist__");
286           needcomma=true;
287         }
288
289         if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
290           TypeDescriptor ptd=null;
291           if(bestmd.getThis() != null) {
292             ptd = bestmd.getThis().getType();
293           }
294           if (needcomma)
295             outmethod.print(",");
296           if (ptd.isClass()&&!ptd.isArray())
297             outmethod.print("(struct "+ptd.getSafeSymbol()+" *) ");
298           outmethod.print("&(global_defs_p->"+t_cd.getSafeSymbol()+"classobj)");
299           needcomma=true;
300         }
301
302         Descriptor var=bestmd.getParameter(0);
303         TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
304         if (objectparams.isParamPrim(paramtemp)) {
305           if (needcomma)
306             outmethod.print(", ");
307
308           TypeDescriptor ptd=bestmd.getParamType(0);
309           if (ptd.isClass()&&!ptd.isArray())
310             outmethod.print("(struct "+ptd.getSafeSymbol()+" *) ");
311           outmethod.print(t_cd.getSafeSymbol() + "vmdata");
312           needcomma=true;
313         }
314         outmethod.println(");");
315         */
316         outmethod.println("    global_defs_p->"+t_cd.getSafeSymbol()+"classobj.type = " + t_cd.getId() + ";");
317         
318         outmethod.println("    initlock((struct ___Object___ *)(&(global_defs_p->"+t_cd.getSafeSymbol()+"classobj)));");
319         outmethod.println(" }");
320         
321       }
322     } // else TODO normal java version
323     
324   }
325 }