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