diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/objectGraphAnalyzer/ObjectCallCounter.java b/org.ntlab.traceAnalyzer/src/org/ntlab/objectGraphAnalyzer/ObjectCallCounter.java index 67ca244..f7be5d8 100644 --- a/org.ntlab.traceAnalyzer/src/org/ntlab/objectGraphAnalyzer/ObjectCallCounter.java +++ b/org.ntlab.traceAnalyzer/src/org/ntlab/objectGraphAnalyzer/ObjectCallCounter.java @@ -2,9 +2,13 @@ import java.util.ArrayList; import java.util.HashMap; +import java.util.AbstractMap.SimpleEntry; import org.ntlab.trace.IMethodExecutionVisitor; +import org.ntlab.trace.IStatementVisitor; import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.MethodInvocation; +import org.ntlab.trace.Statement; import org.ntlab.trace.ThreadInstance; import org.ntlab.trace.Trace; import org.ntlab.trace.TraceJSON; @@ -16,59 +20,218 @@ */ public static void main(String[] args) { TraceJSON trace = new TraceJSON("traces\\jEditNormal.trace"); + + // �I�u�W�F�N�g�����؂̍쐬 final HashMap classNames = new HashMap<>(); + final ArrayList> links = new ArrayList<>(); + final HashMap parentOf = new HashMap<>(); + + trace.traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + if (methodExecution.isConstructor() && methodExecution.getCallerMethodExecution() != null) { + String srcObjId = methodExecution.getCallerMethodExecution().getThisObjId(); + String dstObjId = methodExecution.getThisObjId(); + if (!srcObjId.equals(dstObjId)) { // �e�q�N���X�Ԃ̃��\�b�h�Ăяo�����������ꍇ���l�� + if (Trace.isNull(srcObjId)) { + srcObjId = methodExecution.getCallerMethodExecution().getThisClassName(); + } + classNames.put(srcObjId, methodExecution.getCallerMethodExecution().getThisClassName()); + classNames.put(dstObjId, methodExecution.getThisClassName()); + links.add(new SimpleEntry<>(srcObjId, dstObjId)); + parentOf.put(dstObjId, srcObjId); + } + } + return false; + } + }); + + // �e�I�u�W�F�N�g����������؂̃��[�g�m�[�h�Ɛ[���̌v�Z + final HashMap rootOf = new HashMap<>(); + final HashMap depthOf = new HashMap<>(); + + for (String objId: classNames.keySet()) { + int depth = 0; + String rootObjId = objId; + while (parentOf.get(rootObjId) != null) { + rootObjId = parentOf.get(rootObjId); + depth++; + if (depthOf.get(rootObjId) != null) { + depth += depthOf.get(rootObjId); + rootObjId = rootOf.get(rootObjId); + } + } + rootOf.put(objId, rootObjId); + depthOf.put(objId, depth); + } + + // �I�u�W�F�N�g�����؏�ł̊e�Ăяo�������A�Ăяo���񐔂̌v�Z + final HashMap maxCallDistances = new HashMap<>(); + final HashMap totalCallDistances = new HashMap<>(); + final HashMap> callDistances = new HashMap<>(); final HashMap callCounts = new HashMap<>(); - for (ThreadInstance thread: trace.getAllThreads().values()) { - thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { - @Override - public boolean preVisitThread(ThreadInstance thread) { - return false; - } - - @Override - public boolean preVisitMethodExecution(MethodExecution methodExecution) { - String objId = methodExecution.getThisObjId(); - if (!Trace.isNull(objId)) { - String key = objId + ":" + methodExecution.getSignature(); - if (classNames.get(key) == null) { - classNames.put(key, methodExecution.getThisClassName()); - } - if (callCounts.get(key) == null) { - callCounts.put(key, 1); - } else { - callCounts.put(key, callCounts.get(key) + 1); - } - } else { - String className = methodExecution.getThisClassName(); - String key = className + ":" + methodExecution.getSignature(); - if (classNames.get(key) == null) { - classNames.put(key, className); - } - if (callCounts.get(key) == null) { - callCounts.put(key, 1); - } else { - callCounts.put(key, callCounts.get(key) + 1); - } + trace.traverseStatementsInTrace(new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { + if (statement instanceof MethodInvocation) { + MethodInvocation c = (MethodInvocation)statement; + String srcObjId = c.getThisObjId(); + String dstObjId = c.getCalledMethodExecution().getThisObjId(); + if (Trace.isNull(srcObjId)) { + srcObjId = c.getThisClassName(); } - return false; + if (Trace.isNull(dstObjId)) { + dstObjId = c.getCalledMethodExecution().getThisClassName(); + } + int distance; + if (rootOf.get(srcObjId) == null) { + rootOf.put(srcObjId, srcObjId); + depthOf.put(srcObjId, 0); + classNames.put(srcObjId, srcObjId); + } + if (rootOf.get(dstObjId) == null) { + rootOf.put(dstObjId, dstObjId); + depthOf.put(dstObjId, 0); + classNames.put(dstObjId, c.getCalledMethodExecution().getThisClassName()); + } +// if (rootOf.get(srcObjId).equals(rootOf.get(dstObjId))) { + ArrayList srcPath = new ArrayList<>(); + srcPath.add(srcObjId); + String rootObjId = srcObjId; + while (parentOf.get(rootObjId) != null) { + rootObjId = parentOf.get(rootObjId); + srcPath.add(0, rootObjId); + } + + ArrayList dstPath = new ArrayList<>(); + dstPath.add(dstObjId); + rootObjId = dstObjId; + while (parentOf.get(rootObjId) != null) { + rootObjId = parentOf.get(rootObjId); + dstPath.add(0, rootObjId); + } + + int srcDepth = depthOf.get(srcObjId); + int dstDepth = depthOf.get(dstObjId); + int depth = 0; + while (srcPath.get(depth).equals(dstPath.get(depth))) { + depth++; + if (depth >= srcPath.size() || depth >= dstPath.size()) break; + } + distance = srcDepth + dstDepth - 2 * (depth - 1); +// } else { +// if (depthOf.get(dstObjId) != null) { +// distance = depthOf.get(dstObjId) + 2; // �V�X�e���S�̂̃��[�g�܂ł�1�A�V�X�e���S�̂̃��[�g����e�N���X�I�u�W�F�N�g�܂ł�1�Ƃ��� +// } else { +// distance = 2; +// } +// } + if (callDistances.get(dstObjId) == null) { + callDistances.put(dstObjId, new HashMap()); + } + HashMap callDistance = callDistances.get(dstObjId); + if (callDistance.get(srcObjId) == null) { + callDistance.put(srcObjId, distance); + } + if (totalCallDistances.get(dstObjId) != null) { + totalCallDistances.put(dstObjId, totalCallDistances.get(dstObjId) + distance); + } else { + totalCallDistances.put(dstObjId, distance); + } + if (callCounts.get(dstObjId) != null) { + callCounts.put(dstObjId, callCounts.get(dstObjId) + 1); + } else { + callCounts.put(dstObjId, 1); + } + if (maxCallDistances.get(dstObjId) == null || distance > maxCallDistances.get(dstObjId)) { + maxCallDistances.put(dstObjId, distance); + } } - - @Override - public boolean postVisitThread(ThreadInstance thread) { - return false; - } - - @Override - public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { - return false; - } - }); + return false; + } + @Override + public boolean postVisitStatement(Statement statement) { + return false; + } + }); + + // �I�u�W�F�N�gid�A�N���X���A���Ăяo���񐔁A���Ăяo�������A�ő�Ăяo�������A�Ăяo�����I�u�W�F�N�g���A�Ăяo�����I�u�W�F�N�g�P�ʂ̌Ăяo�������̑��a�̏o�� + for (String objId: callCounts.keySet()) { + int variation = 0; + int sum = 0; + for (String srcObjId: callDistances.get(objId).keySet()) { + sum += callDistances.get(objId).get(srcObjId); + variation++; + } + System.out.println(objId + ":" + classNames.get(objId) + ":" + callCounts.get(objId) + ":" + totalCallDistances.get(objId) + ":" + maxCallDistances.get(objId)+ ":" + variation + ":" + sum); } - for (String objId: callCounts.keySet()) { - System.out.println(objId + ":" + classNames.get(objId) + ":" + callCounts.get(objId)); - } +// final HashMap classNames = new HashMap<>(); +// final HashMap callCounts = new HashMap<>(); +// +// for (ThreadInstance thread: trace.getAllThreads().values()) { +// thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { +// @Override +// public boolean preVisitThread(ThreadInstance thread) { +// return false; +// } +// +// @Override +// public boolean preVisitMethodExecution(MethodExecution methodExecution) { +// String objId = methodExecution.getThisObjId(); +// if (!Trace.isNull(objId)) { +// String key = objId; +// if (classNames.get(key) == null) { +// classNames.put(key, methodExecution.getThisClassName()); +// } +// if (callCounts.get(key) == null) { +// callCounts.put(key, 1); +// } else { +// callCounts.put(key, callCounts.get(key) + 1); +// } +// } else { +// String className = methodExecution.getThisClassName(); +// String key = className; +// if (classNames.get(key) == null) { +// classNames.put(key, className); +// } +// if (callCounts.get(key) == null) { +// callCounts.put(key, 1); +// } else { +// callCounts.put(key, callCounts.get(key) + 1); +// } +// } +// return false; +// } +// +// @Override +// public boolean postVisitThread(ThreadInstance thread) { +// return false; +// } +// +// @Override +// public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { +// return false; +// } +// }); +// } +// +// for (String objId: callCounts.keySet()) { +// System.out.println(objId + ":" + classNames.get(objId) + ":" + callCounts.get(objId)); +// } } } diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/objectGraphAnalyzer/ObjectCreationGraphConstructor.java b/org.ntlab.traceAnalyzer/src/org/ntlab/objectGraphAnalyzer/ObjectCreationGraphConstructor.java new file mode 100644 index 0000000..82a8210 --- /dev/null +++ b/org.ntlab.traceAnalyzer/src/org/ntlab/objectGraphAnalyzer/ObjectCreationGraphConstructor.java @@ -0,0 +1,81 @@ +package org.ntlab.objectGraphAnalyzer; + +import java.util.AbstractMap.SimpleEntry; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map.Entry; + +import org.ntlab.trace.FieldUpdate; +import org.ntlab.trace.IMethodExecutionVisitor; +import org.ntlab.trace.IStatementVisitor; +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.MethodInvocation; +import org.ntlab.trace.Statement; +import org.ntlab.trace.ThreadInstance; +import org.ntlab.trace.Trace; +import org.ntlab.trace.TraceJSON; + +public class ObjectCreationGraphConstructor { + + /** + * @param args + */ + public static void main(String[] args) { + TraceJSON trace = new TraceJSON("traces\\jEditNormal.trace"); + + // �I�u�W�F�N�g�����؂̐��� + final HashMap classNames = new HashMap<>(); + final ArrayList> links = new ArrayList<>(); + final HashMap parentOf = new HashMap<>(); + + trace.traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + if (methodExecution.isConstructor() && methodExecution.getCallerMethodExecution() != null) { + String srcObjId = methodExecution.getCallerMethodExecution().getThisObjId(); + String dstObjId = methodExecution.getThisObjId(); + if (!srcObjId.equals(dstObjId)) { // �e�q�N���X�Ԃ̃��\�b�h�Ăяo�����������ꍇ���l�� + if (Trace.isNull(srcObjId)) { + srcObjId = methodExecution.getCallerMethodExecution().getThisClassName(); + } + classNames.put(srcObjId, methodExecution.getCallerMethodExecution().getThisClassName()); + classNames.put(dstObjId, methodExecution.getThisClassName()); + links.add(new SimpleEntry<>(srcObjId, dstObjId)); + parentOf.put(dstObjId, srcObjId); + } + } + return false; + } + }); + + String objectLabel; + String objectElements[]; + System.out.println("digraph jEditNormal {"); + for (String objectId: classNames.keySet()) { + objectElements = objectId.split("\\."); + objectLabel = objectElements[objectElements.length - 1].replace("$", "_"); + System.out.println(objectLabel + " [label=\"" + objectId + ":" + classNames.get(objectId)+ "\"]"); + } + for (SimpleEntry link: links) { + String srcObjId = link.getKey(); + String dstObjId = link.getValue(); + objectElements = srcObjId.split("\\."); + objectLabel = objectElements[objectElements.length - 1].replace("$", "_"); + System.out.println(objectLabel + " -> " + dstObjId); + } + System.out.println("}"); + } +} diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/objectGraphAnalyzer/ObjectGraphReconstructor.java b/org.ntlab.traceAnalyzer/src/org/ntlab/objectGraphAnalyzer/ObjectGraphReconstructor.java index 1019261..229eb34 100644 --- a/org.ntlab.traceAnalyzer/src/org/ntlab/objectGraphAnalyzer/ObjectGraphReconstructor.java +++ b/org.ntlab.traceAnalyzer/src/org/ntlab/objectGraphAnalyzer/ObjectGraphReconstructor.java @@ -1,11 +1,15 @@ package org.ntlab.objectGraphAnalyzer; +import java.util.ArrayList; import java.util.HashMap; import org.ntlab.trace.FieldUpdate; +import org.ntlab.trace.IMethodExecutionVisitor; import org.ntlab.trace.IStatementVisitor; +import org.ntlab.trace.MethodExecution; import org.ntlab.trace.MethodInvocation; import org.ntlab.trace.Statement; +import org.ntlab.trace.ThreadInstance; import org.ntlab.trace.Trace; import org.ntlab.trace.TraceJSON; @@ -15,9 +19,52 @@ * @param args */ public static void main(String[] args) { + final HashMap callCounts = new HashMap<>(); + TraceJSON trace = new TraceJSON("traces\\jEditNormal.trace"); + + for (ThreadInstance thread: trace.getAllThreads().values()) { + thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + String objId = methodExecution.getThisObjId(); + if (!Trace.isNull(objId)) { + String key = objId; + if (callCounts.get(key) == null) { + callCounts.put(key, 1); + } else { + callCounts.put(key, callCounts.get(key) + 1); + } + } else { + String className = methodExecution.getThisClassName(); + String key = className; + if (callCounts.get(key) == null) { + callCounts.put(key, 1); + } else { + callCounts.put(key, callCounts.get(key) + 1); + } + } + return false; + } + + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }); + } + final HashMap classNames = new HashMap<>(); final HashMap links = new HashMap<>(); - TraceJSON trace = new TraceJSON("traces\\jEditNormal.trace"); trace.traverseStatementsInTrace(new IStatementVisitor() { @Override public boolean preVisitStatement(Statement statement) { @@ -64,18 +111,27 @@ String fieldElements[]; System.out.println("digraph jEditNormal {"); for (String objectId: classNames.keySet()) { - objectElements = objectId.split("\\."); - objectLabel = objectElements[objectElements.length - 1].replace("$", "_"); - System.out.println(objectLabel + " [label=\"" + objectId + ":" + classNames.get(objectId)+ "\"]"); + if (callCounts.get(objectId) != null && callCounts.get(objectId) >= 200) { + objectElements = objectId.split("\\."); + objectLabel = objectElements[objectElements.length - 1].replace("$", "_"); + System.out.println(objectLabel + " [label=\"" + objectId + ":" + classNames.get(objectId)+ "\"]"); + } } + String srcObjId; + String dstObjId; for (String linkId: links.keySet()) { linkElements = linkId.split(":"); - fieldElements = linkElements[1].split("\\."); - objectElements = linkElements[0].split("\\."); - objectLabel = objectElements[objectElements.length - 1].replace("$", "_"); - System.out.println(objectLabel + " -> " - + links.get(linkId) - + " [label=\"" + fieldElements[fieldElements.length - 1] +"\"]"); + srcObjId = linkElements[0]; + dstObjId = links.get(linkId); + if (callCounts.get(srcObjId) != null && callCounts.get(srcObjId) >= 200 + && callCounts.get(dstObjId) != null && callCounts.get(dstObjId) >= 200) { + fieldElements = linkElements[1].split("\\."); + objectElements = srcObjId.split("\\."); + objectLabel = objectElements[objectElements.length - 1].replace("$", "_"); + System.out.println(objectLabel + " -> " + + dstObjId + + " [label=\"" + fieldElements[fieldElements.length - 1] +"\"]"); + } } System.out.println("}"); }