From 404514d8aa66ea997fa38d6d21baf22db9f133e5 Mon Sep 17 00:00:00 2001 From: jzhou Date: Fri, 4 Feb 2011 00:47:47 +0000 Subject: [PATCH] Roll back to use the simple Class constructor to support class lock. Fix a bug for static field initialization: the initialization of a static field was invoked each time the field is used. The initialization of a static field should be invoked only once and be invoked before it is used. To simplify the implementation, we create a static block to contain the initializations of all the static fields of a class and invoke this static block at the beginning of the main method. --- Robust/src/ClassLibrary/Character.java | 11 +- Robust/src/IR/Flat/BuildCode.java | 50 +++++--- Robust/src/IR/Flat/BuildCodeMGC.java | 138 +++++++++++++++++++++- Robust/src/IR/Flat/BuildFlat.java | 41 +++++-- Robust/src/IR/Tree/BuildIR.java | 39 +++++- Robust/src/IR/Tree/SemanticCheck.java | 8 ++ Robust/src/Parse/java14.cup | 20 ++-- Robust/src/Tests/MGC/SynchonizedTest.java | 57 +++++++-- 8 files changed, 317 insertions(+), 47 deletions(-) diff --git a/Robust/src/ClassLibrary/Character.java b/Robust/src/ClassLibrary/Character.java index 1febbc3c..85406ad8 100644 --- a/Robust/src/ClassLibrary/Character.java +++ b/Robust/src/ClassLibrary/Character.java @@ -1,5 +1,5 @@ public class Character { - + public static int digit(char ch, int radix) { if (ch>='0'&&ch<='9') return ch-'0'; @@ -14,6 +14,15 @@ public class Character { } return -1; } + + public static boolean isDigit(char ch) { + // TODO This is a temparory implementation, there are other groups of digits + // besides '0' ~ '9' + if (ch>='0'&&ch<='9') + return true; + else + return false; + } char value; diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 6e877932..fee74315 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -346,17 +346,7 @@ public class BuildCode { * */ protected void outputClassObjects(PrintWriter outmethod) { // for each class, initialize its Class object - if(state.MGC) { - SymbolTable ctbl = this.state.getClassSymbolTable(); - Iterator it_classes = ctbl.getDescriptorsIterator(); - while(it_classes.hasNext()) { - ClassDescriptor t_cd = (ClassDescriptor)it_classes.next(); - outmethod.println(" {"); - outmethod.println(" global_defs_p->"+t_cd.getSafeSymbol()+"classobj.type="+t_cd.getId()+";"); - outmethod.println(" initlock((struct ___Object___ *)(&(global_defs_p->"+t_cd.getSafeSymbol()+"classobj)));"); - outmethod.println(" }"); - } - } // else TODO normal java version + // TODO } /* This code just generates the main C method for java programs. @@ -585,6 +575,12 @@ public class BuildCode { //Store table of supertypes generateSuperTypeTable(outmethod); + + // Store table of classnames + /*if(state.MGC) { + // TODO add code for normal Java later + generateClassNameTable(outmethod); + }*/ //Store the layout of classes generateLayoutStructs(outmethod); @@ -719,7 +715,7 @@ public class BuildCode { } // for each class, create a global object - outglobaldefs.println(" struct Class "+cn.getSafeSymbol()+"classobj;"); + outglobaldefs.println(" struct ___Object___ "+cn.getSafeSymbol()+"classobj;"); } } outclassdefs.println(""); @@ -833,10 +829,10 @@ public class BuildCode { outclassdefs.println("extern int hasflags[];"); outclassdefs.println("extern unsigned INTPTR * pointerarray[];"); outclassdefs.println("extern int supertypes[];"); - if(state.MGC) { + /*if(state.MGC) { // TODO add version for normal Java later - outclassdefs.println("#include \"globaldefs.h\""); - } + outclassdefs.println("extern char * classname[];"); + }*/ outclassdefs.println(""); } @@ -1474,6 +1470,23 @@ public class BuildCode { } output.println("};"); } + + /** Print out table to give us classnames */ + /*private void generateClassNameTable(PrintWriter output) { + output.println("char * classname[]={"); + boolean needcomma=false; + for(int i=0; i" + + fc.getThis().getType().getClassDesc().getSafeSymbol() +"classobj));"); + return; + } } output.println("{"); diff --git a/Robust/src/IR/Flat/BuildCodeMGC.java b/Robust/src/IR/Flat/BuildCodeMGC.java index 2e1211d8..9ffcc8d1 100644 --- a/Robust/src/IR/Flat/BuildCodeMGC.java +++ b/Robust/src/IR/Flat/BuildCodeMGC.java @@ -4,7 +4,9 @@ import java.io.FileOutputStream; import java.io.PrintWriter; import java.util.Hashtable; import java.util.Iterator; +import java.util.Set; +import Analysis.Locality.LocalityBinding; import Analysis.Prefetch.*; import Analysis.TaskStateAnalysis.SafetyAnalysis; import IR.ClassDescriptor; @@ -20,7 +22,11 @@ import IR.TypeUtil; import IR.VarDescriptor; import IR.Tree.DNFFlag; import IR.Tree.DNFFlagAtom; +import IR.Tree.ExpressionNode; +import IR.Tree.FlagEffect; +import IR.Tree.FlagEffects; import IR.Tree.FlagExpressionNode; +import IR.Tree.TagEffect; import IR.Tree.TagExpressionList; public class BuildCodeMGC extends BuildCode { @@ -98,6 +104,8 @@ public class BuildCodeMGC extends BuildCode { ClassDescriptor cn=(ClassDescriptor)it.next(); super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs); } + // TODO add version for normal Java later + outclassdefs.println("#include \"globaldefs.h\""); outclassdefs.println("#endif"); outclassdefs.close(); outglobaldefs.println("};"); @@ -144,7 +152,7 @@ public class BuildCodeMGC extends BuildCode { outmethod.println(" int i;"); outputStaticBlocks(outmethod); - super.outputClassObjects(outmethod); + outputClassObjects(outmethod); if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);"); @@ -204,4 +212,132 @@ public class BuildCodeMGC extends BuildCode { outmethod.println("#undef MGC_STATIC_INIT_CHECK"); } } + + protected void outputClassObjects(PrintWriter outmethod) { + // for each class, initialize its Class object + if(state.MGC) { + SymbolTable ctbl = this.state.getClassSymbolTable(); + Iterator it_classes = ctbl.getDescriptorsIterator(); + + /*TypeDescriptor[] tdarray=new TypeDescriptor[1]; + tdarray[0] = new TypeDescriptor(((ClassDescriptor)this.state.getClassSymbolTable().get("Object"))); + + TypeDescriptor typetolookin=new TypeDescriptor(((ClassDescriptor)this.state.getClassSymbolTable().get("Class")));; + + //find the constructor for 'Class' class + ClassDescriptor classtolookin=typetolookin.getClassDesc(); + + Set methoddescriptorset=classtolookin.getMethodTable().getSet(typetolookin.getSymbol()); + MethodDescriptor bestmd=null; +NextMethod: + for(Iterator methodit=methoddescriptorset.iterator(); methodit.hasNext();) { + MethodDescriptor currmd=(MethodDescriptor)methodit.next(); + // Need correct number of parameters + if (1!=currmd.numParameters()) + continue; + for(int i=0; i<1; i++) { + if (!typeutil.isSuperorType(currmd.getParamType(i),tdarray[i])) + continue NextMethod; + } + // Local allocations can't call global allocator + if (currmd.isGlobal()) + continue; + + // Method okay so far + if (bestmd==null) + bestmd=currmd; + else { + if (typeutil.isMoreSpecific(currmd,bestmd)) { + bestmd=currmd; + } else if (!typeutil.isMoreSpecific(bestmd, currmd)) { + throw new Error("No method is most specific"); + } + + // Is this more specific than bestmd + } + } + if (bestmd==null) + throw new Error("No constructor found for Class in "); + */ + while(it_classes.hasNext()) { + ClassDescriptor t_cd = (ClassDescriptor)it_classes.next(); + /*if(t_cd.getSymbol().equals("Class") || t_cd.getSymbol().equals("VMClass")) { + continue; + }*/ + // TODO initialize the Class object for this class ++ + outmethod.println(" {"); + /* + // create the vmdata object that record the class's type + if(this.state.MULTICOREGC) { + outmethod.println(" void * " + t_cd.getSafeSymbol() + "vmdata=allocate_new("+localsprefixaddr+", "+t_cd.getId()+");"); + } else { + outmethod.println(" void * " + t_cd.getSafeSymbol() + "vmdata=allocate_new("+t_cd.getId()+");"); + } + // invoke the Class.constructor + ParamsObject objectparams=(ParamsObject)paramstable.get(bestmd); + if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { + outmethod.print(" struct "+classtolookin.getSafeSymbol()+bestmd.getSafeSymbol()+"_"+bestmd.getSafeMethodDescriptor()+"_params __parameterlist__={"); + outmethod.print(objectparams.numPointers()); + outmethod.print(", "+localsprefixaddr); + if (bestmd.getThis()!=null) { + outmethod.print(", "); + outmethod.print("(struct "+bestmd.getThis().getType().getSafeSymbol() +" *)&(global_defs_p->"+t_cd.getSafeSymbol()+"classobj)"); + } + + Descriptor var=bestmd.getParameter(0); + TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var); + if (objectparams.isParamPtr(paramtemp)) { + outmethod.print(", "); + TypeDescriptor td=bestmd.getParamType(0); + outmethod.print("(struct "+bestmd.getParamType(0).getSafeSymbol() +" *)" + t_cd.getSafeSymbol() + "vmdata"); + } + outmethod.println("};"); + } + outmethod.print(" "); + + outmethod.print(classtolookin.getSafeSymbol()+bestmd.getSafeSymbol()+"_"+bestmd.getSafeMethodDescriptor()); + + outmethod.print("("); + boolean needcomma=false; + if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { + outmethod.print("&__parameterlist__"); + needcomma=true; + } + + if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) { + TypeDescriptor ptd=null; + if(bestmd.getThis() != null) { + ptd = bestmd.getThis().getType(); + } + if (needcomma) + outmethod.print(","); + if (ptd.isClass()&&!ptd.isArray()) + outmethod.print("(struct "+ptd.getSafeSymbol()+" *) "); + outmethod.print("&(global_defs_p->"+t_cd.getSafeSymbol()+"classobj)"); + needcomma=true; + } + + Descriptor var=bestmd.getParameter(0); + TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var); + if (objectparams.isParamPrim(paramtemp)) { + if (needcomma) + outmethod.print(", "); + + TypeDescriptor ptd=bestmd.getParamType(0); + if (ptd.isClass()&&!ptd.isArray()) + outmethod.print("(struct "+ptd.getSafeSymbol()+" *) "); + outmethod.print(t_cd.getSafeSymbol() + "vmdata"); + needcomma=true; + } + outmethod.println(");"); + */ + outmethod.println(" global_defs_p->"+t_cd.getSafeSymbol()+"classobj.type = " + t_cd.getId() + ";"); + + outmethod.println(" initlock((struct ___Object___ *)(&(global_defs_p->"+t_cd.getSafeSymbol()+"classobj)));"); + outmethod.println(" }"); + + } + } // else TODO normal java version + + } } diff --git a/Robust/src/IR/Flat/BuildFlat.java b/Robust/src/IR/Flat/BuildFlat.java index 44201311..207dae3c 100644 --- a/Robust/src/IR/Flat/BuildFlat.java +++ b/Robust/src/IR/Flat/BuildFlat.java @@ -188,8 +188,15 @@ public class BuildFlat { FlatNode fn=np.getBegin(); if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) { MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter"); - TempDescriptor thistd=getTempforVar(currmd.getThis()); - FlatCall fc=new FlatCall(memd, null, thistd, new TempDescriptor[0]); + TempDescriptor thistd=null; + if(currmd.getModifiers().isStatic()) { + // need to lock the Class object + thistd=new TempDescriptor("classobj", cn); + } else { + // lock this object + thistd=getTempforVar(currmd.getThis()); + } + FlatCall fc = new FlatCall(memd, null, thistd, new TempDescriptor[0]); fc.addNext(fn); fn=fc; if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) { @@ -1263,7 +1270,14 @@ public class BuildFlat { FlatNode ln=rnflat; if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) { MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit"); - TempDescriptor thistd=getTempforVar(currmd.getThis()); + TempDescriptor thistd=null; + if(currmd.getModifiers().isStatic()) { + // need to lock the Class object + thistd=new TempDescriptor("classobj", currmd.getClassDesc()); + } else { + // lock this object + thistd=getTempforVar(currmd.getThis()); + } FlatCall fc=new FlatCall(memd, null, thistd, new TempDescriptor[0]); fc.addNext(ln); ln=fc; @@ -1325,8 +1339,17 @@ public class BuildFlat { } private NodePair flattenSynchronizedNode(SynchronizedNode sbn) { - TempDescriptor montmp=TempDescriptor.tempFactory("monitor",sbn.getExpr().getType()); - NodePair npexp=flattenExpressionNode(sbn.getExpr(), montmp); + TempDescriptor montmp=null; + FlatNode first = null; + FlatNode end = null; + if(sbn.getExpr() instanceof ClassTypeNode) { + montmp=new TempDescriptor("classobj", ((ClassTypeNode)sbn.getExpr()).getType().getClassDesc()); + } else { + montmp = TempDescriptor.tempFactory("monitor",sbn.getExpr().getType()); + NodePair npexp=flattenExpressionNode(sbn.getExpr(), montmp); + first = npexp.getBegin(); + end = npexp.getEnd(); + } NodePair npblock=flattenBlockNode(sbn.getBlockNode()); MethodDescriptor menmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter"); @@ -1335,10 +1358,14 @@ public class BuildFlat { MethodDescriptor mexmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit"); FlatCall fcex=new FlatCall(mexmd, null, montmp, new TempDescriptor[0]); - npexp.getEnd().addNext(fcen); + if(first != null) { + end.addNext(fcen); + } else { + first = fcen; + } fcen.addNext(npblock.getBegin()); npblock.getEnd().addNext(fcex); - return new NodePair(npexp.getBegin(), fcex); + return new NodePair(first, fcex); } private NodePair flattenAtomicNode(AtomicNode sbn) { diff --git a/Robust/src/IR/Tree/BuildIR.java b/Robust/src/IR/Tree/BuildIR.java index b3bec386..391d0cd7 100644 --- a/Robust/src/IR/Tree/BuildIR.java +++ b/Robust/src/IR/Tree/BuildIR.java @@ -641,8 +641,43 @@ public class BuildIR { ParseNode epn=vardecl.getChild("initializer"); ExpressionNode en=null; - if (epn!=null) - en=parseExpression(epn.getFirstChild()); + if (epn!=null) { + en=parseExpression(epn.getFirstChild()); + if(state.MGC && m.isStatic()) { + // for static field, the initializer should be considered as a + // static block + boolean isfirst = false; + MethodDescriptor md = (MethodDescriptor)cn.getMethodTable().get("staticblocks"); + if(md == null) { + // the first static block for this class + Modifiers m_i=new Modifiers(); + m_i.addModifier(Modifiers.STATIC); + md = new MethodDescriptor(m_i, "staticblocks", false); + md.setAsStaticBlock(); + isfirst = true; + } + if(isfirst) { + cn.addMethod(md); + } + cn.incStaticBlocks(); + BlockNode bn=new BlockNode(); + NameNode nn=new NameNode(new NameDescriptor(identifier)); + AssignmentNode an=new AssignmentNode(nn,en,new AssignOperation(1)); + bn.addBlockStatement(new BlockExpressionNode(an)); + if(isfirst) { + state.addTreeCode(md,bn); + } else { + BlockNode obn = state.getMethodBody(md); + for(int ii = 0; ii < bn.size(); ii++) { + BlockStatementNode bsn = bn.get(ii); + obn.addBlockStatement(bsn); + } + //TODO state.addTreeCode(md, obn); + bn = null; + } + en = null; + } + } cn.addField(new FieldDescriptor(m, arrayt, identifier, en, isglobal)); } diff --git a/Robust/src/IR/Tree/SemanticCheck.java b/Robust/src/IR/Tree/SemanticCheck.java index 6b057ed5..5f0adb6e 100644 --- a/Robust/src/IR/Tree/SemanticCheck.java +++ b/Robust/src/IR/Tree/SemanticCheck.java @@ -526,10 +526,18 @@ public class SemanticCheck { case Kind.ArrayInitializerNode: checkArrayInitializerNode(md, nametable, (ArrayInitializerNode) en, td); return; + + case Kind.ClassTypeNode: + checkClassTypeNode(md, nametable, (ClassTypeNode) en, td); + return; } throw new Error(); } + void checkClassTypeNode(Descriptor md, SymbolTable nametable, ClassTypeNode tn, TypeDescriptor td) { + checkTypeDescriptor(tn.getType()); + } + void checkCastNode(Descriptor md, SymbolTable nametable, CastNode cn, TypeDescriptor td) { /* Get type descriptor */ if (cn.getType()==null) { diff --git a/Robust/src/Parse/java14.cup b/Robust/src/Parse/java14.cup index 6f489a67..bb39c86f 100644 --- a/Robust/src/Parse/java14.cup +++ b/Robust/src/Parse/java14.cup @@ -1696,17 +1696,17 @@ primary_no_new_array ::= pn.addChild(id); RESULT=pn; :} - | primitive_type:pt DOT CLASS {: - ParseNode pn=new ParseNode("class_type"); - pn.addChild(pt); - RESULT=pn; - :} +// | primitive_type:pt DOT CLASS {: +// ParseNode pn=new ParseNode("class_type"); +// pn.addChild(pt); +// RESULT=pn; +// :} // | VOID DOT CLASS - | array_type:at DOT CLASS {: - ParseNode pn=new ParseNode("class_type"); - pn.addChild(at); - RESULT=pn; - :} +// | array_type:at DOT CLASS {: +// ParseNode pn=new ParseNode("class_type"); +// pn.addChild(at); +// RESULT=pn; +// :} | name:name DOT CLASS {: ParseNode pn=new ParseNode("class_type"); pn.addChild("type").addChild("class").addChild(name); diff --git a/Robust/src/Tests/MGC/SynchonizedTest.java b/Robust/src/Tests/MGC/SynchonizedTest.java index 7d322ffb..5e633dde 100644 --- a/Robust/src/Tests/MGC/SynchonizedTest.java +++ b/Robust/src/Tests/MGC/SynchonizedTest.java @@ -7,7 +7,7 @@ public class Counter{ } public add(long value){ - synchronized (this) { + synchronized (Counter.class) { this.count += value; } } @@ -36,6 +36,43 @@ public class CounterThread extends Thread{ } } +public class CounterS{ + + static long count = 1; + + public CounterS() { + } + + public add(long value){ + synchronized (CounterS.class) { + CounterS.count += value; + } + } + + public synchronized static long getCounter() { + return CounterS.count; + } +} + +public class CounterSThread extends Thread{ + + String name; + protected CounterS counter; + + public CounterSThread(String name, CounterS counter){ + this.name = name; + this.counter = counter; + } + + public void run() { + for(int i=0; i<10; i++){ + System.printString(this.name); + counter.add(i); + System.printString(" " + counter.getCounter() + "\n"); + } + } +} + public class SynchonizedTest { public SynchonizedTest() { } @@ -47,15 +84,13 @@ public class SynchonizedTest { threadA.start(); threadB.start(); - } - - /*public static void main(String[] args){ - Counter counterA = new Counter(); - Counter counterB = new Counter(); - Thread threadA = new CounterThread("A\n",counterA); - Thread threadB = new CounterThread("B\n",counterB); - threadA.start(); - threadB.start(); - }*/ + CounterS countersA = new CounterS(); + CounterS countersB = new CounterS(); + Thread threadsA = new CounterSThread("C\n",countersA); + Thread threadsB = new CounterSThread("D\n",countersB); + + threadsA.start(); + threadsB.start(); + } } -- 2.34.1