From: jzhou <jzhou>
Date: Fri, 4 Feb 2011 00:47:47 +0000 (+0000)
Subject: Roll back to use the simple Class constructor to support class lock.  Fix a bug for... 
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=404514d8aa66ea997fa38d6d21baf22db9f133e5;p=IRC.git

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.
---

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<state.numClasses(); i++) {
+      ClassDescriptor cn=cdarray[i];
+      if (needcomma)
+    output.println(",");
+      needcomma=true;
+      if ((cn != null) && (cn.getSuperDesc()!=null)) {
+    output.print("\"" + cn.getSymbol() + "\"");
+      } else
+    output.print("\"\"");
+    }
+    output.println("};");
+  }*/
 
   /** Force consistent field ordering between inherited classes. */
 
@@ -3010,6 +3023,13 @@ public class BuildCode {
         }
       }
     }
+    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;
+    }
     }
     
     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(); 
+  }
 }