diff --git a/src/org/ntlab/deltaViewer/CollaborationAliasCollector.java b/src/org/ntlab/deltaViewer/CollaborationAliasCollector.java index 979f5f7..f53236d 100644 --- a/src/org/ntlab/deltaViewer/CollaborationAliasCollector.java +++ b/src/org/ntlab/deltaViewer/CollaborationAliasCollector.java @@ -8,6 +8,8 @@ import org.ntlab.deltaExtractor.Alias; import org.ntlab.deltaExtractor.IAliasCollector; import org.ntlab.featureExtractor.Extract; +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.TracePoint; /** * CollaborationAliasCollector is IAliasCollector implementation class to merge aliasList in time stamp order. @@ -52,8 +54,13 @@ if (extract != null && extract.isToConnect() && otherIdx == 0) { Alias thisPrevAlias = aliasList.get(aliasList.size() - 1); if (!otherAlias.getMethodExecution().isStatic() && otherAlias.getMethodExecution().getCallerMethodExecution() != thisPrevAlias.getMethodExecution()) { - // Add a dummy alias to connect disjunct call hierarchies. - aliasList.add(new Alias(Alias.AliasType.RECEIVER, 0, otherAlias.getMethodExecution().getThisObjId(), thisPrevAlias.getOccurrencePoint())); + // Add a dummy alias to connect disjunct call hierarchies. (thisPrevAlias -> otherAlias) + MethodExecution caller = thisPrevAlias.getMethodExecution(); + MethodExecution callee = otherAlias.getMethodExecution(); + DummyMethodInvocation dummyInv = new DummyMethodInvocation(callee, caller.getThisClassName(), caller.getThisObjId(), 0, thisPrevAlias.getOccurrencePoint().getStatement().getThreadNo()); + dummyInv.setTimeStamp(callee.getEntryTime()); + DummyTracePoint dummyTp = new DummyTracePoint(caller, dummyInv); + aliasList.add(new Alias(Alias.AliasType.RECEIVER, 0, callee.getThisObjId(), dummyTp)); thisIdx++; } } @@ -73,8 +80,13 @@ if (extract != null && extract.isToConnect() && otherIdx == 0 && thisIdx > 0) { Alias thisPrevAlias = aliasList.get(thisIdx - 1); if (!otherAlias.getMethodExecution().isStatic() && otherAlias.getMethodExecution().getCallerMethodExecution() != thisPrevAlias.getMethodExecution()) { - // Add a dummy alias to connect disjunct call hierarchies. - aliasList.add(thisIdx, new Alias(Alias.AliasType.RECEIVER, 0, otherAlias.getMethodExecution().getThisObjId(), thisPrevAlias.getOccurrencePoint())); + // Add a dummy alias to connect disjunct call hierarchies. (thisPrevAlias -> otherAlias) + MethodExecution caller = thisPrevAlias.getMethodExecution(); + MethodExecution callee = otherAlias.getMethodExecution(); + DummyMethodInvocation dummyInv = new DummyMethodInvocation(callee, caller.getThisClassName(), caller.getThisObjId(), 0, thisPrevAlias.getOccurrencePoint().getStatement().getThreadNo()); + dummyInv.setTimeStamp(callee.getEntryTime()); + DummyTracePoint dummyTp = new DummyTracePoint(caller, dummyInv); + aliasList.add(new Alias(Alias.AliasType.RECEIVER, 0, callee.getThisObjId(), dummyTp)); thisIdx++; } } @@ -84,8 +96,13 @@ if (extract != null && extract.isToConnect() && thisOrgIdx == 0 && otherIdx > 0) { Alias otherPrevAlias = otherAliasList.get(otherIdx - 1); if (!thisAlias.getMethodExecution().isStatic() && thisAlias.getMethodExecution().getCallerMethodExecution() != otherPrevAlias.getMethodExecution()) { - // Add a dummy alias to connect disjunct call hierarchies. - aliasList.add(thisIdx, new Alias(Alias.AliasType.RECEIVER, 0, thisAlias.getMethodExecution().getThisObjId(), otherPrevAlias.getOccurrencePoint())); + // Add a dummy alias to connect disjunct call hierarchies. (otherPrevAlias -> thisAlias) + MethodExecution caller = otherPrevAlias.getMethodExecution(); + MethodExecution callee = thisAlias.getMethodExecution(); + DummyMethodInvocation dummyInv = new DummyMethodInvocation(callee, caller.getThisClassName(), caller.getThisObjId(), 0, otherPrevAlias.getOccurrencePoint().getStatement().getThreadNo()); + dummyInv.setTimeStamp(callee.getEntryTime()); + DummyTracePoint dummyTp = new DummyTracePoint(caller, dummyInv); + aliasList.add(new Alias(Alias.AliasType.RECEIVER, 0, callee.getThisObjId(), dummyTp)); thisIdx++; } } @@ -105,8 +122,13 @@ Alias thisAlias = aliasList.get(thisIdx); Alias otherPrevAlias = otherAliasList.get(otherIdx - 1); if (!thisAlias.getMethodExecution().isStatic() && thisAlias.getMethodExecution().getCallerMethodExecution() != otherPrevAlias.getMethodExecution()) { - // Add a dummy alias to connect disjunct call hierarchies. - aliasList.add(thisIdx, new Alias(Alias.AliasType.RECEIVER, 0, thisAlias.getMethodExecution().getThisObjId(), otherPrevAlias.getOccurrencePoint())); + // Add a dummy alias to connect disjunct call hierarchies. (otherPrevAlias -> thisAlias) + MethodExecution caller = otherPrevAlias.getMethodExecution(); + MethodExecution callee = thisAlias.getMethodExecution(); + DummyMethodInvocation dummyInv = new DummyMethodInvocation(callee, caller.getThisClassName(), caller.getThisObjId(), 0, otherPrevAlias.getOccurrencePoint().getStatement().getThreadNo()); + dummyInv.setTimeStamp(callee.getEntryTime()); + DummyTracePoint dummyTp = new DummyTracePoint(caller, dummyInv); + aliasList.add(new Alias(Alias.AliasType.RECEIVER, 0, callee.getThisObjId(), dummyTp)); } } } diff --git a/src/org/ntlab/deltaViewer/DeltaAliasCollector.java b/src/org/ntlab/deltaViewer/DeltaAliasCollector.java index b5a4369..d6c6f03 100644 --- a/src/org/ntlab/deltaViewer/DeltaAliasCollector.java +++ b/src/org/ntlab/deltaViewer/DeltaAliasCollector.java @@ -13,6 +13,7 @@ import org.ntlab.trace.MethodExecution; import org.ntlab.trace.MethodInvocation; import org.ntlab.trace.Statement; +import org.ntlab.trace.Trace; import org.ntlab.trace.TracePoint; /** @@ -87,6 +88,7 @@ List standardMethodInvocations = collectStandardMethodInvocations(aliasList); List> invocationChains = collectInvocationChains(standardMethodInvocations); aliasList = replaceInvocationChains(aliasList, invocationChains); + aliasList = removeEnclosingInstanceAccessor(aliasList); Map> newToOldMethodExecMap = collectNewToOldMethodExecutionMap(oldAliasList, aliasList); // for debug. @@ -107,7 +109,7 @@ } return newToOldMethodExecMap; } - + private List collectStandardMethodInvocations(List aliasList) { List standardMethodInvocations = new ArrayList<>(); List standardMethodInvsIdx = new ArrayList<>(); @@ -294,6 +296,51 @@ return replacedAliasList; } + private List removeEnclosingInstanceAccessor(List aliasList2) { + List removedAliasList = new ArrayList<>(aliasList); +// MethodInvocation mi = null; + MethodExecution caller = null; + MethodExecution accessor = null; + for (int i = 0; i < removedAliasList.size(); i++) { + Alias a = removedAliasList.get(i); + if (a.getAliasType() == Alias.AliasType.ACTUAL_ARGUMENT) { + Statement st = a.getOccurrencePoint().getStatement(); + if (st instanceof MethodInvocation) { + if (Trace.getMethodName(((MethodInvocation) st).getCalledMethodExecution().getSignature()).startsWith("access$")) { + caller = a.getMethodExecution(); + MethodInvocation mi = ((MethodInvocation) st); + accessor = mi.getCalledMethodExecution(); + removedAliasList.remove(i); + i--; + } + } + } else if (a.getAliasType() == Alias.AliasType.FORMAL_PARAMETER) { + if (Trace.getMethodName(a.getMethodSignature()).startsWith("access$")) { + removedAliasList.remove(i); + i--; + } + } + if (a.getMethodExecution() == accessor) { + if (a.getAliasType() == Alias.AliasType.ACTUAL_ARGUMENT) { + MethodExecution callee = ((MethodInvocation) a.getOccurrencePoint().getStatement()).getCalledMethodExecution(); + DummyMethodInvocation dummyInv = new DummyMethodInvocation(callee, caller.getThisClassName(), caller.getThisObjId(), 0, a.getOccurrencePoint().getStatement().getThreadNo()); + dummyInv.setTimeStamp(callee.getEntryTime()); + DummyTracePoint dummyTp = new DummyTracePoint(caller, dummyInv); + Alias newAlias = new Alias(Alias.AliasType.ACTUAL_ARGUMENT, a.getIndex(), a.getObjectId(), dummyTp); + removedAliasList.set(i, newAlias); + } else if (a.getAliasType() == Alias.AliasType.RECEIVER) { + MethodExecution callee = ((MethodInvocation) a.getOccurrencePoint().getStatement()).getCalledMethodExecution(); + DummyMethodInvocation dummyInv = new DummyMethodInvocation(callee, caller.getThisClassName(), caller.getThisObjId(), 0, a.getOccurrencePoint().getStatement().getThreadNo()); + dummyInv.setTimeStamp(callee.getEntryTime()); + DummyTracePoint dummyTp = new DummyTracePoint(caller, dummyInv); + Alias newAlias = new Alias(Alias.AliasType.RECEIVER, a.getIndex(), a.getObjectId(), dummyTp); + removedAliasList.set(i, newAlias); + } + } + } + return removedAliasList; + } + /** * Collect methodExecutions for Alias that are not equal in oldAliasList and newAliasList. * @param oldAliasList diff --git a/src/org/ntlab/deltaViewer/DummyMethodInvocation.java b/src/org/ntlab/deltaViewer/DummyMethodInvocation.java new file mode 100644 index 0000000..b0fca17 --- /dev/null +++ b/src/org/ntlab/deltaViewer/DummyMethodInvocation.java @@ -0,0 +1,25 @@ +package org.ntlab.deltaViewer; + +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.MethodInvocation; + +public class DummyMethodInvocation extends MethodInvocation { + private long timeStamp; + + public DummyMethodInvocation(MethodInvocation methodInvocation) { + super(methodInvocation.getCalledMethodExecution(), methodInvocation.getThisClassName(), methodInvocation.getThisObjId(), methodInvocation.getLineNo(), methodInvocation.getThreadNo()); + } + + public DummyMethodInvocation(MethodExecution methodExecution, String thisClassName, String thisObjId, int lineNo, String threadNo) { + super(methodExecution, thisClassName, thisObjId, lineNo, threadNo); + } + + public void setTimeStamp(long timeStamp) { + this.timeStamp = timeStamp; + } + + public long getTimeStamp() { + return timeStamp; + } + +} diff --git a/src/org/ntlab/deltaViewer/DummyTracePoint.java b/src/org/ntlab/deltaViewer/DummyTracePoint.java new file mode 100644 index 0000000..83b27c7 --- /dev/null +++ b/src/org/ntlab/deltaViewer/DummyTracePoint.java @@ -0,0 +1,18 @@ +package org.ntlab.deltaViewer; + +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.Statement; +import org.ntlab.trace.TracePoint; + +public class DummyTracePoint extends TracePoint { + private Statement statement = null; + + public DummyTracePoint(MethodExecution methodExecution, Statement statement) { + super(methodExecution, 0); + this.statement = statement; + } + + public Statement getStatement() { + return statement; + } +}