3 import java.io.FileOutputStream;
4 import java.io.PrintWriter;
5 import java.util.Hashtable;
6 import java.util.Iterator;
8 import Analysis.TaskStateAnalysis.SafetyAnalysis;
9 import IR.ClassDescriptor;
10 import IR.MethodDescriptor;
12 import IR.SymbolTable;
15 public class BuildCodeMGC extends BuildCode {
19 int startupcorenum; // record the core containing startup task, s
20 // uppose only one core can have startup object
22 public BuildCodeMGC(State st,
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;
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;
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) {
57 /* Fix field safe symbols due to shadowing */
58 FieldShadow.handleFieldShadow(state);
60 /* Build the virtual dispatch tables */
61 super.buildVirtualTables(outvirtual);
63 /* Tag the methods that are invoked by static blocks */
64 super.tagMethodInvokedByStaticBlock();
67 outmethodheader.println("#ifndef METHODHEADERS_H");
68 outmethodheader.println("#define METHODHEADERS_H");
69 outmethodheader.println("#include \"structdefs.h\"");
71 /* Output Structures */
72 super.outputStructs(outstructs);
74 outglobaldefs.println("#ifndef __GLOBALDEF_H_");
75 outglobaldefs.println("#define __GLOBALDEF_H_");
76 outglobaldefs.println("");
77 outglobaldefs.println("struct global_defs_t {");
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);
85 // Output function prototypes and structures for parameters
86 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
87 int numclasses = this.state.numClasses();
89 ClassDescriptor cn=(ClassDescriptor)it.next();
90 super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs);
92 // TODO add version for normal Java later
93 outclassdefs.println("#include \"globaldefs.h\"");
94 outclassdefs.println("#endif");
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();
103 /* Build the actual methods */
104 super.outputMethods(outmethod);
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);
122 if (state.main!=null) {
123 /* Generate main method */
124 outputMainMethod(outmethod);
128 outmethodheader.println("#endif");
129 outmethodheader.close();
131 outstructs.println("#endif");
135 protected void outputMainMethod(PrintWriter outmethod) {
136 outmethod.println("int mgc_main(int argc, const char *argv[]) {");
137 outmethod.println(" int i;");
139 outputStaticBlocks(outmethod);
140 outputClassObjects(outmethod);
142 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
143 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
145 outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
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);");
152 outmethod.println(" struct ___String___ *newstring=NewString(argv[i], length);");
154 outmethod.println(" ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
155 outmethod.println(" }");
157 MethodDescriptor md=typeutil.getMain();
158 ClassDescriptor cd=typeutil.getMainClass();
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__);");
166 outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
168 outmethod.println(" }");
170 outmethod.println("}");
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");
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__);");
189 outmethod.println(" "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
191 outmethod.println(" }");
194 outmethod.println("#undef MGC_STATIC_INIT_CHECK");
198 protected void outputClassObjects(PrintWriter outmethod) {
199 // for each class, initialize its Class object
201 SymbolTable ctbl = this.state.getClassSymbolTable();
202 Iterator it_classes = ctbl.getDescriptorsIterator();
204 /*TypeDescriptor[] tdarray=new TypeDescriptor[1];
205 tdarray[0] = new TypeDescriptor(((ClassDescriptor)this.state.getClassSymbolTable().get("Object")));
207 TypeDescriptor typetolookin=new TypeDescriptor(((ClassDescriptor)this.state.getClassSymbolTable().get("Class")));;
209 //find the constructor for 'Class' class
210 ClassDescriptor classtolookin=typetolookin.getClassDesc();
212 Set methoddescriptorset=classtolookin.getMethodTable().getSet(typetolookin.getSymbol());
213 MethodDescriptor bestmd=null;
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())
220 for(int i=0; i<1; i++) {
221 if (!typeutil.isSuperorType(currmd.getParamType(i),tdarray[i]))
224 // Local allocations can't call global allocator
225 if (currmd.isGlobal())
228 // Method okay so far
232 if (typeutil.isMoreSpecific(currmd,bestmd)) {
234 } else if (!typeutil.isMoreSpecific(bestmd, currmd)) {
235 throw new Error("No method is most specific");
238 // Is this more specific than bestmd
242 throw new Error("No constructor found for Class in ");
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")) {
249 // TODO initialize the Class object for this class ++
250 outmethod.println(" {");
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()+");");
256 outmethod.println(" void * " + t_cd.getSafeSymbol() + "vmdata=allocate_new("+t_cd.getId()+");");
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)");
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");
276 outmethod.println("};");
278 outmethod.print(" ");
280 outmethod.print(classtolookin.getSafeSymbol()+bestmd.getSafeSymbol()+"_"+bestmd.getSafeMethodDescriptor());
282 outmethod.print("(");
283 boolean needcomma=false;
284 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
285 outmethod.print("&__parameterlist__");
289 if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
290 TypeDescriptor ptd=null;
291 if(bestmd.getThis() != null) {
292 ptd = bestmd.getThis().getType();
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)");
302 Descriptor var=bestmd.getParameter(0);
303 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
304 if (objectparams.isParamPrim(paramtemp)) {
306 outmethod.print(", ");
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");
314 outmethod.println(");");
316 outmethod.println(" global_defs_p->"+t_cd.getSafeSymbol()+"classobj.type = " + t_cd.getId() + ";");
318 outmethod.println(" initlock((struct ___Object___ *)(&(global_defs_p->"+t_cd.getSafeSymbol()+"classobj)));");
319 outmethod.println(" }");
322 } // else TODO normal java version