collects live-in var's allocation sites when it references to parameter heap region.
[IRC.git] / Robust / src / Analysis / MLP / MLPAnalysis.java
index 37ae074c73430903cc7e14726002a08701165365..e646ec6bf82b47b2d94e8790150521103c1641a8 100644 (file)
@@ -48,6 +48,8 @@ public class MLPAnalysis {
   private Hashtable< FlatNode, CodePlan                 > codePlans;
 
   private Hashtable< FlatEdge, FlatWriteDynamicVarNode  > wdvNodesToSpliceIn;
+  
+  private Hashtable< MethodContext, HashSet<AllocationSite>> mapMethodContextToLiveInAllocationSiteSet;
 
   public static int maxSESEage = -1;
 
@@ -101,6 +103,8 @@ public class MLPAnalysis {
     codePlans            = new Hashtable< FlatNode, CodePlan                 >();
     wdvNodesToSpliceIn   = new Hashtable< FlatEdge, FlatWriteDynamicVarNode  >();
     
+    mapMethodContextToLiveInAllocationSiteSet = new Hashtable< MethodContext, HashSet<AllocationSite>>();
+    
 
     FlatMethod fmMain = state.getMethodFlat( typeUtil.getMain() );
 
@@ -186,12 +190,32 @@ public class MLPAnalysis {
     
     // new pass
     methItr = ownAnalysis.descriptorsToAnalyze.iterator();
+       JavaCallGraph javaCallGraph = new JavaCallGraph(state,tu);
     while( methItr.hasNext() ) {
       Descriptor d  = methItr.next();      
       FlatMethod fm = state.getMethodFlat( d );
-      methodEffects(fm);
-      // notAvailableForward( fm );
+      methodEffects(fm,javaCallGraph);
     }
+    
+    // disjoint analysis with a set of flagged allocation sites of live-in variable
+       try {
+               OwnershipAnalysis oa2 = new OwnershipAnalysis(state, tu, callGraph,
+                               state.OWNERSHIPALLOCDEPTH, false,
+                               false, state.OWNERSHIPALIASFILE,
+                               state.METHODEFFECTS,
+                               mapMethodContextToLiveInAllocationSiteSet);
+               // debug
+               methItr = oa2.descriptorsToAnalyze.iterator();
+               while (methItr.hasNext()) {
+                       Descriptor d = methItr.next();
+                       FlatMethod fm = state.getMethodFlat(d);
+                       debugFunction(oa2, fm);
+               }
+               //
+       } catch (IOException e) {
+               System.err.println(e);
+       }
+    
 
 
     // 7th pass
@@ -790,7 +814,35 @@ public class MLPAnalysis {
     } // end switch
   }
   
-       private void methodEffects(FlatMethod fm) {
+  private void debugFunction(OwnershipAnalysis oa2, FlatMethod fm) {
+         
+         String methodName="doSomeWork";
+         
+         MethodDescriptor md=fm.getMethod();
+               HashSet<MethodContext> mcSet=oa2.getAllMethodContextSetByDescriptor(md);
+               Iterator<MethodContext> mcIter=mcSet.iterator();
+               
+               while(mcIter.hasNext()){
+                       MethodContext mc=mcIter.next();
+                       
+                       OwnershipGraph og=oa2.getOwnvershipGraphByMethodContext(mc);
+                       
+                       if(fm.toString().indexOf(methodName)>0){
+                                try {
+                                og.writeGraph(methodName + "SECONDGRAPH", true, true, true, true, false);
+                                } catch (IOException e) {
+                                System.out.println("Error writing debug capture.");
+                                System.exit(0);
+                                }
+                       }
+                       
+
+
+               }
+         
+  }
+  
+       private void methodEffects(FlatMethod fm, CallGraph callGraph) {
 
                MethodDescriptor md=fm.getMethod();
                HashSet<MethodContext> mcSet=ownAnalysis.getAllMethodContextSetByDescriptor(md);
@@ -799,7 +851,6 @@ public class MLPAnalysis {
                while(mcIter.hasNext()){
                        MethodContext mc=mcIter.next();
                        
-//                     System.out.println("#method effects="+fm+" with mc="+mc);
                        Set<FlatNode> visited = new HashSet<FlatNode>();
                        
                        Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
@@ -813,7 +864,7 @@ public class MLPAnalysis {
                                assert seseStack != null;
 
                                if (!seseStack.empty()) {
-                                       effects_nodeActions(mc, fn, seseStack.peek());
+                                       effects_nodeActions(mc, fn, seseStack.peek(), callGraph);
                                }
 
                                flatNodesToVisit.remove(fn);
@@ -832,9 +883,143 @@ public class MLPAnalysis {
                }
                
        }
+       
+       private void analyzeRelatedAllocationSite(MethodDescriptor callerMD,
+                       MethodContext calleeMC, HashSet<Integer> paramIndexSet) {
+
+               HashSet<MethodContext> mcSet = ownAnalysis
+                               .getAllMethodContextSetByDescriptor(callerMD);
+               Iterator<MethodContext> mcIter = mcSet.iterator();
+
+               FlatMethod callerFM = state.getMethodFlat(callerMD);
+
+               while (mcIter.hasNext()) {
+                       MethodContext mc = mcIter.next();
+
+                       Set<FlatNode> visited = new HashSet<FlatNode>();
+                       Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
+                       flatNodesToVisit.add(callerFM);
+
+                       while (!flatNodesToVisit.isEmpty()) {
+                               FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
+                               flatNodesToVisit.remove(fn);
+
+                               analyzeRelatedAllocationSite_NodeAction(fn, mc, calleeMC, paramIndexSet);
+
+                               flatNodesToVisit.remove(fn);
+                               visited.add(fn);
+
+                               for (int i = 0; i < fn.numNext(); i++) {
+                                       FlatNode nn = fn.getNext(i);
+                                       if (!visited.contains(nn)) {
+                                               flatNodesToVisit.add(nn);
+                                       }
+                               }
+                       }
+
+               }
+
+       }
+       
+       private void analyzeRelatedAllocationSite_NodeAction(FlatNode fn, MethodContext callerMC,
+                       MethodContext calleeMC, HashSet<Integer> paramIndexSet) {
+
+               OwnershipGraph og = ownAnalysis
+                               .getOwnvershipGraphByMethodContext(callerMC);
+
+               switch (fn.kind()) {
+
+               case FKind.FlatCall: {
+
+                       FlatCall fc = (FlatCall) fn;
+
+                       MethodContext calleeMCfromOG = ownAnalysis.getCalleeMethodContext(
+                                       callerMC, fc);
+
+                       if (calleeMC.equals(calleeMCfromOG)) {
+                               // in this case, this method context calls corresponding callee.
+                               int base;
+                               if (((MethodDescriptor) calleeMC.getDescriptor()).isStatic()) {
+                                       base = 0;
+                               } else {
+                                       base = 1;
+                               }
+                               
+                               for (Iterator iterator = paramIndexSet.iterator(); iterator
+                                               .hasNext();) {
+                                       Integer integer = (Integer) iterator.next();
+                                       
+                                       int paramIdx=integer-base;
+                                       if(paramIdx>=0){
+                                               // if paramIdx is less than 0, assumes that it is related with wrong method contexts.
+                                               TempDescriptor arg = fc.getArg(paramIdx );
+                                               LabelNode argLN = og.td2ln.get(arg);
+                                               if (argLN != null) {
+                                                       Iterator<ReferenceEdge> iterEdge = argLN
+                                                                       .iteratorToReferencees();
+                                                       while (iterEdge.hasNext()) {
+                                                               ReferenceEdge referenceEdge = (ReferenceEdge) iterEdge
+                                                                               .next();
+                                                               
+                                                               HeapRegionNode dstHRN=referenceEdge.getDst();
+                                                               if(dstHRN.isParameter()){
+                                                                       setupRelatedAllocSiteAnalysis(og,callerMC,dstHRN);
+                                                               }else{
+                                                                       addLiveInAllocationSite(callerMC, dstHRN
+                                                                                       .getAllocationSite());
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+
+               }
+                       break;
+
+               }
+       }
+       
+       private void setupRelatedAllocSiteAnalysis(OwnershipGraph og,
+                       MethodContext mc, HeapRegionNode dstHRN) {
+
+               HashSet<Integer> paramIndexSet = new HashSet<Integer>();
+
+               // collect corresponding param index
+               Set<Integer> pIndexSet = og.idPrimary2paramIndexSet.get(dstHRN.getID());
+               if (pIndexSet != null) {
+                       for (Iterator iterator = pIndexSet.iterator(); iterator.hasNext();) {
+                               Integer integer = (Integer) iterator.next();
+                               paramIndexSet.add(integer);
+                       }
+               }
+
+               Set<Integer> sIndexSet = og.idSecondary2paramIndexSet.get(dstHRN
+                               .getID());
+               if (sIndexSet != null) {
+                       for (Iterator iterator = sIndexSet.iterator(); iterator.hasNext();) {
+                               Integer integer = (Integer) iterator.next();
+                               paramIndexSet.add(integer);
+                       }
+               }
+
+               if (mc.getDescriptor() instanceof MethodDescriptor) {
+                       Set callerSet = callGraph.getCallerSet((MethodDescriptor) mc
+                                       .getDescriptor());
+                       for (Iterator iterator = callerSet.iterator(); iterator.hasNext();) {
+                               Object obj = (Object) iterator.next();
+                               if (obj instanceof MethodDescriptor) {
+                                       MethodDescriptor callerMD = (MethodDescriptor) obj;
+
+                                       analyzeRelatedAllocationSite(callerMD, mc, paramIndexSet);
+
+                               }
+                       }
+               }
+       }
   
        private void effects_nodeActions(MethodContext mc, FlatNode fn,
-                       FlatSESEEnterNode currentSESE) {
+                       FlatSESEEnterNode currentSESE, CallGraph callGraph) {
 
                OwnershipGraph og = ownAnalysis.getOwnvershipGraphByMethodContext(mc);
 
@@ -855,7 +1040,26 @@ public class MLPAnalysis {
                                if (ln != null) {
                                        int taint = (int) Math.pow(2, idx);
                                        taintLabelNode(ln, taint);
+
+                                       // collects related allocation sites
+                                       Iterator<ReferenceEdge> referenceeIter = ln
+                                                       .iteratorToReferencees();
+                                       while (referenceeIter.hasNext()) {
+                                               ReferenceEdge referenceEdge = (ReferenceEdge) referenceeIter
+                                                               .next();
+                                               HeapRegionNode dstHRN = referenceEdge.getDst();
+                                               if (dstHRN.isParameter()) {
+                                                       
+                                                       setupRelatedAllocSiteAnalysis(og,mc,dstHRN);
+
+                                               } else {
+                                                       addLiveInAllocationSite(mc, dstHRN
+                                                                       .getAllocationSite());
+                                               }
+                                       }
+
                                }
+
                                idx++;
                        }
 
@@ -865,7 +1069,94 @@ public class MLPAnalysis {
                case FKind.FlatSESEExitNode: {
                        FlatSESEExitNode fsexit = (FlatSESEExitNode) fn;
 
-                       fsexit.getFlatEnter().getSeseEffectsSet().printSet();
+                       FlatSESEEnterNode enterNode = fsexit.getFlatEnter();
+                       FlatSESEEnterNode parent = enterNode.getParent();
+                       if (parent != null) {
+
+                               SESEEffectsSet set = enterNode.getSeseEffectsSet();
+                               Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> readTable = set
+                                               .getReadTable();
+                               Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> parentReadTable = parent
+                                               .getSeseEffectsSet().getReadTable();
+                               Set<TempDescriptor> keys = readTable.keySet();
+                               Iterator<TempDescriptor> keyIter = keys.iterator();
+                               while (keyIter.hasNext()) {
+                                       TempDescriptor td = (TempDescriptor) keyIter.next();
+                                       HashSet<SESEEffectsKey> effectsSet = readTable.get(td);
+                                       HashSet<SESEEffectsKey> parentEffectsSet = parentReadTable
+                                                       .get(td);
+                                       if (parentEffectsSet == null) {
+                                               parentEffectsSet = new HashSet<SESEEffectsKey>();
+                                       }
+
+                                       for (Iterator iterator = effectsSet.iterator(); iterator
+                                                       .hasNext();) {
+                                               SESEEffectsKey seseKey = (SESEEffectsKey) iterator
+                                                               .next();
+                                               parentEffectsSet.add(new SESEEffectsKey(seseKey
+                                                               .getFieldDescriptor(), seseKey
+                                                               .getTypeDescriptor(), seseKey.getHRNId()));
+                                       }
+
+                                       parentReadTable.put(td, parentEffectsSet);
+                               }
+
+                               Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> writeTable = set
+                                               .getWriteTable();
+                               Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> parentWriteTable = parent
+                                               .getSeseEffectsSet().getWriteTable();
+                               keys = writeTable.keySet();
+                               keyIter = keys.iterator();
+                               while (keyIter.hasNext()) {
+                                       TempDescriptor td = (TempDescriptor) keyIter.next();
+                                       HashSet<SESEEffectsKey> effectsSet = writeTable.get(td);
+                                       HashSet<SESEEffectsKey> parentEffectsSet = parentWriteTable
+                                                       .get(td);
+                                       if (parentEffectsSet == null) {
+                                               parentEffectsSet = new HashSet<SESEEffectsKey>();
+                                       }
+
+                                       for (Iterator iterator = effectsSet.iterator(); iterator
+                                                       .hasNext();) {
+                                               SESEEffectsKey seseKey = (SESEEffectsKey) iterator
+                                                               .next();
+                                               parentEffectsSet.add(new SESEEffectsKey(seseKey
+                                                               .getFieldDescriptor(), seseKey
+                                                               .getTypeDescriptor(), seseKey.getHRNId()));
+                                       }
+
+                                       parentWriteTable.put(td, parentEffectsSet);
+                               }
+
+                               Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> strongUpdateTable = set
+                                               .getStrongUpdateTable();
+                               Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> parentstrongUpdateTable = parent
+                                               .getSeseEffectsSet().getStrongUpdateTable();
+                               keys = strongUpdateTable.keySet();
+                               keyIter = keys.iterator();
+                               while (keyIter.hasNext()) {
+                                       TempDescriptor td = (TempDescriptor) keyIter.next();
+                                       HashSet<SESEEffectsKey> effectsSet = strongUpdateTable
+                                                       .get(td);
+                                       HashSet<SESEEffectsKey> parentEffectsSet = parentstrongUpdateTable
+                                                       .get(td);
+                                       if (parentEffectsSet == null) {
+                                               parentEffectsSet = new HashSet<SESEEffectsKey>();
+                                       }
+
+                                       for (Iterator iterator = effectsSet.iterator(); iterator
+                                                       .hasNext();) {
+                                               SESEEffectsKey seseKey = (SESEEffectsKey) iterator
+                                                               .next();
+                                               parentEffectsSet.add(new SESEEffectsKey(seseKey
+                                                               .getFieldDescriptor(), seseKey
+                                                               .getTypeDescriptor(), seseKey.getHRNId()));
+                                       }
+
+                                       parentstrongUpdateTable.put(td, parentEffectsSet);
+                               }
+
+                       }
 
                }
                        break;
@@ -883,72 +1174,91 @@ public class MLPAnalysis {
                                                .iterator();
                                while (affectedIter.hasNext()) {
                                        TempDescriptor affectedTD = affectedIter.next();
+
                                        if (currentSESE.getInVarSet().contains(affectedTD)) {
 
-                                               HashSet<Integer> hrnSet = getReferenceHeapIDSet(og,
-                                                               affectedTD);
-                                               Iterator<Integer> hrnIter = hrnSet.iterator();
+                                               HashSet<HeapRegionNode> hrnSet = getReferenceHeapIDSet(
+                                                               og, affectedTD);
+                                               Iterator<HeapRegionNode> hrnIter = hrnSet.iterator();
                                                while (hrnIter.hasNext()) {
-                                                       Integer hrnId = hrnIter.next();
-                                                       currentSESE.readEffects(affectedTD, field
-                                                                       .getSymbol(), src.getType(), hrnId);
+                                                       HeapRegionNode hrn = hrnIter.next();
+
+                                                       Iterator<ReferenceEdge> referencers = hrn
+                                                                       .iteratorToReferencers();
+                                                       while (referencers.hasNext()) {
+                                                               ReferenceEdge referenceEdge = (ReferenceEdge) referencers
+                                                                               .next();
+                                                               if (field.getSymbol().equals(
+                                                                               referenceEdge.getField())) {
+                                                                       currentSESE.readEffects(affectedTD, field
+                                                                                       .getSymbol(), src.getType(),
+                                                                                       referenceEdge.getDst().getID());
+                                                               }
+                                                       }
+
                                                }
                                        }
                                }
 
-                               // / handle tainted case
+                               // handle tainted case
+
                                Iterator<ReferenceEdge> edgeIter = srcLN
                                                .iteratorToReferencees();
                                while (edgeIter.hasNext()) {
                                        ReferenceEdge edge = edgeIter.next();
-                                       HeapRegionNode dstHRN = edge.getDst();
+                                       HeapRegionNode accessHRN = edge.getDst();
+                                       // / follow the chain of reference to identify possible
+                                       // accesses
+                                       Iterator<ReferenceEdge> referIter = accessHRN
+                                                       .iteratorToReferencers();
+                                       while (referIter.hasNext()) {
+                                               ReferenceEdge referEdge = (ReferenceEdge) referIter
+                                                               .next();
+
+                                               // if (referEdge.getTaintIdentifier() >0 ||
+                                               // referEdge.getSESETaintIdentifier()>0 ) {
+                                               HashSet<TempDescriptor> referSet = new HashSet<TempDescriptor>();
+                                               followReference(accessHRN, referSet,
+                                                               new HashSet<HeapRegionNode>(), currentSESE);
+
+                                               Iterator<TempDescriptor> referSetIter = referSet
+                                                               .iterator();
+                                               while (referSetIter.hasNext()) {
+                                                       TempDescriptor tempDescriptor = (TempDescriptor) referSetIter
+                                                                       .next();
+                                                       currentSESE.readEffects(tempDescriptor, field
+                                                                       .getSymbol(), src.getType(), accessHRN
+                                                                       .getID());
+                                               }
+                                               // }
+                                       }
+                                       // /
+                                       if (edge.getTaintIdentifier() > 0
+                                                       || edge.getSESETaintIdentifier() > 0) {
 
-                                       Iterator<ReferenceEdge> referenceeIter = dstHRN
-                                                       .iteratorToReferencees();
-                                       while (referenceeIter.hasNext()) {
-                                               ReferenceEdge re = referenceeIter.next();
-
-                                               if ((re.getField() == null && ffn.getField() == null)
-                                                               || (re.getField() != null
-                                                                               && ffn.getField() != null
-                                                                               && re.getField().equals(
-                                                                                               ffn.getField().getSymbol()) && re
-                                                                               .getType().equals(
-                                                                                               ffn.getField().getType()))) {
-                                                       int taintIdentifier = re.getTaintIdentifier();
-
-                                                       if (taintIdentifier > 0) {
-                                                               HeapRegionNode accessHRN = re.getDst();
-                                                               affectedTDSet = getReferenceNodeSet(accessHRN);
-
-                                                               affectedIter = affectedTDSet.iterator();
-                                                               while (affectedIter.hasNext()) {
-                                                                       TempDescriptor affectedTD = affectedIter
-                                                                                       .next();
-                                                                       if (currentSESE.getInVarSet().contains(
-                                                                                       affectedTD)) {
-
-                                                                               HashSet<Integer> hrnSet = getReferenceHeapIDSet(
-                                                                                               og, affectedTD);
-                                                                               Iterator<Integer> hrnIter = hrnSet
-                                                                                               .iterator();
-                                                                               while (hrnIter.hasNext()) {
-                                                                                       Integer hrnId = hrnIter.next();
-                                                                                       currentSESE.readEffects(affectedTD,
-                                                                                                       field.getSymbol(), src
-                                                                                                                       .getType(), hrnId);
-
-                                                                               }
-                                                                       }
+                                               affectedTDSet = getReferenceNodeSet(accessHRN);
+                                               affectedIter = affectedTDSet.iterator();
+                                               while (affectedIter.hasNext()) {
+                                                       TempDescriptor affectedTD = affectedIter.next();
+
+                                                       if (currentSESE.getInVarSet().contains(affectedTD)) {
+
+                                                               HashSet<HeapRegionNode> hrnSet = getReferenceHeapIDSet(
+                                                                               og, affectedTD);
+                                                               Iterator<HeapRegionNode> hrnIter = hrnSet
+                                                                               .iterator();
+                                                               while (hrnIter.hasNext()) {
+                                                                       HeapRegionNode hrn = hrnIter.next();
+                                                                       currentSESE.readEffects(affectedTD, field
+                                                                                       .getSymbol(), src.getType(), hrn
+                                                                                       .getID());
                                                                }
 
                                                        }
 
                                                }
                                        }
-
                                }
-
                        }
 
                }
@@ -962,6 +1272,30 @@ public class MLPAnalysis {
 
                        LabelNode dstLN = og.td2ln.get(dst);
                        if (dstLN != null) {
+                               // check possible strong updates
+                               boolean strongUpdate = false;
+
+                               if (!field.getType().isImmutable() || field.getType().isArray()) {
+                                       Iterator<ReferenceEdge> itrXhrn = dstLN
+                                                       .iteratorToReferencees();
+                                       while (itrXhrn.hasNext()) {
+                                               ReferenceEdge edgeX = itrXhrn.next();
+                                               HeapRegionNode hrnX = edgeX.getDst();
+
+                                               // we can do a strong update here if one of two cases
+                                               // holds
+                                               if (field != null
+                                                               && field != OwnershipAnalysis
+                                                                               .getArrayField(field.getType())
+                                                               && ((hrnX.getNumReferencers() == 1) || // case 1
+                                                               (hrnX.isSingleObject() && dstLN
+                                                                               .getNumReferencees() == 1) // case 2
+                                                               )) {
+                                                       strongUpdate = true;
+                                               }
+                                       }
+                               }
+
                                HashSet<TempDescriptor> affectedTDSet = getAccessedTaintNodeSet(dstLN);
 
                                Iterator<TempDescriptor> affectedIter = affectedTDSet
@@ -971,68 +1305,86 @@ public class MLPAnalysis {
                                        TempDescriptor affectedTD = affectedIter.next();
                                        if (currentSESE.getInVarSet().contains(affectedTD)) {
 
-                                               HashSet<Integer> hrnSet = getReferenceHeapIDSet(og,
-                                                               affectedTD);
-                                               Iterator<Integer> hrnIter = hrnSet.iterator();
+                                               HashSet<HeapRegionNode> hrnSet = getReferenceHeapIDSet(
+                                                               og, affectedTD);
+                                               Iterator<HeapRegionNode> hrnIter = hrnSet.iterator();
                                                while (hrnIter.hasNext()) {
-                                                       Integer hrnId = hrnIter.next();
-                                                       currentSESE.writeEffects(affectedTD, field
-                                                                       .getSymbol(), dst.getType(), hrnId);
+                                                       HeapRegionNode hrn = hrnIter.next();
+
+                                                       Iterator<ReferenceEdge> referencers = hrn
+                                                                       .iteratorToReferencers();
+                                                       while (referencers.hasNext()) {
+                                                               ReferenceEdge referenceEdge = (ReferenceEdge) referencers
+                                                                               .next();
+                                                               if (field.getSymbol().equals(
+                                                                               referenceEdge.getField())) {
+                                                                       currentSESE.writeEffects(affectedTD, field
+                                                                                       .getSymbol(), dst.getType(),
+                                                                                       referenceEdge.getDst().getID(),
+                                                                                       strongUpdate);
+                                                               }
+                                                       }
+
                                                }
                                        }
                                }
 
-                               // handle tainted case
+                               // handle tainted case
                                Iterator<ReferenceEdge> edgeIter = dstLN
                                                .iteratorToReferencees();
                                while (edgeIter.hasNext()) {
                                        ReferenceEdge edge = edgeIter.next();
-                                       HeapRegionNode dstHRN = edge.getDst();
 
-                                       Iterator<ReferenceEdge> referenceeIter = dstHRN
-                                                       .iteratorToReferencees();
-                                       while (referenceeIter.hasNext()) {
-                                               ReferenceEdge re = referenceeIter.next();
-
-                                               if ((re.getField() == null && fsen.getField() == null)
-                                                               || (re.getField() != null
-                                                                               && fsen.getField() != null
-                                                                               && re.getField().equals(
-                                                                                               fsen.getField().getSymbol()) && re
-                                                                               .getType().equals(
-                                                                                               fsen.getField().getType()))) {
-                                                       int taintIdentifier = re.getTaintIdentifier();
-
-                                                       if (taintIdentifier > 0) {
-                                                               HeapRegionNode accessHRN = re.getDst();
-                                                               affectedTDSet = getReferenceNodeSet(accessHRN);
-
-                                                               affectedIter = affectedTDSet.iterator();
-                                                               while (affectedIter.hasNext()) {
-                                                                       TempDescriptor affectedTD = affectedIter
-                                                                                       .next();
-                                                                       if (currentSESE.getInVarSet().contains(
-                                                                                       affectedTD)) {
-
-                                                                               HashSet<Integer> hrnSet = getReferenceHeapIDSet(
-                                                                                               og, affectedTD);
-                                                                               Iterator<Integer> hrnIter = hrnSet
-                                                                                               .iterator();
-                                                                               while (hrnIter.hasNext()) {
-                                                                                       Integer hrnId = hrnIter.next();
-                                                                                       currentSESE.readEffects(affectedTD,
-                                                                                                       field.getSymbol(), dst
-                                                                                                                       .getType(), hrnId);
-
-                                                                               }
-                                                                       }
+                                       HeapRegionNode accessHRN = edge.getDst();
+                                       // / follow the chain of reference to identify possible
+                                       // accesses
+                                       Iterator<ReferenceEdge> referIter = accessHRN
+                                                       .iteratorToReferencers();
+                                       while (referIter.hasNext()) {
+                                               ReferenceEdge referEdge = (ReferenceEdge) referIter
+                                                               .next();
+
+                                               // if (referEdge.getTaintIdentifier() > 0 ||
+                                               // referEdge.getSESETaintIdentifier() > 0 ) {
+                                               HashSet<TempDescriptor> referSet = new HashSet<TempDescriptor>();
+                                               followReference(accessHRN, referSet,
+                                                               new HashSet<HeapRegionNode>(), currentSESE);
+                                               Iterator<TempDescriptor> referSetIter = referSet
+                                                               .iterator();
+                                               while (referSetIter.hasNext()) {
+                                                       TempDescriptor tempDescriptor = (TempDescriptor) referSetIter
+                                                                       .next();
+                                                       currentSESE.writeEffects(tempDescriptor, field
+                                                                       .getSymbol(), dst.getType(), accessHRN
+                                                                       .getID(), strongUpdate);
+                                               }
+                                               // }
+                                       }
+                                       // /
+                                       if (edge.getTaintIdentifier() > 0
+                                                       || edge.getSESETaintIdentifier() > 0) {
+                                               affectedTDSet = getReferenceNodeSet(accessHRN);
+                                               affectedIter = affectedTDSet.iterator();
+                                               while (affectedIter.hasNext()) {
+                                                       TempDescriptor affectedTD = affectedIter.next();
+                                                       if (currentSESE.getInVarSet().contains(affectedTD)) {
+
+                                                               HashSet<HeapRegionNode> hrnSet = getReferenceHeapIDSet(
+                                                                               og, affectedTD);
+                                                               Iterator<HeapRegionNode> hrnIter = hrnSet
+                                                                               .iterator();
+                                                               while (hrnIter.hasNext()) {
+                                                                       HeapRegionNode hrn = hrnIter.next();
+                                                                       currentSESE.writeEffects(affectedTD, field
+                                                                                       .getSymbol(), dst.getType(), hrn
+                                                                                       .getID(), strongUpdate);
+
                                                                }
 
                                                        }
 
                                                }
                                        }
-
                                }
 
                        }
@@ -1048,6 +1400,13 @@ public class MLPAnalysis {
                        MethodEffects me = ownAnalysis.getMethodEffectsAnalysis()
                                        .getMethodEffectsByMethodContext(calleeMC);
 
+                       OwnershipGraph calleeOG = ownAnalysis
+                                       .getOwnvershipGraphByMethodContext(calleeMC);
+
+                       FlatMethod fm = state.getMethodFlat(fc.getMethod());
+                       ParameterDecomposition decomp = new ParameterDecomposition(
+                                       ownAnalysis, fc, fm, calleeMC, calleeOG, og);
+
                        int base;
                        if (((MethodDescriptor) calleeMC.getDescriptor()).isStatic()) {
                                base = 0;
@@ -1063,6 +1422,9 @@ public class MLPAnalysis {
                                Set<EffectsKey> writeSet = me.getEffects().getWritingSet(
                                                i + base);
 
+                               Set<EffectsKey> strongUpdateSet = me.getEffects()
+                                               .getStrongUpdateSet(i + base);
+
                                LabelNode argLN = og.td2ln.get(arg);
                                if (argLN != null) {
                                        HashSet<TempDescriptor> affectedTDSet = getAccessedTaintNodeSet(argLN);
@@ -1079,12 +1441,18 @@ public class MLPAnalysis {
                                                                                .iterator();
                                                                while (readIter.hasNext()) {
                                                                        EffectsKey key = readIter.next();
-                                                                       // TODO need to verify the correctness of
-                                                                       // hrnID
-                                                                       currentSESE.readEffects(affectedTD, key
-                                                                                       .getFieldDescriptor(), key
-                                                                                       .getTypeDescriptor(), key
-                                                                                       .getHRNId());
+                                                                       Set<Integer> hrnSet = getCallerHRNId(
+                                                                                       new Integer(i + base), calleeOG,
+                                                                                       key.getHRNId(), decomp);
+                                                                       Iterator<Integer> hrnIter = hrnSet
+                                                                                       .iterator();
+                                                                       while (hrnIter.hasNext()) {
+                                                                               Integer hrnID = (Integer) hrnIter
+                                                                                               .next();
+                                                                               currentSESE.readEffects(affectedTD, key
+                                                                                               .getFieldDescriptor(), key
+                                                                                               .getTypeDescriptor(), hrnID);
+                                                                       }
                                                                }
                                                        }
 
@@ -1093,10 +1461,44 @@ public class MLPAnalysis {
                                                                                .iterator();
                                                                while (writeIter.hasNext()) {
                                                                        EffectsKey key = writeIter.next();
-                                                                       currentSESE.writeEffects(affectedTD, key
-                                                                                       .getFieldDescriptor(), key
-                                                                                       .getTypeDescriptor(), key
-                                                                                       .getHRNId());
+
+                                                                       Set<Integer> hrnSet = getCallerHRNId(
+                                                                                       new Integer(i + base), calleeOG,
+                                                                                       key.getHRNId(), decomp);
+                                                                       Iterator<Integer> hrnIter = hrnSet
+                                                                                       .iterator();
+                                                                       while (hrnIter.hasNext()) {
+                                                                               Integer hrnID = (Integer) hrnIter
+                                                                                               .next();
+                                                                               currentSESE.writeEffects(affectedTD,
+                                                                                               key.getFieldDescriptor(), key
+                                                                                                               .getTypeDescriptor(),
+                                                                                               hrnID, false);
+                                                                       }
+
+                                                               }
+                                                       }
+
+                                                       if (strongUpdateSet != null) {
+                                                               Iterator<EffectsKey> strongUpdateIter = strongUpdateSet
+                                                                               .iterator();
+                                                               while (strongUpdateIter.hasNext()) {
+                                                                       EffectsKey key = strongUpdateIter.next();
+
+                                                                       Set<Integer> hrnSet = getCallerHRNId(
+                                                                                       new Integer(i + base), calleeOG,
+                                                                                       key.getHRNId(), decomp);
+                                                                       Iterator<Integer> hrnIter = hrnSet
+                                                                                       .iterator();
+                                                                       while (hrnIter.hasNext()) {
+                                                                               Integer hrnID = (Integer) hrnIter
+                                                                                               .next();
+                                                                               currentSESE.writeEffects(affectedTD,
+                                                                                               key.getFieldDescriptor(), key
+                                                                                                               .getTypeDescriptor(),
+                                                                                               hrnID, true);
+                                                                       }
+
                                                                }
                                                        }
 
@@ -1114,6 +1516,56 @@ public class MLPAnalysis {
                }
        }
        
+       private void addLiveInAllocationSite(MethodContext mc, AllocationSite ac){
+               HashSet<AllocationSite> set=mapMethodContextToLiveInAllocationSiteSet.get(mc);
+               if(set==null){
+                       set=new HashSet<AllocationSite>();                      
+               }
+               set.add(ac);
+               mapMethodContextToLiveInAllocationSiteSet.put(mc, set);
+       }
+       
+       private void followReference(HeapRegionNode hrn,HashSet<TempDescriptor> tdSet, HashSet<HeapRegionNode> visited, FlatSESEEnterNode currentSESE){
+               
+               Iterator<ReferenceEdge> referIter=hrn.iteratorToReferencers();
+               // check whether hrn is referenced by TD
+               while (referIter.hasNext()) {
+                       ReferenceEdge referEdge = (ReferenceEdge) referIter.next();
+                       if(referEdge.getSrc() instanceof LabelNode){
+                               LabelNode ln=(LabelNode)referEdge.getSrc();
+                               if(currentSESE.getInVarSet().contains(ln.getTempDescriptor())){
+                                       tdSet.add(ln.getTempDescriptor());
+                               }
+                       }else if(referEdge.getSrc() instanceof HeapRegionNode){
+                               HeapRegionNode nextHRN=(HeapRegionNode)referEdge.getSrc();
+                               if(!visited.contains(nextHRN)){
+                                       visited.add(nextHRN);
+                                       followReference(nextHRN,tdSet,visited,currentSESE);                             
+                               }
+                               
+                       }
+               }
+               
+       }
+       
+       private Set<Integer> getCallerHRNId(Integer paramIdx,
+                       OwnershipGraph calleeOG, Integer calleeHRNId,
+                       ParameterDecomposition paramDecom) {
+               
+               Integer hrnPrimaryID = calleeOG.paramIndex2idPrimary.get(paramIdx);
+               Integer hrnSecondaryID = calleeOG.paramIndex2idSecondary.get(paramIdx);
+               
+               if (calleeHRNId.equals(hrnPrimaryID)) {
+                       // it references to primary param heap region
+                       return paramDecom.getParamObject_hrnIDs(paramIdx);
+               } else if (calleeHRNId.equals(hrnSecondaryID)) {
+                       // it references to secondary param heap region
+                       return paramDecom.getParamReachable_hrnIDs(paramIdx);
+               }
+
+               return new HashSet<Integer>();
+       }
+       
        private void taintLabelNode(LabelNode ln, int identifier) {
 
                Iterator<ReferenceEdge> edgeIter = ln.iteratorToReferencees();
@@ -1128,6 +1580,8 @@ public class MLPAnalysis {
                                OwnershipNode node = referencerEdge.getSrc();
                                if (node instanceof LabelNode) {
                                        referencerEdge.unionSESETaintIdentifier(identifier);
+                               }else if(node instanceof HeapRegionNode){
+                                       referencerEdge.unionSESETaintIdentifier(identifier);
                                }
                        }
 
@@ -1153,54 +1607,51 @@ public class MLPAnalysis {
        }
        
        
-       private HashSet<Integer> getReferenceHeapIDSet(OwnershipGraph og, TempDescriptor td){
+       private HashSet<HeapRegionNode> getReferenceHeapIDSet(OwnershipGraph og, TempDescriptor td){
                
-               HashSet<Integer> returnSet=new HashSet<Integer>();
+               HashSet<HeapRegionNode> returnSet=new HashSet<HeapRegionNode>();
                
                LabelNode ln=og.td2ln.get(td);
                Iterator<ReferenceEdge> edgeIter=ln.iteratorToReferencees();
                while(edgeIter.hasNext()){
                        ReferenceEdge edge=edgeIter.next();
-                       HeapRegionNode hrn=edge.getDst();
-                       returnSet.add(hrn.getID());
+                               HeapRegionNode hrn=edge.getDst();
+                               returnSet.add(hrn);
                }
                return returnSet;
        }
        
        
-       private HashSet<TempDescriptor> getAccessedTaintNodeSet(LabelNode ln){
-               
-               HashSet<TempDescriptor> returnSet=new HashSet<TempDescriptor>();
-               
-               Iterator<ReferenceEdge> edgeIter=ln.iteratorToReferencees();
-               while(edgeIter.hasNext()){
-                       ReferenceEdge edge=edgeIter.next();
-                       HeapRegionNode hrn=edge.getDst();
-                       
-                       Iterator<ReferenceEdge> edgeReferencerIter= hrn.iteratorToReferencers();
-                       while(edgeReferencerIter.hasNext()){
-                               ReferenceEdge referencerEdge=edgeReferencerIter.next();
-                               
-                               
-                               if(referencerEdge.getSrc() instanceof LabelNode){
-                                       if( !((LabelNode)referencerEdge.getSrc()).equals(ln) ){
-                                               
-                                               if(referencerEdge.getSESETaintIdentifier() > 0){
-                                                       TempDescriptor td=((LabelNode)referencerEdge.getSrc()).getTempDescriptor();
+       private HashSet<TempDescriptor> getAccessedTaintNodeSet(LabelNode ln) {
+
+               HashSet<TempDescriptor> returnSet = new HashSet<TempDescriptor>();
+
+               Iterator<ReferenceEdge> edgeIter = ln.iteratorToReferencees();
+               while (edgeIter.hasNext()) {
+                       ReferenceEdge edge = edgeIter.next();
+                       HeapRegionNode hrn = edge.getDst();
+
+                       Iterator<ReferenceEdge> edgeReferencerIter = hrn
+                                       .iteratorToReferencers();
+                       while (edgeReferencerIter.hasNext()) {
+                               ReferenceEdge referencerEdge = edgeReferencerIter.next();
+
+                               if (referencerEdge.getSrc() instanceof LabelNode) {
+                                       if (!((LabelNode) referencerEdge.getSrc()).equals(ln)) {
+
+                                               if (referencerEdge.getSESETaintIdentifier() > 0) {
+                                                       TempDescriptor td = ((LabelNode) referencerEdge
+                                                                       .getSrc()).getTempDescriptor();
                                                        returnSet.add(td);
                                                }
-
-//                                             int taintId=referencerEdge.getSESETaintIdentifier();
-//                                             edge.unionSESETaintIdentifier(taintId);
                                        }
-                               }                               
+                               }
                        }
-                       
+
                }
-               
+
                return returnSet;
-               
-               
+
        }
 
 
@@ -1532,29 +1983,37 @@ public class MLPAnalysis {
     }
   }
   
-  private String printSESEEffects(){
-         
-         StringWriter writer=new StringWriter();
-         
-         Set<FlatNode> keySet=livenessRootView.keySet();
-         Iterator<FlatNode> keyIter=keySet.iterator();
-         
-         while(keyIter.hasNext()){
-                 FlatNode fn=keyIter.next();
-                 if(fn instanceof FlatSESEEnterNode){
-                         FlatSESEEnterNode seseEnter=(FlatSESEEnterNode)fn;
-                         String result=seseEnter.getSeseEffectsSet().printSet();
-                         if(result.length()>0){
-                                 writer.write("\nSESE "+seseEnter+"\n");
-                                 writer.write(result);
-                         }
-
-                 }
-         }
-         
-         return writer.toString();
-         
-  }
+       private String printSESEEffects() {
+
+               StringWriter writer = new StringWriter();
+
+               Iterator<FlatSESEEnterNode> keyIter = allSESEs.iterator();
+
+               while (keyIter.hasNext()) {
+                       FlatSESEEnterNode seseEnter = keyIter.next();
+                       String result = seseEnter.getSeseEffectsSet().printSet();
+                       if (result.length() > 0) {
+                               writer.write("\nSESE " + seseEnter + "\n");
+                               writer.write(result);
+                       }
+               }
+               keyIter = rootSESEs.iterator();
+               while (keyIter.hasNext()) {
+                       FlatSESEEnterNode seseEnter = keyIter.next();
+                       if (seseEnter.getIsCallerSESEplaceholder()) {
+                               if (!seseEnter.getChildren().isEmpty()) {
+                                       String result = seseEnter.getSeseEffectsSet().printSet();
+                                       if (result.length() > 0) {
+                                               writer.write("\nSESE " + seseEnter + "\n");
+                                               writer.write(result);
+                                       }
+                               }
+                       }
+               }
+
+               return writer.toString();
+
+       }
 
   private void printSESEHierarchy( BufferedWriter bw ) throws java.io.IOException {
     bw.write( "SESE Hierarchy\n--------------\n" );