3 import java.io.FileOutputStream;
4 import java.io.PrintWriter;
5 import java.util.Hashtable;
6 import java.util.Iterator;
9 import Analysis.Locality.LocalityBinding;
10 import Analysis.Prefetch.*;
11 import Analysis.TaskStateAnalysis.SafetyAnalysis;
12 import IR.ClassDescriptor;
14 import IR.FlagDescriptor;
15 import IR.MethodDescriptor;
17 import IR.SymbolTable;
18 import IR.TagVarDescriptor;
19 import IR.TaskDescriptor;
20 import IR.TypeDescriptor;
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;
32 public class BuildCodeMGC extends BuildCode {
36 int startupcorenum; // record the core containing startup task, s
37 // uppose only one core can have startup object
39 public BuildCodeMGC(State st,
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;
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;
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) {
75 /* Build the virtual dispatch tables */
76 super.buildVirtualTables(outvirtual);
78 /* Tag the methods that are invoked by static blocks */
79 super.tagMethodInvokedByStaticBlock();
82 outmethodheader.println("#ifndef METHODHEADERS_H");
83 outmethodheader.println("#define METHODHEADERS_H");
84 outmethodheader.println("#include \"structdefs.h\"");
86 /* Output Structures */
87 super.outputStructs(outstructs);
89 outglobaldefs.println("#ifndef __GLOBALDEF_H_");
90 outglobaldefs.println("#define __GLOBALDEF_H_");
91 outglobaldefs.println("");
92 outglobaldefs.println("struct global_defs_t {");
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);
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);
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();
118 /* Build the actual methods */
119 super.outputMethods(outmethod);
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);
137 if (state.main!=null) {
138 /* Generate main method */
139 outputMainMethod(outmethod);
143 outmethodheader.println("#endif");
144 outmethodheader.close();
146 outstructs.println("#endif");
150 protected void outputMainMethod(PrintWriter outmethod) {
151 outmethod.println("int mgc_main(int argc, const char *argv[]) {");
152 outmethod.println(" int i;");
154 outputStaticBlocks(outmethod);
155 outputClassObjects(outmethod);
157 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
158 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
160 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
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);");
167 outmethod.println(" struct ___String___ *newstring=NewString(argv[i], length);");
169 outmethod.println(" ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
170 outmethod.println(" }");
172 MethodDescriptor md=typeutil.getMain();
173 ClassDescriptor cd=typeutil.getMainClass();
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__);");
181 outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
183 outmethod.println(" }");
185 outmethod.println("}");
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
199 MethodDescriptor t_md = (MethodDescriptor)t_cd.getMethodTable().get("staticblocks");
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__);");
207 outmethod.println(" "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
209 outmethod.println(" }");
212 outmethod.println("#undef MGC_STATIC_INIT_CHECK");
216 protected void outputClassObjects(PrintWriter outmethod) {
217 // for each class, initialize its Class object
219 SymbolTable ctbl = this.state.getClassSymbolTable();
220 Iterator it_classes = ctbl.getDescriptorsIterator();
222 /*TypeDescriptor[] tdarray=new TypeDescriptor[1];
223 tdarray[0] = new TypeDescriptor(((ClassDescriptor)this.state.getClassSymbolTable().get("Object")));
225 TypeDescriptor typetolookin=new TypeDescriptor(((ClassDescriptor)this.state.getClassSymbolTable().get("Class")));;
227 //find the constructor for 'Class' class
228 ClassDescriptor classtolookin=typetolookin.getClassDesc();
230 Set methoddescriptorset=classtolookin.getMethodTable().getSet(typetolookin.getSymbol());
231 MethodDescriptor bestmd=null;
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())
238 for(int i=0; i<1; i++) {
239 if (!typeutil.isSuperorType(currmd.getParamType(i),tdarray[i]))
242 // Local allocations can't call global allocator
243 if (currmd.isGlobal())
246 // Method okay so far
250 if (typeutil.isMoreSpecific(currmd,bestmd)) {
252 } else if (!typeutil.isMoreSpecific(bestmd, currmd)) {
253 throw new Error("No method is most specific");
256 // Is this more specific than bestmd
260 throw new Error("No constructor found for Class in ");
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")) {
267 // TODO initialize the Class object for this class ++
268 outmethod.println(" {");
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()+");");
274 outmethod.println(" void * " + t_cd.getSafeSymbol() + "vmdata=allocate_new("+t_cd.getId()+");");
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)");
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");
294 outmethod.println("};");
296 outmethod.print(" ");
298 outmethod.print(classtolookin.getSafeSymbol()+bestmd.getSafeSymbol()+"_"+bestmd.getSafeMethodDescriptor());
300 outmethod.print("(");
301 boolean needcomma=false;
302 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
303 outmethod.print("&__parameterlist__");
307 if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
308 TypeDescriptor ptd=null;
309 if(bestmd.getThis() != null) {
310 ptd = bestmd.getThis().getType();
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)");
320 Descriptor var=bestmd.getParameter(0);
321 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
322 if (objectparams.isParamPrim(paramtemp)) {
324 outmethod.print(", ");
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");
332 outmethod.println(");");
334 outmethod.println(" global_defs_p->"+t_cd.getSafeSymbol()+"classobj.type = " + t_cd.getId() + ";");
336 outmethod.println(" initlock((struct ___Object___ *)(&(global_defs_p->"+t_cd.getSafeSymbol()+"classobj)));");
337 outmethod.println(" }");
340 } // else TODO normal java version