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