private Hashtable< MethodContext, HashSet<AllocationSite>> mapMethodContextToLiveInAllocationSiteSet;
private Hashtable < FlatNode, ParentChildConflictsMap > conflictsResults;
- private ParentChildConflictsMap currentConflictsMap;
- private Hashtable < ReferenceEdge, StallSite > stallEdgeMapping;
private Hashtable< FlatMethod, MethodSummary > methodSummaryResults;
// temporal data structures to track analysis progress.
mapMethodContextToLiveInAllocationSiteSet = new Hashtable< MethodContext, HashSet<AllocationSite>>();
conflictsResults = new Hashtable < FlatNode, ParentChildConflictsMap >();
- stallEdgeMapping = new Hashtable < ReferenceEdge, StallSite >();
methodSummaryResults=new Hashtable<FlatMethod, MethodSummary>();
FlatMethod fmMain = state.getMethodFlat( typeUtil.getMain() );
FlatCall fc = (FlatCall) fn;
- if(fc.numArgs()>0){
+
+ if(fc.numArgs()>0 && fc.getMethod().equals(calleeMC.getDescriptor())){
MethodContext calleeMCfromOG = ownAnalysis.getCalleeMethodContext(
callerMC, fc);
HashSet<MethodContext> mcSet = ownAnalysis
.getAllMethodContextSetByDescriptor(md);
Iterator<MethodContext> mcIter = mcSet.iterator();
-
- currentMethodSummary=new MethodSummary();
- preeffectsSet=new HashSet<PreEffectsKey>();
-
- while (mcIter.hasNext()) {
+ currentMethodSummary = new MethodSummary();
+ preeffectsSet = new HashSet<PreEffectsKey>();
+
+ while (mcIter.hasNext()) {
MethodContext mc = mcIter.next();
Set<FlatNode> visited = new HashSet<FlatNode>();
Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
flatNodesToVisit.add(fm);
- currentConflictsMap=null;
while (!flatNodesToVisit.isEmpty()) {
FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
- flatNodesToVisit.remove(fn);
-
- conflicts_nodeAction(mc, fn, callGraph, preeffectsSet);
-
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);
+ ParentChildConflictsMap prevResult = conflictsResults
+ .get(fn);
+
+ // merge sets from control flow
+ ParentChildConflictsMap currentConflictsMap = new ParentChildConflictsMap();
+ for (int i = 0; i < fn.numPrev(); i++) {
+ FlatNode prevFlatNode = fn.getPrev(i);
+ ParentChildConflictsMap incoming = conflictsResults
+ .get(prevFlatNode);
+ if (incoming != null) {
+ currentConflictsMap.merge(incoming);
+ }
+ }
+
+ conflicts_nodeAction(mc, fn, callGraph, preeffectsSet,
+ currentConflictsMap);
+
+ // if we have a new result, schedule forward nodes for
+ // analysis
+
+ if(!currentConflictsMap.isAfterChildSESE()){
+ conflictsResults.put(fn, currentConflictsMap);
+ for (int i = 0; i < fn.numNext(); i++) {
+ FlatNode nn = fn.getNext(i);
+ if (!visited.contains(nn)) {
+ flatNodesToVisit.add(nn);
+ }
+ }
+ }else{
+ if (!currentConflictsMap.equals(prevResult)) {
+ conflictsResults.put(fn, currentConflictsMap);
+ for (int i = 0; i < fn.numNext(); i++) {
+ FlatNode nn = fn.getNext(i);
+ flatNodesToVisit.add(nn);
+ }
}
}
+
}
}
methodSummaryResults.put(fm, currentMethodSummary);
}
private void conflicts_nodeAction(MethodContext mc, FlatNode fn,
- CallGraph callGraph, HashSet<PreEffectsKey> preeffectsSet) {
+ CallGraph callGraph, HashSet<PreEffectsKey> preeffectsSet,ParentChildConflictsMap currentConflictsMap) {
OwnershipGraph og = ownAnalysis.getOwnvershipGraphByMethodContext(mc);
switch (fn.kind()) {
case FKind.FlatSESEEnterNode: {
-
+
FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
if (!fsen.getIsCallerSESEplaceholder()) {
currentMethodSummary.increaseChildSESECount();
break;
case FKind.FlatSESEExitNode: {
- // all object variables are inaccessible.
- currentConflictsMap = new ParentChildConflictsMap();
+
+ FlatSESEExitNode fsen = (FlatSESEExitNode) fn;
+
+ if (!fsen.getFlatEnter().getIsCallerSESEplaceholder()) {
+ // all object variables are inaccessible.
+ currentConflictsMap.setAfterChildSESE(true);
+ currentConflictsMap = new ParentChildConflictsMap();
+ }
+
}
break;
case FKind.FlatNew: {
- if (currentConflictsMap != null) {
+ if (currentConflictsMap.isAfterChildSESE()) {
FlatNew fnew = (FlatNew) fn;
TempDescriptor dst = fnew.getDst();
currentConflictsMap.addAccessibleVar(dst);
TempDescriptor src = ffn.getSrc();
FieldDescriptor field = ffn.getField();
- if (currentConflictsMap != null) {
+ if (currentConflictsMap.isAfterChildSESE()) {
HashSet<TempDescriptor> srcTempSet = getTempDescSetReferenceToSameHRN(
og, src);
TempDescriptor possibleSrc = (TempDescriptor) iterator
.next();
if (!currentConflictsMap.isAccessible(possibleSrc)) {
- currentConflictsMap.addStallSite(possibleSrc);
+ HashSet<HeapRegionNode> refHRN=getReferenceHeapIDSet(og, possibleSrc);
+ currentConflictsMap.addStallSite(possibleSrc,refHRN);
}
currentConflictsMap.addAccessibleVar(possibleSrc);
TempDescriptor dst = fsen.getDst();
FieldDescriptor field = fsen.getField();
TempDescriptor src = fsen.getSrc();
-
- if (currentConflictsMap != null) {
+
+ if (currentConflictsMap.isAfterChildSESE()) {
HashSet<TempDescriptor> srcTempSet = getTempDescSetReferenceToSameHRN(
og, src);
TempDescriptor possibleSrc = (TempDescriptor) iterator
.next();
if (!currentConflictsMap.isAccessible(possibleSrc)) {
- currentConflictsMap.addStallSite(possibleSrc);
+ HashSet<HeapRegionNode> refHRN=getReferenceHeapIDSet(og, possibleSrc);
+ currentConflictsMap.addStallSite(possibleSrc,refHRN);
}
currentConflictsMap.addAccessibleVar(possibleSrc);
}
.next();
if (!currentConflictsMap.isAccessible(possibleDst)) {
- currentConflictsMap.addStallSite(possibleDst);
+ HashSet<HeapRegionNode> refHRN=getReferenceHeapIDSet(og, possibleDst);
+ currentConflictsMap.addStallSite(possibleDst,refHRN);
}
currentConflictsMap.addAccessibleVar(possibleDst);
// contribute write effect on destination's stall site
.hasNext();) {
ReferenceEdge referenceEdge = (ReferenceEdge) iterator
.next();
- stallEdgeMapping.put(referenceEdge, ss);
- // System.out.println("STALL EDGE MAPPING WITH "+referenceEdge+" -> "+ss);
+ if(!(referenceEdge.getSrc() instanceof LabelNode)){
+ currentConflictsMap.addStallEdge(referenceEdge, ss);
+ }
}
}
}
break;
case FKind.FlatOpNode: {
- if (currentConflictsMap != null) {
+ if (currentConflictsMap.isAfterChildSESE()) {
// destination variable gets the status of source.
FlatOpNode fon = (FlatOpNode) fn;
- if (fon.getOp().getOp() == Operation.ASSIGN
- && currentConflictsMap != null) {
+ if (fon.getOp().getOp() == Operation.ASSIGN) {
TempDescriptor dst = fon.getDest();
TempDescriptor src = fon.getLeft();
}
break;
- case FKind.FlatNop: {
-
- FlatNop fnop = (FlatNop) fn;
- if (fnop.numPrev() > 1) {
- // merge point
- for (int i = 0; i < fnop.numPrev(); i++) {
- FlatNode prev = fnop.getPrev(i);
- ParentChildConflictsMap prevConflictsMap = conflictsResults
- .get(prev);
- if (prevConflictsMap != null) {
- if (currentConflictsMap == null) {
- currentConflictsMap = new ParentChildConflictsMap();
- }
- currentConflictsMap.merge(prevConflictsMap);
- }
- }
- }
-
- // TODO: need to merge edge mappings
-
- }
- break;
-
case FKind.FlatCall: {
FlatCall fc = (FlatCall) fn;
for (int i = 0; i < fc.numArgs(); i++) {
TempDescriptor paramTemp = fc.getArg(i);
- if (currentConflictsMap != null) {
+ if (currentConflictsMap.isAfterChildSESE()) {
if (currentConflictsMap.isAccessible(paramTemp)
&& currentConflictsMap.hasStallSite(paramTemp)) {
// preeffect contribute its effect to caller's stall
// when return value is inaccessible
currentConflictsMap.addInaccessibleVar(returnTemp);
}
+
+
+ // TODO: need to handle edge mappings from callee
+ HashSet<Integer> stallParamIdx=calleeMethodSummary.getStallParamIdxSet();
+ for (Iterator iterator = stallParamIdx.iterator(); iterator
+ .hasNext();) {
+ Integer paramIdx = (Integer) iterator.next();
+ }
}
- // TODO: need to handle edge mappings from callee
-
}
break;
TempDescriptor returnTD = frn.getReturnTemp();
if (returnTD != null) {
- if (currentConflictsMap == null) {
- // in this case, all variables is accessible. There are no
+ if (!currentConflictsMap.isAfterChildSESE()) {
+ // in this case, all variables are accessible. There are no
// child SESEs.
} else {
if (currentConflictsMap.isAccessible(returnTD)) {
// store method summary when it has at least one child SESE
if (currentMethodSummary.getChildSESECount() > 0) {
- FlatMethod fm = state.getMethodFlat(mc.getDescriptor()); // current
- // flat
- // method
+ // current flat method
+ FlatMethod fm = state.getMethodFlat(mc.getDescriptor());
+ Set<TempDescriptor> stallTempSet=currentConflictsMap.getStallMap().keySet();
+ for (Iterator iterator = stallTempSet.iterator(); iterator
+ .hasNext();) {
+ TempDescriptor stallTD = (TempDescriptor) iterator.next();
+ StallSite ss = currentConflictsMap.getStallMap().get(
+ stallTD);
+
+ HashSet<HeapRegionNode> stallSiteHRNSet = ss.getHRNSet();
+ for (Iterator iterator2 = stallSiteHRNSet.iterator(); iterator2
+ .hasNext();) {
+ HeapRegionNode stallSiteHRN = (HeapRegionNode) iterator2
+ .next();
+
+ if (stallSiteHRN.isParameter()) {
+ currentMethodSummary
+ .addStallParamIdxSet(og.idPrimary2paramIndexSet
+ .get(stallSiteHRN.getID()));
+ currentMethodSummary
+ .addStallParamIdxSet(og.idSecondary2paramIndexSet
+ .get(stallSiteHRN.getID()));
+ }
+
+ }
+
+ }
methodSummaryResults.put(fm, currentMethodSummary);
}
}
- // for every program point, we keep accessible map and stall map.
- if (currentConflictsMap != null) {
- conflictsResults.put(fn, currentConflictsMap);
- }
-
}
private void preEffectAnalysis(OwnershipGraph og, TempDescriptor td,
}
}
- private MethodSummary analysisMethodCall(FlatMethod fm, OwnershipGraph calleeOG){
-
- MethodSummary methodSummary=new MethodSummary();
-
- Set<FlatNode> visited = new HashSet<FlatNode>();
- Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
- flatNodesToVisit.add(fm);
-
- while (!flatNodesToVisit.isEmpty()) {
- FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
- flatNodesToVisit.remove(fn);
-
-// conflicts_nodeAction(mc, fn, callGraph);
-
- 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);
- }
- }
- }
-
-
-
- return methodSummary;
-
- }
-
-
-
private void codePlansForward( FlatMethod fm ) {
// start from flat method top, visit every node in
import java.util.Iterator;
import java.util.Set;
+import Analysis.OwnershipAnalysis.HeapRegionNode;
import Analysis.OwnershipAnalysis.ReachabilitySet;
+import Analysis.OwnershipAnalysis.ReferenceEdge;
import Analysis.OwnershipAnalysis.TokenTupleSet;
import IR.Flat.TempDescriptor;
private Hashtable<TempDescriptor, Integer> accessibleMap;
private Hashtable<TempDescriptor, StallSite> stallMap;
+ private Hashtable < ReferenceEdge, StallSite > stallEdgeMap;
+
+ private boolean afterChildSESE;
public ParentChildConflictsMap() {
accessibleMap = new Hashtable<TempDescriptor, Integer>();
stallMap = new Hashtable<TempDescriptor, StallSite>();
+ stallEdgeMap= new Hashtable < ReferenceEdge, StallSite >();
+ afterChildSESE=false;
}
+
+ public Hashtable < ReferenceEdge, StallSite > getStallEdgeMap(){
+ return stallEdgeMap;
+ }
+
+ public void addStallEdge(ReferenceEdge edge, StallSite site){
+ stallEdgeMap.put(edge, site);
+ }
+
+ public StallSite getStallSiteByEdge(ReferenceEdge edge){
+ return stallEdgeMap.get(edge);
+ }
+
+ public void setAfterChildSESE(boolean b){
+ this.afterChildSESE=b;
+ }
+
+ public boolean isAfterChildSESE(){
+ return afterChildSESE;
+ }
public Hashtable<TempDescriptor, Integer> getAccessibleMap() {
return accessibleMap;
accessibleMap.put(td, INACCESSIBLE);
}
- public void addStallSite(TempDescriptor td) {
- StallSite stallSite = new StallSite();
+ public void addStallSite(TempDescriptor td, HashSet<HeapRegionNode> heapSet) {
+ StallSite stallSite=new StallSite(heapSet);
stallMap.put(td, stallSite);
}
}
public void merge(ParentChildConflictsMap newConflictsMap) {
+
+ if(afterChildSESE==false && newConflictsMap.isAfterChildSESE()){
+ this.afterChildSESE=true;
+ }
Hashtable<TempDescriptor, Integer> newAccessibleMap = newConflictsMap
.getAccessibleMap();
StallSite newStallSite = newStallMap.get(key);
StallSite currentStallSite = getStallMap().get(key);
+
+ if(currentStallSite==null){
+ currentStallSite=new StallSite();
+ }
// handle effects
HashSet<Effect> currentEffectSet = currentStallSite.getEffectSet();
}
// handle heap region
- HashSet<Integer> currentHRNSet = currentStallSite.getHRNIDSet();
- HashSet<Integer> newHRNSet = newStallSite.getHRNIDSet();
+ HashSet<HeapRegionNode> currentHRNSet = currentStallSite.getHRNSet();
+ HashSet<HeapRegionNode> newHRNSet = newStallSite.getHRNSet();
for (Iterator iterator2 = newHRNSet.iterator(); iterator2.hasNext();) {
- Integer hrnID = (Integer) iterator2.next();
+ HeapRegionNode hrnID = (HeapRegionNode) iterator2.next();
if (!currentHRNSet.contains(hrnID)) {
currentHRNSet.add(hrnID);
}
TokenTupleSet tokenTupleSet = (TokenTupleSet) ttsIter.next();
currentRSet.add(tokenTupleSet);
}
+
+ StallSite merged=new StallSite(currentEffectSet, currentHRNSet,
+ currentRSet);
getStallMap()
.put(
key,
- new StallSite(currentEffectSet, currentHRNSet,
- currentRSet));
+ merged);
}
+
+ // merge edge mapping
+
+ Hashtable<ReferenceEdge, StallSite> newStallEdgeMapping=newConflictsMap.getStallEdgeMap();
+ Set<ReferenceEdge> edgeSet=newStallEdgeMapping.keySet();
+ for (Iterator iterator = edgeSet.iterator(); iterator.hasNext();) {
+ ReferenceEdge stallEdge = (ReferenceEdge) iterator.next();
+ StallSite newStallSite=newStallEdgeMapping.get(stallEdge);
+ getStallEdgeMap().put(stallEdge, newStallSite);
+ }
+
+ }
+
+ public boolean equals(Object o) {
+
+ if (o == null) {
+ return false;
+ }
+
+ if (!(o instanceof ParentChildConflictsMap)) {
+ return false;
+ }
+
+ ParentChildConflictsMap in = (ParentChildConflictsMap) o;
+
+ if (afterChildSESE==in.isAfterChildSESE() && accessibleMap.equals(in.getAccessibleMap())
+ && stallMap.equals(in.getStallMap())) {
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+ public String toString() {
+ return "ParentChildConflictsMap [accessibleMap=" + accessibleMap
+ + ", afterChildSESE=" + afterChildSESE + ", stallMap="
+ + stallMap + "]";
}
}