Use types in program statements to make graph edges more specific, and avoid creating...
authorjjenista <jjenista>
Wed, 4 Nov 2009 22:53:02 +0000 (22:53 +0000)
committerjjenista <jjenista>
Wed, 4 Nov 2009 22:53:02 +0000 (22:53 +0000)
Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java
Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java
Robust/src/Benchmarks/mlp/directto/mlp-java/makefile
Robust/src/Benchmarks/mlp/directto/mlp-small-for-testing/makefile
Robust/src/IR/TypeUtil.java

index bc06db3d4d565d04be374b064fcb12f0f3ef27ed..3f8d4c514780520ef9767f3b5b9914a2233bf239 100644 (file)
@@ -906,7 +906,7 @@ public class OwnershipAnalysis {
       TypeDescriptor td = fcn.getType();
       assert td != null;
       
-      og.assignTypedTempXEqualToTempY(lhs, rhs, td);
+      og.assignTempXEqualToCastedTempY(lhs, rhs, td);
       break;
 
     case FKind.FlatFieldNode:
@@ -955,7 +955,7 @@ public class OwnershipAnalysis {
       FlatSetElementNode fsen = (FlatSetElementNode) fn;
 
       if( arrayReferencees.doesNotCreateNewReaching( fsen ) ) {
-        System.out.println( "Skipping no-heap-effect: "+fsen );
+       // skip this node if it cannot create new reachability paths
         break;
       }
 
@@ -1466,6 +1466,10 @@ public class OwnershipAnalysis {
   boolean stopAfterCapture = true;
 
   // increments every visit to debugSnapshot, don't fiddle with it
+  // IMPORTANT NOTE FOR SETTING THE FOLLOWING VALUES: this
+  // counter increments just after every node is analyzed
+  // from the body of the method whose symbol is specified
+  // above.
   int debugCounter = 0;
 
   // the value of debugCounter to start reporting the debugCounter
index cf29903d7072ecc6e48ff879540dc324d1135a3a..6bf0fb841de1fb3ca7ee21c066b185726e0d85ae 100644 (file)
@@ -89,7 +89,6 @@ public class OwnershipGraph {
   public Hashtable< TempDescriptor, Set<AccessPath> > temp2accessPaths;
 
 
-
   public OwnershipGraph() {
 
     id2hrn                    = new Hashtable<Integer,        HeapRegionNode>();
@@ -231,6 +230,13 @@ public class OwnershipGraph {
     referencee.addReferencer(edge);
   }
 
+  protected void removeReferenceEdge(ReferenceEdge e) {
+    removeReferenceEdge(e.getSrc(),
+                       e.getDst(),
+                       e.getType(),
+                       e.getField() );
+  }
+
   protected void removeReferenceEdge(OwnershipNode referencer,
                                      HeapRegionNode referencee,
                                      TypeDescriptor type,
@@ -354,45 +360,70 @@ public class OwnershipGraph {
   }
 
 
-  public void assignTempXEqualToTempY(TempDescriptor x,
-                                      TempDescriptor y) {
-    assignTypedTempXEqualToTempY( x, y, null );
+  public void assignTempXEqualToTempY( TempDescriptor x,
+                                      TempDescriptor y ) {
+    assignTempXEqualToCastedTempY( x, y, null );
   }
 
+  public void assignTempXEqualToCastedTempY( TempDescriptor x,
+                                            TempDescriptor y,
+                                            TypeDescriptor tdCast ) {
 
-  public void assignTypedTempXEqualToTempY(TempDescriptor x,
-                                          TempDescriptor y,
-                                          TypeDescriptor type) {
-
-    LabelNode lnX = getLabelNodeFromTemp(x);
-    LabelNode lnY = getLabelNodeFromTemp(y);
+    LabelNode lnX = getLabelNodeFromTemp( x );
+    LabelNode lnY = getLabelNodeFromTemp( y );
     
-    clearReferenceEdgesFrom(lnX, null, null, true);
+    clearReferenceEdgesFrom( lnX, null, null, true );
+
+    // note it is possible that the types of temps in the
+    // flat node to analyze will reveal that some typed
+    // edges in the reachability graph are impossible
+    Set<ReferenceEdge> impossibleEdges = new HashSet<ReferenceEdge>();
 
     Iterator<ReferenceEdge> itrYhrn = lnY.iteratorToReferencees();
     while( itrYhrn.hasNext() ) {
       ReferenceEdge  edgeY      = itrYhrn.next();
       HeapRegionNode referencee = edgeY.getDst();
       ReferenceEdge  edgeNew    = edgeY.copy();
-      edgeNew.setSrc( lnX );
 
-      if( type != null ) {
-       edgeNew.setType( type );
-       edgeNew.setField( null );
+      if( !isSuperiorType( x.getType(), edgeY.getType() ) ) {
+       impossibleEdges.add( edgeY );
+       continue;
       }
 
-      addReferenceEdge(lnX, referencee, edgeNew);
+      edgeNew.setSrc( lnX );
+      
+      edgeNew.setType( mostSpecificType( y.getType(),
+                                        tdCast, 
+                                        edgeY.getType(), 
+                                        referencee.getType() 
+                                        ) 
+                      );
+
+      edgeNew.setField( null );
+
+      addReferenceEdge( lnX, referencee, edgeNew );
+    }
+
+    Iterator<ReferenceEdge> itrImp = impossibleEdges.iterator();
+    while( itrImp.hasNext() ) {
+      ReferenceEdge edgeImp = itrImp.next();
+      removeReferenceEdge( edgeImp );
     }
   }
 
 
-  public void assignTempXEqualToTempYFieldF(TempDescriptor x,
-                                            TempDescriptor y,
-                                            FieldDescriptor f) {
-    LabelNode lnX = getLabelNodeFromTemp(x);
-    LabelNode lnY = getLabelNodeFromTemp(y);
+  public void assignTempXEqualToTempYFieldF( TempDescriptor  x,
+                                            TempDescriptor  y,
+                                            FieldDescriptor f ) {
+    LabelNode lnX = getLabelNodeFromTemp( x );
+    LabelNode lnY = getLabelNodeFromTemp( y );
+
+    clearReferenceEdgesFrom( lnX, null, null, true );
 
-    clearReferenceEdgesFrom(lnX, null, null, true);
+    // note it is possible that the types of temps in the
+    // flat node to analyze will reveal that some typed
+    // edges in the reachability graph are impossible
+    Set<ReferenceEdge> impossibleEdges = new HashSet<ReferenceEdge>();
 
     Iterator<ReferenceEdge> itrYhrn = lnY.iteratorToReferencees();
     while( itrYhrn.hasNext() ) {
@@ -406,37 +437,70 @@ public class OwnershipGraph {
        HeapRegionNode  hrnHrn  = edgeHrn.getDst();
        ReachabilitySet betaHrn = edgeHrn.getBeta();
 
-       if( edgeHrn.getType() == null ||            
-           (edgeHrn.getType() .equals( f.getType()   ) &&
-            edgeHrn.getField().equals( f.getSymbol() )    )
-         ) {
+       // prune edges that are not a matching field
+       if( edgeHrn.getType() != null &&                    
+           !edgeHrn.getField().equals( f.getSymbol() )     
+           ) {
+         continue;
+       }
 
-         ReferenceEdge edgeNew = new ReferenceEdge(lnX,
-                                                   hrnHrn,
-                                                   f.getType(),
-                                                   null,
-                                                   false,
-                                                   betaY.intersection(betaHrn) );
+       // check for impossible edges
+       if( !isSuperiorType( x.getType(), edgeHrn.getType() ) ) {
+         impossibleEdges.add( edgeHrn );
+         continue;
+       }
+
+       TypeDescriptor tdNewEdge =
+         mostSpecificType( edgeHrn.getType(), 
+                           hrnHrn.getType() 
+                           );       
          
-         int newTaintIdentifier=getTaintIdentifierFromHRN(hrnHrn);
-         edgeNew.setTaintIdentifier(newTaintIdentifier);
+       ReferenceEdge edgeNew = new ReferenceEdge( lnX,
+                                                  hrnHrn,
+                                                  tdNewEdge,
+                                                  null,
+                                                  false,
+                                                  betaY.intersection( betaHrn )
+                                                  );
+       
+       int newTaintIdentifier=getTaintIdentifierFromHRN(hrnHrn);
+       edgeNew.setTaintIdentifier(newTaintIdentifier);
+       
+       addReferenceEdge( lnX, hrnHrn, edgeNew );       
+      }
+    }
 
-         addReferenceEdge(lnX, hrnHrn, edgeNew);
-       }
+    Iterator<ReferenceEdge> itrImp = impossibleEdges.iterator();
+    while( itrImp.hasNext() ) {
+      ReferenceEdge edgeImp = itrImp.next();
+      removeReferenceEdge( edgeImp );
+    }
+
+    // anytime you might remove edges between heap regions
+    // you must global sweep to clean up broken reachability
+    if( !impossibleEdges.isEmpty() ) {
+      if( !DISABLE_GLOBAL_SWEEP ) {
+       globalSweep();
       }
     }
   }
 
 
-  public void assignTempXFieldFEqualToTempY(TempDescriptor x,
-                                            FieldDescriptor f,
-                                            TempDescriptor y) {
-    LabelNode lnX = getLabelNodeFromTemp(x);
-    LabelNode lnY = getLabelNodeFromTemp(y);
+  public void assignTempXFieldFEqualToTempY( TempDescriptor  x,
+                                            FieldDescriptor f,
+                                            TempDescriptor  y ) {
+
+    LabelNode lnX = getLabelNodeFromTemp( x );
+    LabelNode lnY = getLabelNodeFromTemp( y );
 
     HashSet<HeapRegionNode> nodesWithNewAlpha = new HashSet<HeapRegionNode>();
     HashSet<ReferenceEdge>  edgesWithNewBeta  = new HashSet<ReferenceEdge>();
 
+    // note it is possible that the types of temps in the
+    // flat node to analyze will reveal that some typed
+    // edges in the reachability graph are impossible
+    Set<ReferenceEdge> impossibleEdges = new HashSet<ReferenceEdge>();
+
     // first look for possible strong updates and remove those edges
     boolean strongUpdate = false;
 
@@ -462,23 +526,27 @@ public class OwnershipGraph {
     // then do all token propagation
     itrXhrn = lnX.iteratorToReferencees();
     while( itrXhrn.hasNext() ) {
-      ReferenceEdge edgeX = itrXhrn.next();
-      HeapRegionNode hrnX = edgeX.getDst();
+      ReferenceEdge   edgeX = itrXhrn.next();
+      HeapRegionNode  hrnX  = edgeX.getDst();
       ReachabilitySet betaX = edgeX.getBeta();
-
-      ReachabilitySet R = hrnX.getAlpha().intersection(edgeX.getBeta() );
+      ReachabilitySet R     = hrnX.getAlpha().intersection( edgeX.getBeta() );
 
       Iterator<ReferenceEdge> itrYhrn = lnY.iteratorToReferencees();
       while( itrYhrn.hasNext() ) {
-       ReferenceEdge edgeY = itrYhrn.next();
-       HeapRegionNode hrnY = edgeY.getDst();
-       ReachabilitySet O = edgeY.getBeta();
+       ReferenceEdge   edgeY = itrYhrn.next();
+       HeapRegionNode  hrnY  = edgeY.getDst();
+       ReachabilitySet O     = edgeY.getBeta();
 
+       // check for impossible edges
+       if( !isSuperiorType( f.getType(), edgeY.getType() ) ) {
+         impossibleEdges.add( edgeY );
+         continue;
+       }
 
        // propagate tokens over nodes starting from hrnSrc, and it will
        // take care of propagating back up edges from any touched nodes
-       ChangeTupleSet Cy = O.unionUpArityToChangeSet(R);
-       propagateTokensOverNodes(hrnY, Cy, nodesWithNewAlpha, edgesWithNewBeta);
+       ChangeTupleSet Cy = O.unionUpArityToChangeSet( R );
+       propagateTokensOverNodes( hrnY, Cy, nodesWithNewAlpha, edgesWithNewBeta );
 
 
        // then propagate back just up the edges from hrn
@@ -491,13 +559,13 @@ public class OwnershipGraph {
        Iterator<ReferenceEdge> referItr = hrnX.iteratorToReferencers();
        while( referItr.hasNext() ) {
          ReferenceEdge edgeUpstream = referItr.next();
-         todoEdges.add(edgeUpstream);
-         edgePlannedChanges.put(edgeUpstream, Cx);
+         todoEdges.add( edgeUpstream );
+         edgePlannedChanges.put( edgeUpstream, Cx );
        }
 
-       propagateTokensOverEdges(todoEdges,
-                                edgePlannedChanges,
-                                edgesWithNewBeta);
+       propagateTokensOverEdges( todoEdges,
+                                 edgePlannedChanges,
+                                 edgesWithNewBeta );
       }
     }
 
@@ -519,54 +587,74 @@ public class OwnershipGraph {
     while( itrXhrn.hasNext() ) {
       ReferenceEdge edgeX = itrXhrn.next();
       HeapRegionNode hrnX = edgeX.getDst();
-
+      
       Iterator<ReferenceEdge> itrYhrn = lnY.iteratorToReferencees();
       while( itrYhrn.hasNext() ) {
        ReferenceEdge edgeY = itrYhrn.next();
        HeapRegionNode hrnY = edgeY.getDst();
 
+       // skip impossible edges here, we already marked them
+       // when computing reachability propagations above
+       if( !isSuperiorType( f.getType(), edgeY.getType() ) ) {
+         continue;
+       }
+       
        // prepare the new reference edge hrnX.f -> hrnY
-       ReferenceEdge edgeNew = new ReferenceEdge(hrnX,
-                                                 hrnY,
-                                                 f.getType(),
-                                                 f.getSymbol(),
-                                                 false,
-                                                 edgeY.getBeta().pruneBy( hrnX.getAlpha() )
-                                                 );
+       TypeDescriptor tdNewEdge =      
+         mostSpecificType( y.getType(),
+                           edgeY.getType(), 
+                           hrnY.getType()
+                           );  
+
+       ReferenceEdge edgeNew = new ReferenceEdge( hrnX,
+                                                  hrnY,
+                                                  tdNewEdge,
+                                                  f.getSymbol(),
+                                                  false,
+                                                  edgeY.getBeta().pruneBy( hrnX.getAlpha() )
+                                                  );
 
        // look to see if an edge with same field exists
        // and merge with it, otherwise just add the edge
        ReferenceEdge edgeExisting = hrnX.getReferenceTo( hrnY, 
-                                                         f.getType(),
+                                                         tdNewEdge,
                                                          f.getSymbol() );
        
        if( edgeExisting != null ) {
          edgeExisting.setBeta(
                               edgeExisting.getBeta().union( edgeNew.getBeta() )
                              );
+
          if((!hrnX.isParameter() && hrnY.isParameter()) || ( hrnX.isParameter() && hrnY.isParameter())){
-                 int newTaintIdentifier=getTaintIdentifierFromHRN(hrnY);
-                 edgeExisting.unionTaintIdentifier(newTaintIdentifier);
+           int newTaintIdentifier=getTaintIdentifierFromHRN(hrnY);
+           edgeExisting.unionTaintIdentifier(newTaintIdentifier);
          }
          // a new edge here cannot be reflexive, so existing will
          // always be also not reflexive anymore
          edgeExisting.setIsInitialParam( false );
        } else {
                
-               if((!hrnX.isParameter() && hrnY.isParameter()) || ( hrnX.isParameter() && hrnY.isParameter())){
-                       int newTaintIdentifier=getTaintIdentifierFromHRN(hrnY);
-                       edgeNew.setTaintIdentifier(newTaintIdentifier);
-               }
-               //currently, taint isn't propagated through the chain of refrences
-        //propagateTaintIdentifier(hrnX,newTaintIdentifier,new HashSet<HeapRegionNode>());
+         if((!hrnX.isParameter() && hrnY.isParameter()) || ( hrnX.isParameter() && hrnY.isParameter())){
+           int newTaintIdentifier=getTaintIdentifierFromHRN(hrnY);
+           edgeNew.setTaintIdentifier(newTaintIdentifier);
+         }
+         //currently, taint isn't propagated through the chain of refrences
+         //propagateTaintIdentifier(hrnX,newTaintIdentifier,new HashSet<HeapRegionNode>());
+         
          addReferenceEdge( hrnX, hrnY, edgeNew );
        }
       }
     }
 
+    Iterator<ReferenceEdge> itrImp = impossibleEdges.iterator();
+    while( itrImp.hasNext() ) {
+      ReferenceEdge edgeImp = itrImp.next();
+      removeReferenceEdge( edgeImp );
+    }
+
     // if there was a strong update, make sure to improve
     // reachability with a global sweep
-    if( strongUpdate ) {    
+    if( strongUpdate || !impossibleEdges.isEmpty() ) {    
       if( !DISABLE_GLOBAL_SWEEP ) {
         globalSweep();
       }
@@ -2881,7 +2969,7 @@ public class OwnershipGraph {
          Iterator srcItr = possibleCallerSrcs.iterator();
          while( srcItr.hasNext() ) {
            HeapRegionNode src = (HeapRegionNode) srcItr.next();
-
+           
            if( !hasMatchingField( src, edgeCallee ) ) {
              // prune this source node possibility
              continue;
@@ -2896,10 +2984,38 @@ public class OwnershipGraph {
                continue;
              }
 
+             
+             /*
+           //// KEEP THIS HACK AROUND FOR EXPERIMENTING WITH EDGE REMOVAL
+             TypeDescriptor tdX = src.getType();
+             TypeDescriptor tdY = dst.getType();
+             if( tdX != null && tdY != null ) {
+               if( tdX.toPrettyString().equals( "Object[]" ) &&
+                   tdY.toPrettyString().equals( "D2" ) ) {
+                 System.out.println( "Skipping an edge from Object[] -> D2 during call mapping" );
+                 continue;
+               }
+               if( tdX.toPrettyString().equals( "Object[]" ) &&
+                   tdY.toPrettyString().equals( "MessageList" ) ) {
+                 System.out.println( "Skipping an edge from Object[] -> MessageList during call mapping" );
+                 continue;
+               }
+             }
+             */
+
+
              // otherwise the caller src and dst pair can match the edge, so make it
+             TypeDescriptor tdNewEdge =
+               mostSpecificType( edgeCallee.getType(),
+                                 hrnChildCallee.getType(),
+                                 dst.getType()
+                                 );          
+
              ReferenceEdge edgeNewInCaller = edgeNewInCallerTemplate.copy();
              edgeNewInCaller.setSrc( src );
              edgeNewInCaller.setDst( dst );         
+             edgeNewInCaller.setType( tdNewEdge );
+
              
              // handle taint info if callee created this edge
              // added by eom
@@ -2948,7 +3064,16 @@ public class OwnershipGraph {
       LabelNode lnReturnCallee = ogCallee.getLabelNodeFromTemp( tdReturn );
       Iterator<ReferenceEdge> edgeCalleeItr = lnReturnCallee.iteratorToReferencees();
       while( edgeCalleeItr.hasNext() ) {
-       ReferenceEdge edgeCallee = edgeCalleeItr.next();
+       ReferenceEdge  edgeCallee     = edgeCalleeItr.next();
+       HeapRegionNode hrnChildCallee = edgeCallee.getDst();
+
+       // some edge types are not possible return values when we can
+       // see what type variable we are assigning it to
+       if( !isSuperiorType( returnTemp.getType(), edgeCallee.getType() ) ) {
+         System.out.println( "*** NOT EXPECTING TO SEE THIS: Throwing out "+edgeCallee+" for return temp "+returnTemp );
+         // prune
+         continue;
+       }       
 
        ReferenceEdge edgeNewInCallerTemplate = new ReferenceEdge( null,
                                                                   null,
@@ -2985,18 +3110,26 @@ public class OwnershipGraph {
        while( itrHrn.hasNext() ) {
          HeapRegionNode hrnCaller = itrHrn.next();
 
-         if( !hasMatchingType( edgeCallee, hrnCaller ) ) {
-           // prune
+         // don't make edge in caller if it is disallowed by types
+         if( !isSuperiorType( returnTemp.getType(), hrnCaller.getType() ) ) {
+           // prune       
            continue;
          }
 
+         TypeDescriptor tdNewEdge =
+           mostSpecificType( edgeCallee.getType(),
+                             hrnChildCallee.getType(),
+                             hrnCaller.getType()
+                             );              
+
          // otherwise caller node can match callee edge, so make it
          ReferenceEdge edgeNewInCaller = edgeNewInCallerTemplate.copy();
          edgeNewInCaller.setSrc( lnLhsCaller );
          edgeNewInCaller.setDst( hrnCaller );
+         edgeNewInCaller.setType( tdNewEdge );
 
          ReferenceEdge edgeExisting = lnLhsCaller.getReferenceTo( hrnCaller, 
-                                                                  edgeNewInCaller.getType(),
+                                                                  tdNewEdge,
                                                                   edgeNewInCaller.getField() );
          if( edgeExisting == null ) {
 
@@ -3200,31 +3333,30 @@ public class OwnershipGraph {
 
 
   protected boolean hasMatchingType(ReferenceEdge edge, HeapRegionNode dst) {
-   
+    
     // if the region has no type, matches everything
     TypeDescriptor tdDst = dst.getType();
     if( tdDst == null ) {
       return true;
     }
-
     // if the type is not a class or an array, don't
     // match because primitives are copied, no aliases
     ClassDescriptor cdDst = tdDst.getClassDesc();
     if( cdDst == null && !tdDst.isArray() ) {
       return false;
     }
-
     // if the edge type is null, it matches everything
     TypeDescriptor tdEdge = edge.getType();
     if( tdEdge == null ) {
       return true;
     }
-
     return typeUtil.isSuperorType(tdEdge, tdDst);
   }
 
 
-
   protected void unshadowTokens(AllocationSite as, ReferenceEdge edge) {
     edge.setBeta(edge.getBeta().unshadowTokens(as) );
   }
@@ -4864,7 +4996,52 @@ public class OwnershipGraph {
          }       
          
   }
+
+
+  // in this analysis specifically:
+  // we have a notion that a null type is the "match any" type,
+  // so wrap calls to the utility methods that deal with null
+  public TypeDescriptor mostSpecificType( TypeDescriptor td1,
+                                         TypeDescriptor td2 ) {
+    if( td1 == null ) {
+      return td2;
+    }
+    if( td2 == null ) {
+      return td1;
+    }
+    return typeUtil.mostSpecific( td1, td2 );
+  }
+  
+  public TypeDescriptor mostSpecificType( TypeDescriptor td1,
+                                         TypeDescriptor td2,
+                                         TypeDescriptor td3 ) {
+    
+    return mostSpecificType( td1, 
+                            mostSpecificType( td2, td3 )
+                            );
+  }  
   
+  public TypeDescriptor mostSpecificType( TypeDescriptor td1,
+                                         TypeDescriptor td2,
+                                         TypeDescriptor td3,
+                                         TypeDescriptor td4 ) {
+    
+    return mostSpecificType( mostSpecificType( td1, td2 ), 
+                            mostSpecificType( td3, td4 )
+                            );
+  }  
+
+  // remember, in this analysis a null type means "any type"
+  public boolean isSuperiorType( TypeDescriptor possibleSuper,
+                                TypeDescriptor possibleChild ) {
+    if( possibleSuper == null ||
+       possibleChild == null ) {
+      return true;
+    }
+    
+    return typeUtil.isSuperorType( possibleSuper, possibleChild );
+  }
+
   public String generateUniqueIdentifier(FlatMethod fm, int paramIdx, String type){
          
          //type: A->aliapsed parameter heap region
@@ -4896,7 +5073,5 @@ public class OwnershipGraph {
          
          return identifier;
          
-  }
-
-  
+  }  
 }
index df0027f98719a6dcf3a3c101c64bd160c69e52a7..6892efc2e0b637206f7c77b469f5b9b028770eeb 100644 (file)
@@ -4,7 +4,7 @@ PROGRAM=test
 SOURCE_FILES=D2.java #smalltest.java
 
 BUILDSCRIPT=~/research/Robust/src/buildscript
-BSFLAGS= -debug -nooptimize -mainclass $(MAIN_CLASS) #-justanalyze -ownership -ownallocdepth 1 -ownwritedots final -ownaliasfile aliases.txt -enable-assertions
+BSFLAGS= -debug -nooptimize -mainclass $(MAIN_CLASS) -justanalyze -ownership -ownallocdepth 1 -ownwritedots final -ownaliasfile aliases.txt -enable-assertions
 
 all: $(PROGRAM).bin
 
index 158577edfe83c6ebb7869e684750dc8b13347e84..43a226ef3ee834642276d1fabccfd96d589e09fa 100644 (file)
@@ -4,7 +4,7 @@ PROGRAM=test
 SOURCE_FILES=D2.java
 
 BUILDSCRIPT=~/research/Robust/src/buildscript
-BSFLAGS= -debug -mainclass $(MAIN_CLASS) -flatirusermethods -flatirlibmethods -joptimize #-nooptimize
+BSFLAGS= -debug -mainclass $(MAIN_CLASS) -joptimize -flatirusermethods #-flatirlibmethods
 
 #DBCALLFLAGS= -owndebugcaller main -owndebugcallee executeAll 
 #DBCALLFLAGS= -owndebugcaller executeAll -owndebugcallee executeMessage -owndebugcallcount 0
@@ -16,7 +16,7 @@ BSFLAGS= -debug -mainclass $(MAIN_CLASS) -flatirusermethods -flatirlibmethods -j
 #DBCALLFLAGS= -owndebugcaller amendFlightPlan -owndebugcallee getFlight -owndebugcallcount 0
 #DBCALLFLAGS= -owndebugcaller amendFlightPlan -owndebugcallee addFix -owndebugcallcount 0
 #DBCALLFLAGS= -owndebugcaller addFix -owndebugcallee addFix -owndebugcallcount 0
-DBCALLFLAGS= -owndebugcaller addFix -owndebugcallee insertElementAt -owndebugcallcount 0
+#DBCALLFLAGS= -owndebugcaller addFix -owndebugcallee insertElementAt -owndebugcallcount 0
 #DBCALLFLAGS= -owndebugcaller insertElementAt -owndebugcallee ensureCapacity -owndebugcallcount 0
 
 ANALYZEFLAGS= -justanalyze $(DBCALLFLAGS) -ownership -ownallocdepth 1 -ownwritedots final -ownaliasfile aliases.txt -enable-assertions
index 50b02076f5a9150bf72064159ece52382cf52066..d289a9535e8d20ba2956d174d2826fbc65460b41 100644 (file)
@@ -305,6 +305,19 @@ NextMethod:
       throw new Error("Case not handled:"+possiblesuper+" "+cd2);
   }
 
+  public TypeDescriptor mostSpecific(TypeDescriptor td1, TypeDescriptor td2) {
+    if( isSuperorType( td1, td2 ) ) {
+      return td2;
+    }
+    if( isSuperorType( td2, td1 ) ) {
+      return td1;
+    }
+    throw new Error( td1+" and "+td2+" have no superclass relationship" );
+  }
+
+  public TypeDescriptor mostSpecific(TypeDescriptor td1, TypeDescriptor td2, TypeDescriptor td3) {
+    return mostSpecific( td1, mostSpecific( td2, td3 ) );
+  }
 
   public boolean isSuperorType(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
     if (possiblesuper==cd2)