From d7c4bd424a8f042fb032ce09db70af69df570c58 Mon Sep 17 00:00:00 2001 From: jzhou Date: Wed, 2 Mar 2011 00:42:13 +0000 Subject: [PATCH] Fix bugs for static fields/blocks and instanceof operation. To effectively support static fields/blocks, we need to generate a special version for methods that could be invoked in static blocks or when initializing static fields. In the special version, if there are classes with static fields/blocks are involved, we'll check if the static fields have been initialized and if the static blocks have been executed. Previously we misused C micros to implement this(MGC_STATIC_INIT_CHECK). Now we remove this wrong macro and generate the required special version. For instanceof operation, we fix two bugs. One is that previously we did not take interfaces into consider and the other is that in the instanceof(struct Object *, int) function we did not check if the Object is NULL or not. If the Object is NULL, we shall always return false. --- Robust/src/ClassLibrary/MGC/gnu/TreeMap.java | 2 +- Robust/src/ClassLibrary/MGC/gnu/TreeNode.java | 16 +- Robust/src/IR/Flat/BuildCode.java | 295 ++++++++++++++++-- Robust/src/IR/Flat/BuildCodeMGC.java | 4 + Robust/src/Runtime/bamboo/multicoreruntime.c | 20 +- Robust/src/Runtime/bamboo/multicoreruntime.h | 2 + 6 files changed, 293 insertions(+), 46 deletions(-) diff --git a/Robust/src/ClassLibrary/MGC/gnu/TreeMap.java b/Robust/src/ClassLibrary/MGC/gnu/TreeMap.java index 54b23c02..809e64fa 100644 --- a/Robust/src/ClassLibrary/MGC/gnu/TreeMap.java +++ b/Robust/src/ClassLibrary/MGC/gnu/TreeMap.java @@ -114,7 +114,7 @@ public class TreeMap// extends AbstractMap * to be black. This object must never be used as a key in a TreeMap, or * it will break bounds checking of a SubMap. */ - static final TreeNode nil = new TreeNode(null, null, BLACK); + static final TreeNode nil = new TreeNode(/*null, null, */BLACK); static { // Nil is self-referential, so we must initialize it after creation. diff --git a/Robust/src/ClassLibrary/MGC/gnu/TreeNode.java b/Robust/src/ClassLibrary/MGC/gnu/TreeNode.java index 1c985f93..11246dbf 100644 --- a/Robust/src/ClassLibrary/MGC/gnu/TreeNode.java +++ b/Robust/src/ClassLibrary/MGC/gnu/TreeNode.java @@ -13,11 +13,11 @@ public static final class TreeNode// extends AbstractMap.SimpleEntry Object value; /** The left child node. */ - TreeNode left = TreeMap.nil; + TreeNode left;// = TreeMap.nil; /** The right child node. */ - TreeNode right = TreeMap.nil; + TreeNode right;// = TreeMap.nil; /** The parent node. */ - TreeNode parent = TreeMap.nil; + TreeNode parent;// = TreeMap.nil; /** * Simple constructor. @@ -29,6 +29,16 @@ public static final class TreeNode// extends AbstractMap.SimpleEntry key = key; value = value; this.color = color; + left = TreeMap.nil; + right = TreeMap.nil; + parent = TreeMap.nil; + } + + TreeNode(int color) + { + key = null; + value = null; + this.color = color; } public boolean equals(Object o) diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 3d007057..9e99824d 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -50,6 +50,7 @@ public class BuildCode { CallGraph callgraph; Hashtable printedfieldstbl; int globaldefscount=0; + boolean mgcstaticinit = false; public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) { this(st, temptovar, typeutil, null); @@ -291,7 +292,6 @@ public class BuildCode { SymbolTable sctbl = this.state.getSClassSymbolTable(); Iterator it_sclasses = sctbl.getDescriptorsIterator(); if(it_sclasses.hasNext()) { - outmethod.println("#define MGC_STATIC_INIT_CHECK"); while(it_sclasses.hasNext()) { ClassDescriptor t_cd = (ClassDescriptor)it_sclasses.next(); MethodDescriptor t_md = (MethodDescriptor)t_cd.getMethodTable().get("staticblocks"); @@ -307,7 +307,6 @@ public class BuildCode { outmethod.println(" }"); } } - outmethod.println("#undef MGC_STATIC_INIT_CHECK"); } } @@ -1208,10 +1207,41 @@ public class BuildCode { } output.println("};"); } + + private int checkarraysupertype(ClassDescriptor arraycd, TypeDescriptor arraytd) { + int type=-1; + + TypeDescriptor supertd=new TypeDescriptor(arraycd); + supertd.setArrayCount(arraytd.getArrayCount()); + type=state.getArrayNumber(supertd); + if (type!=-1) { + return type; + } + + ClassDescriptor cd = arraycd.getSuperDesc(); + if(cd != null) { + type = checkarraysupertype(cd, arraytd); + if(type != -1) { + return type; + } + } + + Iterator it_sifs = arraycd.getSuperInterfaces(); + while(it_sifs.hasNext()) { + ClassDescriptor ifcd = (ClassDescriptor)it_sifs.next(); + type = checkarraysupertype(ifcd, arraytd); + if(type != -1) { + return type; + } + } + + return type; + } /** Print out table to give us supertypes */ protected void generateSuperTypeTable(PrintWriter output) { + ClassDescriptor objectclass=typeutil.getClass(TypeUtil.ObjectClass); for(int i=0; i" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {"); if(cn.getNumStaticBlocks() != 0) { MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks"); @@ -2056,21 +2293,20 @@ public class BuildCode { output.println(" global_defsprim_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;"); } output.println("}"); - output.println("#endif // MGC_STATIC_INIT_CHECK"); } } } 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->" + + md.getSafeMethodDescriptor() + "((struct ___Object___*)(global_defs_p->" + fc.getThis().getType().getClassDesc().getSafeSymbol() +"classobj));"); return; } output.println("{"); if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { - output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={"); + output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+mdstring+"_params __parameterlist__={"); output.print(objectparams.numPointers()); output.print(", "+localsprefixaddr); if (md.getThis()!=null) { @@ -2107,7 +2343,7 @@ public class BuildCode { /* Do we need to do virtual dispatch? */ if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) { //no - output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()); + output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+mdstring); } else { //yes output.print("(("); @@ -2121,7 +2357,7 @@ public class BuildCode { boolean printcomma=false; if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { - output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "); + output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+mdstring+"_params * "); printcomma=true; } @@ -2208,18 +2444,17 @@ public class BuildCode { protected void generateFlatFieldNode(FlatMethod fm, FlatFieldNode ffn, PrintWriter output) { if(ffn.getField().isStatic() || ffn.getField().isVolatile()) { // static field - if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) { + if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic()/* && mgcstaticinit*/)) { // 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 { + } else if(mgcstaticinit) { + // 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("#ifdef MGC_STATIC_INIT_CHECK"); 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"); @@ -2228,7 +2463,6 @@ public class BuildCode { output.println(" global_defsprim_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;"); } output.println("}"); - output.println("#endif // MGC_STATIC_INIT_CHECK"); } } } @@ -2269,22 +2503,18 @@ public class BuildCode { if(fsfn.getField().isStatic()) { // static field - if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) { + if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic()/* && mgcstaticinit*/)) { // 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 { + } else if(mgcstaticinit){ + // 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("#ifdef MGC_STATIC_INIT_CHECK"); output.println("if(global_defsprim_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()+"();"); @@ -2292,7 +2522,6 @@ public class BuildCode { output.println(" global_defsprim_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;"); } output.println("}"); - output.println("#endif // MGC_STATIC_INIT_CHECK"); } } } @@ -2496,6 +2725,7 @@ public class BuildCode { md=(MethodDescriptor) des; else task=(TaskDescriptor) des; + String mdstring = md != null ? md.getSafeMethodDescriptor() : null; ClassDescriptor cn=md!=null ? md.getClassDesc() : null; @@ -2510,14 +2740,17 @@ public class BuildCode { //catch the constructor case output.print("void "); if (md!=null) { - output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"("); + if(mgcstaticinit) { + mdstring += "staticinit"; + } + output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+mdstring+"("); } else output.print(task.getSafeSymbol()+"("); boolean printcomma=false; if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { 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); printcomma=true; diff --git a/Robust/src/IR/Flat/BuildCodeMGC.java b/Robust/src/IR/Flat/BuildCodeMGC.java index b00f1750..f08ed4be 100644 --- a/Robust/src/IR/Flat/BuildCodeMGC.java +++ b/Robust/src/IR/Flat/BuildCodeMGC.java @@ -153,6 +153,10 @@ public class BuildCodeMGC extends BuildCode { outmethod.println("int mgc_main(int argc, const char *argv[]) {"); outmethod.println(" int i;"); + if (state.MULTICOREGC) { + outmethod.println(" global_defs_p->size="+globaldefscount+";"); + } + outputStaticBlocks(outmethod); outputClassObjects(outmethod); diff --git a/Robust/src/Runtime/bamboo/multicoreruntime.c b/Robust/src/Runtime/bamboo/multicoreruntime.c index cd7ec4d1..d1ee9875 100644 --- a/Robust/src/Runtime/bamboo/multicoreruntime.c +++ b/Robust/src/Runtime/bamboo/multicoreruntime.c @@ -39,6 +39,9 @@ int instanceofif(int otype, int type) { if(otype == type) { return 1; } + if(otype == -1) { + return 0; + } int num = supertypes[otype][0]; for(int i = 1; i < num + 1; i++) { int t = supertypes[otype][i]; @@ -50,24 +53,19 @@ int instanceofif(int otype, int type) { } int instanceof(struct ___Object___ *ptr, int type) { + if(ptr == NULL) { + return 0; + } int i=ptr->type; - /*do { - if (i==type) - return 1; - i=typearray[i]; - } while(i!=-1); - i=ptr->type;*/ - /*if(instanceofif(i, type) == 1) { + if(instanceofif(i, type) == 1) { return 1; - }*/ + } if (i>NUMCLASSES) { do { if (i==type) return 1; i=typearray2[i-NUMCLASSES]; } while(i!=-1); - } else { - return instanceofif(i, type); } return 0; } @@ -183,7 +181,7 @@ void arraycopy(struct ___Object___ *src, int srcPos, struct ___Object___ *dst, i int srctype=((int *)src)[0]; //not an array or type mismatch - if (dsttype