X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=Robust%2Fsrc%2FIR%2FFlat%2FBuildCode.java;h=11e4b0ccde09b118164e000aa26cef623bdeb786;hb=04ff08dbf682fdda4e70d940174fe18268aa806c;hp=501b4bda09c436fdf28d86c43556bb91292634ba;hpb=e340225160b755bbf9963bc7a9db6e24a8542d07;p=IRC.git diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 501b4bda..11e4b0cc 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -6,6 +6,7 @@ import IR.Tree.DNFFlagAtom; import IR.Tree.TagExpressionList; import IR.Tree.OffsetNode; import IR.*; +import IR.Tree.JavaBuilder; import java.util.*; import java.io.*; @@ -41,39 +42,57 @@ public class BuildCode { public static String arraytype="ArrayObject"; public static int flagcount = 0; Virtual virtualcalls; - TypeUtil typeutil; + public TypeUtil typeutil; protected int maxtaskparams=0; protected int maxcount=0; ClassDescriptor[] cdarray; + ClassDescriptor[] ifarray; TypeDescriptor[] arraytable; SafetyAnalysis sa; CallGraph callgraph; - Hashtable printedfieldstbl; + Hashtable printedfieldstbl; + int globaldefscount=0; + boolean mgcstaticinit = false; + JavaBuilder javabuilder; + String strObjType; - public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) { - this(st, temptovar, typeutil, null); + public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, CallGraph callgraph, JavaBuilder javabuilder) { + this(st, temptovar, typeutil, null, callgraph, javabuilder); } - public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa) { + public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, CallGraph callgraph) { + this(st, temptovar, typeutil, null, callgraph, null); + } + + public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, CallGraph callgraph) { + this(st, temptovar, typeutil, sa, callgraph, null); + } + + public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, CallGraph callgraph, JavaBuilder javabuilder) { this.sa=sa; state=st; - callgraph=new CallGraph(state); + this.javabuilder=javabuilder; + this.callgraph=callgraph; this.temptovar=temptovar; paramstable=new Hashtable(); tempstable=new Hashtable(); fieldorder=new Hashtable(); flagorder=new Hashtable(); this.typeutil=typeutil; - virtualcalls=new Virtual(state, null); - printedfieldstbl = new Hashtable(); + State.logEvent("Virtual"); + virtualcalls=new Virtual(state, null, callgraph); + printedfieldstbl = new Hashtable(); + extensions = new Vector(); + this.strObjType = + "struct "+ + typeutil.getClass( TypeUtil.ObjectClass ).getSafeSymbol(); } /** The buildCode method outputs C code for all the methods. The Flat * versions of the methods must already be generated and stored in * the State object. */ - public void buildCode() { /* Create output streams to write to */ PrintWriter outclassdefs=null; @@ -87,28 +106,32 @@ public class BuildCode { PrintWriter outoptionalarrays=null; PrintWriter optionalheaders=null; PrintWriter outglobaldefs=null; + PrintWriter outglobaldefsprim=null; + State.logEvent("Beginning of buildCode"); try { - buildCodeSetup();//EXTENSION POINT + buildCodeSetup(); //EXTENSION POINT + for(BuildCodeExtension bcx: extensions) { + bcx.buildCodeSetup(); + } + outstructs=new CodePrinter(new FileOutputStream(PREFIX+"structdefs.h"), true); outmethodheader=new CodePrinter(new FileOutputStream(PREFIX+"methodheaders.h"), true); outclassdefs=new CodePrinter(new FileOutputStream(PREFIX+"classdefs.h"), true); - if(state.MGC) { - // TODO add version for normal Java later - outglobaldefs=new CodePrinter(new FileOutputStream(PREFIX+"globaldefs.h"), true); - } + outglobaldefs=new CodePrinter(new FileOutputStream(PREFIX+"globaldefs.h"), true); + outglobaldefsprim=new CodePrinter(new FileOutputStream(PREFIX+"globaldefsprim.h"), true); outmethod=new CodePrinter(new FileOutputStream(PREFIX+"methods.c"), true); outvirtual=new CodePrinter(new FileOutputStream(PREFIX+"virtualtable.h"), true); if (state.TASK) { - outtask=new CodePrinter(new FileOutputStream(PREFIX+"task.h"), true); - outtaskdefs=new CodePrinter(new FileOutputStream(PREFIX+"taskdefs.c"), true); - if (state.OPTIONAL) { - outoptionalarrays=new CodePrinter(new FileOutputStream(PREFIX+"optionalarrays.c"), true); - optionalheaders=new CodePrinter(new FileOutputStream(PREFIX+"optionalstruct.h"), true); - } + outtask=new CodePrinter(new FileOutputStream(PREFIX+"task.h"), true); + outtaskdefs=new CodePrinter(new FileOutputStream(PREFIX+"taskdefs.c"), true); + if (state.OPTIONAL) { + outoptionalarrays=new CodePrinter(new FileOutputStream(PREFIX+"optionalarrays.c"), true); + optionalheaders=new CodePrinter(new FileOutputStream(PREFIX+"optionalstruct.h"), true); + } } if (state.structfile!=null) { - outrepairstructs=new CodePrinter(new FileOutputStream(PREFIX+state.structfile+".struct"), true); + outrepairstructs=new CodePrinter(new FileOutputStream(PREFIX+state.structfile+".struct"), true); } } catch (Exception e) { e.printStackTrace(); @@ -134,50 +157,39 @@ public class BuildCode { } additionalIncludesMethodsHeader(outmethodheader); + for(BuildCodeExtension bcx: extensions) { + bcx.additionalIncludesMethodsHeader(outmethodheader); + } /* Output Structures */ outputStructs(outstructs); - // Output the C class declarations - // These could mutually reference each other - - if(state.MGC) { - // TODO add version for normal Java later - outglobaldefs.println("#ifndef __GLOBALDEF_H_"); - outglobaldefs.println("#define __GLOBALDEF_H_"); - outglobaldefs.println(""); - outglobaldefs.println("struct global_defs_t {"); - } + initOutputGlobals(outglobaldefs, outglobaldefsprim); outclassdefs.println("#ifndef __CLASSDEF_H_"); outclassdefs.println("#define __CLASSDEF_H_"); - outputClassDeclarations(outclassdefs, outglobaldefs); + outputClassDeclarations(outclassdefs, outglobaldefs, outglobaldefsprim); // Output function prototypes and structures for parameters Iterator it=state.getClassSymbolTable().getDescriptorsIterator(); while(it.hasNext()) { ClassDescriptor cn=(ClassDescriptor)it.next(); - generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs); + generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs, outglobaldefsprim); } + outclassdefs.println("#include \"globaldefs.h\""); + outclassdefs.println("#include \"globaldefsprim.h\""); outclassdefs.println("#endif"); outclassdefs.close(); - if(state.MGC) { - // TODO add version for normal Java later - outglobaldefs.println("};"); - outglobaldefs.println(""); - outglobaldefs.println("extern struct global_defs_t * global_defs_p;"); - outglobaldefs.println("#endif"); - outglobaldefs.flush(); - outglobaldefs.close(); - } + + finalOutputGlobals(outglobaldefs, outglobaldefsprim); if (state.TASK) { /* Map flags to integers */ /* The runtime keeps track of flags using these integers */ it=state.getClassSymbolTable().getDescriptorsIterator(); while(it.hasNext()) { - ClassDescriptor cn=(ClassDescriptor)it.next(); - mapFlags(cn); + ClassDescriptor cn=(ClassDescriptor)it.next(); + mapFlags(cn); } /* Generate Tasks */ generateTaskStructs(outstructs, outmethodheader); @@ -187,26 +199,29 @@ public class BuildCode { outputTaskTypes(outtask); } - // an opportunity for subclasses to do extra // initialization preCodeGenInitialization(); + for(BuildCodeExtension bcx: extensions) { + bcx.preCodeGenInitialization(); + } - + State.logEvent("Start outputMethods"); /* Build the actual methods */ outputMethods(outmethod); - + State.logEvent("End outputMethods"); // opportunity for subclasses to gen extra code - additionalCodeGen(outmethodheader, - outstructs, - outmethod); - + additionalCodeGen(outmethodheader, outstructs, outmethod); + for(BuildCodeExtension bcx: extensions) { + bcx.additionalCodeGen(outmethodheader, outstructs, outmethod); + } if (state.TASK) { /* Output code for tasks */ outputTaskCode(outtaskdefs, outmethod); outtaskdefs.close(); + outtask.close(); /* Record maximum number of task parameters */ outstructs.println("#define MAXTASKPARAMS "+maxtaskparams); } else if (state.main!=null) { @@ -218,6 +233,7 @@ public class BuildCode { if (state.TASK&&state.OPTIONAL) { generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors()); outoptionalarrays.close(); + optionalheaders.close(); } /* Output structure definitions for repair tool */ @@ -231,64 +247,167 @@ public class BuildCode { outmethodheader.close(); outmethod.close(); outstructs.println("#endif"); + outstructs.println(); outstructs.close(); - - postCodeGenCleanUp(); - } + for(BuildCodeExtension bcx: extensions) { + bcx.postCodeGenCleanUp(); + } + State.logEvent("End of buildCode"); + } + protected void initOutputGlobals(PrintWriter outglobaldefs, PrintWriter outglobaldefsprim) { + // Output the C class declarations + // These could mutually reference each other + outglobaldefs.println("#ifndef __GLOBALDEF_H_"); + outglobaldefs.println("#define __GLOBALDEF_H_"); + outglobaldefs.println(""); + outglobaldefs.println("struct global_defs_t {"); + outglobaldefs.println(" int size;"); + outglobaldefs.println(" void * next;"); + outglobaldefs.println(" struct ArrayObject * classobjs;"); + outglobaldefsprim.println("#ifndef __GLOBALDEFPRIM_H_"); + outglobaldefsprim.println("#define __GLOBALDEFPRIM_H_"); + outglobaldefsprim.println(""); + outglobaldefsprim.println("struct global_defsprim_t {"); + } + + protected void finalOutputGlobals(PrintWriter outglobaldefs, PrintWriter outglobaldefsprim) { + outglobaldefs.println("};"); + outglobaldefs.println(""); + outglobaldefs.println("extern struct global_defs_t * global_defs_p;"); + outglobaldefs.println("#endif"); + outglobaldefs.flush(); + outglobaldefs.close(); + + outglobaldefsprim.println("};"); + outglobaldefsprim.println(""); + outglobaldefsprim.println("extern struct global_defsprim_t * global_defsprim_p;"); + outglobaldefsprim.println("#endif"); + outglobaldefsprim.flush(); + outglobaldefsprim.close(); + } /* This method goes though the call graph and tag those methods that are * invoked inside static blocks */ protected void tagMethodInvokedByStaticBlock() { - if(state.MGC) { - Iterator it_sclasses = this.state.getSClassSymbolTable().getDescriptorsIterator(); - MethodDescriptor current_md=null; - HashSet tovisit=new HashSet(); - HashSet visited=new HashSet(); - - while(it_sclasses.hasNext()) { - ClassDescriptor cd = (ClassDescriptor)it_sclasses.next(); - MethodDescriptor md = (MethodDescriptor)cd.getMethodTable().get("staticblocks"); - if(md != null) { - tovisit.add(md); - } + Iterator it_sclasses = this.state.getSClassSymbolTable().getDescriptorsIterator(); + MethodDescriptor current_md=null; + HashSet tovisit=new HashSet(); + HashSet visited=new HashSet(); + + while(it_sclasses.hasNext()) { + ClassDescriptor cd = (ClassDescriptor)it_sclasses.next(); + MethodDescriptor md = (MethodDescriptor)cd.getMethodTable().get("staticblocks"); + if(md != null) { + tovisit.add(md); } + } - while(!tovisit.isEmpty()) { - current_md=(MethodDescriptor)tovisit.iterator().next(); - tovisit.remove(current_md); - visited.add(current_md); - Iterator it_callee = this.callgraph.getCalleeSet(current_md).iterator(); - while(it_callee.hasNext()) { - Descriptor d = (Descriptor)it_callee.next(); - if(d instanceof MethodDescriptor) { - if(!visited.contains(d)) { - ((MethodDescriptor)d).setIsInvokedByStatic(true); - tovisit.add(d); - } - } - } + while(!tovisit.isEmpty()) { + current_md=(MethodDescriptor)tovisit.iterator().next(); + tovisit.remove(current_md); + visited.add(current_md); + Iterator it_callee = this.callgraph.getCalleeSet(current_md).iterator(); + while(it_callee.hasNext()) { + Descriptor d = (Descriptor)it_callee.next(); + if(d instanceof MethodDescriptor) { + if(!visited.contains(d)) { + ((MethodDescriptor)d).setIsInvokedByStatic(true); + tovisit.add(d); + } + } } - } // TODO for normal Java version + } } /* This code generates code for each static block and static field * initialization.*/ protected void outputStaticBlocks(PrintWriter outmethod) { // execute all the static blocks and all the static field initializations - // TODO + // execute all the static blocks and all the static field initializations + SymbolTable sctbl = this.state.getSClassSymbolTable(); + Iterator it_sclasses = sctbl.getDescriptorsIterator(); + Vector tooutput = new Vector(); + Queue toprocess=new LinkedList(); + Vector outputs = new Vector(); + while(it_sclasses.hasNext()) { + ClassDescriptor t_cd = (ClassDescriptor)it_sclasses.next(); + if(!outputs.contains(t_cd)) { + tooutput.clear(); + tooutput.add(t_cd); + toprocess.clear(); + toprocess.add(t_cd); + while(!toprocess.isEmpty()) { + ClassDescriptor pcd = toprocess.poll(); + // check super interfaces + Iterator it_sinterfaces = pcd.getSuperInterfaces(); + while(it_sinterfaces.hasNext()) { + ClassDescriptor sint = (ClassDescriptor)it_sinterfaces.next(); + if(!outputs.contains(sint)) { + toprocess.add(sint); + if(sctbl.contains(sint.getClassName())) { + tooutput.add(sint); + } + } + } + // check super classes + ClassDescriptor supercd = pcd.getSuperDesc(); + if(supercd!=null && !outputs.contains(supercd)) { + toprocess.add(supercd); + if(sctbl.contains(supercd.getClassName())) { + tooutput.add(supercd); + } + } + } + + for(int i = tooutput.size()-1; i>=0; i--) { + ClassDescriptor output = tooutput.elementAt(i); + MethodDescriptor t_md = (MethodDescriptor)output.getMethodTable().get("staticblocks"); + + if(t_md != null&&callgraph.isInit(output)) { + outmethod.println(" {"); + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) { + outmethod.print(" struct "+output.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"_params __parameterlist__={"); + outmethod.println("0, NULL};"); + outmethod.println(" "+output.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"(& __parameterlist__);"); + } else { + outmethod.println(" "+output.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();"); + } + outmethod.println(" }"); + } + outputs.add(output); + } + } + } } /* This code generates code to create a Class object for each class for * getClass() method. * */ protected void outputClassObjects(PrintWriter outmethod) { - // for each class, initialize its Class object - // TODO + // create a global classobj array + outmethod.println(" {"); + outmethod.println(" int i = 0;"); + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) { + outmethod.println(" struct garbagelist dummy={0,NULL};"); + outmethod.println(" global_defs_p->classobjs = allocate_newarray(&dummy, OBJECTARRAYTYPE, " + + (state.numClasses()+state.numArrays()+state.numInterfaces()) + ");"); + } else { + outmethod.println(" global_defs_p->classobjs = allocate_newarray(OBJECTARRAYTYPE, " + + (state.numClasses()+state.numArrays()+state.numInterfaces()) + ");"); + } + outmethod.println(" for(i = 0; i < " + (state.numClasses()+state.numArrays()+state.numInterfaces()) + "; i++) {"); + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) { + outmethod.println(" ((void **)(((char *) &(global_defs_p->classobjs->___length___))+sizeof(int)))[i] = allocate_new(NULL, " +typeutil.getClass(TypeUtil.ObjectClass).getId() + ");"); + } else { + outmethod.println(" ((void **)(((char *) &(global_defs_p->classobjs->___length___))+sizeof(int)))[i] = allocate_new(" +typeutil.getClass(TypeUtil.ObjectClass).getId() + ");"); + } + outmethod.println(" }"); + outmethod.println(" }"); } /* This code just generates the main C method for java programs. @@ -298,18 +417,27 @@ public class BuildCode { protected void outputMainMethod(PrintWriter outmethod) { outmethod.println("int main(int argc, const char *argv[]) {"); outmethod.println(" int i;"); - - outputStaticBlocks(outmethod); + if (state.THREAD) { + outmethod.println("initializethreads();"); + } + outmethod.println(" global_defs_p=calloc(1, sizeof(struct global_defs_t));"); + outmethod.println(" global_defsprim_p=calloc(1, sizeof(struct global_defsprim_t));"); + if (GENERATEPRECISEGC) { + outmethod.println(" global_defs_p->size="+globaldefscount+";"); + outmethod.println(" for(i=0;i<"+globaldefscount+";i++) {"); + outmethod.println(" ((struct garbagelist *)global_defs_p)->array[i]=NULL;"); + outmethod.println(" }"); + } outputClassObjects(outmethod); - + outputStaticBlocks(outmethod); additionalCodeAtTopOfMain(outmethod); - - if (state.THREAD) { - outmethod.println("initializethreads();"); + for(BuildCodeExtension bcx: extensions) { + bcx.additionalCodeAtTopOfMain(outmethod); } - if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { + + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) { outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);"); } else { outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);"); @@ -317,19 +445,29 @@ public class BuildCode { outmethod.println(" for(i=1;i___length___)+sizeof(int)))[i-1]=newstring;"); outmethod.println(" }"); + + additionalCodeForCommandLineArgs(outmethod, "stringarray"); + for(BuildCodeExtension bcx: extensions) { + bcx.additionalCodeForCommandLineArgs(outmethod, "stringarray"); + } + + MethodDescriptor md=typeutil.getMain(); ClassDescriptor cd=typeutil.getMainClass(); outmethod.println(" {"); - if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) { outmethod.print(" struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={"); outmethod.println("1, NULL,"+"stringarray};"); outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);"); @@ -354,6 +492,10 @@ public class BuildCode { additionalCodeAtBottomOfMain(outmethod); + for(BuildCodeExtension bcx: extensions) { + bcx.additionalCodeAtBottomOfMain(outmethod); + } + outmethod.println("}"); } @@ -368,6 +510,7 @@ public class BuildCode { while(taskit.hasNext()) { TaskDescriptor td=(TaskDescriptor)taskit.next(); FlatMethod fm=state.getMethodFlat(td); + generateFlatMethod(fm, outmethod); generateTaskDescriptor(outtaskdefs, fm, td); } @@ -379,9 +522,9 @@ public class BuildCode { while(taskit.hasNext()) { TaskDescriptor td=(TaskDescriptor)taskit.next(); if (first) - first=false; + first=false; else - outtaskdefs.println(","); + outtaskdefs.println(","); outtaskdefs.print("&task_"+td.getSafeSymbol()); } outtaskdefs.println("};"); @@ -398,17 +541,22 @@ public class BuildCode { outmethod.println("#include \"methodheaders.h\""); outmethod.println("#include \"virtualtable.h\""); outmethod.println("#include \"runtime.h\""); + if (state.JNI) { + outmethod.println("#include \"jni-private.h\""); + } // always include: compiler directives will leave out // instrumentation when option is not set - outmethod.println("#include \"coreprof/coreprof.h\""); + if(!state.MULTICORE) { + outmethod.println("#include \"coreprof/coreprof.h\""); + } if (state.FASTCHECK) { outmethod.println("#include \"localobjects.h\""); } if(state.MULTICORE) { if(state.TASK) { - outmethod.println("#include \"task.h\""); + outmethod.println("#include \"task.h\""); } outmethod.println("#include \"multicoreruntime.h\""); outmethod.println("#include \"runtime_arch.h\""); @@ -422,18 +570,20 @@ public class BuildCode { if (state.main!=null) { outmethod.println("#include "); } + if (state.SSJAVA_GENCODE_PREVENT_CRASHES){ + outmethod.println("#include "); + } if (state.CONSCHECK) { outmethod.println("#include \"checkers.h\""); } - additionalIncludesMethodsImplementation(outmethod); - - - if(state.MGC) { - // TODO add version for normal Java later - outmethod.println("struct global_defs_t * global_defs_p;"); + for(BuildCodeExtension bcx: extensions) { + bcx.additionalIncludesMethodsImplementation(outmethod); } + + outmethod.println("struct global_defs_t * global_defs_p;"); + outmethod.println("struct global_defsprim_t * global_defsprim_p;"); //Store the sizes of classes & array elements generateSizeArray(outmethod); @@ -445,6 +595,10 @@ public class BuildCode { additionalCodeAtTopMethodsImplementation(outmethod); + for(BuildCodeExtension bcx: extensions) { + bcx.additionalCodeAtTopMethodsImplementation(outmethod); + } + generateMethods(outmethod); } @@ -456,19 +610,25 @@ public class BuildCode { ClassDescriptor cn=(ClassDescriptor)classit.next(); Iterator methodit=cn.getMethods(); while(methodit.hasNext()) { - /* Classify parameters */ - MethodDescriptor md=(MethodDescriptor)methodit.next(); - FlatMethod fm=state.getMethodFlat(md); - if (!md.getModifiers().isNative()) { - generateFlatMethod(fm, outmethod); - } + /* Classify parameters */ + MethodDescriptor md=(MethodDescriptor)methodit.next(); + if (!callgraph.isCallable(md)&&(!md.isStaticBlock()||!callgraph.isInit(cn))) { + continue; + } + + FlatMethod fm=state.getMethodFlat(md); + if (!md.getModifiers().isNative()) { + generateFlatMethod(fm, outmethod); + } else if (state.JNI) { + generateNativeFlatMethod(fm, outmethod); + } } } } protected void outputStructs(PrintWriter outstructs) { - outstructs.println("#ifndef STRUCTDEFS_H"); - outstructs.println("#define STRUCTDEFS_H"); + outstructs.println("#ifndef __STRUCTDEFS_H__"); + outstructs.println("#define __STRUCTDEFS_H__"); outstructs.println("#include \"classdefs.h\""); outstructs.println("#ifndef INTPTR"); outstructs.println("#ifdef BIT64"); @@ -480,6 +640,9 @@ public class BuildCode { additionalIncludesStructsHeader(outstructs); + for(BuildCodeExtension bcx: extensions) { + bcx.additionalIncludesStructsHeader(outstructs); + } /* Output #defines that the runtime uses to determine type @@ -496,6 +659,7 @@ public class BuildCode { outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId()); + outstructs.println("#define OBJECTTYPE "+typeutil.getClass(TypeUtil.ObjectClass).getId()); outstructs.println("#define CHARARRAYTYPE "+ (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses())); @@ -506,7 +670,7 @@ public class BuildCode { (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses())); outstructs.println("#define NUMCLASSES "+state.numClasses()); - int totalClassSize = state.numClasses() + state.numArrays(); + int totalClassSize = state.numClasses() + state.numArrays() + state.numInterfaces(); outstructs.println("#define TOTALNUMCLASSANDARRAY "+ totalClassSize); if (state.TASK) { outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId()); @@ -516,7 +680,7 @@ public class BuildCode { } } - protected void outputClassDeclarations(PrintWriter outclassdefs, PrintWriter outglobaldefs) { + protected void outputClassDeclarations(PrintWriter outclassdefs, PrintWriter outglobaldefs, PrintWriter outglobaldefsprim) { if (state.THREAD||state.DSM||state.SINGLETM) outclassdefs.println("#include "); outclassdefs.println("#ifndef INTPTR"); @@ -535,65 +699,77 @@ public class BuildCode { ClassDescriptor cn=(ClassDescriptor)it.next(); outclassdefs.println("struct "+cn.getSafeSymbol()+";"); - if(state.MGC) { - // TODO add version for normal Java later - if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) { - // this class has static fields/blocks, need to add a global flag to - // indicate if its static fields have been initialized and/or if its - // static blocks have been executed - outglobaldefs.println(" int "+cn.getSafeSymbol()+"static_block_exe_flag;"); - } - - // for each class, create a global object - outglobaldefs.println(" struct ___Object___ "+cn.getSafeSymbol()+"classobj;"); + if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) { + // this class has static fields/blocks, need to add a global flag to + // indicate if its static fields have been initialized and/or if its + // static blocks have been executed + outglobaldefsprim.println(" int "+cn.getSafeSymbol()+"static_block_exe_flag;"); } } outclassdefs.println(""); //Print out definition for array type outclassdefs.println("struct "+arraytype+" {"); outclassdefs.println(" int type;"); + outclassdefs.println(" int hashcode;"); additionalClassObjectFields(outclassdefs); + for(BuildCodeExtension bcx: extensions) { + bcx.additionalClassObjectFields(outclassdefs); + } if (state.EVENTMONITOR) { outclassdefs.println(" int objuid;"); } if (state.THREAD) { - outclassdefs.println(" pthread_t tid;"); - outclassdefs.println(" void * lockentry;"); - outclassdefs.println(" int lockcount;"); + outclassdefs.println(" volatile int tid;"); + outclassdefs.println(" volatile int notifycount;"); } if(state.MGC) { outclassdefs.println(" int mutex;"); - outclassdefs.println(" int objlock;"); + outclassdefs.println(" volatile int notifycount;"); + outclassdefs.println(" volatile int objlock;"); if(state.MULTICOREGC) { - outclassdefs.println(" int marked;"); + //outclassdefs.println(" int marked;"); + } + if(state.PMC) { + outclassdefs.println(" int marked;"); + outclassdefs.println(" void * backward;"); } } if (state.TASK) { outclassdefs.println(" int flag;"); + outclassdefs.println(" int ___cachedCode___;"); if(!state.MULTICORE) { - outclassdefs.println(" void * flagptr;"); + outclassdefs.println(" void * flagptr;"); } else { - outclassdefs.println(" int version;"); - outclassdefs.println(" int * lock;"); // lock entry for this obj - outclassdefs.println(" int mutex;"); - outclassdefs.println(" int lockcount;"); - if(state.MULTICOREGC) { + outclassdefs.println(" int version;"); + outclassdefs.println(" int * lock;"); // lock entry for this obj + outclassdefs.println(" int mutex;"); + outclassdefs.println(" volatile int lockcount;"); + if(state.MULTICOREGC) { + //outclassdefs.println(" int marked;"); + } + if(state.PMC) { outclassdefs.println(" int marked;"); + outclassdefs.println(" void * backward;"); } } if(state.OPTIONAL) { - outclassdefs.println(" int numfses;"); - outclassdefs.println(" int * fses;"); + outclassdefs.println(" int numfses;"); + outclassdefs.println(" int * fses;"); } } - printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs, outglobaldefs); + printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs, outglobaldefs, outglobaldefsprim); printedfieldstbl.clear(); + printExtraArrayFields(outclassdefs); + for(BuildCodeExtension bcx: extensions) { + bcx.printExtraArrayFields(outclassdefs); + } + if (state.ARRAYPAD) { outclassdefs.println(" int paddingforarray;"); } @@ -601,60 +777,11 @@ public class BuildCode { outclassdefs.println(" int ___length___;"); outclassdefs.println("};\n"); - if(state.MGC) { - // TODO add version for normal Java later - outclassdefs.println(""); - //Print out definition for Class type - outclassdefs.println("struct Class {"); - outclassdefs.println(" int type;"); - - - additionalClassObjectFields(outclassdefs); - - - if (state.EVENTMONITOR) { - outclassdefs.println(" int objuid;"); - } - if (state.THREAD) { - outclassdefs.println(" pthread_t tid;"); - outclassdefs.println(" void * lockentry;"); - outclassdefs.println(" int lockcount;"); - } - if(state.MGC) { - outclassdefs.println(" int mutex;"); - outclassdefs.println(" int objlock;"); - if(state.MULTICOREGC) { - outclassdefs.println(" int marked;"); - } - } - if (state.TASK) { - outclassdefs.println(" int flag;"); - if(!state.MULTICORE) { - outclassdefs.println(" void * flagptr;"); - } else { - outclassdefs.println(" int version;"); - outclassdefs.println(" int * lock;"); // lock entry for this obj - outclassdefs.println(" int mutex;"); - outclassdefs.println(" int lockcount;"); - if(state.MULTICOREGC) { - outclassdefs.println(" int marked;"); - } - } - if(state.OPTIONAL) { - outclassdefs.println(" int numfses;"); - outclassdefs.println(" int * fses;"); - } - } - printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs, outglobaldefs); - printedfieldstbl.clear(); - outclassdefs.println("};\n"); - } - outclassdefs.println(""); outclassdefs.println("extern int classsize[];"); outclassdefs.println("extern int hasflags[];"); outclassdefs.println("extern unsigned INTPTR * pointerarray[];"); - outclassdefs.println("extern int supertypes[];"); + outclassdefs.println("extern int* supertypes[];"); outclassdefs.println(""); } @@ -692,10 +819,10 @@ public class BuildCode { outrepairstructs.println("structure "+cn.getSymbol()+" {"); outrepairstructs.println(" int __type__;"); if (state.TASK) { - outrepairstructs.println(" int __flag__;"); - if(!state.MULTICORE) { - outrepairstructs.println(" int __flagptr__;"); - } + outrepairstructs.println(" int __flag__;"); + if(!state.MULTICORE) { + outrepairstructs.println(" int __flagptr__;"); + } } printRepairStruct(cn, outrepairstructs); outrepairstructs.println("}\n"); @@ -722,13 +849,13 @@ public class BuildCode { for(int i=0; imaxcount) - maxcount=virtualcalls.getMethodCount(cd); + maxcount=virtualcalls.getMethodCount(cd); } MethodDescriptor[][] virtualtable=null; virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount]; @@ -837,7 +964,7 @@ public class BuildCode { while(classit.hasNext()) { ClassDescriptor cd=(ClassDescriptor)classit.next(); if(cd.isInterface()) { - continue; + continue; } fillinRow(cd, virtualtable, cd.getId()); } @@ -854,15 +981,15 @@ public class BuildCode { boolean needcomma=false; for(int i=0; i0) { - outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")"); + outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")"); } else { - outclassdefs.print("0"); + outclassdefs.print("0"); } needcomma=true; } @@ -955,12 +1097,19 @@ public class BuildCode { for(int i=0; i0 ? cd.getSuperDesc() : null; + ClassDescriptor supercd=i>0?cd.getSuperDesc():null; + if(supercd != null && supercd.isInterface()) { + throw new Error("Super class can not be interfaces"); + } if (needcomma) - outclassdefs.print(", "); + outclassdefs.print(", "); if (supercd==null) - outclassdefs.print("-1"); + outclassdefs.print("-1"); else - outclassdefs.print(supercd.getId()); + outclassdefs.print(supercd.getId()); needcomma=true; } @@ -985,30 +1137,45 @@ public class BuildCode { TypeDescriptor arraytd=arraytable[i]; ClassDescriptor arraycd=arraytd.getClassDesc(); if (arraycd==null) { - if (needcomma) - outclassdefs.print(", "); - outclassdefs.print(objectclass.getId()); - needcomma=true; - continue; + if (needcomma) + outclassdefs.print(", "); + outclassdefs.print(objectclass.getId()); + needcomma=true; + continue; } ClassDescriptor cd=arraycd.getSuperDesc(); int type=-1; while(cd!=null) { - TypeDescriptor supertd=new TypeDescriptor(cd); - supertd.setArrayCount(arraytd.getArrayCount()); - type=state.getArrayNumber(supertd); - if (type!=-1) { - type+=state.numClasses(); - break; - } - cd=cd.getSuperDesc(); + TypeDescriptor supertd=new TypeDescriptor(cd); + supertd.setArrayCount(arraytd.getArrayCount()); + type=state.getArrayNumber(supertd); + if (type!=-1) { + type+=state.numClasses(); + break; + } + cd=cd.getSuperDesc(); } if (needcomma) - outclassdefs.print(", "); + outclassdefs.print(", "); outclassdefs.print(type); needcomma=true; } + for(int i=0; i0; level--) { - TypeDescriptor supertd=new TypeDescriptor(objectclass); - supertd.setArrayCount(level); - type=state.getArrayNumber(supertd); - if (type!=-1) { - type+=state.numClasses(); - break; - } + TypeDescriptor supertd=new TypeDescriptor(objectclass); + supertd.setArrayCount(level); + type=state.getArrayNumber(supertd); + if (type!=-1) { + type+=state.numClasses(); + break; + } } if (needcomma) - outclassdefs.print(", "); + outclassdefs.print(", "); outclassdefs.print(type); needcomma=true; } @@ -1053,7 +1220,7 @@ public class BuildCode { protected void generateTempStructs(FlatMethod fm) { MethodDescriptor md=fm.getMethod(); TaskDescriptor task=fm.getTask(); - ParamsObject objectparams=md!=null ? new ParamsObject(md,tag++) : new ParamsObject(task, tag++); + ParamsObject objectparams=md!=null?new ParamsObject(md,tag++):new ParamsObject(task, tag++); if (md!=null) paramstable.put(md, objectparams); else @@ -1062,21 +1229,21 @@ public class BuildCode { for(int i=0; i"+ - fd.getSafeSymbol()+"))"); - } + for(Iterator allit=cn.getFieldTable().getAllDescriptorsIterator(); allit.hasNext(); ) { + FieldDescriptor fd=(FieldDescriptor)allit.next(); + if(fd.isStatic()) { + continue; + } + TypeDescriptor type=fd.getType(); + if (type.isPtr()) { + output.print(", "); + output.print("((unsigned INTPTR)&(((struct "+cn.getSafeSymbol() +" *)0)->"+ + fd.getSafeSymbol()+"))"); + } + } + if(state.TASK) { + // output the lock field + output.print(", "); + output.print("((unsigned INTPTR)&(((struct "+cn.getSafeSymbol() +" *)0)->lock))"); } output.println("};"); } + output.println("unsigned INTPTR * pointerarray[]={"); boolean needcomma=false; for(int i=0; imax) - max=number.intValue()+1; - } + Hashtable superflags=(Hashtable)flagorder.get(sp); + Iterator superflagit=superflags.keySet().iterator(); + while(superflagit.hasNext()) { + FlagDescriptor fd=(FlagDescriptor)superflagit.next(); + Integer number=(Integer)superflags.get(fd); + flags.put(fd, number); + if ((number.intValue()+1)>max) + max=number.intValue()+1; + } } Iterator flagit=cn.getFlags(); while(flagit.hasNext()) { - FlagDescriptor fd=(FlagDescriptor)flagit.next(); - if (sp==null||!sp.getFlagTable().contains(fd.getSymbol())) - flags.put(fd, new Integer(max++)); + FlagDescriptor fd=(FlagDescriptor)flagit.next(); + if (sp==null||!sp.getFlagTable().contains(fd.getSymbol())) + flags.put(fd, new Integer(max++)); } } } @@ -1343,50 +1671,65 @@ public class BuildCode { * passed in (when PRECISE GC is enabled) and (2) function * prototypes for the methods */ - protected void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout, PrintWriter globaldefout) { + protected void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout, PrintWriter globaldefout, PrintWriter globaldefprimout) { /* Output class structure */ classdefout.println("struct "+cn.getSafeSymbol()+" {"); classdefout.println(" int type;"); - + classdefout.println(" int hashcode;"); additionalClassObjectFields(classdefout); + for(BuildCodeExtension bcx: extensions) { + bcx.additionalClassObjectFields(classdefout); + } if (state.EVENTMONITOR) { classdefout.println(" int objuid;"); } if (state.THREAD) { - classdefout.println(" pthread_t tid;"); - classdefout.println(" void * lockentry;"); - classdefout.println(" int lockcount;"); + classdefout.println(" volatile int tid;"); + classdefout.println(" volatile int notifycount;"); } - if(state.MGC) { + if (state.MGC) { classdefout.println(" int mutex;"); - classdefout.println(" int objlock;"); + classdefout.println(" volatile int notifycount;"); + classdefout.println(" volatile int objlock;"); if(state.MULTICOREGC) { - classdefout.println(" int marked;"); + //classdefout.println(" int marked;"); + } + if(state.PMC) { + classdefout.println(" int marked;"); + classdefout.println(" void * backward;"); } } if (state.TASK) { classdefout.println(" int flag;"); + classdefout.println(" int ___cachedCode___;"); if((!state.MULTICORE) || (cn.getSymbol().equals("TagDescriptor"))) { - classdefout.println(" void * flagptr;"); - } else if (state.MULTICORE) { - classdefout.println(" int version;"); - classdefout.println(" int * lock;"); // lock entry for this obj - classdefout.println(" int mutex;"); - classdefout.println(" int lockcount;"); - if(state.MULTICOREGC) { + classdefout.println(" void * flagptr;"); + } + if (state.MULTICORE) { + classdefout.println(" int version;"); + classdefout.println(" int * lock;"); // lock entry for this obj + classdefout.println(" int mutex;"); + classdefout.println(" volatile int lockcount;"); + if(state.MULTICOREGC) { + //classdefout.println(" int marked;"); + } + if(state.PMC) { classdefout.println(" int marked;"); + classdefout.println(" void * backward;"); } } if (state.OPTIONAL) { - classdefout.println(" int numfses;"); - classdefout.println(" int * fses;"); + classdefout.println(" int numfses;"); + classdefout.println(" int * fses;"); } } - printClassStruct(cn, classdefout, globaldefout); - printedfieldstbl.clear();// = new Hashtable(); + if (javabuilder==null||javabuilder.hasLayout(cn)) + printClassStruct(cn, classdefout, globaldefout, globaldefprimout); + + printedfieldstbl.clear(); // = new Hashtable(); classdefout.println("};\n"); generateCallStructsMethods(cn, output, headersout); } @@ -1395,49 +1738,139 @@ public class BuildCode { protected void generateCallStructsMethods(ClassDescriptor cn, PrintWriter output, PrintWriter headersout) { for(Iterator methodit=cn.getMethods(); methodit.hasNext(); ) { MethodDescriptor md=(MethodDescriptor)methodit.next(); + + FlatMethod fm=state.getMethodFlat(md); + + if (!callgraph.isCallable(md)&&(!md.isStaticBlock()||!callgraph.isInit(cn))) { + if (callgraph.isCalled(md)) { + generateTempStructs(fm); + generateMethodParam(cn, md, output); + } + continue; + } + + generateTempStructs(fm); + generateMethodParam(cn, md, output); + generateMethod(cn, md, headersout, output); - } + } } protected void generateMethodParam(ClassDescriptor cn, MethodDescriptor md, PrintWriter output) { /* Output parameter structure */ - if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) { + if(md.isInvokedByStatic() && !md.isStaticBlock() && !md.getModifiers().isNative()) { + // generate the staticinit version + String mdstring = md.getSafeMethodDescriptor() + "staticinit"; + + ParamsObject objectparams=(ParamsObject) paramstable.get(md); + output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+mdstring+"_params {"); + output.println(" int size;"); + output.println(" void * next;"); + for(int i=0; imaxtaskparams) { - maxtaskparams=objectparams.numPointers()+fm.numTags(); - } + output.println("};\n"); + if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) { + maxtaskparams=objectparams.numPointers()+fm.numTags(); + } } /* Output temp structure */ - if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { - output.println("struct "+task.getSafeSymbol()+"_locals {"); - output.println(" int size;"); - output.println(" void * next;"); - for(int i=0; iclassobjs->___length___))+sizeof(int)))[" + cd.getId() + "]);"); + } else { + outmethod.println("jobject rec=JNIWRAP("+generateTemp(fm, fm.getParameter(0))+");"); + startindex=1; + } + for(int i=startindex; i" + cn.getSafeSymbol()+"static_block_exe_flag != 0) {"); - output.println(" return;"); - output.println(" }"); - output.println(""); - } - if((!fm.getMethod().isStaticBlock()) && (fm.getMethod().getReturnType() == null) && (cn != null)) { - // is a constructor, check and output initialization of the static fields - // here does not initialize the static fields of the class, instead it - // redirect the corresponding fields in the object to the global_defs_p - Vector fields=cn.getFieldVec(); - - for(int i=0; i"+fd.getSafeSymbol()+"=&(global_defs_p->"+fd.getSafeSymbol()+");"); - } - } - } + if(fm.getMethod()!=null&&fm.getMethod().isStaticBlock()) { + // a static block, check if it has been executed + output.println(" if(global_defsprim_p->" + cn.getSafeSymbol()+"static_block_exe_flag != 0) {"); + output.println(" return;"); + output.println(" }"); + output.println(""); } generateCode(fm.getNext(0), fm, null, output); output.println("}\n\n"); + + mgcstaticinit = false; } protected void generateCode(FlatNode first, @@ -1649,73 +2195,70 @@ public class BuildCode { tovisit.add(first); while(current_node!=null||!tovisit.isEmpty()) { if (current_node==null) { - current_node=(FlatNode)tovisit.iterator().next(); - tovisit.remove(current_node); + current_node=(FlatNode)tovisit.iterator().next(); + tovisit.remove(current_node); } else if (tovisit.contains(current_node)) { - tovisit.remove(current_node); + tovisit.remove(current_node); } visited.add(current_node); if (nodetolabel.containsKey(current_node)) { - output.println("L"+nodetolabel.get(current_node)+":"); + output.println("L"+nodetolabel.get(current_node)+":"); } if (state.INSTRUCTIONFAILURE) { - if (state.THREAD) { - output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}"); - } else - output.println("if ((--instructioncount)==0) injectinstructionfailure();"); + if (state.THREAD) { + output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}"); + } else + output.println("if ((--instructioncount)==0) injectinstructionfailure();"); } if (current_node.numNext()==0||stopset!=null&&stopset.contains(current_node)) { - output.print(" "); - generateFlatNode(fm, current_node, output); - - if (state.OOOJAVA && stopset!=null) { - assert first.getPrev(0) instanceof FlatSESEEnterNode; - assert current_node instanceof FlatSESEExitNode; - FlatSESEEnterNode fsen = (FlatSESEEnterNode) first.getPrev(0); - FlatSESEExitNode fsxn = (FlatSESEExitNode) current_node; - assert fsen.getFlatExit().equals(fsxn); - assert fsxn.getFlatEnter().equals(fsen); - } - if (current_node.kind()!=FKind.FlatReturnNode) { - if(state.MGC) { - // TODO add version for normal Java later - if((fm.getMethod() != null) && (fm.getMethod().isStaticBlock())) { - // a static block, check if it has been executed - output.println(" global_defs_p->" + fm.getMethod().getClassDesc().getSafeSymbol()+"static_block_exe_flag = 1;"); - output.println(""); - } - } - output.println(" return;"); - } - current_node=null; + output.print(" "); + generateFlatNode(fm, current_node, output); + + if (state.OOOJAVA && stopset!=null) { + assert first.getPrev(0) instanceof FlatSESEEnterNode; + assert current_node instanceof FlatSESEExitNode; + FlatSESEEnterNode fsen = (FlatSESEEnterNode) first.getPrev(0); + FlatSESEExitNode fsxn = (FlatSESEExitNode) current_node; + assert fsen.getFlatExit().equals(fsxn); + assert fsxn.getFlatEnter().equals(fsen); + } + if (current_node.kind()!=FKind.FlatReturnNode) { + if((fm.getMethod() != null) && (fm.getMethod().isStaticBlock())) { + // a static block, check if it has been executed + output.println(" global_defsprim_p->" + fm.getMethod().getClassDesc().getSafeSymbol()+"static_block_exe_flag = 1;"); + output.println(""); + } + output.println(" return;"); + } + current_node=null; } else if(current_node.numNext()==1) { - FlatNode nextnode; - if (state.OOOJAVA && - current_node.kind()==FKind.FlatSESEEnterNode) { - FlatSESEEnterNode fsen = (FlatSESEEnterNode)current_node; - generateFlatNode(fm, current_node, output); - nextnode=fsen.getFlatExit().getNext(0); - } else { - output.print(" "); - generateFlatNode(fm, current_node, output); - nextnode=current_node.getNext(0); - } - if (visited.contains(nextnode)) { - output.println("goto L"+nodetolabel.get(nextnode)+";"); - current_node=null; - } else - current_node=nextnode; + FlatNode nextnode; + if (state.OOOJAVA && + current_node.kind()==FKind.FlatSESEEnterNode) { + FlatSESEEnterNode fsen = (FlatSESEEnterNode)current_node; + generateFlatNode(fm, current_node, output); + nextnode=fsen.getFlatExit().getNext(0); + } else { + output.print(" "); + generateFlatNode(fm, current_node, output); + nextnode=current_node.getNext(0); + } + if (visited.contains(nextnode)) { + output.println("goto L"+nodetolabel.get(nextnode)+";"); + current_node=null; + } else + current_node=nextnode; } else if (current_node.numNext()==2) { - /* Branch */ - output.print(" "); - generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output); - if (!visited.contains(current_node.getNext(1))) - tovisit.add(current_node.getNext(1)); - if (visited.contains(current_node.getNext(0))) { - output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";"); - current_node=null; - } else - current_node=current_node.getNext(0); + /* Branch */ + output.print(" "); + generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output); + if (!visited.contains(current_node.getNext(1))) + tovisit.add(current_node.getNext(1)); + if (visited.contains(current_node.getNext(0))) { + output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";"); + current_node=null; + } else + current_node=current_node.getNext(0); } else throw new Error(); } } @@ -1737,24 +2280,24 @@ public class BuildCode { if(lastset!=null&&lastset.contains(fn)) { - // if last is not null and matches, don't go - // any further for assigning labels - continue; + // if last is not null and matches, don't go + // any further for assigning labels + continue; } for(int i=0; i0) { - //1) Edge >1 of node - nodetolabel.put(nn,new Integer(labelindex++)); - } - if (!visited.contains(nn)&&!tovisit.contains(nn)) { - tovisit.add(nn); - } else { - //2) Join point - nodetolabel.put(nn,new Integer(labelindex++)); - } + if(i>0) { + //1) Edge >1 of node + nodetolabel.put(nn,new Integer(labelindex++)); + } + if (!visited.contains(nn)&&!tovisit.contains(nn)) { + tovisit.add(nn); + } else { + //2) Join point + nodetolabel.put(nn,new Integer(labelindex++)); + } } } return nodetolabel; @@ -1764,7 +2307,7 @@ public class BuildCode { protected String generateTemp(FlatMethod fm, TempDescriptor td) { MethodDescriptor md=fm.getMethod(); TaskDescriptor task=fm.getTask(); - TempObject objecttemps=(TempObject) tempstable.get(md!=null ? md : task); + TempObject objecttemps=(TempObject) tempstable.get(md!=null?md:task); if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) { return td.getSafeSymbol(); @@ -1784,7 +2327,12 @@ public class BuildCode { protected void generateFlatNode(FlatMethod fm, FlatNode fn, PrintWriter output) { + if(state.LINENUM) printSourceLineNumber(fm,fn,output); + additionalCodePreNode(fm, fn, output); + for(BuildCodeExtension bcx: extensions) { + bcx.additionalCodePreNode(fm, fn, output); + } switch(fn.kind()) { @@ -1865,7 +2413,8 @@ public class BuildCode { break; case FKind.FlatGenReachNode: - // this node is just for generating a reach graph + case FKind.FlatGenDefReachNode: + // these nodes are just for generating analysis data // in disjointness analysis at a particular program point break; @@ -1898,15 +2447,19 @@ public class BuildCode { } additionalCodePostNode(fm, fn, output); + for(BuildCodeExtension bcx: extensions) { + bcx.additionalCodePostNode(fm, fn, output); + } + } public void generateFlatBackEdge(FlatMethod fm, FlatBackEdge fn, PrintWriter output) { if (((state.OOOJAVA||state.THREAD)&&GENERATEPRECISEGC) - || (this.state.MULTICOREGC)) { - if(this.state.MULTICOREGC) { - output.println("if (gcflag) gc("+localsprefixaddr+");"); + || state.MULTICOREGC||state.PMC) { + if (state.MULTICOREGC||state.PMC) { + output.println("GCCHECK("+localsprefixaddr+");"); } else { - output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");"); + output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");"); } } else output.println("/* nop */"); @@ -1915,8 +2468,10 @@ public class BuildCode { public void generateFlatOffsetNode(FlatMethod fm, FlatOffsetNode fofn, PrintWriter output) { output.println("/* FlatOffsetNode */"); FieldDescriptor fd=fofn.getField(); - output.println(generateTemp(fm, fofn.getDst())+ " = (short)(int) (&((struct "+fofn.getClassType().getSafeSymbol() +" *)0)->"+ - fd.getSafeSymbol()+");"); + if(!fd.isStatic()) { + output.println(generateTemp(fm, fofn.getDst())+ " = (short)(int) (&((struct "+fofn.getClassType().getSafeSymbol() +" *)0)->"+ + fd.getSafeSymbol()+");"); + } output.println("/* offset */"); } @@ -1928,16 +2483,27 @@ public class BuildCode { public void generateFlatInstanceOfNode(FlatMethod fm, FlatInstanceOfNode fion, PrintWriter output) { int type; + int otype; if (fion.getType().isArray()) { type=state.getArrayNumber(fion.getType())+state.numClasses(); + } else if (fion.getType().getClassDesc().isInterface()) { + type=fion.getType().getClassDesc().getId()+state.numClasses()+state.numArrays(); } else { type=fion.getType().getClassDesc().getId(); } + if (fion.getSrc().getType().isArray()) { + otype=state.getArrayNumber(fion.getSrc().getType())+state.numClasses(); + } else if (fion.getSrc().getType().getClassDesc().isInterface()) { + otype=fion.getSrc().getType().getClassDesc().getId()+state.numClasses()+state.numArrays(); + } else { + otype=fion.getSrc().getType().getClassDesc().getId(); + } if (fion.getType().getSymbol().equals(TypeUtil.ObjectClass)) - output.println(generateTemp(fm, fion.getDst())+"=1;"); - else + output.println(generateTemp(fm, fion.getDst())+"=(" + generateTemp(fm,fion.getSrc()) + "!= NULL);"); + else { output.println(generateTemp(fm, fion.getDst())+"=instanceof("+generateTemp(fm,fion.getSrc())+","+type+");"); + } } public void generateFlatAtomicEnterNode(FlatMethod fm, FlatAtomicEnterNode faen, PrintWriter output) { @@ -1976,7 +2542,7 @@ public class BuildCode { TempDescriptor[] temps=fcn.getTemps(); String[] vars=fcn.getVars(); for(int i=0; i"+vars[i]+"=(unsigned int)"+generateTemp(fm, temps[i])+";"); + output.println(varname+"->"+vars[i]+"=(unsigned int)"+generateTemp(fm, temps[i])+";"); } output.println("if (doanalysis"+specname+"("+varname+")) {"); @@ -1993,75 +2559,96 @@ public class BuildCode { protected void generateFlatCall(FlatMethod fm, FlatCall fc, PrintWriter output) { MethodDescriptor md=fc.getMethod(); ParamsObject objectparams=(ParamsObject)paramstable.get(md); + ClassDescriptor cn=md.getClassDesc(); + String mdstring = md.getSafeMethodDescriptor(); + if(mgcstaticinit && !md.isStaticBlock() && !md.getModifiers().isNative()) { + mdstring += "staticinit"; + } // if the called method is a static block or a static method or a constructor // need to check if it can be invoked inside some static block - if(state.MGC) { - // TODO add version for normal Java later - if((md.isStatic() || md.isStaticBlock() || md.isConstructor()) && - ((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic()))) { - if(!md.isInvokedByStatic()) { - System.err.println("Error: a method that is invoked inside a static block is not tagged!"); - } - // is a static block or is invoked in some static block - ClassDescriptor cd = fm.getMethod().getClassDesc(); - if(cd == cn) { - // the same class, do nothing - // TODO may want to invoke static field initialization here - } else { - if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) { - // need to check if the class' static fields have been initialized and/or - // its static blocks have been executed - output.println("#ifdef MGC_STATIC_INIT_CHECK"); - output.println("if(global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {"); - if(cn.getNumStaticBlocks() != 0) { - MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks"); - output.println(" "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();"); - } else { - output.println(" global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;"); - } - output.println("}"); - output.println("#endif // MGC_STATIC_INIT_CHECK"); - } - } + if((md.isStatic() || md.isStaticBlock() || md.isConstructor()) && + ((fm.getMethod() != null) && ((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())))) { + if(!md.isInvokedByStatic()) { + System.err.println("Error: a method that is invoked inside a static block is not tagged!"); + } + // is a static block or is invoked in some static block + ClassDescriptor cd = fm.getMethod().getClassDesc(); + if(cd != cn && mgcstaticinit && callgraph.isInit(cn)) { + // generate static init check code if it has not done static init in main() + if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) { + // need to check if the class' static fields have been initialized and/or + // its static blocks have been executed + output.println("if(global_defsprim_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {"); + if(cn.getNumStaticBlocks() != 0) { + MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks"); + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) { + output.print(" struct "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"_params __parameterlist__={"); + output.println("0, NULL};"); + output.println(" "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"(& __parameterlist__);"); + } else { + output.println(" "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();"); + } + } else { + output.println(" global_defsprim_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;"); + } + output.println("}"); + } } - if((md.getSymbol().equals("MonitorEnter") || md.getSymbol().equals("MonitorExit")) && fc.getThis().getSymbol().equals("classobj")) { - // call MonitorEnter/MonitorExit on a class obj - output.println(" " + cn.getSafeSymbol()+md.getSafeSymbol()+"_" - +md.getSafeMethodDescriptor() + "((struct ___Object___*)(&global_defs_p->" - + fc.getThis().getType().getClassDesc().getSafeSymbol() +"classobj));"); - return; + } + if((md.getSymbol().equals("MonitorEnter") || md.getSymbol().equals("MonitorExit")) && fc.getThis().getSymbol().equals("classobj")) { + output.println("{"); + if(md.getSymbol().equals("MonitorEnter") && state.OBJECTLOCKDEBUG) { + output.println("int monitorenterline = __LINE__;"); + } + // call MonitorEnter/MonitorExit on a class obj + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) { + output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={"); + output.println("1," + localsprefixaddr + ", ((void **)(((char *) &(global_defs_p->classobjs->___length___))+sizeof(int)))[" + fc.getThis().getType().getClassDesc().getId() + "]};"); + if(md.getSymbol().equals("MonitorEnter") && state.OBJECTLOCKDEBUG) { + output.println(" "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__, monitorenterline);"); + } else { + output.println(" "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);"); + } + } else { + output.println(" " + cn.getSafeSymbol()+md.getSafeSymbol()+"_" + + md.getSafeMethodDescriptor() + "((struct ___Object___*)(((void **)(((char *) &(global_defs_p->classobjs->___length___))+sizeof(int)))[" + + fc.getThis().getType().getClassDesc().getId() + "]));"); } + output.println("}"); + return; } output.println("{"); - if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { - output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={"); + if(md.getSymbol().equals("MonitorEnter")) { + output.println("int monitorenterline = __LINE__;"); + } + if (GENERATEPRECISEGC || state.MULTICOREGC||state.PMC) { + output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+mdstring+"_params __parameterlist__={"); output.print(objectparams.numPointers()); output.print(", "+localsprefixaddr); if (md.getThis()!=null) { - output.print(", "); - output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis())); + output.print(", "); + output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis())); } if (fc.getThis()!=null&&md.getThis()==null) { - System.out.println("WARNING!!!!!!!!!!!!"); - System.out.println("Source code calls static method "+md+" on an object in "+fm.getMethod()+"!"); + System.out.println("WARNING!!!!!!!!!!!!"); + System.out.println("Source code calls static method "+md+" on an object in "+fm.getMethod()+"!"); } - for(int i=0; itype*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])"); } output.print("("); boolean needcomma=false; - if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) { output.print("&__parameterlist__"); needcomma=true; } - if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) { + if (!GENERATEPRECISEGC && !state.MULTICOREGC&&!state.PMC) { if (fc.getThis()!=null) { - TypeDescriptor ptd=null; - if(md.getThis() != null) { - ptd = md.getThis().getType(); - } else { - ptd = fc.getThis().getType(); - } - if (needcomma) - output.print(","); - if(state.MGC && ptd.isClass() && ptd.getClassDesc().isEnum()) { - // do nothing - } else if (ptd.isClass()&&!ptd.isArray()) - output.print("(struct "+ptd.getSafeSymbol()+" *) "); - output.print(generateTemp(fm,fc.getThis())); - needcomma=true; + TypeDescriptor ptd=null; + if(md.getThis() != null) { + ptd = md.getThis().getType(); + } else { + ptd = fc.getThis().getType(); + } + if (needcomma) + output.print(","); + if(ptd.isClass() && ptd.getClassDesc().isEnum()) { + // do nothing + } else if (ptd.isClass()&&!ptd.isArray()) + output.print("(struct "+ptd.getSafeSymbol()+" *) "); + output.print(generateTemp(fm,fc.getThis())); + needcomma=true; } } @@ -2139,82 +2729,143 @@ public class BuildCode { Descriptor var=md.getParameter(i); TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var); if (objectparams.isParamPrim(paramtemp)) { - TempDescriptor targ=fc.getArg(i); - if (needcomma) - output.print(", "); + TempDescriptor targ=fc.getArg(i); + if (needcomma) + output.print(", "); - TypeDescriptor ptd=md.getParamType(i); - if (state.MGC && ptd.isClass() && ptd.getClassDesc().isEnum()) { - // do nothing - } else if (ptd.isClass()&&!ptd.isArray()) - output.print("(struct "+ptd.getSafeSymbol()+" *) "); - output.print(generateTemp(fm, targ)); - needcomma=true; + TypeDescriptor ptd=md.getParamType(i); + if (ptd.isClass() && ptd.getClassDesc().isEnum()) { + // do nothing + } else if (ptd.isClass()&&!ptd.isArray()) + output.print("(struct "+ptd.getSafeSymbol()+" *) "); + output.print(generateTemp(fm, targ)); + needcomma=true; } } - output.println(");"); + if(md.getSymbol().equals("MonitorEnter") && state.OBJECTLOCKDEBUG) { + output.println(", monitorenterline);"); + } else { + output.println(");"); + } output.println(" }"); } protected boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) { - Set subclasses=typeutil.getSubClasses(thiscd); - if (subclasses==null) - return true; - for(Iterator classit=subclasses.iterator(); classit.hasNext(); ) { - ClassDescriptor cd=(ClassDescriptor)classit.next(); - Set possiblematches=cd.getMethodTable().getSetFromSameScope(md.getSymbol()); - for(Iterator matchit=possiblematches.iterator(); matchit.hasNext(); ) { - MethodDescriptor matchmd=(MethodDescriptor)matchit.next(); - if (md.matches(matchmd)) - return false; + if(thiscd.isInterface()) { + // for interfaces, always need virtual dispatch + return false; + } else { + Set subclasses=typeutil.getSubClasses(thiscd); + if (subclasses==null) + return true; + for(Iterator classit=subclasses.iterator(); classit.hasNext(); ) { + ClassDescriptor cd=(ClassDescriptor)classit.next(); + Set possiblematches=cd.getMethodTable().getSetFromSameScope(md.getSymbol()); + for(Iterator matchit=possiblematches.iterator(); matchit.hasNext(); ) { + MethodDescriptor matchmd=(MethodDescriptor)matchit.next(); + if (md.matches(matchmd)) + return false; + } } } return true; } protected void generateFlatFieldNode(FlatMethod fm, FlatFieldNode ffn, PrintWriter output) { - if(state.MGC) { - // TODO add version for normal Java later - if(ffn.getField().isStatic()) { - // static field - if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) { - // is a static block or is invoked in some static block - ClassDescriptor cd = fm.getMethod().getClassDesc(); - ClassDescriptor cn = ffn.getSrc().getType().getClassDesc(); - if(cd == cn) { - // the same class, do nothing - // TODO may want to invoke static field initialization here - } else { - if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) { - // need to check if the class' static fields have been initialized and/or - // its static blocks have been executed - output.println("#ifdef MGC_STATIC_INIT_CHECK"); - output.println("if(global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {"); - if(cn.getNumStaticBlocks() != 0) { - MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks"); - output.println(" "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();"); - } else { - output.println(" global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;"); - } - output.println("}"); - output.println("#endif // MGC_STATIC_INIT_CHECK"); + + if(ffn.getField().isStatic()) { + // static field + if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) { + // is a static block or is invoked in some static block + ClassDescriptor cd = fm.getMethod().getClassDesc(); + ClassDescriptor cn = ffn.getSrc().getType().getClassDesc(); + if(cd != cn && mgcstaticinit && callgraph.isInit(cn)) { + // generate the static init check code if has not done the static init in main() + if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) { + // need to check if the class' static fields have been initialized and/or + // its static blocks have been executed + output.println("if(global_defsprim_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {"); + if(cn.getNumStaticBlocks() != 0) { + MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks"); + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) { + output.print(" struct "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"_params __parameterlist__={"); + output.println("0, NULL};"); + output.println(" "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"(& __parameterlist__);"); + } else { + output.println(" "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();"); + } + } else { + output.println(" global_defsprim_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;"); + } + output.println("}"); + } + } + } + // redirect to the global_defs_p structure + if(state.SSJAVA_GENCODE_PREVENT_CRASHES){ + if (ffn.getField().getType().isPtr()){ + output.println("if ( global_defs_p == NULL) {"); + output.println("printf(\"SSJAVA: Dereferencing NULL Pointer at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);"); + output.println(generateTemp(fm, ffn.getDst())+"= NULL;"); + }else{ + output.println("if ( global_defsprim_p == NULL) {"); + output.println("printf(\"SSJAVA: Dereferencing NULL Pointer at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);"); + output.println(generateTemp(fm, ffn.getDst())+"= 0;"); + } + output.println("}else{"); + if (ffn.getField().getType().isPtr()) + output.println(generateTemp(fm, ffn.getDst())+"=global_defs_p->"+ffn.getField().getSafeSymbol()+";"); + else + output.println(generateTemp(fm, ffn.getDst())+"=global_defsprim_p->"+ffn.getField().getSafeSymbol()+";"); + output.println("}"); + }else{ + if (ffn.getField().getType().isPtr()) + output.println(generateTemp(fm, ffn.getDst())+"=global_defs_p->"+ffn.getField().getSafeSymbol()+";"); + else + output.println(generateTemp(fm, ffn.getDst())+"=global_defsprim_p->"+ffn.getField().getSafeSymbol()+";"); + } + } else if (ffn.getField().isEnum()) { + // an Enum value, directly replace the field access as int + output.println(generateTemp(fm, ffn.getDst()) + "=" + ffn.getField().enumValue() + ";"); + } else if(state.SSJAVA_GENCODE_PREVENT_CRASHES){ + output.println("if (" + generateTemp(fm,ffn.getSrc()) + " == NULL) {"); + output.println("printf(\"SSJAVA: Dereferencing NULL Pointer at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);"); + if(ffn.getDst().getType().isPrimitive()){ + output.println(generateTemp(fm, ffn.getDst())+"= 0;"); + }else{ + output.println(generateTemp(fm, ffn.getDst())+"= NULL;"); + } + output.println("}else{"); + output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";"); + output.println("}"); + }else if (ffn.getField().getSymbol().equals("this")) { + // an inner class refers to itself + if( state.CAPTURE_NULL_DEREFERENCES ) { + output.println("#ifdef CAPTURE_NULL_DEREFERENCES"); + output.println("if (" + generateTemp(fm,ffn.getSrc()) + " == NULL) {"); + output.println("printf(\" NULL ptr error: %s, %s, %d \\n\", __FILE__, __func__, __LINE__);"); + if(state.MULTICOREGC||state.PMC) { + output.println("failednullptr(&___locals___);"); + } else { + output.println("failednullptr(NULL);"); } - } - } - // redirect to the global_defs_p structure - if((ffn.getField().isStatic()) || (ffn.getSrc().getType().isClassNameRef())) { - // reference to the static field with Class name - output.println(generateTemp(fm, ffn.getDst())+"=global_defs_p->"+ffn.getField().getSafeSymbol()+";"); - } else { - output.println(generateTemp(fm, ffn.getDst())+"=*"+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";"); + output.println("}"); + output.println("#endif //CAPTURE_NULL_DEREFERENCES"); } - } else if (ffn.getField().isEnum()) { - // an Enum value, directly replace the field access as int - output.println(generateTemp(fm, ffn.getDst()) + "=" + ffn.getField().enumValue() + ";"); - } else { - output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";"); - } + output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+";"); } else { + if( state.CAPTURE_NULL_DEREFERENCES ) { + output.println("#ifdef CAPTURE_NULL_DEREFERENCES"); + output.println("if (" + generateTemp(fm,ffn.getSrc()) + " == NULL) {"); + output.println("printf(\" NULL ptr error: %s, %s, %d \\n\", __FILE__, __func__, __LINE__);"); + if(state.MULTICOREGC||state.PMC) { + output.println("failednullptr(&___locals___);"); + } else { + output.println("failednullptr(NULL);"); + } + output.println("}"); + output.println("#endif //CAPTURE_NULL_DEREFERENCES"); + } output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";"); } } @@ -2227,80 +2878,147 @@ public class BuildCode { String dst=generateTemp(fm, fsfn.getDst()); output.println("if(!"+dst+"->"+localcopystr+") {"); /* Link object into list */ - if (GENERATEPRECISEGC || this.state.MULTICOREGC) - output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");"); + if (GENERATEPRECISEGC || state.MULTICOREGC||state.PMC) + output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");"); else - output.println("COPY_OBJ("+dst+");"); + output.println("COPY_OBJ("+dst+");"); output.println(dst+"->"+nextobjstr+"="+fcrevert+";"); output.println(fcrevert+"=(struct ___Object___ *)"+dst+";"); output.println("}"); } - if(state.MGC) { - // TODO add version for normal Java later - if(fsfn.getField().isStatic()) { - // static field - if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) { - // is a static block or is invoked in some static block - ClassDescriptor cd = fm.getMethod().getClassDesc(); - ClassDescriptor cn = fsfn.getDst().getType().getClassDesc(); - if(cd == cn) { - // the same class, do nothing - // TODO may want to invoke static field initialization here - } else { - if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) { - // need to check if the class' static fields have been initialized and/or - // its static blocks have been executed - output.println("#ifdef MGC_STATIC_INIT_CHECK"); - output.println("if(global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {"); - if(cn.getNumStaticFields() != 0) { - // TODO add static field initialization here - } - if(cn.getNumStaticBlocks() != 0) { - MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks"); - output.println(" "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();"); - } else { - output.println(" global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;"); - } - output.println("}"); - output.println("#endif // MGC_STATIC_INIT_CHECK"); - } - } - } - // redirect to the global_defs_p structure - if(fsfn.getDst().getType().isClassNameRef()) { - // reference to the static field with Class name - output.println("global_defs_p->" + - fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";"); - } else { - output.println("*"+generateTemp(fm, fsfn.getDst())+"->"+ - fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";"); - } - } else { - output.println(generateTemp(fm, fsfn.getDst())+"->"+ - fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";"); + + if(fsfn.getField().isStatic()) { + // static field + if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) { + // is a static block or is invoked in some static block + ClassDescriptor cd = fm.getMethod().getClassDesc(); + ClassDescriptor cn = fsfn.getDst().getType().getClassDesc(); + if(cd != cn && mgcstaticinit && callgraph.isInit(cn)) { + // generate static init check code if has not done the static init in main() + if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) { + // need to check if the class' static fields have been initialized and/or + // its static blocks have been executed + output.println("if(global_defsprim_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {"); + if(cn.getNumStaticBlocks() != 0) { + MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks"); + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) { + output.print(" struct "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"_params __parameterlist__={"); + output.println("0, NULL};"); + output.println(" "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"(& __parameterlist__);"); + } else { + output.println(" "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();"); + } + } else { + output.println(" global_defsprim_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;"); + } + output.println("}"); + } + } } + // redirect to the global_defs_p structure + if(state.SSJAVA_GENCODE_PREVENT_CRASHES){ + if (fsfn.getField().getType().isPtr()) { + output.println("if ( global_defs_p == NULL) {"); + output.println("printf(\"SSJAVA: Discard a write due to dereferencing NULL Pointer at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);"); + output.println("}else{"); + if (fsfn.getField().getType()!=fsfn.getSrc().getType()){ + output.println("global_defs_p->" + + fsfn.getField().getSafeSymbol()+"=(struct "+ fsfn.getField().getType().getSafeSymbol()+" *)"+generateTemp(fm,fsfn.getSrc())+";"); + }else{ + output.println("global_defs_p->" + + fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";"); + } + output.println("}"); + } else{ + output.println("if ( global_defsprim_p == NULL) {"); + output.println("printf(\"SSJAVA: Discard a write due to dereferencing NULL Pointer at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);"); + output.println("}else{"); + output.println("global_defsprim_p->" + + fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";"); + output.println("}"); + } + }else{ + if (fsfn.getField().getType().isPtr()) { + if (fsfn.getField().getType()!=fsfn.getSrc().getType()) + output.println("global_defs_p->" + + fsfn.getField().getSafeSymbol()+"=(struct "+ fsfn.getField().getType().getSafeSymbol()+" *)"+generateTemp(fm,fsfn.getSrc())+";"); + else + output.println("global_defs_p->" + + fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";"); + } else + output.println("global_defsprim_p->" + + fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";"); + } + } else if(state.SSJAVA_GENCODE_PREVENT_CRASHES){ + output.println("if (" + generateTemp(fm,fsfn.getDst()) + " == NULL) {"); + output.println("printf(\"SSJAVA: Dereferencing NULL Pointer at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);"); + output.println("}else{"); + if (fsfn.getSrc().getType().isPtr()&&fsfn.getSrc().getType()!=fsfn.getField().getType()) + output.println(generateTemp(fm, fsfn.getDst())+"->"+ + fsfn.getField().getSafeSymbol()+"=(struct "+ fsfn.getField().getType().getSafeSymbol()+"*)"+generateTemp(fm,fsfn.getSrc())+";"); + else + output.println(generateTemp(fm, fsfn.getDst())+"->"+ + fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";"); + output.println("}"); } else { - output.println(generateTemp(fm, fsfn.getDst())+"->"+ - fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";"); + if( state.CAPTURE_NULL_DEREFERENCES ) { + output.println("#ifdef CAPTURE_NULL_DEREFERENCES"); + output.println("if (" + generateTemp(fm,fsfn.getDst()) + " == NULL) {"); + output.println("printf(\" NULL ptr error: %s, %s, %d \\n\", __FILE__, __func__, __LINE__);"); + if(state.MULTICOREGC||state.PMC) { + output.println("failednullptr(&___locals___);"); + } else { + output.println("failednullptr(NULL);"); + } + output.println("}"); + output.println("#endif //CAPTURE_NULL_DEREFERENCES"); + } + + if (fsfn.getSrc().getType().isPtr()&&fsfn.getSrc().getType()!=fsfn.getField().getType()) + output.println(generateTemp(fm, fsfn.getDst())+"->"+ + fsfn.getField().getSafeSymbol()+"=(struct "+ fsfn.getField().getType().getSafeSymbol()+"*)"+generateTemp(fm,fsfn.getSrc())+";"); + else + output.println(generateTemp(fm, fsfn.getDst())+"->"+ + fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";"); } } - + + protected void generateFlatElementNode(FlatMethod fm, FlatElementNode fen, PrintWriter output) { TypeDescriptor elementtype=fen.getSrc().getType().dereference(); String type=""; - if (state.MGC && elementtype.isClass() && elementtype.getClassDesc().isEnum()) { + if (elementtype.isClass() && elementtype.getClassDesc().isEnum()) { type="int "; } else if (elementtype.isArray()||elementtype.isClass()) type="void *"; else type=elementtype.getSafeSymbol()+" "; - - if (this.state.ARRAYBOUNDARYCHECK && fen.needsBoundsCheck()) { - output.println("if (unlikely(((unsigned int)"+generateTemp(fm, fen.getIndex())+") >= "+generateTemp(fm,fen.getSrc()) + "->___length___))"); - output.println("failedboundschk();"); + + if(state.SSJAVA_GENCODE_PREVENT_CRASHES){ + output.println("if (" + generateTemp(fm,fen.getSrc()) + " == NULL) {"); + output.println("printf(\"SSJAVA: Dereferencing NULL Pointer at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);"); + output.println("}else{"); + output.println("if (unlikely( ((unsigned int)"+generateTemp(fm, fen.getIndex())+") >= "+generateTemp(fm,fen.getSrc()) + "->___length___)){"); + output.println("printf(\"SSJAVA: Array out of bounds at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);"); + if(fen.getDst().getType().isPrimitive()){ + output.println(generateTemp(fm, fen.getDst())+"= 0;"); + }else{ + output.println(generateTemp(fm, fen.getDst())+"= NULL;"); + } + output.println("}else{"); + output.println(generateTemp(fm, fen.getDst())+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc())+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex())+"];"); + output.println("}"); + output.println("}"); + }else{ + if (this.state.ARRAYBOUNDARYCHECK && fen.needsBoundsCheck()) { + output.println("if (unlikely(((unsigned int)"+generateTemp(fm, fen.getIndex())+") >= "+generateTemp(fm,fen.getSrc()) + "->___length___))"); + output.println("failedboundschk(__LINE__, " +generateTemp(fm, fen.getIndex()) +", "+ generateTemp(fm, fen.getSrc()) + ");"); + } + output.println(generateTemp(fm, fen.getDst())+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc())+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex())+"];"); } - output.println(generateTemp(fm, fen.getDst())+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc())+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex())+"];"); + + } protected void generateFlatSetElementNode(FlatMethod fm, FlatSetElementNode fsen, PrintWriter output) { @@ -2310,58 +3028,75 @@ public class BuildCode { TypeDescriptor elementtype=fsen.getDst().getType().dereference(); String type=""; - if (state.MGC && elementtype.isClass() && elementtype.getClassDesc().isEnum()) { + if (elementtype.isClass() && elementtype.getClassDesc().isEnum()) { type="int "; - } else if (elementtype.isArray()||elementtype.isClass() || (state.MGC && elementtype.isNull())) + } else if (elementtype.isArray()||elementtype.isClass() || (elementtype.isNull())) type="void *"; else type=elementtype.getSafeSymbol()+" "; - - if (this.state.ARRAYBOUNDARYCHECK && fsen.needsBoundsCheck()) { - output.println("if (unlikely(((unsigned int)"+generateTemp(fm, fsen.getIndex())+") >= "+generateTemp(fm,fsen.getDst()) + "->___length___))"); - output.println("failedboundschk();"); - } - if (state.FASTCHECK) { - String dst=generateTemp(fm, fsen.getDst()); - output.println("if(!"+dst+"->"+localcopystr+") {"); - /* Link object into list */ - if (GENERATEPRECISEGC || this.state.MULTICOREGC) - output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");"); - else - output.println("COPY_OBJ("+dst+");"); - output.println(dst+"->"+nextobjstr+"="+fcrevert+";"); - output.println(fcrevert+"=(struct ___Object___ *)"+dst+";"); + + if(state.SSJAVA_GENCODE_PREVENT_CRASHES){ + output.println("if ("+generateTemp(fm,fsen.getDst())+"==NULL){"); + output.println("printf(\"SSJAVA: Dereferencing NULL Pointer at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);"); + output.println("}else{"); + output.println("if (unlikely(((unsigned int)"+generateTemp(fm, fsen.getIndex())+") >= "+generateTemp(fm,fsen.getDst()) + "->___length___)){"); + output.println("printf(\"SSJAVA: Discard a write due to array out of bounds at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);"); + output.println("}else{"); + output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst())+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex())+"]="+generateTemp(fm,fsen.getSrc())+";"); + output.println("}"); output.println("}"); + }else{ + if (this.state.ARRAYBOUNDARYCHECK && fsen.needsBoundsCheck()) { + output.println("if (unlikely(((unsigned int)"+generateTemp(fm, fsen.getIndex())+") >= "+generateTemp(fm,fsen.getDst()) + "->___length___))"); + output.println("failedboundschk(__LINE__, " +generateTemp(fm, fsen.getIndex()) +", "+ generateTemp(fm, fsen.getDst()) + ");"); + } + if (state.FASTCHECK) { + String dst=generateTemp(fm, fsen.getDst()); + output.println("if(!"+dst+"->"+localcopystr+") {"); + /* Link object into list */ + if (GENERATEPRECISEGC || state.MULTICOREGC||state.PMC) + output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");"); + else + output.println("COPY_OBJ("+dst+");"); + output.println(dst+"->"+nextobjstr+"="+fcrevert+";"); + output.println(fcrevert+"=(struct ___Object___ *)"+dst+";"); + output.println("}"); + } + output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst())+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex())+"]="+generateTemp(fm,fsen.getSrc())+";"); } - output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst())+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex())+"]="+generateTemp(fm,fsen.getSrc())+";"); + } protected void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) { + String dst=generateTemp(fm,fn.getDst()); + if (fn.getType().isArray()) { int arrayid=state.getArrayNumber(fn.getType())+state.numClasses(); - if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { - output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize())+");"); + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) { + output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize())+");"); } else { - output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");"); + output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");"); } } else { - if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { - output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");"); + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) { + output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");"); } else { - output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");"); + output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");"); } } if (state.FASTCHECK) { - String dst=generateTemp(fm,fn.getDst()); output.println(dst+"->___localcopy___=(struct ___Object___*)1;"); output.println(dst+"->"+nextobjstr+"="+fcrevert+";"); output.println(fcrevert+"=(struct ___Object___ *)"+dst+";"); } + for(BuildCodeExtension bcx: extensions) { + bcx.additionalCodeNewObject(output, dst, fn); + } } protected void generateFlatTagDeclaration(FlatMethod fm, FlatTagDeclaration fn, PrintWriter output) { - if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) { output.println(generateTemp(fm,fn.getDst())+"=allocate_tag("+localsprefixaddr+", "+state.getTagId(fn.getType())+");"); } else { output.println(generateTemp(fm,fn.getDst())+"=allocate_tag("+state.getTagId(fn.getType())+");"); @@ -2371,15 +3106,31 @@ public class BuildCode { protected void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) { if (fon.getRight()!=null) { if (fon.getOp().getOp()==Operation.URIGHTSHIFT) { - if (fon.getLeft().getType().isLong()) - output.println(generateTemp(fm, fon.getDest())+" = ((unsigned long long)"+generateTemp(fm, fon.getLeft())+")>>"+generateTemp(fm,fon.getRight())+";"); - else - output.println(generateTemp(fm, fon.getDest())+" = ((unsigned int)"+generateTemp(fm, fon.getLeft())+")>>"+generateTemp(fm,fon.getRight())+";"); + if (fon.getLeft().getType().isLong()) + output.println(generateTemp(fm, fon.getDest())+" = ((unsigned long long)"+generateTemp(fm, fon.getLeft())+")>>"+generateTemp(fm,fon.getRight())+";"); + else + output.println(generateTemp(fm, fon.getDest())+" = ((unsigned int)"+generateTemp(fm, fon.getLeft())+")>>"+generateTemp(fm,fon.getRight())+";"); - } else - output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";"); + } else { + if(state.SSJAVA_GENCODE_PREVENT_CRASHES && fon.getOp().getOp()==Operation.DIV){ + output.println("if (unlikely("+generateTemp(fm,fon.getRight())+"==0)){"); + output.println("printf(\"SSJAVA: Divided by zero at file:%s, func:%s, line:%d \\n\", __FILE__, __func__, __LINE__);"); + output.println(generateTemp(fm, fon.getDest())+" = 0;"); + output.println("}else{"); + output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";"); + output.println("}"); + }else{ + if (fon.getLeft().getType().isPtr()&&fon.getLeft().getType()!=fon.getRight().getType()&&!fon.getRight().getType().isNull()) + output.println(generateTemp(fm, fon.getDest())+" = (struct "+fon.getRight().getType().getSafeSymbol()+"*)"+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";"); + else + output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";"); + } + } } else if (fon.getOp().getOp()==Operation.ASSIGN) - output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";"); + if (fon.getDest().getType().isPtr()&&fon.getDest().getType()!=fon.getLeft().getType()) + output.println(generateTemp(fm, fon.getDest())+" = (struct "+fon.getDest().getType().getSafeSymbol()+"*)"+generateTemp(fm, fon.getLeft())+";"); + else + output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";"); else if (fon.getOp().getOp()==Operation.UNARYPLUS) output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";"); else if (fon.getOp().getOp()==Operation.UNARYMINUS) @@ -2398,7 +3149,7 @@ public class BuildCode { /* TODO: Do type check here */ if (fcn.getType().isArray()) { output.println(generateTemp(fm,fcn.getDst())+"=(struct ArrayObject *)"+generateTemp(fm,fcn.getSrc())+";"); - } else if (state.MGC && fcn.getType().isClass() && fcn.getType().getClassDesc().isEnum()) { + } else if (fcn.getType().isClass() && fcn.getType().getClassDesc().isEnum()) { output.println(generateTemp(fm,fcn.getDst())+"=(int)"+generateTemp(fm,fcn.getSrc())+";"); } else if (fcn.getType().isClass()) output.println(generateTemp(fm,fcn.getDst())+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc())+";"); @@ -2406,23 +3157,41 @@ public class BuildCode { output.println(generateTemp(fm,fcn.getDst())+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc())+";"); } + int flncount=0; + protected void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) { if (fln.getValue()==null) output.println(generateTemp(fm, fln.getDst())+"=0;"); else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) { - if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { - output.println(generateTemp(fm, fln.getDst())+"=NewString("+localsprefixaddr+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");"); + String str=(String)fln.getValue(); + output.println("{"); + output.print("short str"+flncount+"[]={"); + for(int i=0; i" + fm.getMethod().getClassDesc().getSafeSymbol()+"static_block_exe_flag = 1;"); - output.println(""); - } + if((fm.getMethod() != null) && (fm.getMethod().isStaticBlock())) { + // a static block, check if it has been executed + output.println(" global_defsprim_p->" + fm.getMethod().getClassDesc().getSafeSymbol()+"static_block_exe_flag = 1;"); + output.println(""); } + if (frn.getReturnTemp()!=null) { if (frn.getReturnTemp().getType().isPtr()) - output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp())+";"); + output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp())+";"); else - output.println("return "+generateTemp(fm, frn.getReturnTemp())+";"); + output.println("return "+generateTemp(fm, frn.getReturnTemp())+";"); } else { output.println("return;"); } @@ -2467,68 +3234,72 @@ public class BuildCode { md=(MethodDescriptor) des; else task=(TaskDescriptor) des; + String mdstring = md != null?md.getSafeMethodDescriptor():null; - ClassDescriptor cn=md!=null ? md.getClassDesc() : null; + ClassDescriptor cn=md!=null?md.getClassDesc():null; if (md!=null&&md.getReturnType()!=null) { - if (state.MGC && md.getReturnType().isClass() && md.getReturnType().getClassDesc().isEnum()) { - output.print("int "); + if (md.getReturnType().isClass() && md.getReturnType().getClassDesc().isEnum()) { + output.print("int "); } else if (md.getReturnType().isClass()||md.getReturnType().isArray()) - output.print("struct " + md.getReturnType().getSafeSymbol()+" * "); + output.print("struct " + md.getReturnType().getSafeSymbol()+" * "); else - output.print(md.getReturnType().getSafeSymbol()+" "); + output.print(md.getReturnType().getSafeSymbol()+" "); } else //catch the constructor case output.print("void "); if (md!=null) { - output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"("); + if(mgcstaticinit && !md.isStaticBlock() && !md.getModifiers().isNative()) { + mdstring += "staticinit"; + } + output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+mdstring+"("); } else output.print(task.getSafeSymbol()+"("); boolean printcomma=false; - if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) { if (md!=null) { - output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix); + output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+mdstring+"_params * "+paramsprefix); } else - output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix); + output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix); printcomma=true; } if (md!=null) { /* Method */ for(int i=0; imaxtaskparams) - maxtaskparams=objectparams.numPrimitives()+fm.numTags(); + maxtaskparams=objectparams.numPrimitives()+fm.numTags(); } else output.println(") {"); } @@ -2548,9 +3319,9 @@ public class BuildCode { TempDescriptor tagtmp=ttp.getTagTemp(); boolean tagstatus=ffan.getTagChange(ttp); if (tagstatus) { - tagsettable.put(objtmp, tagtmp); + tagsettable.put(objtmp, tagtmp); } else { - tagcleartable.put(objtmp, tagtmp); + tagcleartable.put(objtmp, tagtmp); } } @@ -2566,30 +3337,30 @@ public class BuildCode { Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc()); FlagDescriptor flag=tfp.getFlag(); if (flag==null) { - //Newly allocate objects that don't set any flags case - if (flagortable.containsKey(temp)) { - throw new Error(); - } - int mask=0; - flagortable.put(temp,new Integer(mask)); + //Newly allocate objects that don't set any flags case + if (flagortable.containsKey(temp)) { + throw new Error(); + } + int mask=0; + flagortable.put(temp,new Integer(mask)); } else { - int flagid=1<<((Integer)flagtable.get(flag)).intValue(); - boolean flagstatus=ffan.getFlagChange(tfp); - if (flagstatus) { - int mask=0; - if (flagortable.containsKey(temp)) { - mask=((Integer)flagortable.get(temp)).intValue(); - } - mask|=flagid; - flagortable.put(temp,new Integer(mask)); - } else { - int mask=0xFFFFFFFF; - if (flagandtable.containsKey(temp)) { - mask=((Integer)flagandtable.get(temp)).intValue(); - } - mask&=(0xFFFFFFFF^flagid); - flagandtable.put(temp,new Integer(mask)); - } + int flagid=1<<((Integer)flagtable.get(flag)).intValue(); + boolean flagstatus=ffan.getFlagChange(tfp); + if (flagstatus) { + int mask=0; + if (flagortable.containsKey(temp)) { + mask=((Integer)flagortable.get(temp)).intValue(); + } + mask|=flagid; + flagortable.put(temp,new Integer(mask)); + } else { + int mask=0xFFFFFFFF; + if (flagandtable.containsKey(temp)) { + mask=((Integer)flagandtable.get(temp)).intValue(); + } + mask&=(0xFFFFFFFF^flagid); + flagandtable.put(temp,new Integer(mask)); + } } } @@ -2607,35 +3378,35 @@ public class BuildCode { Set tagtmps=tagcleartable.get(temp); if (tagtmps!=null) { - Iterator tagit=tagtmps.iterator(); - while(tagit.hasNext()) { - TempDescriptor tagtmp=(TempDescriptor)tagit.next(); - if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) - output.println("tagclear("+localsprefixaddr+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");"); - else - output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");"); - } + Iterator tagit=tagtmps.iterator(); + while(tagit.hasNext()) { + TempDescriptor tagtmp=(TempDescriptor)tagit.next(); + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) + output.println("tagclear("+localsprefixaddr+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");"); + else + output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");"); + } } tagtmps=tagsettable.get(temp); if (tagtmps!=null) { - Iterator tagit=tagtmps.iterator(); - while(tagit.hasNext()) { - TempDescriptor tagtmp=(TempDescriptor)tagit.next(); - if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) - output.println("tagset("+localsprefixaddr+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");"); - else - output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");"); - } + Iterator tagit=tagtmps.iterator(); + while(tagit.hasNext()) { + TempDescriptor tagtmp=(TempDescriptor)tagit.next(); + if ((GENERATEPRECISEGC) || state.MULTICOREGC||state.PMC) + output.println("tagset("+localsprefixaddr+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");"); + else + output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");"); + } } int ormask=0; int andmask=0xFFFFFFF; if (flagortable.containsKey(temp)) - ormask=((Integer)flagortable.get(temp)).intValue(); + ormask=((Integer)flagortable.get(temp)).intValue(); if (flagandtable.containsKey(temp)) - andmask=((Integer)flagandtable.get(temp)).intValue(); + andmask=((Integer)flagandtable.get(temp)).intValue(); generateFlagOrAnd(ffan, fm, temp, output, ormask, andmask); generateObjectDistribute(ffan, fm, temp, output); } @@ -2731,33 +3502,33 @@ public class BuildCode { output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={"); int numberterms=0; if (fen_hashset!=null) { - for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext(); ) { - FlagExpressionNode fen = (FlagExpressionNode)fen_it.next(); - if (fen!=null) { - DNFFlag dflag=fen.getDNF(); - numberterms+=dflag.size(); - - Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc()); - - for(int j=0; j fsset=new TreeSet(); - //iterate through possible FSes corresponding to - //the state when entering - - for(Iterator fses = otd.enterflagstates.iterator(); fses.hasNext(); ) { - FlagState fs = (FlagState)fses.next(); - int flagid=0; - for(Iterator flags = fs.getFlags(); flags.hasNext(); ) { - FlagDescriptor flagd = (FlagDescriptor)flags.next(); - int id=1<<((Integer)flaginfo.get(flagd)).intValue(); - flagid|=id; - } - fsset.add(new Integer(flagid)); - //tag information not needed because tag - //changes are not tolerated. - } - - output.println("int enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={"); - boolean needcomma=false; - for(Iterator it=fsset.iterator(); it.hasNext(); ) { - if(needcomma) - output.print(", "); - output.println(it.next()); - } - - output.println("};\n"); - - - //generate optionaltaskdescriptor that actually - //includes exit fses, predicate and the task - //concerned - output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={"); - output.println("&task_"+otd.td.getSafeSymbol()+","); - output.println("/*index*/"+otd.getIndex()+","); - output.println("/*number of enter flags*/"+fsset.size()+","); - output.println("enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+","); - output.println("/*number of members */"+predicateindex+","); - output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+","); - output.println("};\n"); - } + for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext(); ) { + OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next(); + + //generate the int arrays for the predicate + Predicate predicate = otd.predicate; + int predicateindex = generateOptionalPredicate(predicate, otd, cdtemp, output); + TreeSet fsset=new TreeSet(); + //iterate through possible FSes corresponding to + //the state when entering + + for(Iterator fses = otd.enterflagstates.iterator(); fses.hasNext(); ) { + FlagState fs = (FlagState)fses.next(); + int flagid=0; + for(Iterator flags = fs.getFlags(); flags.hasNext(); ) { + FlagDescriptor flagd = (FlagDescriptor)flags.next(); + int id=1<<((Integer)flaginfo.get(flagd)).intValue(); + flagid|=id; + } + fsset.add(new Integer(flagid)); + //tag information not needed because tag + //changes are not tolerated. + } + + output.println("int enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={"); + boolean needcomma=false; + for(Iterator it=fsset.iterator(); it.hasNext(); ) { + if(needcomma) + output.print(", "); + output.println(it.next()); + } + + output.println("};\n"); + + + //generate optionaltaskdescriptor that actually + //includes exit fses, predicate and the task + //concerned + output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={"); + output.println("&task_"+otd.td.getSafeSymbol()+","); + output.println("/*index*/"+otd.getIndex()+","); + output.println("/*number of enter flags*/"+fsset.size()+","); + output.println("enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+","); + output.println("/*number of members */"+predicateindex+","); + output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+","); + output.println("};\n"); + } } else - continue; + continue; // if there are no optionals, there is no need to build the rest of the struct output.println("struct optionaltaskdescriptor * otdarray"+cdtemp.getSafeSymbol()+"[]={"); c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values(); if( !c_otd.isEmpty() ) { - boolean needcomma=false; - for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext(); ) { - OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next(); - if(needcomma) - output.println(","); - needcomma=true; - output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()); - } + boolean needcomma=false; + for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext(); ) { + OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next(); + if(needcomma) + output.println(","); + needcomma=true; + output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()); + } } output.println("};\n"); @@ -2894,107 +3665,107 @@ public class BuildCode { TreeSet fsts=new TreeSet(new FlagComparator(flaginfo)); fsts.addAll(hashtbtemp.keySet()); for(Iterator fsit=fsts.iterator(); fsit.hasNext(); ) { - FlagState fs = (FlagState)fsit.next(); - fscounter++; - - //get the set of OptionalTaskDescriptors corresponding - HashSet availabletasks = (HashSet)hashtbtemp.get(fs); - //iterate through the OptionalTaskDescriptors and - //store the pointers to the optionals struct (see on - //top) into an array - - output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {"); - for(Iterator mos = ordertd(availabletasks).iterator(); mos.hasNext(); ) { - OptionalTaskDescriptor mm = mos.next(); - if(!mos.hasNext()) - output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()); - else - output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+","); - } + FlagState fs = (FlagState)fsit.next(); + fscounter++; + + //get the set of OptionalTaskDescriptors corresponding + HashSet availabletasks = (HashSet)hashtbtemp.get(fs); + //iterate through the OptionalTaskDescriptors and + //store the pointers to the optionals struct (see on + //top) into an array + + output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {"); + for(Iterator mos = ordertd(availabletasks).iterator(); mos.hasNext(); ) { + OptionalTaskDescriptor mm = mos.next(); + if(!mos.hasNext()) + output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()); + else + output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+","); + } - output.println("};\n"); + output.println("};\n"); - //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose. + //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose. - int flagid=0; - for(Iterator flags = fs.getFlags(); flags.hasNext(); ) { - FlagDescriptor flagd = (FlagDescriptor)flags.next(); - int id=1<<((Integer)flaginfo.get(flagd)).intValue(); - flagid|=id; - } + int flagid=0; + for(Iterator flags = fs.getFlags(); flags.hasNext(); ) { + FlagDescriptor flagd = (FlagDescriptor)flags.next(); + int id=1<<((Integer)flaginfo.get(flagd)).intValue(); + flagid|=id; + } - //process tag information - - int tagcounter = 0; - boolean first = true; - Enumeration tag_enum = fs.getTags(); - output.println("int tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={"); - while(tag_enum.hasMoreElements()) { - tagcounter++; - TagDescriptor tagd = (TagDescriptor)tag_enum.nextElement(); - if(first==true) - first = false; - else - output.println(", "); - output.println("/*tagid*/"+state.getTagId(tagd)); - } - output.println("};"); - - Set tiset=sa.getTaskIndex(fs); - for(Iterator itti=tiset.iterator(); itti.hasNext(); ) { - TaskIndex ti=itti.next(); - if (ti.isRuntime()) - continue; - - Set otdset=sa.getOptions(fs, ti); - - output.print("struct optionaltaskdescriptor * optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array[] = {"); - boolean needcomma=false; - for(Iterator otdit=ordertd(otdset).iterator(); otdit.hasNext(); ) { - OptionalTaskDescriptor otd=otdit.next(); - if(needcomma) - output.print(", "); - needcomma=true; - output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()); - } - output.println("};"); - - output.print("struct taskfailure taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+" = {"); - output.print("&task_"+ti.getTask().getSafeSymbol()+", "); - output.print(ti.getIndex()+", "); - output.print(otdset.size()+", "); - output.print("optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array"); - output.println("};"); - } + //process tag information + + int tagcounter = 0; + boolean first = true; + Enumeration tag_enum = fs.getTags(); + output.println("int tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={"); + while(tag_enum.hasMoreElements()) { + tagcounter++; + TagDescriptor tagd = (TagDescriptor)tag_enum.nextElement(); + if(first==true) + first = false; + else + output.println(", "); + output.println("/*tagid*/"+state.getTagId(tagd)); + } + output.println("};"); + + Set tiset=sa.getTaskIndex(fs); + for(Iterator itti=tiset.iterator(); itti.hasNext(); ) { + TaskIndex ti=itti.next(); + if (ti.isRuntime()) + continue; + + Set otdset=sa.getOptions(fs, ti); + + output.print("struct optionaltaskdescriptor * optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array[] = {"); + boolean needcomma=false; + for(Iterator otdit=ordertd(otdset).iterator(); otdit.hasNext(); ) { + OptionalTaskDescriptor otd=otdit.next(); + if(needcomma) + output.print(", "); + needcomma=true; + output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()); + } + output.println("};"); + + output.print("struct taskfailure taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+" = {"); + output.print("&task_"+ti.getTask().getSafeSymbol()+", "); + output.print(ti.getIndex()+", "); + output.print(otdset.size()+", "); + output.print("optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array"); + output.println("};"); + } - tiset=sa.getTaskIndex(fs); - boolean needcomma=false; - int runtimeti=0; - output.println("struct taskfailure * taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={"); - for(Iterator itti=tiset.iterator(); itti.hasNext(); ) { - TaskIndex ti=itti.next(); - if (ti.isRuntime()) { - runtimeti++; - continue; - } - if (needcomma) - output.print(", "); - needcomma=true; - output.print("&taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()); - } - output.println("};\n"); + tiset=sa.getTaskIndex(fs); + boolean needcomma=false; + int runtimeti=0; + output.println("struct taskfailure * taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={"); + for(Iterator itti=tiset.iterator(); itti.hasNext(); ) { + TaskIndex ti=itti.next(); + if (ti.isRuntime()) { + runtimeti++; + continue; + } + if (needcomma) + output.print(", "); + needcomma=true; + output.print("&taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()); + } + output.println("};\n"); - //Store the result in fsanalysiswrapper + //Store the result in fsanalysiswrapper - output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={"); - output.println("/*flag*/"+flagid+","); - output.println("/* number of tags*/"+tagcounter+","); - output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+","); - output.println("/* numtask failures */"+(tiset.size()-runtimeti)+","); - output.println("taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+","); - output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+","); - output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()); - output.println("};\n"); + output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={"); + output.println("/*flag*/"+flagid+","); + output.println("/* number of tags*/"+tagcounter+","); + output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+","); + output.println("/* numtask failures */"+(tiset.size()-runtimeti)+","); + output.println("taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+","); + output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+","); + output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()); + output.println("};\n"); } @@ -3002,9 +3773,9 @@ public class BuildCode { output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {"); boolean needcomma=false; for(int i = 0; i0) - output.print(", "); + output.print(", "); if ((cn != null) && (processedcd.contains(cn))) - output.print("&classanalysiswrapper_"+cn.getSafeSymbol()); + output.print("&classanalysiswrapper_"+cn.getSafeSymbol()); else - output.print("NULL"); + output.print("NULL"); } output.println("};"); @@ -3047,14 +3818,27 @@ public class BuildCode { for(Iterator it=r.keySet().iterator(); it.hasNext(); ) { Set s=r.get(it.next()); for(Iterator it2=s.iterator(); it2.hasNext(); ) { - OptionalTaskDescriptor otd=(OptionalTaskDescriptor)it2.next(); - l.add(otd); + OptionalTaskDescriptor otd=(OptionalTaskDescriptor)it2.next(); + l.add(otd); } } return l; } + + + // either create and register an extension object with buildcode + // or look at the following option of subclassing BuildCode + private Vector extensions; + + // note that extensions are invoked in the order they are added + // to BuildCode + public void registerExtension( BuildCodeExtension bcx ) { + extensions.add( bcx ); + } + + // override these methods in a subclass of BuildCode // to generate code for additional systems protected void printExtraArrayFields(PrintWriter outclassdefs) { @@ -3077,6 +3861,8 @@ public class BuildCode { } protected void additionalCodeAtTopOfMain(PrintWriter outmethod) { } + protected void additionalCodeForCommandLineArgs(PrintWriter outmethod, String argsVar) { + } protected void additionalCodeAtBottomOfMain(PrintWriter outmethod) { } protected void additionalIncludesMethodsImplementation(PrintWriter outmethod) { @@ -3093,6 +3879,34 @@ public class BuildCode { } protected void additionalCodePostNode(FlatMethod fm, FlatNode fn, PrintWriter output) { } + + private void printSourceLineNumber(FlatMethod fm, FlatNode fn, PrintWriter output) { + // we do not print out line number if no one explicitly set the number + if(fn.getNumLine()!=-1) { + + int lineNum=fn.getNumLine(); + + // do not generate the line number if it is same as the previous one + boolean needtoprint; + if(fn.prev.size()==0) { + needtoprint=true; + } else { + needtoprint=false; + } + + for(int i=0; i