Initialize class objects first as in the staic blocks there might be references to...
[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.TaskStateAnalysis.SafetyAnalysis;
9 import Analysis.CallGraph.CallGraph;
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, CallGraph callgraph) {
30     super(st, temptovar, typeutil, sa, callgraph);
31     this.coreNum = coreNum; // # of the active cores
32     this.tcoreNum = tcoreNum; // # of the total number of cores
33     this.gcoreNum = gcoreNum; // # of the cores for gc if any
34     this.startupcorenum = 0;
35   }
36
37   public void buildCode() {
38     /* Create output streams to write to */
39     PrintWriter outclassdefs=null;
40     PrintWriter outglobaldefs=null;
41     PrintWriter outglobaldefsprim=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       outglobaldefsprim=new PrintWriter(new FileOutputStream(PREFIX+"globaldefsprim.h"), true);
53       outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
54       outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
55     } catch (Exception e) {
56       e.printStackTrace();
57       System.exit(-1);
58     }
59
60     /* Fix field safe symbols due to shadowing */
61     FieldShadow.handleFieldShadow(state);
62
63     /* Build the virtual dispatch tables */
64     super.buildVirtualTables(outvirtual);
65
66     /* Tag the methods that are invoked by static blocks */
67     super.tagMethodInvokedByStaticBlock();
68
69     /* Output includes */
70     outmethodheader.println("#ifndef METHODHEADERS_H");
71     outmethodheader.println("#define METHODHEADERS_H");
72     outmethodheader.println("#include \"structdefs.h\"");
73
74     /* Output Structures */
75     super.outputStructs(outstructs);
76
77     outglobaldefs.println("#ifndef __GLOBALDEF_H_");
78     outglobaldefs.println("#define __GLOBALDEF_H_");
79     outglobaldefs.println("");
80     outglobaldefs.println("struct global_defs_t {");
81     outglobaldefs.println("  int size;");
82     outglobaldefs.println("  void * next;");
83     outglobaldefs.println("  struct ArrayObject * classobjs;");
84
85     outglobaldefsprim.println("#ifndef __GLOBALDEFPRIM_H_");
86     outglobaldefsprim.println("#define __GLOBALDEFPRIM_H_");
87     outglobaldefsprim.println("");
88     outglobaldefsprim.println("struct global_defsprim_t {");
89
90     // Output the C class declarations
91     // These could mutually reference each other
92     outclassdefs.println("#ifndef __CLASSDEF_H_");
93     outclassdefs.println("#define __CLASSDEF_H_");
94     super.outputClassDeclarations(outclassdefs, outglobaldefs, outglobaldefsprim);
95
96     // Output function prototypes and structures for parameters
97     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
98     while(it.hasNext()) {
99       ClassDescriptor cn=(ClassDescriptor)it.next();
100       super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs, outglobaldefsprim);
101     }
102     // TODO add version for normal Java later
103     outclassdefs.println("#include \"globaldefs.h\"");
104     outclassdefs.println("#include \"globaldefsprim.h\"");
105     outclassdefs.println("#endif");
106     outclassdefs.close();
107     outglobaldefs.println("};");
108     outglobaldefs.println("");
109     outglobaldefs.println("extern struct global_defs_t * global_defs_p;");
110     outglobaldefs.println("#endif");
111     outglobaldefs.flush();
112     outglobaldefs.close();
113
114     outglobaldefsprim.println("};");
115     outglobaldefsprim.println("");
116     outglobaldefsprim.println("extern struct global_defsprim_t * global_defsprim_p;");
117     outglobaldefsprim.println("#endif");
118     outglobaldefsprim.flush();
119     outglobaldefsprim.close();
120
121     /* Build the actual methods */
122     super.outputMethods(outmethod);
123
124     /* Record maximum number of task parameters */
125     //outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
126     /* Record maximum number of all types, i.e. length of classsize[] */
127     outstructs.println("#define NUMTYPES "+(state.numClasses() + state.numArrays() + state.numInterfaces()));
128     /* Record number of total cores */
129     outstructs.println("#define NUMCORES "+this.tcoreNum);
130     /* Record number of active cores */
131     outstructs.println("#define NUMCORESACTIVE "+this.coreNum); // this.coreNum
132     // can be reset by the scheduling analysis
133     /* Record number of garbage collection cores */
134     outstructs.println("#if defined(MULTICORE_GC)||defined(PMC_GC)");
135     outstructs.println("#define NUMCORES4GC "+this.gcoreNum);
136     outstructs.println("#endif");
137     /* Record number of core containing startup task */
138     outstructs.println("#define STARTUPCORE "+this.startupcorenum);
139
140     if (state.main!=null) {
141       /* Generate main method */
142       outputMainMethod(outmethod);
143     }
144
145     /* Close files */
146     outmethodheader.println("#endif");
147     outmethodheader.close();
148     outmethod.close();
149     outstructs.println("#endif");
150     outstructs.close();
151   }
152
153   protected void outputMainMethod(PrintWriter outmethod) {
154     outmethod.println("int mgc_main(int argc, const char *argv[]) {");
155     outmethod.println("  int i;");
156
157     if (state.MULTICOREGC||state.PMC) {
158       outmethod.println("  global_defs_p->size="+globaldefscount+";");
159       outmethod.println("  global_defs_p->next=NULL;");
160       outmethod.println("  for(i=0;i<"+globaldefscount+";i++) {");
161       outmethod.println("    ((struct garbagelist *)global_defs_p)->array[i]=NULL;");
162       outmethod.println("  }");
163     }
164
165     outputClassObjects(outmethod);
166     outputStaticBlocks(outmethod);
167
168     if ((GENERATEPRECISEGC) || state.MULTICOREGC || state.PMC) {
169       outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
170     } else {
171       outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
172     }
173     outmethod.println("  for(i=1;i<argc;i++) {");
174     outmethod.println("    int length=strlen(argv[i]);");
175     if ((GENERATEPRECISEGC) || state.MULTICOREGC || state.PMC) {
176       outmethod.println("    struct ___String___ *newstring=NewString(NULL, argv[i], length);");
177     } else {
178       outmethod.println("    struct ___String___ *newstring=NewString(argv[i], length);");
179     }
180     outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
181     outmethod.println("  }");
182
183     MethodDescriptor md=typeutil.getMain();
184     ClassDescriptor cd=typeutil.getMainClass();
185
186     outmethod.println("   {");
187     if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) {
188       outmethod.print("       struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
189       outmethod.println("1, NULL,"+"stringarray};");
190       outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
191     } else {
192       outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
193     }
194     outmethod.println("   }");
195     outmethod.println("   return 0;");
196     outmethod.println("}");
197   }
198 }