3 import java.io.FileOutputStream;
4 import java.io.PrintWriter;
5 import java.util.Hashtable;
6 import java.util.Iterator;
8 import Analysis.Prefetch.*;
9 import Analysis.TaskStateAnalysis.SafetyAnalysis;
10 import IR.ClassDescriptor;
11 import IR.MethodDescriptor;
13 import IR.SymbolTable;
16 public class BuildCodeMGC extends BuildCode {
20 int startupcorenum; // record the core containing startup task, s
21 // uppose only one core can have startup object
23 public BuildCodeMGC(State st,
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;
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;
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) {
59 /* Build the virtual dispatch tables */
60 super.buildVirtualTables(outvirtual);
62 /* Tag the methods that are invoked by static blocks */
63 super.tagMethodInvokedByStaticBlock();
66 outmethodheader.println("#ifndef METHODHEADERS_H");
67 outmethodheader.println("#define METHODHEADERS_H");
68 outmethodheader.println("#include \"structdefs.h\"");
70 /* Output Structures */
71 super.outputStructs(outstructs);
73 outglobaldefs.println("#ifndef __GLOBALDEF_H_");
74 outglobaldefs.println("#define __GLOBALDEF_H_");
75 outglobaldefs.println("");
76 outglobaldefs.println("struct global_defs_t {");
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);
84 // Output function prototypes and structures for parameters
85 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
86 int numclasses = this.state.numClasses();
88 ClassDescriptor cn=(ClassDescriptor)it.next();
89 super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs);
91 // TODO add version for normal Java later
92 outclassdefs.println("#include \"globaldefs.h\"");
93 outclassdefs.println("#endif");
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();
102 /* Build the actual methods */
103 super.outputMethods(outmethod);
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);
121 if (state.main!=null) {
122 /* Generate main method */
123 outputMainMethod(outmethod);
127 outmethodheader.println("#endif");
128 outmethodheader.close();
130 outstructs.println("#endif");
134 protected void outputMainMethod(PrintWriter outmethod) {
135 outmethod.println("int mgc_main(int argc, const char *argv[]) {");
136 outmethod.println(" int i;");
138 outputStaticBlocks(outmethod);
139 outputClassObjects(outmethod);
141 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
142 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
144 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
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);");
151 outmethod.println(" struct ___String___ *newstring=NewString(argv[i], length);");
153 outmethod.println(" ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
154 outmethod.println(" }");
156 MethodDescriptor md=typeutil.getMain();
157 ClassDescriptor cd=typeutil.getMainClass();
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__);");
165 outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
167 outmethod.println(" }");
169 outmethod.println("}");
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
183 MethodDescriptor t_md = (MethodDescriptor)t_cd.getMethodTable().get("staticblocks");
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__);");
191 outmethod.println(" "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
193 outmethod.println(" }");
196 outmethod.println("#undef MGC_STATIC_INIT_CHECK");
200 protected void outputClassObjects(PrintWriter outmethod) {
201 // for each class, initialize its Class object
203 SymbolTable ctbl = this.state.getClassSymbolTable();
204 Iterator it_classes = ctbl.getDescriptorsIterator();
206 /*TypeDescriptor[] tdarray=new TypeDescriptor[1];
207 tdarray[0] = new TypeDescriptor(((ClassDescriptor)this.state.getClassSymbolTable().get("Object")));
209 TypeDescriptor typetolookin=new TypeDescriptor(((ClassDescriptor)this.state.getClassSymbolTable().get("Class")));;
211 //find the constructor for 'Class' class
212 ClassDescriptor classtolookin=typetolookin.getClassDesc();
214 Set methoddescriptorset=classtolookin.getMethodTable().getSet(typetolookin.getSymbol());
215 MethodDescriptor bestmd=null;
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())
222 for(int i=0; i<1; i++) {
223 if (!typeutil.isSuperorType(currmd.getParamType(i),tdarray[i]))
226 // Local allocations can't call global allocator
227 if (currmd.isGlobal())
230 // Method okay so far
234 if (typeutil.isMoreSpecific(currmd,bestmd)) {
236 } else if (!typeutil.isMoreSpecific(bestmd, currmd)) {
237 throw new Error("No method is most specific");
240 // Is this more specific than bestmd
244 throw new Error("No constructor found for Class in ");
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")) {
251 // TODO initialize the Class object for this class ++
252 outmethod.println(" {");
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()+");");
258 outmethod.println(" void * " + t_cd.getSafeSymbol() + "vmdata=allocate_new("+t_cd.getId()+");");
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)");
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");
278 outmethod.println("};");
280 outmethod.print(" ");
282 outmethod.print(classtolookin.getSafeSymbol()+bestmd.getSafeSymbol()+"_"+bestmd.getSafeMethodDescriptor());
284 outmethod.print("(");
285 boolean needcomma=false;
286 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
287 outmethod.print("&__parameterlist__");
291 if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
292 TypeDescriptor ptd=null;
293 if(bestmd.getThis() != null) {
294 ptd = bestmd.getThis().getType();
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)");
304 Descriptor var=bestmd.getParameter(0);
305 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
306 if (objectparams.isParamPrim(paramtemp)) {
308 outmethod.print(", ");
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");
316 outmethod.println(");");
318 outmethod.println(" global_defs_p->"+t_cd.getSafeSymbol()+"classobj.type = " + t_cd.getId() + ";");
320 outmethod.println(" initlock((struct ___Object___ *)(&(global_defs_p->"+t_cd.getSafeSymbol()+"classobj)));");
321 outmethod.println(" }");
324 } // else TODO normal java version