changes:
authorbdemsky <bdemsky>
Mon, 15 Jun 2009 23:09:28 +0000 (23:09 +0000)
committerbdemsky <bdemsky>
Mon, 15 Jun 2009 23:09:28 +0000 (23:09 +0000)
(1) Add support for synchronized blocks
(2) Fix analysis bug
(3) Start support for delaying operations until commit

12 files changed:
Robust/src/Analysis/Locality/DelayComputation.java [new file with mode: 0644]
Robust/src/Analysis/Locality/DiscoverConflicts.java
Robust/src/Analysis/Loops/CSE.java
Robust/src/Analysis/Loops/GlobalFieldType.java
Robust/src/Analysis/Loops/LoopInvariant.java
Robust/src/Analysis/Loops/localCSE.java
Robust/src/IR/Flat/BuildFlat.java
Robust/src/IR/Tree/BuildIR.java
Robust/src/IR/Tree/Kind.java
Robust/src/IR/Tree/SemanticCheck.java
Robust/src/IR/TypeDescriptor.java
Robust/src/Parse/java14.cup

diff --git a/Robust/src/Analysis/Locality/DelayComputation.java b/Robust/src/Analysis/Locality/DelayComputation.java
new file mode 100644 (file)
index 0000000..5a8fe1a
--- /dev/null
@@ -0,0 +1,228 @@
+package Analysis.Locality;
+import IR.State;
+import IR.MethodDescriptor;
+import IR.TypeDescriptor;
+import IR.FieldDescriptor;
+import IR.Flat.*;
+import Analysis.Loops.GlobalFieldType;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+import java.util.Iterator;
+
+public class DelayComputation {
+  State state;
+  LocalityAnalysis locality;
+  TypeAnalysis typeanalysis;
+  GlobalFieldType gft;
+
+  public DelayComputation(LocalityAnalysis locality, State state, TypeAnalysis typeanalysis, GlobalFieldType gft) {
+    this.locality=locality;
+    this.state=state;
+    this.typeanalysis=typeanalysis;
+    this.gft=gft;
+  }
+
+  public void doAnalysis() {
+    Set<LocalityBinding> localityset=locality.getLocalityBindings();
+    for(Iterator<LocalityBinding> lb=localityset.iterator();lb.hasNext();) {
+      analyzeMethod(lb.next());
+    }
+  }
+
+  public void analyzeMethod(LocalityBinding lb) {
+    MethodDescriptor md=lb.getMethod();
+    FlatMethod fm=state.getMethodFlat(md);
+    HashSet<FlatNode> cannotdelay=new HashSet<FlatNode>();
+    Hashtable<FlatNode, Integer> atomictable=locality.getAtomic(lb);
+    if (lb.isAtomic()) {
+      //We are in a transaction already...
+      //skip past this method or something
+      return;
+    }
+
+    HashSet<FlatNode> toanalyze=new HashSet<FlatNode>();
+    toanalyze.addAll(fm.getNodeSet());
+
+    //Build the hashtables
+    Hashtable<FlatNode, HashSet<TempDescriptor>> nodelaytemps=new Hashtable<FlatNode, HashSet<TempDescriptor>>();
+    Hashtable<FlatNode, HashSet<FieldDescriptor>> nodelayfieldswr=new Hashtable<FlatNode, HashSet<FieldDescriptor>>();
+    Hashtable<FlatNode, HashSet<TypeDescriptor>> nodelayarrayswr=new Hashtable<FlatNode, HashSet<TypeDescriptor>>();
+    Hashtable<FlatNode, HashSet<FieldDescriptor>> nodelayfieldsrd=new Hashtable<FlatNode, HashSet<FieldDescriptor>>();
+    Hashtable<FlatNode, HashSet<TypeDescriptor>> nodelayarraysrd=new Hashtable<FlatNode, HashSet<TypeDescriptor>>();
+    
+    //Effect of adding something to nodelay set is to move it up past everything in delay set
+    //Have to make sure we can do this commute
+
+    while(!toanalyze.isEmpty()) {
+      FlatNode fn=toanalyze.iterator().next();
+      toanalyze.remove(fn);
+      
+      boolean isatomic=atomictable.get(fn).intValue()>0;
+
+      if (!isatomic)
+       continue;
+      boolean isnodelay=false;
+
+      /* Compute incoming nodelay sets */
+      HashSet<TempDescriptor> nodelaytempset=new HashSet<TempDescriptor>();
+      HashSet<FieldDescriptor> nodelayfieldwrset=new HashSet<FieldDescriptor>();
+      HashSet<TypeDescriptor> nodelayarraywrset=new HashSet<TypeDescriptor>();
+      HashSet<FieldDescriptor> nodelayfieldrdset=new HashSet<FieldDescriptor>();
+      HashSet<TypeDescriptor> nodelayarrayrdset=new HashSet<TypeDescriptor>();
+      for(int i=0;i<fn.numNext();i++) {
+       if (nodelaytemps.containsKey(fn.getNext(i)))
+         nodelaytempset.addAll(nodelaytemps.get(fn.getNext(i)));
+       //do field/array write sets
+       if (nodelayfieldswr.containsKey(fn.getNext(i)))
+         nodelayfieldwrset.addAll(nodelayfieldswr.get(fn.getNext(i)));   
+       if (nodelayarrayswr.containsKey(fn.getNext(i)))
+         nodelayarraywrset.addAll(nodelayarrayswr.get(fn.getNext(i)));   
+       //do read sets
+       if (nodelayfieldsrd.containsKey(fn.getNext(i)))
+         nodelayfieldrdset.addAll(nodelayfieldsrd.get(fn.getNext(i)));   
+       if (nodelayarrayswr.containsKey(fn.getNext(i)))
+         nodelayarraywrset.addAll(nodelayarrayswr.get(fn.getNext(i)));   
+      }
+      
+      /* Check our temp write set */
+
+      TempDescriptor writeset[]=fn.writesTemps();
+      for(int i=0;i<writeset.length;i++) {
+       TempDescriptor tmp=writeset[i];
+       if (nodelaytempset.contains(tmp)) {
+         //We are writing to a nodelay temp
+         //Therefore we are nodelay
+         isnodelay=true;
+         //Kill temp we wrote to
+         nodelaytempset.remove(tmp);
+       }
+      }
+      
+      //See if flatnode is definitely no delay
+      if (fn.kind()==FKind.FlatCall) {
+       isnodelay=true;
+       //Have to deal with fields/arrays
+       FlatCall fcall=(FlatCall)fn;
+       MethodDescriptor mdcall=fcall.getMethod();
+       nodelayfieldwrset.addAll(gft.getFieldsAll(mdcall));
+       nodelayarraywrset.addAll(typeanalysis.expandSet(gft.getArraysAll(mdcall)));
+       //Have to deal with field/array reads
+       nodelayfieldrdset.addAll(gft.getFieldsRdAll(mdcall));
+       nodelayarrayrdset.addAll(typeanalysis.expandSet(gft.getArraysRdAll(mdcall)));
+      }
+      
+      // Can't delay branches
+      if (fn.kind()==FKind.FlatCondBranch) {
+       isnodelay=true;
+      }
+
+      //Check for field conflicts
+      if (fn.kind()==FKind.FlatSetFieldNode) {
+       FieldDescriptor fd=((FlatSetFieldNode)fn).getField();
+       //write conflicts
+       if (nodelayfieldwrset.contains(fd))
+         isnodelay=true;
+       //read 
+       if (nodelayfieldrdset.contains(fd))
+         isnodelay=true;
+      }
+
+      if (fn.kind()==FKind.FlatFieldNode) {
+       FieldDescriptor fd=((FlatFieldNode)fn).getField();
+       //write conflicts
+       if (nodelayfieldwrset.contains(fd))
+         isnodelay=true;
+      }
+
+      //Check for array conflicts
+      if (fn.kind()==FKind.FlatSetElementNode) {
+       TypeDescriptor td=((FlatSetElementNode)fn).getDst().getType();
+       //check for write conflicts
+       if (nodelayarraywrset.contains(td))
+         isnodelay=true;
+       //check for read conflicts
+       if (nodelayarrayrdset.contains(td))
+         isnodelay=true;
+      }
+      if (fn.kind()==FKind.FlatElementNode) {
+       TypeDescriptor td=((FlatElementNode)fn).getSrc().getType();
+       //check for write conflicts
+       if (nodelayarraywrset.contains(td))
+         isnodelay=true;
+      }
+      
+      //If we are no delay, then the temps we read are no delay
+      if (isnodelay) {
+       /* Add our read set */
+       TempDescriptor readset[]=fn.readsTemps();
+       for(int i=0;i<readset.length;i++) {
+         TempDescriptor tmp=readset[i];
+         nodelaytempset.add(tmp);
+       }
+       cannotdelay.add(fn);
+
+       /* Do we write to fields */
+       if (fn.kind()==FKind.FlatSetFieldNode) {
+         nodelayfieldwrset.add(((FlatSetFieldNode)fn).getField());
+       }
+       /* Do we read from fields */
+       if (fn.kind()==FKind.FlatFieldNode) {
+         nodelayfieldrdset.add(((FlatFieldNode)fn).getField());
+       }
+
+       /* Do we write to arrays */
+       if (fn.kind()==FKind.FlatSetElementNode) {
+         //have to do expansion
+         nodelayarraywrset.addAll(typeanalysis.expand(((FlatSetElementNode)fn).getDst().getType()));     
+       }
+       /* Do we read from arrays */
+       if (fn.kind()==FKind.FlatElementNode) {
+         //have to do expansion
+         nodelayarrayrdset.addAll(typeanalysis.expand(((FlatSetElementNode)fn).getSrc().getType()));     
+       }
+      }
+      
+      boolean changed=false;
+      //See if we need to propagate changes
+      if (!nodelaytemps.containsKey(fn)||
+         !nodelaytemps.get(fn).equals(nodelaytempset)) {
+       nodelaytemps.put(fn, nodelaytempset);
+       changed=true;
+      }
+
+      //See if we need to propagate changes
+      if (!nodelayfieldswr.containsKey(fn)||
+         !nodelayfieldswr.get(fn).equals(nodelayfieldwrset)) {
+       nodelayfieldswr.put(fn, nodelayfieldwrset);
+       changed=true;
+      }
+
+      //See if we need to propagate changes
+      if (!nodelayfieldsrd.containsKey(fn)||
+         !nodelayfieldsrd.get(fn).equals(nodelayfieldrdset)) {
+       nodelayfieldsrd.put(fn, nodelayfieldrdset);
+       changed=true;
+      }
+
+      //See if we need to propagate changes
+      if (!nodelayarrayswr.containsKey(fn)||
+         !nodelayarrayswr.get(fn).equals(nodelayarraywrset)) {
+       nodelayarrayswr.put(fn, nodelayarraywrset);
+       changed=true;
+      }
+
+      //See if we need to propagate changes
+      if (!nodelayarraysrd.containsKey(fn)||
+         !nodelayarraysrd.get(fn).equals(nodelayarrayrdset)) {
+       nodelayarraysrd.put(fn, nodelayarrayrdset);
+       changed=true;
+      }
+
+      if (changed)
+       for(int i=0;i<fn.numPrev();i++)
+         toanalyze.add(fn.getPrev(i));
+    } //end of while loop
+
+  } //end of method
+} //end of class
\ No newline at end of file
index 928733c40c4a5b394cc01a93fb4eaf98f94b39c4..87930f3a09b4d3c6839e86a286deb99e5c881b95 100644 (file)
@@ -38,7 +38,9 @@ public class DiscoverConflicts {
   }
   
   public void doAnalysis() {
-    //Compute fields and arrays for all transactions
+    //Compute fields and arrays for all transactions.  Note that we
+    //only look at changes to old objects
+
     Set<LocalityBinding> localityset=locality.getLocalityBindings();
     for(Iterator<LocalityBinding> lb=localityset.iterator();lb.hasNext();) {
       computeModified(lb.next());
@@ -383,7 +385,8 @@ public class DiscoverConflicts {
     return tmptofnset;
   }
   
-  /* See what fields and arrays transactions might modify. */
+  /* See what fields and arrays transactions might modify.  We only
+   * look at changes to old objects. */
 
   public void computeModified(LocalityBinding lb) {
     MethodDescriptor md=lb.getMethod();
@@ -408,6 +411,11 @@ public class DiscoverConflicts {
     }
   }
     
+
+  //Returns a table that maps a flatnode to a set of temporaries
+  //This set of temporaries is old (meaning they may point to object
+  //allocated before the beginning of the current transaction
+
   Hashtable<FlatNode, Set<TempDescriptor>> computeOldTemps(LocalityBinding lb) {
     Hashtable<FlatNode, Set<TempDescriptor>> fntooldtmp=new Hashtable<FlatNode, Set<TempDescriptor>>();
     HashSet<FlatNode> discovered=new HashSet<FlatNode>();
index c17768481c5c6de5f3ea287bbfb395bfabdf4035..e3ce58287f9282b8d1fc099943bf8cb26182ee83 100644 (file)
@@ -55,9 +55,9 @@ public class CSE {
        {
          FlatCall fc=(FlatCall) fn;
          MethodDescriptor md=fc.getMethod();
-         Set<FieldDescriptor> fields=gft.getFields(md);
-         Set<TypeDescriptor> arrays=gft.getArrays(md);
-         killexpressions(tab, fields, arrays, gft.containsAtomic(md)||gft.containsBarrier(md));
+         Set<FieldDescriptor> fields=gft.getFieldsAll(md);
+         Set<TypeDescriptor> arrays=gft.getArraysAll(md);
+         killexpressions(tab, fields, arrays, gft.containsAtomicAll(md)||gft.containsBarrierAll(md));
          break;
        }
       case FKind.FlatOpNode:
index c81fdab50808a90d92c083caeade820f3b524431..3aa5ef8973bb6ef32de64ee81621eaa0ad5c05ce 100644 (file)
@@ -18,6 +18,8 @@ public class GlobalFieldType {
   MethodDescriptor root;
   Hashtable<MethodDescriptor, Set<FieldDescriptor>> fields;
   Hashtable<MethodDescriptor, Set<TypeDescriptor>> arrays;
+  Hashtable<MethodDescriptor, Set<FieldDescriptor>> fieldsrd;
+  Hashtable<MethodDescriptor, Set<TypeDescriptor>> arraysrd;
   HashSet<MethodDescriptor> containsAtomic;
   HashSet<MethodDescriptor> containsBarrier;
   
@@ -27,6 +29,8 @@ public class GlobalFieldType {
     this.root=root;
     this.fields=new Hashtable<MethodDescriptor, Set<FieldDescriptor>>();
     this.arrays=new Hashtable<MethodDescriptor, Set<TypeDescriptor>>();
+    this.fieldsrd=new Hashtable<MethodDescriptor, Set<FieldDescriptor>>();
+    this.arraysrd=new Hashtable<MethodDescriptor, Set<TypeDescriptor>>();
     this.containsAtomic=new HashSet<MethodDescriptor>();
     this.containsBarrier=new HashSet<MethodDescriptor>();
     doAnalysis();
@@ -84,6 +88,10 @@ public class GlobalFieldType {
            changed=true;
          if (arrays.get(md).addAll(arrays.get(md2)))
            changed=true;
+         if (fieldsrd.get(md).addAll(fieldsrd.get(md2)))
+           changed=true;
+         if (arraysrd.get(md).addAll(arraysrd.get(md2)))
+           changed=true;
          if (containsAtomic.contains(md2)) {
            if (containsAtomic.add(md))
              changed=true;
@@ -113,9 +121,83 @@ public class GlobalFieldType {
     return arrays.get(md);
   }
 
+  public Set<FieldDescriptor> getFieldsRd(MethodDescriptor md) {
+    return fieldsrd.get(md);
+  }
+
+  public Set<TypeDescriptor> getArraysRd(MethodDescriptor md) {
+    return arraysrd.get(md);
+  }
+
+  public boolean containsAtomicAll(MethodDescriptor md) {
+    Set methodset=cg.getMethods(md);
+    for(Iterator it=methodset.iterator();it.hasNext();) {
+      MethodDescriptor md2=(MethodDescriptor)it.next();
+      if (containsAtomic.contains(md2))
+       return true;
+    }
+    return false;
+  }
+
+  public boolean containsBarrierAll(MethodDescriptor md) {
+    Set methodset=cg.getMethods(md);
+    for(Iterator it=methodset.iterator();it.hasNext();) {
+      MethodDescriptor md2=(MethodDescriptor)it.next();
+      if (containsBarrier.contains(md2))
+       return true;
+    }
+    return false;
+  }
+  
+  public Set<FieldDescriptor> getFieldsAll(MethodDescriptor md) {
+    HashSet<FieldDescriptor> s=new HashSet<FieldDescriptor>();
+    Set methodset=cg.getMethods(md);
+    for(Iterator it=methodset.iterator();it.hasNext();) {
+      MethodDescriptor md2=(MethodDescriptor)it.next();
+      if (fields.containsKey(md2))
+       s.addAll(fields.get(md2));
+    }
+    return s;
+  }
+
+  public Set<TypeDescriptor> getArraysAll(MethodDescriptor md) {
+    HashSet<TypeDescriptor> s=new HashSet<TypeDescriptor>();
+    Set methodset=cg.getMethods(md);
+    for(Iterator it=methodset.iterator();it.hasNext();) {
+      MethodDescriptor md2=(MethodDescriptor)it.next();
+      if (arrays.containsKey(md2))
+       s.addAll(arrays.get(md2));
+    }
+    return s;
+  }
+
+  public Set<FieldDescriptor> getFieldsRdAll(MethodDescriptor md) {
+    HashSet<FieldDescriptor> s=new HashSet<FieldDescriptor>();
+    Set methodset=cg.getMethods(md);
+    for(Iterator it=methodset.iterator();it.hasNext();) {
+      MethodDescriptor md2=(MethodDescriptor)it.next();
+      if (fieldsrd.containsKey(md2))
+       s.addAll(fieldsrd.get(md2));
+    }
+    return s;
+  }
+
+  public Set<TypeDescriptor> getArraysRdAll(MethodDescriptor md) {
+    HashSet<TypeDescriptor> s=new HashSet<TypeDescriptor>();
+    Set methodset=cg.getMethods(md);
+    for(Iterator it=methodset.iterator();it.hasNext();) {
+      MethodDescriptor md2=(MethodDescriptor)it.next();
+      if (arraysrd.containsKey(md2))
+       s.addAll(arraysrd.get(md2));
+    }
+    return s;
+  }
+
   public void analyzeMethod(MethodDescriptor md) {
     fields.put(md, new HashSet<FieldDescriptor>());
     arrays.put(md, new HashSet<TypeDescriptor>());
+    fieldsrd.put(md, new HashSet<FieldDescriptor>());
+    arraysrd.put(md, new HashSet<TypeDescriptor>());
     
     FlatMethod fm=st.getMethodFlat(md);
     for(Iterator it=fm.getNodeSet().iterator();it.hasNext();) {
@@ -123,9 +205,15 @@ public class GlobalFieldType {
       if (fn.kind()==FKind.FlatSetElementNode) {
        FlatSetElementNode fsen=(FlatSetElementNode)fn;
        arrays.get(md).add(fsen.getDst().getType());
+      } else if (fn.kind()==FKind.FlatElementNode) {
+       FlatElementNode fen=(FlatElementNode)fn;
+       arraysrd.get(md).add(fen.getSrc().getType());
       } else if (fn.kind()==FKind.FlatSetFieldNode) {
        FlatSetFieldNode fsfn=(FlatSetFieldNode)fn;
        fields.get(md).add(fsfn.getField());
+      } else if (fn.kind()==FKind.FlatFieldNode) {
+       FlatFieldNode ffn=(FlatFieldNode)fn;
+       fieldsrd.get(md).add(ffn.getField());
       } else if (fn.kind()==FKind.FlatAtomicEnterNode) {
        containsAtomic.add(md);
       } else if (fn.kind()==FKind.FlatCall) {
index 9fbc99909151e382d75a6b0771a09c82d61812e1..60bdc5a9363e55e342eaeb1c5369b617b1a11802 100644 (file)
@@ -72,13 +72,13 @@ public class LoopInvariant {
        } else if (fn.kind()==FKind.FlatCall) {
          FlatCall fcall=(FlatCall)fn;
          MethodDescriptor md=fcall.getMethod();
-         Set<FieldDescriptor> f=gft.getFields(md);
-         Set<TypeDescriptor> t=gft.getArrays(md);
+         Set<FieldDescriptor> f=gft.getFieldsAll(md);
+         Set<TypeDescriptor> t=gft.getArraysAll(md);
          if (f!=null)
            fields.addAll(f);
          if (t!=null)
            types.addAll(t);
-         if (gft.containsAtomic(md)||gft.containsBarrier(md)) {
+         if (gft.containsAtomicAll(md)||gft.containsBarrierAll(md)) {
            unsafe=true;
          }
        } else if (fn.kind()==FKind.FlatSetFieldNode) {
index 108d992e7a44bd550a5f0cbe5ec4485b5126c827..b42c9955772ffe5ae84a08cdeaccf4cdb6401521 100644 (file)
@@ -154,9 +154,9 @@ public class localCSE {
          //do side effects
          FlatCall fc=(FlatCall)fn;
          MethodDescriptor md=fc.getMethod();
-         Set<FieldDescriptor> fields=gft.getFields(md);
-         Set<TypeDescriptor> arrays=gft.getArrays(md);
-         kill(table, fields, arrays, gft.containsAtomic(md), gft.containsBarrier(md));
+         Set<FieldDescriptor> fields=gft.getFieldsAll(md);
+         Set<TypeDescriptor> arrays=gft.getArraysAll(md);
+         kill(table, fields, arrays, gft.containsAtomicAll(md), gft.containsBarrierAll(md));
        }
        default: {
          TempDescriptor[] writes=fn.writesTemps();
index d2f4727a40f12447e5eed5aee1215e0adf713de8..3e683db340dbc53933d12b7678332cf89369352c 100644 (file)
@@ -1136,6 +1136,23 @@ public class BuildFlat {
     return flattenBlockNode(sbn.getBlockNode());
   }
 
+  private NodePair flattenSynchronizedNode(SynchronizedNode sbn) {
+    TempDescriptor montmp=TempDescriptor.tempFactory("monitor",sbn.getExpr().getType());
+    NodePair npexp=flattenExpressionNode(sbn.getExpr(), montmp);
+    NodePair npblock=flattenBlockNode(sbn.getBlockNode());
+
+    MethodDescriptor menmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter");
+    FlatCall fcen=new FlatCall(menmd, null, montmp, new TempDescriptor[0]);
+
+    MethodDescriptor mexmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
+    FlatCall fcex=new FlatCall(mexmd, null, montmp, new TempDescriptor[0]);
+
+    npexp.getEnd().addNext(fcen);
+    fcen.addNext(npblock.getBegin());
+    npblock.getEnd().addNext(fcex);
+    return new NodePair(npexp.getBegin(), fcex);
+  }
+
   private NodePair flattenAtomicNode(AtomicNode sbn) {
     NodePair np=flattenBlockNode(sbn.getBlockNode());
     FlatAtomicEnterNode faen=new FlatAtomicEnterNode();
@@ -1276,6 +1293,9 @@ public class BuildFlat {
     case Kind.AtomicNode:
       return flattenAtomicNode((AtomicNode)bsn);
 
+    case Kind.SynchronizedNode:
+      return flattenSynchronizedNode((SynchronizedNode)bsn);
+
     case Kind.SESENode:
       return flattenSESENode((SESENode)bsn);
 
index f57330cf9df7e5e665c00d2e504899e9ecbf38d0..2e2fc524bc15721f207ff3bc3e4a5aa664f0eaad 100644 (file)
@@ -701,6 +701,10 @@ public class BuildIR {
     } else if (isNode(pn,"atomic")) {
       BlockNode bn=parseBlockHelper(pn);
       blockstatements.add(new AtomicNode(bn));
+    } else if (isNode(pn,"synchronized")) {
+      BlockNode bn=parseBlockHelper(pn.getChild("block"));
+      ExpressionNode en=parseExpression(pn.getChild("expr").getFirstChild());
+      blockstatements.add(new SynchronizedNode(en, bn));
     } else if (isNode(pn,"return")) {
       if (isEmpty(pn.getTerminal()))
        blockstatements.add(new ReturnNode());
index a50a67f60698d44f59f1f572ddf1b5aa076688e0..40375f467103d4f025af6e8703cf03b4326693e5 100644 (file)
@@ -28,4 +28,5 @@ public class Kind {
   public final static int TertiaryNode=25;
   public final static int InstanceOfNode=26;
   public final static int ArrayInitializerNode=27;
+  public final static int SynchronizedNode=28;
 }
index 0f731f91c2ced15129e2f4d4ccddab61f3431cc0..389fc208c49398b6855134c7b17f6a4710d0f0f6 100644 (file)
@@ -296,6 +296,10 @@ public class SemanticCheck {
       checkAtomicNode(md, nametable, (AtomicNode)bsn);
       return;
 
+    case Kind.SynchronizedNode:
+      checkSynchronizedNode(md, nametable, (SynchronizedNode)bsn);
+      return;
+
     case Kind.ContinueBreakNode:
        checkContinueBreakNode(md, nametable, (ContinueBreakNode) bsn);
        return;
@@ -343,6 +347,12 @@ public class SemanticCheck {
     checkBlockNode(md, nametable, sbn.getBlockNode());
   }
 
+  void checkSynchronizedNode(Descriptor md, SymbolTable nametable, SynchronizedNode sbn) {
+    checkBlockNode(md, nametable, sbn.getBlockNode());
+    //todo this could be Object
+    checkExpressionNode(md, nametable, sbn.getExpr(), null);
+  }
+
   void checkContinueBreakNode(Descriptor md, SymbolTable nametable, ContinueBreakNode cbn) {
       if (loopstack.empty())
          throw new Error("continue/break outside of loop");
@@ -485,6 +495,7 @@ public class SemanticCheck {
       fd=(FieldDescriptor) ltd.getClassDesc().getFieldTable().get(fieldname);
     if (fd==null)
       throw new Error("Unknown field "+fieldname + " in "+fan.printNode(0)+" in "+md);
+
     if (fd.getType().iswrapper()) {
       FieldAccessNode fan2=new FieldAccessNode(left, fieldname);
       fan2.setField(fd);
index 7725f61070dd1d5d36fea460a88f225ef52525f7..4ee6857061b497325928a45e06945bd598f03d0c 100644 (file)
@@ -58,7 +58,7 @@ public class TypeDescriptor extends Descriptor {
   }
 
   public boolean iswrapper() {
-    if (arraycount!=0||!isClass())
+    if (arraycount!=0||isClass())
       return false;
     return (name.equals("bytewrapper")||
            name.equals("booleanwrapper")||
index edc61cb7192fc16ecf06b097be30d837a139421d..01f07d0de4ea26729630051042f4970634386216 100644 (file)
@@ -188,7 +188,8 @@ non terminal ParseNode statement_expression_list;
 non terminal ParseNode break_statement, continue_statement;
 non terminal ParseNode return_statement;
 //non terminal ParseNode throw_statement;
-//non terminal ParseNode synchronized_statement, try_statement;
+non terminal ParseNode synchronized_statement;
+//non terminal ParseNode try_statement;
 //non terminal ParseNode catches_opt;
 //non terminal ParseNode catches, catch_clause;
 //non terminal ParseNode finally;
@@ -1188,7 +1189,7 @@ statement_without_trailing_substatement ::=
        |       task_exitstatement:st {: RESULT=st; :}
        |       atomic_statement:st {: RESULT=st; :}
        |       sese_statement:st {: RESULT=st; :}
-//     |       synchronized_statement
+       |       synchronized_statement:st {: RESULT=st; :}
 //     |       throw_statement
 //     |       try_statement
 //     |       assert_statement
@@ -1362,9 +1363,14 @@ return_statement ::=
 //throw_statement ::=
 //             THROW expression SEMICOLON
 //     ;
-//synchronized_statement ::=
-//             SYNCHRONIZED LPAREN expression RPAREN block
-//     ;
+synchronized_statement ::=
+               SYNCHRONIZED LPAREN expression:e RPAREN block:b {: 
+               ParseNode pn=new ParseNode("synchronized");
+               pn.addChild("expr").addChild(e);
+               pn.addChild("block").addChild(b);
+               RESULT=pn;
+               :}
+       ;
 atomic_statement ::=
                ATOMIC block:blk {: 
        RESULT=(new ParseNode("atomic")).addChild(blk).getRoot();