diff --git a/org.ntlab.traceAnalyzer/.classpath b/org.ntlab.traceAnalyzer/.classpath
new file mode 100644
index 0000000..b1dabee
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/org.ntlab.traceAnalyzer/.project b/org.ntlab.traceAnalyzer/.project
new file mode 100644
index 0000000..24555c8
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/.project
@@ -0,0 +1,28 @@
+
+
+ org.ntlab.traceAnalyzer
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/org.ntlab.traceAnalyzer/.settings/org.eclipse.jdt.core.prefs b/org.ntlab.traceAnalyzer/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..11f6e46
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/org.ntlab.traceAnalyzer/META-INF/MANIFEST.MF b/org.ntlab.traceAnalyzer/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..dbd5834
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: TraceAnalyzer
+Bundle-SymbolicName: org.ntlab.traceAnalyzer;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.ntlab.traceanalyzer.Activator
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Import-Package: org.eclipse.ui.internal.views,
+ org.osgi.framework;version="1.3.0",
+ org.osgi.util.tracker;version="1.3.1"
+Bundle-ActivationPolicy: lazy
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.jface,
+ org.eclipse.core.runtime;bundle-version="3.8.0",
+ org.eclipse.core.resources;bundle-version="3.8.1",
+ org.eclipse.jdt.core;bundle-version="3.8.3",
+ org.eclipse.jdt.ui;bundle-version="3.8.2"
diff --git a/org.ntlab.traceAnalyzer/build.properties b/org.ntlab.traceAnalyzer/build.properties
new file mode 100644
index 0000000..41eb6ad
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/org.ntlab.traceAnalyzer/icons/full/read_obj.gif b/org.ntlab.traceAnalyzer/icons/full/read_obj.gif
new file mode 100644
index 0000000..c876ebd
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/icons/full/read_obj.gif
Binary files differ
diff --git a/org.ntlab.traceAnalyzer/icons/full/stckframe_obj.gif b/org.ntlab.traceAnalyzer/icons/full/stckframe_obj.gif
new file mode 100644
index 0000000..f1e585b
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/icons/full/stckframe_obj.gif
Binary files differ
diff --git a/org.ntlab.traceAnalyzer/icons/full/stckframe_obj2.gif b/org.ntlab.traceAnalyzer/icons/full/stckframe_obj2.gif
new file mode 100644
index 0000000..0fdf558
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/icons/full/stckframe_obj2.gif
Binary files differ
diff --git a/org.ntlab.traceAnalyzer/icons/full/stckframe_obj3.gif b/org.ntlab.traceAnalyzer/icons/full/stckframe_obj3.gif
new file mode 100644
index 0000000..ab64f22
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/icons/full/stckframe_obj3.gif
Binary files differ
diff --git a/org.ntlab.traceAnalyzer/icons/full/threads_obj.gif b/org.ntlab.traceAnalyzer/icons/full/threads_obj.gif
new file mode 100644
index 0000000..45c23a9
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/icons/full/threads_obj.gif
Binary files differ
diff --git a/org.ntlab.traceAnalyzer/icons/full/threads_obj2.gif b/org.ntlab.traceAnalyzer/icons/full/threads_obj2.gif
new file mode 100644
index 0000000..94d122a
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/icons/full/threads_obj2.gif
Binary files differ
diff --git a/org.ntlab.traceAnalyzer/plugin.xml b/org.ntlab.traceAnalyzer/plugin.xml
new file mode 100644
index 0000000..188ad0e
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/plugin.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/Delta.java b/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/Delta.java
new file mode 100644
index 0000000..7964f23
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/Delta.java
@@ -0,0 +1,27 @@
+package org.ntlab.deltaExtractor;
+
+import java.util.ArrayList;
+
+import org.ntlab.trace.Reference;
+
+public class Delta {
+
+ private ArrayList srcSide = new ArrayList();
+ private ArrayList dstSide = new ArrayList();
+
+ public void addSrcSide(Reference r){
+ getSrcSide().add(r);
+ }
+
+ public void addDstSide(Reference r){
+ getDstSide().add(r);
+ }
+
+ public ArrayList getSrcSide() {
+ return srcSide;
+ }
+
+ public ArrayList getDstSide() {
+ return dstSide;
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/DeltaAugmentationInfo.java b/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/DeltaAugmentationInfo.java
new file mode 100644
index 0000000..d887b4f
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/DeltaAugmentationInfo.java
@@ -0,0 +1,34 @@
+package org.ntlab.deltaExtractor;
+
+import org.ntlab.trace.AugmentationInfo;
+
+public class DeltaAugmentationInfo extends AugmentationInfo {
+ private Boolean isCoodinator = false;
+ private Boolean isSetter = true;
+ private int traceObjectId = 0;
+
+ public void setTraceObjectId(int traceObjectId) {
+ this.traceObjectId = traceObjectId;
+ }
+
+ public int getTraceObjectId() {
+ return traceObjectId;
+ }
+
+ public void setSetterSide(boolean isSetter) {
+ this.isSetter = isSetter;
+ }
+
+ public boolean isSetterSide() {
+ return isSetter;
+ }
+
+ public void setCoodinator(boolean isCoodinator) {
+ this.isCoodinator = isCoodinator;
+ }
+
+ public boolean isCoodinator() {
+ return isCoodinator;
+ }
+
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/DeltaExtractor.java b/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/DeltaExtractor.java
new file mode 100644
index 0000000..a192105
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/DeltaExtractor.java
@@ -0,0 +1,1033 @@
+package org.ntlab.deltaExtractor;
+
+import java.util.ArrayList;
+
+import org.ntlab.trace.FieldAccess;
+import org.ntlab.trace.FieldUpdate;
+import org.ntlab.trace.MethodExecution;
+import org.ntlab.trace.MethodInvocation;
+import org.ntlab.trace.ObjectReference;
+import org.ntlab.trace.Reference;
+import org.ntlab.trace.Statement;
+import org.ntlab.trace.Trace;
+import org.ntlab.trace.TracePoint;
+
+public class DeltaExtractor {
+ private static final int LOST_DECISION_EXTENSION = 0; // ��{�� 0 �ɐݒ�Bfinal�ϐ��̒ǐՃA���S���Y���̕s��C����͕s�v�̂͂��B
+ private ArrayList data = new ArrayList();
+ private ArrayList objList = new ArrayList(2);
+ private ArrayList methodList = new ArrayList();
+ private ExtractedStructure eStructure = new ExtractedStructure();
+ private ObjectReference srcObject = null;
+ private ObjectReference dstObject = null;
+ private String returnValue;
+ private String threadNo;
+ private boolean isLost = false;
+ private ArrayList checkList = new ArrayList();
+ private Trace trace = null;
+ private int finalCount = 0; // final�ϐ������o�ł��Ȃ��\��������̂ŁA�R���̉������ł��Ȃ������ꍇ�ł����炭�ǐՂ��Â���
+
+ private static final boolean DEBUG1 = true;
+ private static final boolean DEBUG2 = true;
+
+ public DeltaExtractor(String traceFile) {
+ trace = new Trace(traceFile);
+ }
+
+ public DeltaExtractor(Trace trace) {
+ this.trace = trace;
+ }
+
+// public MethodExecution getMethodExecution(Reference createdReference, MethodExecution before) {
+// return trace.getMethodExecution(createdReference, before);
+// }
+//
+// public MethodExecution getMethodExecution(String methodSignature) {
+// return trace.getMethodExecution(methodSignature);
+// }
+//
+// public MethodExecution getMethodExecutionBackwardly(String methodSignature) {
+// return trace.getMethodExecutionBackwardly(methodSignature);
+// }
+//
+// public MethodExecution getCollectionTypeMethodExecution(Reference r, MethodExecution before) {
+// return trace.getCollectionTypeMethodExecution(r, before);
+// }
+//
+// public MethodExecution getArraySetMethodExecution(Reference r, MethodExecution before) {
+// return trace.getArraySetMethodExecution(r, before);
+// }
+//
+// public CallTree getLastCallTree(ArrayList refs,
+// ArrayList colls,
+// ArrayList arrys,
+// int endLine,
+// Reference[] lastRef) throws TraceFileException {
+// return trace.getLastCallTree(refs, colls, arrys, endLine, lastRef);
+// }
+
+ /**
+ * �f���^���o�A���S���Y���̌Ăяo�����T�������icalleeSearch�Ƒ��ݍċA�ɂȂ��Ă���j
+ * @param trace�@��͑Ώۃg���[�X
+ * @param methodExecution �T�����郁�\�b�h���s
+ * @param objList�@�ǐՒ��̃I�u�W�F�N�g
+ * @param child�@���O�ɒT�����Ă����Ăяo����̃��\�b�h���s
+ * @return ���������R�[�f�B�l�[�^
+ * @throws TraceFileException
+ */
+ private MethodExecution callerSearch(Trace trace, TracePoint tracePoint, ArrayList objList, MethodExecution childMethodExecution) {
+ MethodExecution methodExecution = tracePoint.getMethodExecution();
+ methodExecution.setAugmentation(new DeltaAugmentationInfo());
+ eStructure.createParent(methodExecution);
+ String thisObjectId = methodExecution.getThisObjId();
+ ArrayList removeList = new ArrayList(); // �ǐՂ��Ă���I�u�W�F�N�g���ō폜�ΏۂƂȂ��Ă������
+ ArrayList creationList = new ArrayList(); // ���̃��\�b�h���s���ɐ������ꂽ�I�u�W�F�N�g
+ int existsInFields = 0; // ���̃��\�b�h���s���Ńt�B�[���h�ɗR�����Ă���I�u�W�F�N�g�̐�(1�ȏ�Ȃ炱�̃��\�b�h���s����this�Ɉˑ�)
+ boolean isTrackingThis = false; // �Ăяo�����this�Ɉˑ�����
+ boolean isSrcSide = true; // �Q�ƌ����Q�Ɛ�̂�����̑��̃I�u�W�F�N�g�̗R�������ǂ���this�I�u�W�F�N�g�ɓ��B������?
+ ArrayList fieldArrays = new ArrayList();
+ ArrayList fieldArrayElements = new ArrayList();
+ ObjectReference thisObj = new ObjectReference(thisObjectId, methodExecution.getThisClassName(),
+ Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor()), Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstructor()));
+
+ if (childMethodExecution == null) {
+ // �T���J�n���͈�U�폜���A�Ăяo�����̒T���𑱂���ۂɕ���������
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ isTrackingThis = true; // �Ăяo�����T���O�ɕ���
+ }
+
+ if (childMethodExecution != null && objList.contains(childMethodExecution.getThisObjId())) {
+ // �Ăяo�����this�Ɉˑ�����
+ if (thisObjectId.equals(childMethodExecution.getThisObjId())) {
+ // �I�u�W�F�N�g���Ăяo���̂Ƃ��݈̂�U�폜���A�Ăяo�����̒T���𑱂���ۂɕ���������
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ isTrackingThis = true; // �Ăяo�����T���O�ɕ���
+ }
+ }
+
+ if (childMethodExecution != null && childMethodExecution.isConstructor()) {
+ // �Ăяo���悪�R���X�g���N�^�������ꍇ
+ int newIndex = objList.indexOf(childMethodExecution.getThisObjId());
+ if (newIndex != -1) {
+ // �Ăяo���悪�ǐՑΏۂ̃R���X�g���N�^��������field�Ɠ��l�ɏ���
+ removeList.add(childMethodExecution.getThisObjId());
+ existsInFields++;
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ }
+ }
+
+ if (childMethodExecution != null && Trace.getMethodName(childMethodExecution.getSignature()).startsWith("access$")) {
+ // �G���N���[�W���O�C���X�^���X�ɑ��郁�\�b�h�Ăяo���������ꍇ
+ String enclosingObj = childMethodExecution.getArguments().get(0).getId(); // �G���N���[�W���O�C���X�^���X�͑������ɓ����Ă���炵��
+ int encIndex = objList.indexOf(enclosingObj);
+ if (encIndex != -1) {
+ // thisObject �ɒu����������Afield�Ɠ��l�ɏ���
+ removeList.add(enclosingObj);
+ existsInFields++;
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ }
+ }
+
+ // �߂�l�ɒT���Ώۂ��܂܂�Ă����calleeSearch���ċA�Ăяo��
+ while (tracePoint.stepBackOver()) {
+ Statement statement = tracePoint.getStatement();
+ // ���ڎQ�Ƃ���уt�B�[���h�Q�Ƃ̒T��
+ if (statement instanceof FieldAccess) {
+ FieldAccess fs = (FieldAccess)statement;
+ String refObjectId = fs.getValueObjId();
+ int index = objList.indexOf(refObjectId);
+ if (index != -1) {
+ String ownerObjectId = fs.getContainerObjId();
+ if (ownerObjectId.equals(thisObjectId)) {
+ // �t�B�[���h�Q�Ƃ̏ꍇ
+ removeList.add(refObjectId);
+ existsInFields++; // set�������get�����o������\��������
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ } else {
+ // ���ڎQ�Ƃ̏ꍇ
+ if (refObjectId.equals(srcObject.getId())) {
+ eStructure.addSrcSide(new Reference(ownerObjectId, refObjectId,
+ fs.getContainerClassName(), srcObject.getActualType()));
+ srcObject = new ObjectReference(ownerObjectId, fs.getContainerClassName());
+ } else if(refObjectId.equals(dstObject.getId())) {
+ eStructure.addDstSide(new Reference(ownerObjectId, refObjectId,
+ fs.getContainerClassName(), dstObject.getActualType()));
+ dstObject = new ObjectReference(ownerObjectId, fs.getContainerClassName());
+ }
+ objList.set(index, ownerObjectId);
+ }
+ } else {
+ // �ŏI�I�ɃI�u�W�F�N�g�̗R����������Ȃ������ꍇ�ɁA�����ŎQ�Ƃ����z������̗v�f�ɗR�����Ă���\��������
+ String refObjType = fs.getValueClassName();
+ if (refObjType.startsWith("[L")) {
+ // �Q�Ƃ����t�B�[���h���z��̏ꍇ
+ ObjectReference trackingObj = null;
+ if ((srcObject.getActualType() != null && refObjType.endsWith(srcObject.getActualType() + ";"))
+ || (srcObject.getCalleeType() != null && refObjType.endsWith(srcObject.getCalleeType() + ";"))
+ || (srcObject.getCallerType() != null && refObjType.endsWith(srcObject.getCallerType() + ";"))) {
+ trackingObj = srcObject;
+ } else if ((dstObject.getActualType() != null && refObjType.endsWith(dstObject.getActualType() + ";"))
+ || (dstObject.getCalleeType() != null && refObjType.endsWith(dstObject.getCalleeType() + ";"))
+ || (dstObject.getCallerType() != null && refObjType.endsWith(dstObject.getCallerType() + ";"))) {
+ trackingObj = dstObject;
+ }
+ if (trackingObj != null) {
+ // �ǐՒ��̃I�u�W�F�N�g�ɁA�z��v�f�Ɠ����^�����I�u�W�F�N�g�����݂���ꍇ
+ String ownerObjectId = fs.getContainerObjId();
+ if (ownerObjectId.equals(thisObjectId)) {
+ // �t�B�[���h�Q�Ƃ̏ꍇ�i���ɗR���̉\�����Ȃ��Ƃ킩�������_�ŁA���̔z��̗v�f�ɗR�����Ă�����̂Ɛ�������B�j
+ fieldArrays.add(new ObjectReference(refObjectId, refObjType));
+ fieldArrayElements.add(trackingObj);
+ } else {
+ // ���ڎQ�Ƃ̏ꍇ(�{���ɂ��̔z��̗v�f����擾���ꂽ���̂Ȃ炱���ŒǐՑΏۂ�u��������ׂ������A
+ // ���̎��_�ő��̗R���̉\����r���ł��Ȃ��B�����ŒǐՑΏۂ�u�������Ă��܂��ƁA��ŕʂɗR�������邱�Ƃ��킩�����ꍇ��
+ // ��蒼��������B)
+ }
+ }
+ }
+ }
+ } else if (statement instanceof MethodInvocation) {
+ MethodExecution prevChildMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution();
+ if (!prevChildMethodExecution.equals(childMethodExecution)) {
+ // �߂�l
+ ObjectReference ret = prevChildMethodExecution.getReturnValue();
+ if (ret != null) {
+ int retIndex = -1;
+ retIndex = objList.indexOf(ret.getId());
+ if (retIndex != -1) {
+ // �߂�l���R��������
+ prevChildMethodExecution.setAugmentation(new DeltaAugmentationInfo());
+ if (prevChildMethodExecution.isConstructor()) {
+ // �ǐՑΏۂ�constractor���Ă�ł�����(�I�u�W�F�N�g�̐�����������)field�Ɠ��l�ɏ���
+ String newObjId = ret.getId();
+ creationList.add(newObjId);
+ removeList.add(newObjId);
+ existsInFields++;
+ // objList.remove(callTree.getThisObjId());
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(newObjId)); // �ǐՑΏ�
+ ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setSetterSide(false); // getter�Ăяo���Ɠ��l
+ continue;
+ }
+ String retObj = objList.get(retIndex);
+ if (removeList.contains(retObj)) {
+ // ��xget�Ō��o���ăt�B�[���h�Ɉˑ����Ă���Ɣ��f�������{���̗R�����߂�l���������Ƃ����������̂ŁA�t�B�[���h�ւ̈ˑ����L�����Z������
+ removeList.remove(retObj);
+ existsInFields--;
+ if (existsInFields == 0) {
+ removeList.remove(thisObjectId);
+ }
+ }
+ ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(retObj)); // �ǐՑΏ�
+ TracePoint prevChildTracePoint = tracePoint.duplicate();
+ prevChildTracePoint.stepBackNoReturn();
+ calleeSearch(trace, prevChildTracePoint, objList, prevChildMethodExecution.isStatic(), retIndex); // �Ăяo�����T��
+ if (objList.get(retIndex) != null && objList.get(retIndex).equals(prevChildMethodExecution.getThisObjId())
+ && thisObjectId.equals(prevChildMethodExecution.getThisObjId())) {
+ // �Ăяo����Ńt�B�[���h�Ɉˑ����Ă����ꍇ�̏���
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ isTrackingThis = true; // �Ăяo�����T���O�ɕ���
+ }
+ if (isLost) {
+ checkList.add(objList.get(retIndex));
+ isLost = false;
+ }
+ } else {
+ // �ŏI�I�ɃI�u�W�F�N�g�̗R����������Ȃ������ꍇ�ɁA���̖߂�l�Ŏ擾�����z������̗v�f�ɗR�����Ă���\��������
+ String retType = ret.getActualType();
+ if (retType.startsWith("[L")) {
+ // �߂�l���z��̏ꍇ
+ if ((srcObject.getActualType() != null && retType.endsWith(srcObject.getActualType() + ";"))
+ || (srcObject.getCalleeType() != null && retType.endsWith(srcObject.getCalleeType() + ";"))
+ || (srcObject.getCallerType() != null && retType.endsWith(srcObject.getCallerType() + ";"))) {
+ retType = srcObject.getActualType();
+ } else if ((dstObject.getActualType() != null && retType.endsWith(dstObject.getActualType() + ";"))
+ || (dstObject.getCalleeType() != null && retType.endsWith(dstObject.getCalleeType() + ";"))
+ || (dstObject.getCallerType() != null && retType.endsWith(dstObject.getCallerType() + ";"))) {
+ retType = dstObject.getActualType();
+ } else {
+ retType = null;
+ }
+ if (retType != null) {
+ // �{���ɂ��̔z��̗v�f����擾���ꂽ���̂Ȃ炱���ŒǐՑΏۂ�u�������āA�Ăяo�����T�����ׂ������A
+ // ���̎��_�ő��̗R���̉\����r���ł��Ȃ��B�����ŒǐՑΏۂ�u�������Ă��܂��ƁA��ŕʂɗR�������邱�Ƃ��킩�����ꍇ��
+ // ��蒼��������B
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ // --- ���̎��_�� tracePoint �͌Ăяo�������w���Ă��� ---
+
+ // �R���N�V�����^�Ή�
+ if (methodExecution.isCollectionType()) {
+ objList.add(thisObjectId);
+ }
+
+ // �����̎擾
+ ArrayList argments = methodExecution.getArguments();
+
+ // �����ƃt�B�[���h�ɓ���ID�̃I�u�W�F�N�g������ꍇ��z��
+ Reference r;
+ for (int i = 0; i < removeList.size(); i++) {
+ String removeId = removeList.get(i);
+ if (argments.contains(new ObjectReference(removeId))) {
+ removeList.remove(removeId); // �t�B�[���h�ƈ����̗����ɒǐՑΏۂ����݂����ꍇ�A������D��
+ } else if(objList.contains(removeId)) {
+ // �t�B�[���h�ɂ����Ȃ������ꍇ(�������A�I�u�W�F�N�g�̐������t�B�[���h�Ɠ��l�Ɉ���)
+ objList.remove(removeId); // �ǐՑΏۂ���O��
+ if (!removeId.equals(thisObjectId)) {
+ // �t�B�[���h�ithis ���� removeId �ւ̎Q�Ɓj���f���^�̍\���v�f�ɂȂ�
+ if (removeId.equals(srcObject.getId())) {
+ r = new Reference(thisObj, srcObject);
+ r.setCreation(creationList.contains(removeId)); // �I�u�W�F�N�g�̐�����?
+ eStructure.addSrcSide(r);
+ srcObject = thisObj;
+ isSrcSide = true;
+ } else if (removeId.equals(dstObject.getId())) {
+ r = new Reference(thisObj, dstObject);
+ r.setCreation(creationList.contains(removeId)); // �I�u�W�F�N�g�̐�����?
+ eStructure.addDstSide(r);
+ dstObject = thisObj;
+ isSrcSide = false;
+ }
+ }
+ }
+ }
+ // --- ���̎��_�� this ���ǐՑΏۂł������Ƃ��Ă� objList �̒����炢������폜����Ă��� ---
+
+ // �����T��
+ boolean existsInAnArgument = false;
+ for (int i = 0; i < objList.size(); i++) {
+ String objectId = objList.get(i);
+ if (objectId != null) {
+ ObjectReference trackingObj = new ObjectReference(objectId);
+ if (argments.contains(trackingObj)) {
+ // �������R��������
+ existsInAnArgument = true;
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(objectId));
+ } else {
+ // �R�����ǂ��ɂ�������Ȃ�����
+ boolean isSrcSide2 = true;
+ trackingObj = null;
+ if (objectId.equals(srcObject.getId())) {
+ isSrcSide2 = true;
+ trackingObj = srcObject;
+ } else if (objectId.equals(dstObject.getId())) {
+ isSrcSide2 = false;
+ trackingObj = dstObject;
+ }
+ if (trackingObj != null) {
+ // �܂��z������̗v�f��R���Ƃ��ċ^��(������D��)
+ for (int j = 0; j < argments.size(); j++) {
+ ObjectReference argArray = argments.get(j);
+ if (argArray.getActualType().startsWith("[L")
+ && (trackingObj.getActualType() != null && (argArray.getActualType().endsWith(trackingObj.getActualType() + ";"))
+ || (trackingObj.getCalleeType() != null && argArray.getActualType().endsWith(trackingObj.getCalleeType() + ";"))
+ || (trackingObj.getCallerType() != null && argArray.getActualType().endsWith(trackingObj.getCallerType() + ";")))) {
+ // �^����v������z������̗v�f��R���Ƃ݂Ȃ�
+ existsInAnArgument = true;
+ objList.remove(objectId);
+ objList.add(argArray.getId()); // �ǐՑΏۂ�z��v�f����z��ɒu������
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(argArray.getId()));
+ r = new Reference(argArray.getId(), trackingObj.getId(),
+ argArray.getActualType(), trackingObj.getActualType());
+ r.setArray(true);
+ if (isSrcSide2) {
+ eStructure.addSrcSide(r);
+ srcObject = new ObjectReference(argArray.getId(), argArray.getActualType());
+ } else {
+ eStructure.addDstSide(r);
+ dstObject = new ObjectReference(argArray.getId(), argArray.getActualType());
+ }
+ objectId = null;
+ break;
+ }
+ }
+ if (objectId != null) {
+ // ���ɔz��t�B�[���h�̗v�f��R���Ƃ��ċ^��(�t�B�[���h�͈�������)
+ int index = fieldArrayElements.indexOf(trackingObj);
+ if (index != -1) {
+ // �^����v���Ă�̂Ŕz��t�B�[���h�̗v�f��R���Ƃ݂Ȃ�
+ ObjectReference fieldArray = fieldArrays.get(index);
+ existsInFields++;
+ objList.remove(objectId);
+ r = new Reference(fieldArray.getId(), trackingObj.getId(),
+ fieldArray.getActualType(), trackingObj.getActualType());
+ r.setArray(true);
+ if (isSrcSide2) {
+ eStructure.addSrcSide(r);
+ eStructure.addSrcSide(new Reference(thisObjectId, fieldArray.getId(),
+ methodExecution.getThisClassName(), fieldArray.getActualType()));
+ srcObject = thisObj;
+ isSrcSide = true;
+ } else {
+ eStructure.addDstSide(r);
+ eStructure.addDstSide(new Reference(thisObjectId, fieldArray.getId(),
+ methodExecution.getThisClassName(), fieldArray.getActualType()));
+ dstObject = thisObj;
+ isSrcSide = false;
+ }
+ }
+ }
+ if (trackingObj.getActualType() != null && trackingObj.getActualType().startsWith("[L")) {
+ // �ǂ��ɂ�������Ȃ������ꍇ�A�T���Ă���̂��z��^�Ȃ�A���̃��\�b�h���Ő������ꂽ���̂ƍl����
+ objList.remove(objectId);
+ if (isSrcSide2) {
+ eStructure.addSrcSide(new Reference(thisObjectId, trackingObj.getId(),
+ methodExecution.getThisClassName(), trackingObj.getActualType()));
+ srcObject = thisObj;
+ isSrcSide = true;
+ } else {
+ eStructure.addDstSide(new Reference(thisObjectId, trackingObj.getId(),
+ methodExecution.getThisClassName(), trackingObj.getActualType()));
+ dstObject = thisObj;
+ isSrcSide = false;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (existsInAnArgument) {
+ // ������1�ł��ǐՑΏۂ����݂����ꍇ
+ if (existsInFields > 0 || isTrackingThis) {
+ // this�I�u�W�F�N�g��ǐՒ��̏ꍇ
+ if (!Trace.isNull(thisObjectId)) {
+ objList.add(thisObjectId); // ����ɒT������ꍇ�A��U��菜���� thisObject ��
+ } else {
+ objList.add(null); // ������static�Ăяo���������ꍇ�A����ȏ�ǐՂ��Ȃ�
+ }
+ }
+// if (existsInFields > 0) {
+// // �t�B�[���h��R���Ɏ��I�u�W�F�N�g�����݂����ꍇ
+// if (isSrcSide) {
+// srcObject = thisObj;
+// } else {
+// dstObject = thisObj;
+// }
+// }
+ if (tracePoint.isValid()) {
+ finalCount = 0;
+ return callerSearch(trace, tracePoint, objList, methodExecution); // �Ăяo����������ɒT��
+ }
+ }
+
+ for (int i = 0; i < objList.size(); i++) {
+ objList.remove(null);
+ }
+ if (objList.isEmpty()) {
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setCoodinator(true);
+ } else {
+ // �R���������ł��Ȃ�����
+ if (!methodExecution.isStatic()) {
+ finalCount++;
+ if (finalCount <= LOST_DECISION_EXTENSION) {
+ // final�ϐ����Q�Ƃ��Ă���ꍇ�R���������ł��Ȃ��\��������̂ŁA�ǐՂ������I�������P�\���Ԃ�݂���
+ if (tracePoint.isValid()) {
+ MethodExecution c = callerSearch(trace, tracePoint, objList, methodExecution); // �Ăяo����������ɒT��
+ if (((DeltaAugmentationInfo)c.getAugmentation()).isCoodinator()) {
+ methodExecution = c; // �ǐՂ𑱂������ʃR�[�f�B�l�[�^����������
+ }
+ }
+ } else if (thisObj.getActualType().contains("$")) {
+ // �����������܂��͖����N���X�̏ꍇ�A���������I�u�W�F�N�g���O�����\�b�h�̓���final�ϐ�����擾�����Ƃ݂Ȃ��A����Ɏ����̒��̃t�B�[���h�̈��Ƃ݂Ȃ�
+ for (int i = objList.size() - 1; i >= 0; i--) {
+ String objectId = objList.get(i);
+ if (objectId != null) {
+ ObjectReference trackingObj = new ObjectReference(objectId);
+ boolean isSrcSide2 = true;
+ trackingObj = null;
+ if (objectId.equals(srcObject.getId())) {
+ isSrcSide2 = true;
+ trackingObj = srcObject;
+ } else if (objectId.equals(dstObject.getId())) {
+ isSrcSide2 = false;
+ trackingObj = dstObject;
+ }
+ if (trackingObj != null) {
+ r = new Reference(thisObjectId, trackingObj.getId(),
+ methodExecution.getThisClassName(), trackingObj.getActualType());
+ r.setFinalLocal(true);
+ if (isSrcSide2) {
+ eStructure.addSrcSide(r);
+ srcObject = thisObj;
+ isSrcSide = true;
+ } else {
+ eStructure.addDstSide(r);
+ dstObject = thisObj;
+ isSrcSide = false;
+ }
+ existsInFields++;
+ objList.remove(objectId);
+ }
+ }
+ }
+ }
+ }
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setCoodinator(false);
+ }
+ finalCount = 0;
+ return methodExecution;
+ }
+
+ /**
+ * �f���^���o�A���S���Y���̌Ăяo����T������(�ċA�Ăяo���ɂȂ��Ă���)
+ * @param trace ��͑Ώۃg���[�X
+ * @param methodExecution �T�����郁�\�b�h���s
+ * @param objList �ǐՒ��̃I�u�W�F�N�g
+ * @param isStatic�@�ÓI���\�b�h���ۂ�
+ * @param index�@objList���̂ǂ̃I�u�W�F�N�g��ǐՂ��Ă��̃��\�b�h���s�ɓ����Ă����̂�
+ * @throws TraceFileException
+ */
+ private void calleeSearch(Trace trace, TracePoint tracePoint, ArrayList objList, Boolean isStatic, int index) {
+ MethodExecution methodExecution = tracePoint.getMethodExecution();
+ Boolean isResolved = false;
+ String objectId = objList.get(index); // calleeSearch() �ł͒ǐՑΏۂ̃I�u�W�F�N�g�͈�����A��objList��index�Ԗڂ̗v�f�ȊO�ύX���Ă͂����Ȃ�
+ String thisObjectId = methodExecution.getThisObjId();
+ ArrayList fieldArrays = new ArrayList();
+ ArrayList fieldArrayElements = new ArrayList();
+ ObjectReference thisObj = new ObjectReference(thisObjectId, methodExecution.getThisClassName(),
+ Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor()),
+ Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstructor()));
+
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setSetterSide(false); // ��{�I��getter�Ăяo���̂͂������A����
+ ArrayList argments = methodExecution.getArguments();
+ ObjectReference trackingObj = null;
+ //static���o�R�����null�������Ă��鎞������
+ if (objectId != null) {
+ String returnType = Trace.getReturnType(methodExecution.getSignature());
+ if (objectId.equals(srcObject.getId())) {
+ trackingObj = srcObject;
+ trackingObj.setCalleeType(returnType);
+ } else if(objectId.equals(dstObject.getId())) {
+ trackingObj = dstObject;
+ trackingObj.setCalleeType(returnType);
+ } else {
+ trackingObj = new ObjectReference(objectId, null, returnType);
+ }
+
+ Reference r;
+ // �߂�l�ɒT���Ώۂ��܂܂�Ă����calleeSearch�Ăяo��
+ do {
+ if (!tracePoint.isValid()) break;
+ Statement statement = tracePoint.getStatement();
+ // ���ڎQ�Ƃ���уt�B�[���h�Q�Ƃ̒T��
+ if (statement instanceof FieldAccess) {
+ FieldAccess fs = (FieldAccess)statement;
+ if (objectId != null && objectId.equals(fs.getValueObjId())) {
+ String ownerObjectId = fs.getContainerObjId();
+ if (ownerObjectId.equals(thisObjectId)) {
+ // �t�B�[���h�Q�Ƃ̏ꍇ
+ if (objectId.equals(srcObject.getId())) {
+ eStructure.addSrcSide(new Reference(thisObj, srcObject));
+ srcObject = thisObj;
+ trackingObj = srcObject;
+ } else if(objectId.equals(dstObject.getId())) {
+ eStructure.addDstSide(new Reference(thisObj, dstObject));
+ dstObject = thisObj;
+ trackingObj = dstObject;
+ }
+ if (Trace.isNull(thisObjectId)) objectId = null; // static�ϐ��̏ꍇ
+ else objectId = thisObjectId;
+ objList.set(index, objectId);
+ } else {
+ // ���ڎQ�Ƃ̏ꍇ
+ if (objectId.equals(srcObject.getId())) {
+ eStructure.addSrcSide(new Reference(ownerObjectId, objectId,
+ fs.getContainerClassName(), srcObject.getActualType()));
+ srcObject = new ObjectReference(ownerObjectId, fs.getContainerClassName());
+ trackingObj = srcObject;
+ } else if(objectId.equals(dstObject.getId())) {
+ eStructure.addDstSide(new Reference(ownerObjectId, objectId,
+ fs.getContainerClassName(), dstObject.getActualType()));
+ dstObject = new ObjectReference(ownerObjectId, fs.getContainerClassName());
+ trackingObj = dstObject;
+ }
+ if (Trace.isNull(ownerObjectId)) objectId = null; // static�ϐ��̏ꍇ
+ else objectId = ownerObjectId;
+ objList.set(index, objectId);
+ }
+ isResolved = true;
+ } else {
+ // �I�u�W�F�N�g�̗R�������ڌ�����Ȃ������ꍇ�ł��A�����ꂩ�̔z��̗v�f�ɗR�����Ă���\��������
+ String refObjType = fs.getValueClassName();
+ if (refObjType.startsWith("[L")) {
+ // �Q�Ƃ����t�B�[���h���z��̏ꍇ
+ if ((trackingObj.getActualType() != null && refObjType.endsWith(trackingObj.getActualType() + ";"))
+ || (trackingObj.getCalleeType() != null && refObjType.endsWith(trackingObj.getCalleeType() + ";"))
+ || (trackingObj.getCallerType() != null && refObjType.endsWith(trackingObj.getCallerType() + ";"))) {
+ // �z��̗v�f�̕����ǐՒ��̃I�u�W�F�N�g�̌^�ƈ�v�����ꍇ
+ String ownerObjectId = fs.getContainerObjId();
+ if (ownerObjectId.equals(thisObjectId)) {
+ // �t�B�[���h�Q�Ƃ̏ꍇ�i���ɗR���̉\�����Ȃ��Ƃ킩�������_�ŁA���̔z��̗v�f�ɗR�����Ă�����̂Ɛ�������B�j
+ fieldArrays.add(new ObjectReference(fs.getValueObjId(), refObjType));
+ fieldArrayElements.add(trackingObj);
+ } else {
+ // ���ڎQ�Ƃ̏ꍇ(�{���ɂ��̔z��̗v�f����擾���ꂽ���̂Ȃ炱���ŒǐՑΏۂ�u��������ׂ������A
+ // ���̎��_�ő��̗R���̉\����r���ł��Ȃ��B�����ŒǐՑΏۂ�u�������Ă��܂��ƁA��ŕʂɗR�������邱�Ƃ��킩�����ꍇ��
+ // ��蒼��������B)
+ }
+ }
+ }
+ }
+ } else if (statement instanceof MethodInvocation) {
+ // �߂�l
+ MethodExecution childMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution();
+ ObjectReference ret = childMethodExecution.getReturnValue();
+ if (ret != null && objectId != null && objectId.equals(ret.getId())) {
+ childMethodExecution.setAugmentation(new DeltaAugmentationInfo());
+ ((DeltaAugmentationInfo)childMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(objectId));
+ TracePoint childTracePoint = tracePoint.duplicate();
+ childTracePoint.stepBackNoReturn();
+ calleeSearch(trace, childTracePoint, objList, childMethodExecution.isStatic(), index); // �Ăяo���������ɒT��
+ if (childMethodExecution.isConstructor()) {
+ // �R���X�g���N�^�Ăяo���������ꍇ
+ if (objectId.equals(srcObject.getId())) {
+ r = new Reference(thisObj, srcObject);
+ r.setCreation(true);
+ eStructure.addSrcSide(r);
+ srcObject = thisObj;
+ trackingObj = srcObject;
+ } else if (objectId.equals(dstObject.getId())) {
+ r = new Reference(thisObj, dstObject);
+ r.setCreation(true);
+ eStructure.addDstSide(r);
+ dstObject = thisObj;
+ trackingObj = dstObject;
+ }
+ if (Trace.isNull(thisObjectId)) objectId = null; // static�ϐ��̏ꍇ
+ else objectId = thisObjectId;
+ objList.set(index, objectId);
+ isResolved = true;
+ isLost = false;
+ continue;
+ }
+ objectId = objList.get(index);
+ if (objectId == null) {
+ // static�Ăяo���̖߂�l�������ꍇ�i���Ԃ�j
+ trackingObj = null;
+ isResolved = true;
+ } else if (objectId.equals(srcObject.getId())) {
+ trackingObj = srcObject;
+ } else if (objectId.equals(dstObject.getId())) {
+ trackingObj = dstObject;
+ }
+ if (isLost) {
+ checkList.add(objList.get(index));
+ isLost = false;
+ }
+ } else {
+ // �I�u�W�F�N�g�̗R�������ڌ�����Ȃ������ꍇ�ł��A�ǂ����̔z��̗v�f�ɗR�����Ă���\��������
+ String retType = ret.getActualType();
+ if (retType.startsWith("[L")) {
+ // �߂�l���z��̏ꍇ
+ if ((trackingObj.getActualType() != null && retType.endsWith(trackingObj.getActualType() + ";"))
+ || (trackingObj.getCalleeType() != null && retType.endsWith(trackingObj.getCalleeType() + ";"))
+ || (trackingObj.getCallerType() != null && retType.endsWith(trackingObj.getCallerType() + ";"))) {
+ // �{���ɂ��̔z��̗v�f����擾���ꂽ���̂Ȃ炱���ŒǐՑΏۂ�u�������āA�Ăяo�����T�����ׂ������A
+ // ���̎��_�ő��̗R���̉\����r���ł��Ȃ��B�����ŒǐՑΏۂ�u�������Ă��܂��ƁA��ŕʂɗR�������邱�Ƃ��킩�����ꍇ��
+ // ��蒼��������B
+ }
+ }
+ }
+ }
+ } while (tracePoint.stepBackOver());
+
+ //�����T��
+ if (argments.contains(new ObjectReference(objectId))) {
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setSetterSide(true); // �������K�v?
+ isResolved = true;
+ }
+ }
+
+ //�R���N�V�����^�Ή�
+ Reference r;
+ if (methodExecution.isCollectionType()) {
+ if (objectId != null) {
+ // �R���N�V�����^�̏ꍇ�A�����ŌX�̗v�f�ڕێ����Ă���Ɖ��肷��
+ if (objectId.equals(srcObject.getId())) {
+ r = new Reference(thisObj, srcObject);
+ r.setCollection(true);
+ eStructure.addSrcSide(r);
+ srcObject = thisObj;
+ } else if(objectId.equals(dstObject.getId())) {
+ r = new Reference(thisObj, dstObject);
+ r.setCollection(true);
+ eStructure.addDstSide(r);
+ dstObject =thisObj;
+ }
+ }
+ objList.set(index, methodExecution.getThisObjId());
+ isResolved = true; // �K�v�Ȃ̂ł�?
+ }
+
+ if (!isResolved && objectId != null) {
+ // �R�����ǂ��ɂ�������Ȃ�����
+ boolean isSrcSide = true;
+ if (objectId.equals(srcObject.getId())) {
+ isSrcSide = true;
+ } else if (objectId.equals(dstObject.getId())) {
+ isSrcSide = false;
+ }
+ if (trackingObj != null) {
+ // �܂��z������̗v�f��R���Ƃ��ċ^��(�������D��)
+ for (int i = 0; i < argments.size(); i++) {
+ ObjectReference argArray = argments.get(i);
+ if (argArray.getActualType().startsWith("[L")
+ && ((trackingObj.getActualType() != null && argArray.getActualType().endsWith(trackingObj.getActualType() + ";"))
+ || (trackingObj.getCalleeType() != null && argArray.getActualType().endsWith(trackingObj.getCalleeType() + ";"))
+ || (trackingObj.getCallerType() != null && argArray.getActualType().endsWith(trackingObj.getCallerType() + ";")))) {
+ // �^����v������z������̗v�f��R���Ƃ݂Ȃ�
+ isResolved = true;
+ objList.set(index, argArray.getId()); // �ǐՑΏۂ�z��v�f����z��ɒu������
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(argArray.getId()));
+ r = new Reference(argArray.getId(), trackingObj.getId(),
+ argArray.getActualType(), trackingObj.getActualType());
+ r.setArray(true);
+ if (isSrcSide) {
+ eStructure.addSrcSide(r);
+ srcObject = new ObjectReference(argArray.getId(), argArray.getActualType());
+ } else {
+ eStructure.addDstSide(r);
+ dstObject = new ObjectReference(argArray.getId(), argArray.getActualType());
+ }
+ objectId = null;
+ break;
+ }
+ }
+ if (objectId != null) {
+ // ���ɔz��t�B�[���h�̗v�f��R���Ƃ��ċ^��(�t�B�[���h�͈�������)
+ int indArg = fieldArrayElements.indexOf(trackingObj);
+ if (indArg != -1) {
+ // �^����v���Ă�̂Ŕz��t�B�[���h�̗v�f��R���Ƃ݂Ȃ�
+ isResolved = true;
+ ObjectReference fieldArray = fieldArrays.get(indArg);
+ objList.set(index, thisObjectId); // �ǐՑΏۂ�this�ɒu������
+ r = new Reference(fieldArray.getId(), trackingObj.getId(),
+ fieldArray.getActualType(), trackingObj.getActualType());
+ r.setArray(true);
+ if (isSrcSide) {
+ eStructure.addSrcSide(r);
+ eStructure.addSrcSide(new Reference(thisObjectId, fieldArray.getId(),
+ methodExecution.getThisClassName(), fieldArray.getActualType()));
+ srcObject = thisObj;
+ } else {
+ eStructure.addDstSide(r);
+ eStructure.addDstSide(new Reference(thisObjectId, fieldArray.getId(),
+ methodExecution.getThisClassName(), fieldArray.getActualType()));
+ dstObject = thisObj;
+ }
+ }
+ }
+ if (trackingObj.getActualType() != null && trackingObj.getActualType().startsWith("[L")) {
+ // �ǂ��ɂ�������Ȃ������ꍇ�A�T���Ă���̂��z��^�Ȃ�A���̃��\�b�h���Ő������ꂽ���̂ƍl����
+ isResolved = true;
+ objList.set(index, thisObjectId); // �ǐՑΏۂ�this�ɒu������
+ if (isSrcSide) {
+ eStructure.addSrcSide(new Reference(thisObjectId, trackingObj.getId(),
+ methodExecution.getThisClassName(), trackingObj.getActualType()));
+ srcObject = thisObj;
+ } else {
+ eStructure.addDstSide(new Reference(thisObjectId, trackingObj.getId(),
+ methodExecution.getThisClassName(), trackingObj.getActualType()));
+ dstObject = thisObj;
+ }
+ }
+ }
+ }
+
+ if (objectId == null && isResolved && !isStatic) { // static �Ăяo������̖߂�l��Ԃ��Ă���ꍇ
+ objList.set(index, thisObjectId); // ������ǐՂ�����
+ if (Trace.isNull(srcObject.getId())) {
+ srcObject = thisObj;
+ } else if (Trace.isNull(dstObject.getId())) {
+ dstObject = thisObj;
+ }
+ }
+
+ if (isStatic && !isResolved) { // ���͋N���肦�Ȃ�?(get�|�C���g�J�b�g���擾����悤�ɂ�������)
+ objList.set(index, null);
+ }
+ if(!isStatic && !isResolved){
+ isLost = true; // final�ϐ�������N���X�ŎQ�Ƃ��Ă���\�������邪�AcalleeSearch()�͕K���Ăяo�����ɕ��A���Ă����̂ŁA�����ł͉������Ȃ�
+ }
+ }
+
+ /**
+ * �v�ύX��̃A���S���Y���̋N�����\�b�h(������)
+ * @param targetRef �ΏۂƂȂ�Q��
+ * @param before �T���J�n�g���[�X�|�C���g(������ȑO��T��)
+ * @return ���o����
+ */
+ public ExtractedStructure extract(Reference targetRef, TracePoint before) {
+ TracePoint creationTracePoint;
+ if (targetRef.isArray()) {
+ // srcId �̔z��� dstId ���������Ă���\�������郁�\�b�h���s���擾�i�z���p�̏����j
+ creationTracePoint = trace.getArraySetTracePoint(targetRef, before);
+ } else if (targetRef.isCollection()) {
+ // srcId �̃R���N�V�����^�I�u�W�F�N�g�� dstId ���n����Ă��郁�\�b�h���s���擾�i�R���N�V�����^��p�̏����j
+ creationTracePoint = trace.getCollectionAddTracePoint(targetRef, before);
+ } else if (targetRef.isFinalLocal()) {
+ // srcId �̓����܂��͖����N���X�̃C���X�^���X�� final local �ϐ��ɑ������Ă��� dstId �� �I�u�W�F�N�g���n���ꂽ�\�������郁�\�b�h���s���擾�ifinal local�̋^��������ꍇ�̏����j
+ creationTracePoint = trace.getCreationTracePoint(targetRef.getSrcObject(), before);
+ targetRef = new Reference(creationTracePoint.getMethodExecution().getThisObjId(), targetRef.getDstObjectId(), creationTracePoint.getMethodExecution().getThisClassName(), targetRef.getDstClassName());
+ } else {
+ // �I�u�W�F�N�g�ԎQ�� r ���������ꂽ���\�b�h���s���擾�i�ʏ�j
+ creationTracePoint = trace.getFieldUpdateTracePoint(targetRef, before);
+ }
+ if (creationTracePoint == null) {
+ return null;
+ }
+ return extractSub(creationTracePoint, targetRef);
+ }
+
+ /**
+ * �v�ύX��̃A���S���Y���̋N�����\�b�h(������)
+ * @param creationTracePoint �I�u�W�F�N�g�ԎQ�Ɛ����g���[�X�|�C���g(�t�B�[���h�ւ̑��)
+ * @return ���o����
+ */
+ public ExtractedStructure extract(TracePoint creationTracePoint) {
+ Statement statement = creationTracePoint.getStatement();
+ if (statement instanceof FieldUpdate) {
+ Reference targetRef = ((FieldUpdate)statement).getReference();
+ return extractSub(creationTracePoint, targetRef);
+ } else {
+ return null;
+ }
+ }
+
+ private ExtractedStructure extractSub(TracePoint creationTracePoint, Reference targetRef) {
+ eStructure = new ExtractedStructure();
+ ArrayList objList = new ArrayList();
+ srcObject = targetRef.getSrcObject();
+ dstObject = targetRef.getDstObject();
+if (DEBUG1) {
+ System.out.println("extract delta of:" + targetRef.getSrcObject().getActualType() + "(" + targetRef.getSrcObjectId() + ")" + " -> " + targetRef.getDstObject().getActualType() + "(" + targetRef.getDstObjectId() + ")");
+}
+ if (!Trace.isNull(targetRef.getSrcObjectId())) {
+ objList.add(targetRef.getSrcObjectId());
+ } else {
+ objList.add(null);
+ }
+ if (!Trace.isNull(targetRef.getDstObjectId())) {
+ objList.add(targetRef.getDstObjectId());
+ } else {
+ objList.add(null);
+ }
+ return extractSub2(creationTracePoint, objList);
+ }
+
+ public ExtractedStructure extract(TracePoint tracePoint, ObjectReference argObj) {
+ MethodExecution methodExecution = tracePoint.getMethodExecution();
+ eStructure = new ExtractedStructure();
+ ArrayList objList = new ArrayList();
+ String thisObjectId = methodExecution.getThisObjId();
+ objList.add(thisObjectId);
+ objList.add(argObj.getId());
+ srcObject = new ObjectReference(thisObjectId, methodExecution.getThisClassName(),
+ Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor()), Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstructor()));
+ dstObject = argObj;
+if (DEBUG1) {
+ System.out.println("extract delta of:" + methodExecution.getSignature() + " -> " + argObj.getActualType() + "(" + argObj.getId() + ")");
+}
+ return extractSub2(tracePoint, objList);
+ }
+
+ private ExtractedStructure extractSub2(TracePoint creationTracePoint, ArrayList objList) {
+ eStructure.setCreationMethodExecution(creationTracePoint.getMethodExecution());
+ MethodExecution coordinator = callerSearch(trace, creationTracePoint, objList, null);
+ eStructure.setCoordinator(coordinator);
+if (DEBUG2) {
+ if (((DeltaAugmentationInfo)coordinator.getAugmentation()).isCoodinator()) {
+ System.out.println("Coordinator");
+ } else {
+ System.out.println("Warning");
+ }
+ System.out.println("coordinator:" + coordinator.getSignature());
+ System.out.println("srcSide:");
+ for (int i = 0; i < eStructure.getDelta().getSrcSide().size(); i++) {
+ Reference ref = eStructure.getDelta().getSrcSide().get(i);
+ if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) {
+ System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")");
+ }
+ }
+ System.out.println("dstSide:");
+ for (int i = 0; i < eStructure.getDelta().getDstSide().size(); i++) {
+ Reference ref = eStructure.getDelta().getDstSide().get(i);
+ if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) {
+ System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")");
+ }
+ }
+ System.out.println("overCoordinator:");
+ MethodExecution parent = coordinator.getParent();
+ while (parent != null) {
+ System.out.println("\t" + parent.getSignature());
+ parent = parent.getParent();
+ }
+}
+ return eStructure;
+ }
+
+ /**
+ * �Q�ƌ��ƎQ�Ɛ�̃I�u�W�F�N�g���w�肵�ăf���^�𒊏o����(�I�����C����͗p)
+ * @param srcObj �Q�ƌ��I�u�W�F�N�g
+ * @param dstObj �Q�Ɛ�I�u�W�F�N�g
+ * @param before �T���J�n�g���[�X�|�C���g(������ȑO��T��)
+ * @return�@���o����
+ */
+ public ExtractedStructure extract(Object srcObj, Object dstObj, TracePoint before) {
+ Reference targetRef = new Reference(Integer.toString(System.identityHashCode(srcObj)), Integer.toString(System.identityHashCode(dstObj)), null, null);
+ return extract(targetRef, before);
+ }
+
+
+ /**
+ * ���\�b�h���s���̃g���[�X�|�C���g�ƎQ�Ɛ�I�u�W�F�N�g���w�肵�ăf���^�𒊏o����(�I�����C����͗p)
+ * @param tracePoint ���\�b�h���s���̃g���[�X�|�C���g
+ * @param arg �Q�Ɛ�I�u�W�F�N�g(���[�J���ϐ�������ɂ��Q�Ɛ�)
+ * @return ���o����
+ */
+ public ExtractedStructure extract(TracePoint tracePoint, Object arg) {
+ ObjectReference argObj = new ObjectReference(Integer.toString(System.identityHashCode(arg)));
+ return extract(tracePoint, argObj);
+ }
+
+ /**
+ * �w�肵���X���b�h��Ō��ݎ��s���̃��\�b�h���s���擾����(�I�����C����͗p)
+ * @param thread �ΏۃX���b�h
+ * @return thread ��Ō��ݎ��s���̃��\�b�h���s
+ */
+ public MethodExecution getCurrentMethodExecution(Thread thread) {
+ return trace.getCurrentMethodExecution(thread);
+ }
+
+ /**
+ * methodSignature �ɑO����v���郁�\�b�h���������\�b�h�̍Ō�̎��s
+ * @param methodSignature ���\�b�h��(�O����v��������)
+ * @return �Y������Ō�̃��\�b�h���s
+ */
+ public MethodExecution getLastMethodExecution(String methodSignature) {
+ return trace.getLastMethodExecution(methodSignature);
+ }
+
+ /**
+ * methodSignature �ɑO����v���郁�\�b�h���������\�b�h�� before �ȑO�̍Ō�̎��s
+ * @param methodSignature ���\�b�h��(�O����v��������)
+ * @param before�@�T���J�n�g���[�X�|�C���g(������ȑO��T��)
+ * @return�@�Y������Ō�̃��\�b�h���s
+ */
+ public MethodExecution getLastMethodExecution(String methodSignature, TracePoint before) {
+ return trace.getLastMethodExecution(methodSignature, before);
+ }
+
+ public ArrayList getMethodExecutions(String methodSignature) {
+ return trace.getMethodExecutions(methodSignature);
+ }
+
+// public ExtractedStructure extract(MethodExecution caller, MethodExecution callee) {
+// eStructure = new ExtractedStructure();
+// ArrayList objList = new ArrayList();
+// String thisObjectId = caller.getThisObjId();
+// objList.add(thisObjectId);
+// objList.add(callee.getThisObjId());
+// srcObject = new ObjectReference(thisObjectId, caller.getThisClassName(),
+// Trace.getDeclaringType(caller.getSignature(), caller.isConstractor()), Trace.getDeclaringType(caller.getCallerSideSignature(), caller.isConstractor()));
+// dstObject = new ObjectReference(callee.getThisObjId(), callee.getThisClassName(),
+// Trace.getDeclaringType(callee.getSignature(), callee.isConstractor()), Trace.getDeclaringType(callee.getCallerSideSignature(), callee.isConstractor()));
+//if (DEBUG1) {
+// System.out.println("extract delta of:" + caller.getSignature() + " -> " + callee.getSignature());
+//}
+//
+// caller = new MethodExecution(caller); // ��͗p�p�����[�^���������������̂��g�p����
+// eStructure.setCreationMethodExecution(caller);
+// MethodExecution coordinator = callerSearch(trace, caller, objList, null);
+// eStructure.setCoordinator(coordinator);
+//if (DEBUG2) {
+// if (coordinator.isCoodinator()) {
+// System.out.println("Coordinator");
+// } else {
+// System.out.println("Warning");
+// }
+// System.out.println("coordinator:" + coordinator.getSignature());
+// System.out.println("srcSide:");
+// for (int i = 0; i < eStructure.getDelta().getSrcSide().size(); i++) {
+// Reference ref = eStructure.getDelta().getSrcSide().get(i);
+// if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) {
+// System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")");
+// }
+// }
+// System.out.println("dstSide:");
+// for (int i = 0; i < eStructure.getDelta().getDstSide().size(); i++) {
+// Reference ref = eStructure.getDelta().getDstSide().get(i);
+// if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) {
+// System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")");
+// }
+// }
+// System.out.println("overCoordinator:");
+// MethodExecution parent = coordinator.getParent();
+// while (parent != null) {
+// System.out.println("\t" + parent.getSignature());
+// parent = parent.getParent();
+// }
+//}
+// return eStructure;
+// }
+//
+//
+// /**
+// * ���\�b�h�̈����Ƃ��ăI�u�W�F�N�g���Q�Ƃ����ꍇ�̃f���^�𒊏o����
+// * @param caller �Q�ƌ��̃��\�b�h
+// * @param argObj �����Ƃ��ĎQ�Ƃ����I�u�W�F�N�g
+// * @return�@���o����
+// */
+// public ExtractedStructure extract(MethodExecution caller, ObjectReference argObj) {
+// eStructure = new ExtractedStructure();
+// ArrayList objList = new ArrayList();
+// String thisObjectId = caller.getThisObjId();
+// objList.add(thisObjectId);
+// objList.add(argObj.getId());
+// srcObject = new ObjectReference(thisObjectId, caller.getThisClassName(),
+// Trace.getDeclaringType(caller.getSignature(), caller.isConstractor()), Trace.getDeclaringType(caller.getCallerSideSignature(), caller.isConstractor()));
+// dstObject = argObj;
+//if (DEBUG1) {
+// System.out.println("extract delta of:" + caller.getSignature() + " -> " + argObj.getActualType() + "(" + argObj.getId() + ")");
+//}
+//
+// caller = new MethodExecution(caller); // ��͗p�p�����[�^���������������̂��g�p����
+// eStructure.setCreationMethodExecution(caller);
+// MethodExecution coordinator = callerSearch(trace, caller, objList, null);
+// eStructure.setCoordinator(coordinator);
+//if (DEBUG2) {
+// if (coordinator.isCoodinator()) {
+// System.out.println("Coordinator");
+// } else {
+// System.out.println("Warning");
+// }
+// System.out.println("coordinator:" + coordinator.getSignature());
+// System.out.println("srcSide:");
+// for (int i = 0; i < eStructure.getDelta().getSrcSide().size(); i++) {
+// Reference ref = eStructure.getDelta().getSrcSide().get(i);
+// if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) {
+// System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")");
+// }
+// }
+// System.out.println("dstSide:");
+// for (int i = 0; i < eStructure.getDelta().getDstSide().size(); i++) {
+// Reference ref = eStructure.getDelta().getDstSide().get(i);
+// if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) {
+// System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")");
+// }
+// }
+// System.out.println("overCoordinator:");
+// MethodExecution parent = coordinator.getParent();
+// while (parent != null) {
+// System.out.println("\t" + parent.getSignature());
+// parent = parent.getParent();
+// }
+//}
+// return eStructure;
+// }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/ExtractedStructure.java b/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/ExtractedStructure.java
new file mode 100644
index 0000000..6e47f75
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/ExtractedStructure.java
@@ -0,0 +1,68 @@
+package org.ntlab.deltaExtractor;
+
+import org.ntlab.trace.MethodExecution;
+import org.ntlab.trace.Reference;
+
+
+public class ExtractedStructure {
+
+ private Delta delta = new Delta();
+ private MethodExecution coordinator = null;
+ private MethodExecution parent = null;
+ private MethodExecution creationCallTree;
+
+ public Delta getDelta() {
+ return delta;
+ }
+
+ public MethodExecution getCoordinator() {
+ return coordinator;
+ }
+
+ /**
+ * ������ ������ɍ폜���邱��
+ * @param coordinator
+ */
+ public void setCoordinator(MethodExecution coordinator) {
+ this.coordinator = coordinator;
+ }
+
+ public void createParent(MethodExecution methodExecution) {
+ coordinator = methodExecution;
+ parent = null;
+ }
+
+// public void addParent(MethodExecution callTree) {
+// if (parent == null)
+// coordinator.addChild(parent = callTree);
+// else
+// parent.addChild(parent = callTree);
+// }
+//
+// public void addChild(MethodExecution callTree) {
+// if (parent == null)
+// coordinator.addChild(callTree);
+// else
+// parent.addChild(callTree);
+// }
+//
+ public void addSrcSide(Reference reference) {
+ delta.addSrcSide(reference);
+ }
+
+ public void addDstSide(Reference reference) {
+ delta.addDstSide(reference);
+ }
+
+ public void changeParent() {
+ }
+
+ public void setCreationMethodExecution(MethodExecution callTree) {
+ creationCallTree = callTree;
+ }
+
+ public MethodExecution getCreationCallTree() {
+ return creationCallTree;
+ }
+
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/Test.java b/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/Test.java
new file mode 100644
index 0000000..f77e8dc
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/Test.java
@@ -0,0 +1,303 @@
+package org.ntlab.deltaExtractor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.ntlab.trace.MethodExecution;
+import org.ntlab.trace.ObjectReference;
+import org.ntlab.trace.Reference;
+import org.ntlab.trace.ThreadInstance;
+import org.ntlab.trace.Trace;
+import org.ntlab.trace.TraceJSON;
+import org.ntlab.trace.TracePoint;
+
+public class Test {
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ // TODO Auto-generated method stub
+ long time = System.nanoTime();
+// Trace trace = new TraceJSON("documents\\_worstCase.txt");
+// DeltaExtractor s = new DeltaExtractor(trace);
+// HashMap threads = trace.getAllThreads();
+// ThreadInstance thread = threads.values().iterator().next();
+// TracePoint tp = thread.getRoot().get(thread.getRoot().size() - 1).getExitPoint();
+// ExtractedStructure e = s.extract(new Reference(null, null, "worstCase.P", "worstCase.M"), tp);
+
+// Trace trace = new TraceJSON("documents\\_finalLocal.txt");
+// DeltaExtractor s = new DeltaExtractor(trace);
+// HashMap threads = trace.getAllThreads();
+// ThreadInstance thread = threads.values().iterator().next();
+// TracePoint tp = thread.getRoot().get(thread.getRoot().size() - 1).getExitPoint();
+// ExtractedStructure e = s.extract(new Reference(null, null, "finalLocal.Main$1Test", "finalLocal.Main$A"), tp);
+
+// Trace trace = new TraceJSON("documents\\_arraySample.txt");
+// DeltaExtractor s = new DeltaExtractor(trace);
+// HashMap threads = trace.getAllThreads();
+// ThreadInstance thread = threads.values().iterator().next();
+// TracePoint tp = thread.getRoot().get(thread.getRoot().size() - 1).getExitPoint();
+// ExtractedStructure e = s.extract(new Reference(null, null, "arraySample.D", "arraySample.C"), tp);
+
+ Trace trace = new TraceJSON("documents\\_threadSample.txt");
+ DeltaExtractor s = new DeltaExtractor(trace);
+ HashMap threads = trace.getAllThreads();
+ Iterator it = threads.values().iterator();
+ it.next();
+ it.next();
+ ThreadInstance thread = it.next();
+ TracePoint tp = thread.getRoot().get(thread.getRoot().size() - 1).getExitPoint();
+ ExtractedStructure e = s.extract(new Reference(null, null, "threadSample.D", "threadSample.C"), tp);
+
+ // DeltaExtractor s = new DeltaExtractor("documents\\finalLocal.txt");
+ // ExtractedStructure es = s.extract();
+ // s.extract("framework.RWT.RWTFrame3D",
+ // "fight3D.CharacterSelectContainer");
+// s.extract("framework.B", "application.SubC");
+ // s.extract("application.SubA", "framework.B");
+ // FrameworkUsage usage = extractor.extract("framework.B",
+ // "application.SubC");
+ // FrameworkUsage usage = extractor.extract("application.SubA",
+ // "framework.B");
+ // s.extract("framework.model3D.Object3D",
+ // "javax.media.j3d.TransformGroup");
+ // s.extract("fight3D.Character", "fight3D.WeaponModel");
+ // s.extract("test.E","test.C");
+// ExtractedStructure e = s.extract(new Reference("finalLocal.Main$1Test", "finalLocal.Main$A", null, null));
+
+// --------------- Eclipse Core ---------------
+// DeltaExtractor s = new DeltaExtractor("documents\\eclipse-Core.txt");
+// CallTree m = null;
+// ExtractedStructure e = null;
+// do {
+// if (m == null) {
+// m = s.getCallTreeBackwardly("public boolean java.util.HashSet.add(");
+// } else {
+// m = s.getCallTreeBackwardly("public boolean java.util.HashSet.add(", m.getStartLine() - 1);
+// }
+// if (m != null) {
+// ArrayList argments = m.getArguments();
+// System.out.println(m.getSignature() + ":" + argments.size());
+// for (int i = 0; i < argments.size(); i++) {
+// if (argments.get(i).getActualType().equals("org.eclipse.ui.internal.registry.ActionSetDescriptor")) {
+// e = s.extract(m, argments.get(i));
+// break;
+// }
+// }
+// }
+// } while (m != null);
+
+
+// --------------- Eclipse UI ---------------
+// DeltaExtractor s = new DeltaExtractor("documents\\eclipse-ContextMenu.txt");
+// CallTree m = null;
+// ExtractedStructure e = null;
+// do {
+// if (m == null) {
+// m = s.getCallTreeBackwardly("private void org.eclipse.jface.action.ContributionManager.addToGroup(");
+// } else {
+// m = s.getCallTreeBackwardly("private void org.eclipse.jface.action.ContributionManager.addToGroup(", m.getStartLine() - 1);
+// }
+// if (m != null) {
+// ArrayList argments = m.getArguments();
+// System.out.println(m.getSignature() + ":" + argments.size());
+// for (int i = 0; i < argments.size(); i++) {
+// if (argments.get(i).getActualType().equals("org.eclipse.ui.internal.PluginActionCoolBarContributionItem")) {
+// e = s.extract(m, argments.get(i));
+// break;
+// }
+// }
+// }
+// } while (m != null);
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ // //
+ // ICSME2015���e�p //
+ // //
+ ///////////////////////////////////////////////////////////////////////////////////
+
+// // --------------- Eclipse (2014/12/6 �v���O�����������؎��� �ۑ�1, �ȉ���1��ڂ̃f���^) ---------------
+// DeltaExtractor s = new DeltaExtractor("documents\\eclipse-Console2.txt");
+// ExtractedStructure e = null;
+// do {
+// System.out.println(System.nanoTime() - time);
+// if (e == null) {
+// e = s.extract(new Reference(null, null, "org.eclipse.jface.action.ActionContributionItem",
+// "org.eclipse.ui.console.actions.ClearOutputAction"));
+// } else {
+// e = s.extract(new Reference(null, null, "org.eclipse.jface.action.ActionContributionItem",
+// "org.eclipse.ui.console.actions.ClearOutputAction"), e.getCreationCallTree().getEntryPoint());
+// }
+// } while (e != null);
+
+
+// --------------- Eclipse (2014/12/19-20 �v���O�����������؎��� �ۑ�2, �ȉ���2��ڂ̃f���^) ---------------
+// DeltaExtractor s = new DeltaExtractor("documents\\eclipse-JavaEditor.txt");
+// ExtractedStructure e = null;
+// do {
+// System.out.println(System.nanoTime() - time);
+// if (e == null) {
+// e = s.extract(new Reference(null, null, "org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor$AdaptedSourceViewer",
+// "org.eclipse.jface.text.contentassist.ContentAssistant"));
+// } else {
+// e = s.extract(new Reference(null, null, "org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor$AdaptedSourceViewer",
+// "org.eclipse.jface.text.contentassist.ContentAssistant"), e.getCreationCallTree().getEntryPoint());
+// }
+// } while (e != null);
+
+
+// // --------------- ArgoUML (2014/12/19-20 �v���O�����������؎��� �ۑ�3, �ȉ���1��ڂ̃f���^) ---------------
+// DeltaExtractor s = new DeltaExtractor("documents\\ArgoUML-3.txt");
+// MethodExecution m = null;
+// ExtractedStructure e = null;
+// do {
+// System.out.println(System.nanoTime() - time);
+// if (m == null) {
+// m = s.getLastMethodExecution("protected void org.tigris.gef.base.SelectionManager.addFig(");
+// } else {
+// m = s.getLastMethodExecution("protected void org.tigris.gef.base.SelectionManager.addFig(", m.getEntryPoint());
+// }
+// if (m != null) {
+// ArrayList argments = m.getArguments();
+// System.out.println(m.getSignature() + ":" + argments.size());
+// for (int i = 0; i < argments.size(); i++) {
+// if (argments.get(i).getActualType().equals("org.argouml.uml.diagram.static_structure.ui.FigClass")) {
+// e = s.extract(m.getEntryPoint(), argments.get(i));
+// break;
+// }
+// }
+// }
+// } while (m != null);
+
+
+// // --------------- ArgoUML (2014/12/19-20 �v���O�����������؎��� �ۑ�4, �ȉ���3��ڂ̃f���^) ---------------
+// DeltaExtractor s = new DeltaExtractor("documents\\ArgoUML-3.txt");
+// MethodExecution m = null;
+// ExtractedStructure e = null;
+// do {
+// System.out.println(System.nanoTime() - time);
+// if (m == null) {
+// m = s.getLastMethodExecution("public abstract interface boolean java.util.List.add(");
+// } else {
+// m = s.getLastMethodExecution("public abstract interface boolean java.util.List.add(", m.getEntryPoint());
+// }
+// if (m != null) {
+// ArrayList argments = m.getArguments();
+// System.out.println(m.getSignature() + ":" + argments.size());
+// for (int i = 0; i < argments.size(); i++) {
+// if (argments.get(i).getActualType().equals("org.argouml.uml.diagram.static_structure.ui.FigClass")) {
+// e = s.extract(m.getEntryPoint(), argments.get(i));
+// break;
+// }
+// }
+// }
+// } while (m != null);
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ // //
+ // SANER2016���e�p //
+ // //
+ ///////////////////////////////////////////////////////////////////////////////////
+
+ // --------------- Eclipse SWT (2015/10/31 �A�[�L�e�N�`���������؎��� �ۑ�1) ---------------
+ // ��1(1st�f���^), �ȉ��̃f���^
+// DeltaExtractor s = new DeltaExtractor("documents\\eclipse-Console2.txt");
+// MethodExecution m = null;
+// ExtractedStructure e = null;
+// System.out.println(System.nanoTime() - time);
+// do {
+// if (m == null) {
+// m = s.getLastMethodExecution("public void org.eclipse.jface.action.Action.runWithEvent(");
+// } else {
+// TracePoint nextTp = m.getEntryPoint();
+// nextTp.stepBackOver();
+// m = s.getLastMethodExecution("public void org.eclipse.jface.action.Action.runWithEvent(", nextTp);
+// }
+// if (m != null) {
+// ArrayList argments = m.getArguments();
+// for (int i = 0; i < argments.size(); i++) {
+// if (argments.get(i).getActualType().equals("org.eclipse.swt.widgets.Event")) {
+// System.out.println(System.nanoTime() - time);
+// e = s.extract(m.getEntryPoint(), argments.get(i));
+// break;
+// }
+// }
+// }
+// } while (e == null);
+// System.out.println(System.nanoTime() - time);
+// System.out.println("//////////////////////////////////");
+//
+// // ��2,3(2nd�f���^), ��1�̑���, �ȉ��̃f���^
+// Reference nextTarget = e.getDelta().getSrcSide().get(6);
+// e = s.extract(nextTarget, e.getCoordinator().getEntryPoint());
+
+
+// // --------------- Eclipse JDT (2015/10/31 �A�[�L�e�N�`���������؎��� �ۑ�2) ---------------
+// // ��1,2(1st�f���^), �ȉ��̃f���^(���o�Ƃ��Ă�2��)
+// DeltaExtractor s = new DeltaExtractor("documents\\eclipse-Debug1.txt");
+// MethodExecution m = null;
+//
+// System.out.println(System.nanoTime() - time);
+// ExtractedStructure e = null;
+// do {
+// if (m == null) {
+// m = s.getLastMethodExecution("public boolean org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint.handleBreakpointEvent(");
+// } else {
+// TracePoint nextTp = m.getEntryPoint();
+// nextTp.stepBackOver();
+// m = s.getLastMethodExecution("public boolean org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint.handleBreakpointEvent(", nextTp);
+// }
+// if (m != null) {
+// ArrayList argments = m.getArguments();
+// for (int i = 0; i < argments.size(); i++) {
+// if (argments.get(i).getActualType().equals("org.eclipse.jdi.internal.event.BreakpointEventImpl")) {
+// System.out.println(System.nanoTime() - time);
+// e = s.extract(m.getEntryPoint(), argments.get(i));
+// break;
+// }
+// }
+// }
+// } while (e == null);
+// Reference nextTarget = e.getDelta().getDstSide().get(3); // EventDispatcher$1 -> EventSetImpl
+// e = s.extract(nextTarget, m.getEntryPoint());
+// System.out.println(System.nanoTime() - time);
+// System.out.println("//////////////////////////////////");
+//
+// // ��3(2nd�f���^), �ȉ��̃f���^
+// MethodExecution m2 = e.getCoordinator().getChildren().get(21);
+// e = s.extract(m2.getExitPoint(), new ObjectReference("859038530", "org.eclipse.jdi.internal.jdwp.JdwpCommandPacket"));
+// System.out.println(System.nanoTime() - time);
+// System.out.println("//////////////////////////////////");
+//
+//
+// // ��4(3rd�f���^), �ȉ��̃f���^
+// m = e.getCoordinator().getChildren().get(0).getChildren().get(1).getChildren().get(4);
+// Reference lastTarget = new Reference(e.getDelta().getDstSide().get(1).getSrcObject(), e.getDelta().getDstSide().get(0).getDstObject());
+// lastTarget.setCollection(true);
+// e = s.extract(lastTarget, m.getExitPoint());
+
+
+// // --------------- ArgoUML + GEF (2014/12/19-20 �v���O�����������؎��� �ۑ�3, �ȉ��̃f���^) ---------------
+// DeltaExtractor s = new DeltaExtractor("documents\\ArgoUML-3.txt");
+// MethodExecution m = null;
+// ExtractedStructure e = null;
+// System.out.println(System.nanoTime() - time);
+// m = s.getLastMethodExecution("public void org.argouml.uml.diagram.ui.ActionRemoveFromDiagram.actionPerformed(");
+//// m = s.getLastMethodExecution("public java.util.Vector org.tigris.gef.base.SelectionManager.getFigs(");
+// if (m != null) {
+// System.out.println(System.nanoTime() - time);
+// Reference r = new Reference(null, null, "java.util.ArrayList", "org.argouml.uml.diagram.static_structure.ui.SelectionClass");
+// r.setCollection(true);
+// e = s.extract(r, m.getEntryPoint());
+// }
+
+
+ System.out.println(System.nanoTime() - time);
+ System.out.println("//////////////////////////////////");
+// // s.extractArg(e.getCoodinator(), 123456789);
+// // s.getCallHistory(e.getCoodinator());
+
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/featureLocator/ScenarioBasedProbabilisticRanking.java b/org.ntlab.traceAnalyzer/src/org/ntlab/featureLocator/ScenarioBasedProbabilisticRanking.java
new file mode 100644
index 0000000..c7692ad
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/featureLocator/ScenarioBasedProbabilisticRanking.java
@@ -0,0 +1,107 @@
+package org.ntlab.featureLocator;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.ntlab.trace.MethodExecution;
+import org.ntlab.trace.Trace;
+
+public class ScenarioBasedProbabilisticRanking {
+
+ public static void main(String[] args) {
+ Trace positiveTraces[] = new Trace[4];
+ Trace negativeTraces[] = new Trace[4];
+ long starts[] = new long[4];
+ long ends[] = new long[4];
+ positiveTraces[0] = new Trace("documents\\jEdit1578785TC1-2.trace");
+ positiveTraces[1] = new Trace("documents\\jEdit1578785TC2-2.trace");
+ positiveTraces[2] = new Trace("documents\\jEdit1578785TC3-2.trace");
+ positiveTraces[3] = new Trace("documents\\jEdit1578785TC4-2.trace");
+ negativeTraces[0] = new Trace("documents\\jEdit1578785TC1-1.trace");
+ negativeTraces[1] = new Trace("documents\\jEdit1578785TC2-1.trace");
+ negativeTraces[2] = new Trace("documents\\jEdit1578785TC3-1.trace");
+ negativeTraces[3] = new Trace("documents\\jEdit1578785TC4-1.trace");
+ starts[0] = 53110313578062L;
+ ends[0] = 53114687756752L;
+ starts[1] = 53656181043072L;
+ ends[1] = 53662323812706L;
+ starts[2] = 56259479424073L;
+ ends[2] = 56263910205683L;
+ starts[3] = 56003167357539L;
+ ends[3] = 56009513891913L;
+ HashMap totalExecutionsInPositiveTraces = new HashMap<>();
+ HashMap totalExecutionsInNegativeTraces = new HashMap<>();
+ HashMap totalExecutionsInsideMark = new HashMap<>();
+ HashMap totalExecutionsOutsideMark = new HashMap<>();
+ long insideMarkExecutions = 0L;
+ long outsideMarkExecutions = 0L;
+ for (int n = 0; n < positiveTraces.length; n++) {
+ HashMap> positiveExecutions = positiveTraces[n].getAllMethodExecutions();
+ for (String method: positiveExecutions.keySet()) {
+ int positive = positiveExecutions.get(method).size();
+ if (totalExecutionsInPositiveTraces.get(method) == null) {
+ totalExecutionsInPositiveTraces.put(method, positive);
+ } else {
+ totalExecutionsInPositiveTraces.put(method, positive + totalExecutionsInPositiveTraces.get(method));
+ }
+ }
+ HashMap> negativeExecutions = negativeTraces[n].getAllMethodExecutions();
+ for (String method: negativeExecutions.keySet()) {
+ int negatives = negativeExecutions.get(method).size();
+ if (totalExecutionsInNegativeTraces.get(method) == null) {
+ totalExecutionsInNegativeTraces.put(method, negatives);
+ totalExecutionsOutsideMark.put(method, negatives);
+ } else {
+ totalExecutionsInNegativeTraces.put(method, negatives + totalExecutionsInNegativeTraces.get(method));
+ totalExecutionsOutsideMark.put(method, negatives + totalExecutionsOutsideMark.get(method));
+ }
+ outsideMarkExecutions += negatives;
+ }
+ HashMap> positiveMarkedExecutions = positiveTraces[n].getMarkedMethodExecutions(starts[n], ends[n]);
+ for (String method: positiveMarkedExecutions.keySet()) {
+ int marked = positiveMarkedExecutions.get(method).size();
+ if (totalExecutionsInsideMark.get(method) == null) {
+ totalExecutionsInsideMark.put(method, marked);
+ } else {
+ totalExecutionsInsideMark.put(method, marked + totalExecutionsInsideMark.get(method));
+ }
+ insideMarkExecutions += marked;
+ }
+ HashMap> positiveUnmarkedExecutions = positiveTraces[n].getUnmarkedMethodExecutions(starts[n], ends[n]);
+ for (String method: positiveUnmarkedExecutions.keySet()) {
+ int unmarked = positiveUnmarkedExecutions.get(method).size();
+ if (totalExecutionsOutsideMark.get(method) == null) {
+ totalExecutionsOutsideMark.put(method, unmarked);
+ } else {
+ totalExecutionsOutsideMark.put(method, unmarked + totalExecutionsOutsideMark.get(method));
+ }
+ outsideMarkExecutions += unmarked;
+ }
+ }
+
+ // An approach to feature location in distributed systems (Edwards��, Journal of Systems and Software 2006)
+ System.out.println("=== An approach to feature location in distributed systems ===");
+ HashMap relevanceIndexes = new HashMap<>();
+ for (String method: totalExecutionsInPositiveTraces.keySet()) {
+ if (totalExecutionsInNegativeTraces.get(method) == null) continue;
+ double positive = (double)totalExecutionsInPositiveTraces.get(method);
+ double negative = (double)totalExecutionsInNegativeTraces.get(method);
+ double relevanceIndex = positive / (positive + negative);
+ relevanceIndexes.put(method, relevanceIndex);
+ System.out.println(method + ":" + relevanceIndex);
+ }
+
+ // Scenario-Based Probabilistic Ranking (SPR, Antoniol��, ICSM 2006)
+ System.out.println("=== Scenario-Based Probabilistic Ranking ===");
+ HashMap relevanceIndexesSPR = new HashMap<>();
+ for (String method: totalExecutionsInsideMark.keySet()) {
+ if (totalExecutionsOutsideMark.get(method) == null) continue;
+ double mark = (double)totalExecutionsInsideMark.get(method) / (double)insideMarkExecutions;
+ double unmark = (double)totalExecutionsOutsideMark.get(method) / (double)outsideMarkExecutions;
+ double relevanceIndexSPR = mark / (mark + unmark);
+ relevanceIndexesSPR.put(method, relevanceIndexSPR);
+ System.out.println(method + ":" + relevanceIndexSPR);
+ }
+ }
+
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/featureLocator/SoftwareReconnaissance.java b/org.ntlab.traceAnalyzer/src/org/ntlab/featureLocator/SoftwareReconnaissance.java
new file mode 100644
index 0000000..63ddaa8
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/featureLocator/SoftwareReconnaissance.java
@@ -0,0 +1,54 @@
+package org.ntlab.featureLocator;
+
+import java.util.HashSet;
+
+import org.ntlab.trace.Trace;
+
+public class SoftwareReconnaissance {
+
+ public static void main(String[] args) {
+ Trace positiveTraces[] = new Trace[4];
+ Trace negativeTraces[] = new Trace[4];
+ long starts[] = new long[4];
+ long ends[] = new long[4];
+ positiveTraces[0] = new Trace("documents\\jEdit1578785TC1-2.trace");
+ positiveTraces[1] = new Trace("documents\\jEdit1578785TC2-2.trace");
+ positiveTraces[2] = new Trace("documents\\jEdit1578785TC3-2.trace");
+ positiveTraces[3] = new Trace("documents\\jEdit1578785TC4-2.trace");
+ negativeTraces[0] = new Trace("documents\\jEdit1578785TC1-1.trace");
+ negativeTraces[1] = new Trace("documents\\jEdit1578785TC2-1.trace");
+ negativeTraces[2] = new Trace("documents\\jEdit1578785TC3-1.trace");
+ negativeTraces[3] = new Trace("documents\\jEdit1578785TC4-1.trace");
+ starts[0] = 53110313578062L;
+ ends[0] = 53114687756752L;
+ starts[1] = 53656181043072L;
+ ends[1] = 53662323812706L;
+ starts[2] = 56259479424073L;
+ ends[2] = 56263910205683L;
+ starts[3] = 56003167357539L;
+ ends[3] = 56009513891913L;
+
+ HashSet positiveMethods = positiveTraces[0].getAllMethodSignatures();
+ HashSet negativeMethods = negativeTraces[0].getAllMethodSignatures();
+ System.out.println("=== Software Reconnaissance ===");
+ positiveMethods.removeAll(negativeMethods);
+ for (String method: positiveMethods) {
+ System.out.println(method);
+ }
+ System.out.println("=== Marked Software Reconnaissance ===");
+ HashSet markedMethods = positiveTraces[0].getMarkedMethodSignatures(starts[0], ends[0]);
+ HashSet unmarkedMethods = negativeTraces[0].getAllMethodSignatures();
+ unmarkedMethods.addAll(negativeTraces[1].getAllMethodSignatures());
+ unmarkedMethods.addAll(negativeTraces[2].getAllMethodSignatures());
+ unmarkedMethods.addAll(negativeTraces[3].getAllMethodSignatures());
+ unmarkedMethods.addAll(positiveTraces[0].getUnmarkedMethodSignatures(starts[0], ends[0]));
+ unmarkedMethods.addAll(positiveTraces[1].getUnmarkedMethodSignatures(starts[1], ends[1]));
+ unmarkedMethods.addAll(positiveTraces[2].getUnmarkedMethodSignatures(starts[2], ends[2]));
+ unmarkedMethods.addAll(positiveTraces[3].getUnmarkedMethodSignatures(starts[3], ends[3]));
+ markedMethods.removeAll(unmarkedMethods);
+ for (String method: markedMethods) {
+ System.out.println(method);
+ }
+ }
+
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ArrayAccess.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ArrayAccess.java
new file mode 100644
index 0000000..1e1e903
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ArrayAccess.java
@@ -0,0 +1,39 @@
+package org.ntlab.trace;
+
+public class ArrayAccess extends Statement {
+ private String arrayClassName;
+ private String arrayObjectId;
+ private int index;
+ private String valueClassName;
+ private String valueObjectId;
+
+ public ArrayAccess(String arrayClassName, String arrayObjectId, int index, String valueClassName, String valueObjectId,
+ int lineNo, String threadNo, long timeStamp) {
+ super(lineNo, threadNo, timeStamp);
+ this.arrayClassName = arrayClassName;
+ this.arrayObjectId = arrayObjectId;
+ this.index = index;
+ this.valueClassName = valueClassName;
+ this.valueObjectId = valueObjectId;
+ }
+
+ public String getArrayClassName() {
+ return arrayClassName;
+ }
+
+ public String getArrayObjectId() {
+ return arrayObjectId;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ public String getValueClassName() {
+ return valueClassName;
+ }
+
+ public String getValueObjectId() {
+ return valueObjectId;
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ArrayCreate.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ArrayCreate.java
new file mode 100644
index 0000000..18a6acd
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ArrayCreate.java
@@ -0,0 +1,26 @@
+package org.ntlab.trace;
+
+public class ArrayCreate extends Statement {
+ private String arrayClassName;
+ private String arrayObjectId;
+ private int dimension;
+
+ public ArrayCreate(String arrayClassName, String arrayObjectId, int dimension, int lineNo, String threadNo, long timeStamp) {
+ super(lineNo, threadNo, timeStamp);
+ this.arrayClassName = arrayClassName;
+ this.arrayObjectId = arrayObjectId;
+ this.dimension = dimension;
+ }
+
+ public String getArrayClassName() {
+ return arrayClassName;
+ }
+
+ public String getArrayObjectId() {
+ return arrayObjectId;
+ }
+
+ public int getDimension() {
+ return dimension;
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ArrayUpdate.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ArrayUpdate.java
new file mode 100644
index 0000000..f447718
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ArrayUpdate.java
@@ -0,0 +1,39 @@
+package org.ntlab.trace;
+
+public class ArrayUpdate extends Statement {
+ private String arrayClassName;
+ private String arrayObjectId;
+ private int index;
+ private String valueClassName;
+ private String valueObjectId;
+
+ public ArrayUpdate(String arrayClassName, String arrayObjectId, int index, String valueClassName, String valueObjectId,
+ int lineNo, String threadNo, long timeStamp) {
+ super(lineNo, threadNo, timeStamp);
+ this.arrayClassName = arrayClassName;
+ this.arrayObjectId = arrayObjectId;
+ this.index = index;
+ this.valueClassName = valueClassName;
+ this.valueObjectId = valueObjectId;
+ }
+
+ public String getArrayClassName() {
+ return arrayClassName;
+ }
+
+ public String getArrayObjectId() {
+ return arrayObjectId;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ public String getValueClassName() {
+ return valueClassName;
+ }
+
+ public String getValueObjectId() {
+ return valueObjectId;
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/AugmentationInfo.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/AugmentationInfo.java
new file mode 100644
index 0000000..55bfbbe
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/AugmentationInfo.java
@@ -0,0 +1,5 @@
+package org.ntlab.trace;
+
+abstract public class AugmentationInfo {
+
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/BlockEnter.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/BlockEnter.java
new file mode 100644
index 0000000..0d4ccf5
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/BlockEnter.java
@@ -0,0 +1,20 @@
+package org.ntlab.trace;
+
+public class BlockEnter extends Statement {
+ private int blockId;
+ private int incomings;
+
+ public BlockEnter(int blockId, int incomings, int lineNo, String threadNo, long timeStamp) {
+ super(lineNo, threadNo, timeStamp);
+ this.blockId = blockId;
+ this.incomings = incomings;
+ }
+
+ public int getBlockId() {
+ return blockId;
+ }
+
+ public int getIncomings() {
+ return incomings;
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ClassInfo.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ClassInfo.java
new file mode 100644
index 0000000..fe1f6fc
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ClassInfo.java
@@ -0,0 +1,25 @@
+package org.ntlab.trace;
+
+public class ClassInfo {
+ private String name;
+ private String path;
+ private String loaderPath;
+
+ public ClassInfo(String name, String path, String loaderPath) {
+ this.name = name;
+ this.path = path;
+ this.loaderPath = loaderPath;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public String getLoaderPath() {
+ return loaderPath;
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/FieldAccess.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/FieldAccess.java
new file mode 100644
index 0000000..02e6e54
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/FieldAccess.java
@@ -0,0 +1,62 @@
+package org.ntlab.trace;
+
+public class FieldAccess extends Statement {
+ private String containerClassName;
+ private String containerObjId;
+ private String valueClassName;
+ private String valueObjId;
+ protected String thisClassName;
+ protected String thisObjId;
+
+ public FieldAccess(String valueClassName, String valueObjId, String containerClassName,
+ String containerObjId, String thisClassName, String thisObjId,
+ int lineNo, String threadNo) {
+ super(lineNo, threadNo);
+ this.containerClassName = containerClassName;
+ this.containerObjId = containerObjId;
+ this.valueClassName = valueClassName;
+ this.valueObjId = valueObjId;
+ this.thisClassName = thisClassName;
+ this.thisObjId = thisObjId;
+ }
+
+ public FieldAccess(String valueClassName, String valueObjId, String containerClassName,
+ String containerObjId, String thisClassName, String thisObjId,
+ int lineNo, String threadNo, long timeStamp) {
+ super(lineNo, threadNo, timeStamp);
+ this.containerClassName = containerClassName;
+ this.containerObjId = containerObjId;
+ this.valueClassName = valueClassName;
+ this.valueObjId = valueObjId;
+ this.thisClassName = thisClassName;
+ this.thisObjId = thisObjId;
+ }
+
+ public String getContainerClassName() {
+ return containerClassName;
+ }
+
+ public String getContainerObjId() {
+ return containerObjId;
+ }
+
+ public String getValueClassName() {
+ return valueClassName;
+ }
+
+ public String getValueObjId() {
+ return valueObjId;
+ }
+
+ public String getThisClassName() {
+ return thisClassName;
+ }
+
+ public String getThisObjId() {
+ return thisObjId;
+ }
+
+ public Reference getReference() {
+ return new Reference(containerObjId, valueObjId, containerClassName, valueClassName);
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/FieldUpdate.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/FieldUpdate.java
new file mode 100644
index 0000000..b7d8443
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/FieldUpdate.java
@@ -0,0 +1,46 @@
+package org.ntlab.trace;
+
+public class FieldUpdate extends Statement {
+ private String containerClassName;
+ private String containerObjId;
+ private String valueClassName;
+ private String valueObjId;
+
+ public FieldUpdate(String valueClassName, String valueObjId, String containerClassName, String containerObjId,
+ int lineNo, String threadNo) {
+ super(lineNo, threadNo);
+ this.containerClassName = containerClassName;
+ this.containerObjId = containerObjId;
+ this.valueClassName = valueClassName;
+ this.valueObjId = valueObjId;
+ }
+
+ public FieldUpdate(String valueClassName, String valueObjId, String containerClassName, String containerObjId,
+ int lineNo, String threadNo, long timeStamp) {
+ super(lineNo, threadNo, timeStamp);
+ this.containerClassName = containerClassName;
+ this.containerObjId = containerObjId;
+ this.valueClassName = valueClassName;
+ this.valueObjId = valueObjId;
+ }
+
+ public String getContainerClassName() {
+ return containerClassName;
+ }
+
+ public String getContainerObjId() {
+ return containerObjId;
+ }
+
+ public String getValueClassName() {
+ return valueClassName;
+ }
+
+ public String getValueObjId() {
+ return valueObjId;
+ }
+
+ public Reference getReference() {
+ return new Reference(containerObjId, valueObjId, containerClassName, valueClassName);
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/IBoundaryChecker.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/IBoundaryChecker.java
new file mode 100644
index 0000000..f5860a1
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/IBoundaryChecker.java
@@ -0,0 +1,5 @@
+package org.ntlab.trace;
+
+public interface IBoundaryChecker {
+ abstract public boolean withinBoundary(String methodSignature);
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/IMethodExecutionVisitor.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/IMethodExecutionVisitor.java
new file mode 100644
index 0000000..54d368f
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/IMethodExecutionVisitor.java
@@ -0,0 +1,10 @@
+package org.ntlab.trace;
+
+import java.util.ArrayList;
+
+public interface IMethodExecutionVisitor {
+ abstract public boolean preVisitThread(ThreadInstance thread);
+ abstract public boolean postVisitThread(ThreadInstance thread);
+ abstract public boolean preVisitMethodExecution(MethodExecution methodExecution);
+ abstract public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children);
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/IStatementVisitor.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/IStatementVisitor.java
new file mode 100644
index 0000000..aac4f2a
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/IStatementVisitor.java
@@ -0,0 +1,6 @@
+package org.ntlab.trace;
+
+public interface IStatementVisitor {
+ abstract public boolean preVisitStatement(Statement statement);
+ abstract public boolean postVisitStatement(Statement statement);
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/MethodExecution.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/MethodExecution.java
new file mode 100644
index 0000000..3a9387c
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/MethodExecution.java
@@ -0,0 +1,263 @@
+package org.ntlab.trace;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+
+public class MethodExecution {
+ private String signature;
+ private String callerSideSignature;
+ private String thisClassName;
+ private String thisObjId;
+ private ArrayList arguments;
+ private ObjectReference returnValue = null;
+ private boolean isConstructor;
+ private boolean isStatic;
+ private boolean isCollectionType;
+ private ArrayList statements = new ArrayList();
+ private ArrayList children = new ArrayList();
+ private MethodExecution callerMethodExecution = null;
+ private int callerStatementExecution = -1;
+ private boolean isTerminated = false;
+ private AugmentationInfo augmentation = null;
+ private long entryTime = 0L;
+ private long exitTime = 0L;
+
+ public MethodExecution(String signature, String callerSideSignature,
+ String thisClassName, String thisObjId, boolean isConstructor,
+ boolean isStatic, long enterTime) {
+ this.signature = signature;
+ this.callerSideSignature = callerSideSignature;
+ this.thisClassName = thisClassName;
+ this.thisObjId = thisObjId;
+ this.isConstructor = isConstructor;
+ this.isStatic = isStatic;
+ this.isCollectionType = false;
+ this.isTerminated = false;
+ this.entryTime = enterTime;
+ }
+
+ public void setArguments(ArrayList arguments) {
+ this.arguments = arguments;
+ }
+
+ public void setThisObjeId(String thisObjId) {
+ this.thisObjId = thisObjId;
+ }
+
+ public void setReturnValue(ObjectReference returnValue) {
+ this.returnValue = returnValue;
+ }
+
+ public void setCollectionType(boolean isCollectionType) {
+ this.isCollectionType = isCollectionType;
+ }
+
+ public void setTerminated(boolean isTerminated) {
+ this.isTerminated = isTerminated;
+ }
+
+ public String getDeclaringClassName() {
+ return Trace.getDeclaringType(signature, isConstructor);
+ }
+
+ public String getSignature() {
+ return signature;
+ }
+
+ public String getCallerSideSignature() {
+ return callerSideSignature;
+ }
+
+ public String getThisClassName() {
+ return thisClassName;
+ }
+
+ public String getThisObjId() {
+ if (isStatic) return Trace.getNull();
+ return thisObjId;
+ }
+
+ public ArrayList getArguments() {
+ if (arguments == null) arguments = new ArrayList();
+ return arguments;
+ }
+
+ public ObjectReference getReturnValue() {
+ return returnValue;
+ }
+
+ public boolean isConstructor() {
+ return isConstructor;
+ }
+
+ public boolean isStatic() {
+ return isStatic;
+ }
+
+ public boolean isCollectionType() {
+ return isCollectionType;
+ }
+
+ public boolean isTerminated() {
+ return isTerminated;
+ }
+
+ public long getEntryTime() {
+ return entryTime;
+ }
+
+ public long getExitTime() {
+ return exitTime;
+ }
+
+ public void setExitTime(long exitTime) {
+ this.exitTime = exitTime;
+ }
+
+ public void addStatement(Statement statement) {
+ statements.add(statement);
+ if (statement instanceof MethodInvocation) {
+ children.add(((MethodInvocation)statement).getCalledMethodExecution());
+ }
+ }
+
+ public ArrayList getStatements() {
+ return statements;
+ }
+
+ public ArrayList getChildren() {
+ return children;
+ }
+
+ public void setCaller(MethodExecution callerMethodExecution, int callerStatementExecution) {
+ this.callerMethodExecution = callerMethodExecution;
+ this.callerStatementExecution = callerStatementExecution;
+ }
+
+ public MethodExecution getParent() {
+ return callerMethodExecution;
+ }
+
+ public TracePoint getEntryPoint() {
+ return new TracePoint(this, 0);
+ }
+
+ public TracePoint getExitPoint() {
+ return new TracePoint(this, statements.size() - 1);
+ }
+
+ public TracePoint getExitOutPoint() {
+ return new TracePoint(this, statements.size());
+ }
+
+ public MethodExecution getCallerMethodExecution() {
+ return callerMethodExecution;
+ }
+
+ public int getCallerStatementExecution() {
+ return callerStatementExecution;
+ }
+
+ public TracePoint getCallerTracePoint() {
+ if (callerMethodExecution == null) return null;
+ return new TracePoint(callerMethodExecution, callerStatementExecution);
+ }
+
+ /**
+ * ���̃��\�b�h���s����т��̑S�Ăяo������Ăяo���̒��ŋt�����ɒT������(�������Avisitor �� true ��Ԃ��܂�)
+ * @param visitor �r�W�^�[
+ * @return�@true -- �T���𒆒f����, false -- �Ō�܂ŒT������
+ */
+ public boolean traverseMethodExecutionsBackward(IMethodExecutionVisitor visitor) {
+ if (visitor.preVisitMethodExecution(this)) return true;
+ ArrayList calledMethodExecutions = getChildren();
+ for (int i = calledMethodExecutions.size() - 1; i >= 0; i--) {
+ MethodExecution child = calledMethodExecutions.get(i);
+ if (child.traverseMethodExecutionsBackward(visitor)) return true;
+ }
+ if (visitor.postVisitMethodExecution(this, null)) return true;
+ return false;
+ }
+
+ public void traverseMarkedMethodExecutions(IMethodExecutionVisitor visitor, long markStart, long markEnd) {
+ if (entryTime <= markEnd) {
+ if (entryTime >= markStart) {
+ ArrayList markedChildren = new ArrayList();
+ visitor.preVisitMethodExecution(this);
+ for (int i = 0; i < children.size(); i++) {
+ MethodExecution child = children.get(i);
+ if (child.getEntryTime() <= markEnd) {
+ child.traverseMarkedMethodExecutions(visitor, markStart, markEnd);
+ markedChildren.add(child);
+ } else {
+ break;
+ }
+ }
+ visitor.postVisitMethodExecution(this, markedChildren);
+ } else {
+ for (int i = 0; i < children.size(); i++) {
+ MethodExecution child = children.get(i);
+ if (child.getEntryTime() <= markEnd) {
+ child.traverseMarkedMethodExecutions(visitor, markStart, markEnd);
+ }
+ }
+ }
+ }
+ }
+
+ public void getMarkedMethodSignatures(HashSet signatures, long markStart, long markEnd) {
+ if (entryTime <= markEnd) {
+ if (entryTime >= markStart) {
+ signatures.add(getSignature());
+ }
+ for (int i = 0; i < children.size(); i++) {
+ MethodExecution child = children.get(i);
+ child.getMarkedMethodSignatures(signatures, markStart, markEnd);
+ }
+ }
+ }
+
+ public void getUnmarkedMethodSignatures(HashSet signatures, long markStart, long markEnd) {
+ if (entryTime < markStart || entryTime > markEnd) {
+ signatures.add(getSignature());
+ for (int i = 0; i < children.size(); i++) {
+ MethodExecution child = children.get(i);
+ child.getUnmarkedMethodSignatures(signatures, markStart, markEnd);
+ }
+ } else {
+ for (int i = 0; i < children.size(); i++) {
+ MethodExecution child = children.get(i);
+ child.getUnmarkedMethodSignatures(signatures, markStart, markEnd);
+ }
+ }
+ }
+
+ public void getUnmarkedMethodExecutions(HashMap> allExecutions, long markStart, long markEnd) {
+ if (entryTime < markStart || entryTime > markEnd) {
+ ArrayList executions = allExecutions.get(getSignature());
+ if (executions == null) {
+ executions = new ArrayList<>();
+ allExecutions.put(getSignature(), executions);
+ }
+ executions.add(this);
+ for (int i = 0; i < children.size(); i++) {
+ MethodExecution child = children.get(i);
+ child.getUnmarkedMethodExecutions(allExecutions, markStart, markEnd);
+ }
+ } else {
+ for (int i = 0; i < children.size(); i++) {
+ MethodExecution child = children.get(i);
+ child.getUnmarkedMethodExecutions(allExecutions, markStart, markEnd);
+ }
+ }
+ }
+
+ public AugmentationInfo getAugmentation() {
+ return augmentation;
+ }
+
+ public void setAugmentation(AugmentationInfo augmentation) {
+ this.augmentation = augmentation;
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/MethodInvocation.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/MethodInvocation.java
new file mode 100644
index 0000000..b815b2d
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/MethodInvocation.java
@@ -0,0 +1,44 @@
+package org.ntlab.trace;
+
+public class MethodInvocation extends Statement {
+ private MethodExecution calledMethodExecution = null;
+ protected String thisClassName;
+ protected String thisObjId;
+ protected String callerSideMethodName = null;
+
+ public MethodInvocation(MethodExecution methodExecution, String thisClassName, String thisObjId,
+ int lineNo, String threadNo) {
+ super(lineNo, threadNo);
+ this.calledMethodExecution = methodExecution;
+ this.thisClassName = thisClassName;
+ this.thisObjId = thisObjId;
+ }
+
+ public MethodInvocation(String callerSideMethodName, String thisClassName, String thisObjId,
+ int lineNo, String threadNo) {
+ super(lineNo, threadNo);
+ this.callerSideMethodName = callerSideMethodName;
+ this.thisClassName = thisClassName;
+ this.thisObjId = thisObjId;
+ }
+
+ public void setCalledMethodExecution(MethodExecution calledMethodExecution) {
+ this.calledMethodExecution = calledMethodExecution;
+ }
+
+ public MethodExecution getCalledMethodExecution() {
+ return calledMethodExecution;
+ }
+
+ public String getThisClassName() {
+ return thisClassName;
+ }
+
+ public String getThisObjId() {
+ return thisObjId;
+ }
+
+ public String getCallerSideMethodName() {
+ return callerSideMethodName;
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ObjectReference.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ObjectReference.java
new file mode 100644
index 0000000..50dc6fc
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ObjectReference.java
@@ -0,0 +1,70 @@
+package org.ntlab.trace;
+
+public class ObjectReference {
+ private String id;
+ private String actualType = null; // ���ۂ̌^
+ private String calleeType = null; // �Ăяo���惁�\�b�h���ł̌^(�ÓI�Ɍ���ł���^)
+ private String callerType = null; // �Ăяo�������\�b�h���ł̌^(�ÓI�Ɍ���ł���^)
+
+ public ObjectReference(String id) {
+ this.id = id;
+ this.actualType = null;
+ }
+
+ public ObjectReference(String id, String actualType) {
+ this.id = id;
+ this.actualType = actualType;
+ }
+
+ public ObjectReference(String id, String actualType, String calleeType) {
+ this.id = id;
+ this.actualType = actualType;
+ this.calleeType = calleeType;
+ }
+
+ public ObjectReference(String id, String actualType, String calleeType, String callerType) {
+ this.id = id;
+ this.actualType = actualType;
+ this.calleeType = calleeType;
+ this.callerType = callerType;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getActualType() {
+ return actualType;
+ }
+
+ public String getCalleeType() {
+ return calleeType;
+ }
+
+ public String getCallerType() {
+ return callerType;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public void setActualType(String actualType) {
+ this.actualType = actualType;
+ }
+
+ public void setCalleeType(String calleeType) {
+ this.calleeType = calleeType;
+ }
+
+ public void setCallerType(String callerType) {
+ this.callerType = callerType;
+ }
+
+ public boolean equals(Object other) {
+ if (this == other) return true;
+ if (!(other instanceof ObjectReference)) return false;
+ if (id != null && id.equals(((ObjectReference)other).id)) return true;
+ return false;
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/Reference.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/Reference.java
new file mode 100644
index 0000000..ac61644
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/Reference.java
@@ -0,0 +1,119 @@
+package org.ntlab.trace;
+
+public class Reference {
+ private String id;
+ private ObjectReference srcObj; // �Q�ƌ��I�u�W�F�N�g
+ private ObjectReference dstObj; // �Q�Ɛ�I�u�W�F�N�g
+ private boolean bCreation = false; // �Q�ƌ��I�u�W�F�N�g���Q�Ɛ�I�u�W�F�N�g��������?
+ private boolean bArray = false; // �Q�ƌ��I�u�W�F�N�g���z��ŎQ�Ɛ�I�u�W�F�N�g��v�f�Ƃ��ĕێ����Ă��邩?
+ private boolean bCollection = false; // �Q�ƌ��I�u�W�F�N�g���R���N�V�����ŎQ�Ɛ�I�u�W�F�N�g��v�f�Ƃ��ĕێ����Ă��邩?
+ private boolean bFinalLocal = false; // �Q�ƌ��I�u�W�F�N�g�������܂��͓����N���X�̂Ƃ��Q�Ɛ�I�u�W�F�N�g���O���N���X�� final local �ϐ��Ƃ��ĎQ�Ƃ��Ă��邩?
+
+ public Reference(String srcObjectId, String dstObjectId, String srcClassName,
+ String dstClassName) {
+ srcObj = new ObjectReference(srcObjectId, srcClassName);
+ dstObj = new ObjectReference(dstObjectId, dstClassName);
+ }
+
+ public Reference(ObjectReference srcObj, ObjectReference dstObj) {
+ this.srcObj = srcObj;
+ this.dstObj = dstObj;
+ }
+
+ public ObjectReference getSrcObject() {
+ return srcObj;
+ }
+
+ public ObjectReference getDstObject() {
+ return dstObj;
+ }
+
+ public void setSrcClassName(String srcClassName) {
+ this.srcObj.setActualType(srcClassName);
+ }
+
+ public void setDstClassName(String dstClassName) {
+ this.dstObj.setActualType(dstClassName);
+ }
+
+ public void setSrcObjectId(String srcObjectId) {
+ this.srcObj.setId(srcObjectId);
+ }
+
+ public void setDstObjectId(String dstObjectId) {
+ this.dstObj.setId(dstObjectId);
+ }
+
+ public String getSrcClassName() {
+ return srcObj.getActualType();
+ }
+
+ public String getDstClassName() {
+ return dstObj.getActualType();
+ }
+
+ public String getSrcObjectId() {
+ return srcObj.getId();
+ }
+
+ public String getDstObjectId() {
+ return dstObj.getId();
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public void setCreation(boolean bCreation) {
+ this.bCreation = bCreation;
+ }
+
+ public boolean isCreation(){
+ return bCreation;
+ }
+
+ public void setArray(boolean bArray) {
+ this.bArray = bArray;
+ }
+
+ public boolean isArray() {
+ return bArray;
+ }
+
+ public void setCollection(boolean bCollection) {
+ this.bCollection = bCollection;
+ }
+
+ public boolean isCollection() {
+ return bCollection;
+ }
+
+ public void setFinalLocal(boolean bFinalLocal) {
+ this.bFinalLocal = bFinalLocal;
+ }
+
+ public boolean isFinalLocal() {
+ return bFinalLocal;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o instanceof Reference) {
+ if (this.hashCode() != o.hashCode()) return false;
+ return (this.srcObj.getId().equals(((Reference)o).srcObj.getId()) && this.dstObj.getId().equals(((Reference)o).dstObj.getId()));
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ return Integer.parseInt(srcObj.getId()) + Integer.parseInt(dstObj.getId());
+ }
+
+ public String toString() {
+ return srcObj.getId() + "(" + srcObj.getActualType() + ")" + "->" + dstObj.getId() + "(" + dstObj.getActualType() + ")";
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/Statement.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/Statement.java
new file mode 100644
index 0000000..a6473d6
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/Statement.java
@@ -0,0 +1,29 @@
+package org.ntlab.trace;
+
+public class Statement {
+ protected int lineNo;
+ protected String threadNo;
+ protected long timeStamp = 0L;
+
+ public Statement(int lineNo, String threadNo) {
+ this.lineNo = lineNo;
+ this.threadNo = threadNo;
+ }
+
+ public Statement(int lineNo, String threadNo, long timeStamp) {
+ this(lineNo, threadNo);
+ this.timeStamp = timeStamp;
+ }
+
+ public int getLineNo() {
+ return lineNo;
+ }
+
+ public String getThreadNo() {
+ return threadNo;
+ }
+
+ public long getTimeStamp() {
+ return timeStamp;
+ }
+}
\ No newline at end of file
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TestTrace.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TestTrace.java
new file mode 100644
index 0000000..89fa699
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TestTrace.java
@@ -0,0 +1,166 @@
+package org.ntlab.trace;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+
+public class TestTrace {
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+// Trace trace = new Trace("documents\\worstCase.txt");
+ Trace trace = new TraceJSON("documents\\_worstCase.txt");
+// HashSet marked = trace.getMarkedMethodSignatures(1255991806833871L, 1255991808597322L);
+ HashSet marked = trace.getMarkedMethodSignatures(1044823638835493L, 1044823639353788L);
+ System.out.println("===== Marked Methods =====");
+ for (String method: marked) {
+ System.out.println(method);
+ }
+// HashSet unmarked = trace.getUnmarkedMethodSignatures(1255991806833871L, 1255991808597322L);
+ HashSet unmarked = trace.getUnmarkedMethodSignatures(1044823638835493L, 1044823639353788L);
+ System.out.println("===== Unmarked Methods =====");
+ for (String method: unmarked) {
+ System.out.println(method);
+ }
+
+/*
+ * ����������
+ *
+===== Marked Methods =====
+void worstCase.O.passL(worstCase.L)
+worstCase.L worstCase.I.getL()
+worstCase.L worstCase.K.getL()
+worstCase.M worstCase.L.getM()
+worstCase.K worstCase.J.getK()
+void worstCase.N.passI(worstCase.I)
+void worstCase.P.setM(worstCase.M)
+===== Unmarked Methods =====
+worstCase.F worstCase.C.getF()
+worstCase.E worstCase.D.getE()
+worstCase.A()
+public worstCase.M()
+worstCase.F()
+void worstCase.A.m()
+public static void worstCase.main.main(java.lang.String[])
+worstCase.G()
+worstCase.H()
+worstCase.I()
+worstCase.B()
+worstCase.C()
+worstCase.D()
+worstCase.E()
+worstCase.N()
+worstCase.O()
+worstCase.P()
+worstCase.F worstCase.E.getF()
+worstCase.J()
+worstCase.K()
+worstCase.L()
+worstCase.I worstCase.F.getI()
+worstCase.H worstCase.G.getH()
+worstCase.I worstCase.H.getI()
+worstCase.I worstCase.B.getI()
+ */
+ HashSet all = trace.getAllMethodSignatures();
+ System.out.println("===== All Methods =====");
+ for (String method: all) {
+ System.out.println(method);
+ }
+/*
+ * ����������
+ *
+===== All Methods =====
+worstCase.F worstCase.C.getF()
+worstCase.E worstCase.D.getE()
+worstCase.A()
+void worstCase.P.setM(worstCase.M)
+public worstCase.M()
+worstCase.M worstCase.L.getM()
+worstCase.L worstCase.I.getL()
+worstCase.L worstCase.K.getL()
+void worstCase.N.passI(worstCase.I)
+void worstCase.A.m()
+worstCase.F()
+public static void worstCase.main.main(java.lang.String[])
+worstCase.G()
+void worstCase.O.passL(worstCase.L)
+worstCase.H()
+worstCase.I()
+worstCase.B()
+worstCase.C()
+worstCase.D()
+worstCase.E()
+worstCase.N()
+worstCase.O()
+worstCase.K worstCase.J.getK()
+worstCase.F worstCase.E.getF()
+worstCase.P()
+worstCase.J()
+worstCase.K()
+worstCase.I worstCase.F.getI()
+worstCase.I worstCase.H.getI()
+worstCase.H worstCase.G.getH()
+worstCase.L()
+worstCase.I worstCase.B.getI()
+ */
+
+ ArrayList specified = trace.getMethodExecutions("void");
+ System.out.println("===== Specified Methods =====");
+ for (MethodExecution method: specified) {
+ System.out.println(method.getSignature());
+ }
+/*
+ * ����������
+ *
+===== Specified Methods =====
+void worstCase.A.m()
+void worstCase.N.passI(worstCase.I)
+void worstCase.O.passL(worstCase.L)
+void worstCase.P.setM(worstCase.M) *
+ */
+ HashMap> allExecutions = trace.getAllMethodExecutions();
+ System.out.println("===== All Methods and Executions =====");
+ for (String method: allExecutions.keySet()) {
+ System.out.println(method + ":" + allExecutions.get(method).size());
+ }
+/*
+ * ����������
+ *
+===== All Methods and Executions =====
+worstCase.F worstCase.C.getF():1
+worstCase.E worstCase.D.getE():1
+worstCase.A():1
+void worstCase.P.setM(worstCase.M):1
+public worstCase.M():1
+worstCase.M worstCase.L.getM():1
+worstCase.L worstCase.I.getL():1
+worstCase.L worstCase.K.getL():1
+void worstCase.N.passI(worstCase.I):1
+void worstCase.A.m():1
+worstCase.F():1
+public static void worstCase.main.main(java.lang.String[]):1
+worstCase.G():1
+void worstCase.O.passL(worstCase.L):1
+worstCase.H():1
+worstCase.I():1
+worstCase.B():1
+worstCase.C():1
+worstCase.D():1
+worstCase.E():1
+worstCase.N():1
+worstCase.O():1
+worstCase.K worstCase.J.getK():1
+worstCase.F worstCase.E.getF():1
+worstCase.P():1
+worstCase.J():1
+worstCase.K():1
+worstCase.I worstCase.F.getI():1
+worstCase.I worstCase.H.getI():1
+worstCase.H worstCase.G.getH():1
+worstCase.L():1
+worstCase.I worstCase.B.getI():1
+ */
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ThreadInstance.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ThreadInstance.java
new file mode 100644
index 0000000..272a062
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ThreadInstance.java
@@ -0,0 +1,161 @@
+package org.ntlab.trace;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+
+public class ThreadInstance {
+ private ArrayList roots = new ArrayList();
+ private MethodExecution curMethodExecution = null;
+ private MethodInvocation curMethodInvocation = null;
+ private String id;
+
+ public ThreadInstance(String id) {
+ this.id = id;
+ }
+
+ public void addRoot(MethodExecution root) {
+ this.roots.add(root);
+ curMethodExecution = root;
+ }
+
+ public ArrayList getRoot() {
+ return roots;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void preCallMethod(String callerSideSignature, int lineNumOfInvocationStatement) {
+ curMethodInvocation = new MethodInvocation(callerSideSignature, curMethodExecution.getThisClassName(), curMethodExecution.getThisObjId(), lineNumOfInvocationStatement, id);
+ }
+
+ public void callMethod(String signature, String callerSideSignature, String receiverClassName, String receiverObjId,
+ boolean isConstractor, boolean isStatic, long timeStamp) {
+ if (callerSideSignature == null && curMethodInvocation != null) {
+ callerSideSignature = curMethodInvocation.getCallerSideMethodName();
+ }
+ MethodExecution newMethodExecution = new MethodExecution(signature, callerSideSignature, receiverClassName, receiverObjId, isConstractor, isStatic, timeStamp);
+ if (curMethodExecution != null) {
+ if (curMethodInvocation == null) {
+ curMethodExecution.addStatement(new MethodInvocation(newMethodExecution, curMethodExecution.getThisClassName(), curMethodExecution.getThisObjId(), 0, id));
+ } else {
+ curMethodInvocation.setCalledMethodExecution(newMethodExecution);
+ curMethodExecution.addStatement(curMethodInvocation);
+ curMethodInvocation = null;
+ }
+ newMethodExecution.setCaller(curMethodExecution, curMethodExecution.getStatements().size() - 1);
+ curMethodExecution = newMethodExecution;
+ } else {
+ addRoot(newMethodExecution);
+ }
+ }
+
+ public void setArgments(ArrayList arguments) {
+ curMethodExecution.setArguments(arguments);
+ }
+
+ public void returnMethod(ObjectReference returnValue, String thisObjId, boolean isCollectionType) {
+ if (curMethodExecution == null) return;
+ curMethodExecution.setReturnValue(returnValue);
+ if (curMethodExecution.getThisObjId().equals("0")) {
+ curMethodExecution.setThisObjeId(thisObjId);
+ }
+ curMethodExecution.setCollectionType(isCollectionType);
+ curMethodExecution = curMethodExecution.getParent();
+ curMethodInvocation = null; // �O�̂���
+ }
+
+ public void returnMethod(ObjectReference returnValue, String thisObjId, boolean isCollectionType, long exitTime) {
+ if (curMethodExecution != null) curMethodExecution.setExitTime(exitTime);
+ returnMethod(returnValue, thisObjId, isCollectionType);
+ }
+
+ public void terminateMethod() {
+ if (curMethodExecution == null) return;
+ curMethodExecution.setTerminated(true);
+ curMethodExecution = curMethodExecution.getParent();
+ }
+
+ public void fieldAccess(String valueClassName, String valueObjId, String containerClassName, String containerObjId, String thisClassName, String thisId) {
+ FieldAccess fieldAccess = new FieldAccess(valueClassName, valueObjId, containerClassName, containerObjId, thisClassName, thisId, 0, id);
+ if (curMethodExecution != null) curMethodExecution.addStatement(fieldAccess);
+ }
+
+ public void fieldAccess(String valueClassName, String valueObjId, String containerClassName, String containerObjId, String thisClassName, String thisId, int lineNo, long timeStamp) {
+ FieldAccess fieldAccess = new FieldAccess(valueClassName, valueObjId, containerClassName, containerObjId, thisClassName, thisId, lineNo, id, timeStamp);
+ if (curMethodExecution != null) curMethodExecution.addStatement(fieldAccess);
+ }
+
+ public void fieldUpdate(String valueClassName, String valueObjId, String containerClassName, String containerObjId) {
+ FieldUpdate fieldUpdate = new FieldUpdate(valueClassName, valueObjId, containerClassName, containerObjId, 0, id);
+ if (curMethodExecution != null) curMethodExecution.addStatement(fieldUpdate);
+ }
+
+ public void fieldUpdate(String valueClassName, String valueObjId, String containerClassName, String containerObjId, int lineNo, long timeStamp) {
+ FieldUpdate fieldUpdate = new FieldUpdate(valueClassName, valueObjId, containerClassName, containerObjId, lineNo, id, timeStamp);
+ if (curMethodExecution != null) curMethodExecution.addStatement(fieldUpdate);
+ }
+
+ public void arrayCreate(String arrayClassName, String arrayObjectId, int dimension, int lineNo, long timeStamp) {
+ ArrayCreate arrayCreate = new ArrayCreate(arrayClassName, arrayObjectId, dimension, lineNo, id, timeStamp);
+ if (curMethodExecution != null) curMethodExecution.addStatement(arrayCreate);
+ }
+
+ public void arraySet(String arrayClassName, String arrayObjectId, int index, String valueClassName, String valueObjectId, int lineNo, long timeStamp) {
+ ArrayUpdate arraySet = new ArrayUpdate(arrayClassName, arrayObjectId, index, valueClassName, valueObjectId, lineNo, id, timeStamp);
+ if (curMethodExecution != null) curMethodExecution.addStatement(arraySet);
+ }
+
+ public void arrayGet(String arrayClassName, String arrayObjectId, int index, String valueClassName, String valueObjectId, int lineNo, long timeStamp) {
+ ArrayAccess arrayGet = new ArrayAccess(arrayClassName, arrayObjectId, index, valueClassName, valueObjectId, lineNo, id, timeStamp);
+ if (curMethodExecution != null) curMethodExecution.addStatement(arrayGet);
+ }
+
+ public void blockEnter(int blockId, int incomings, int lineNo, long timeStamp) {
+ BlockEnter blockEnter = new BlockEnter(blockId, incomings, lineNo, id, timeStamp);
+ if (curMethodExecution != null) curMethodExecution.addStatement(blockEnter);
+ }
+
+ public void traverseMethodExecutionsBackward(IMethodExecutionVisitor visitor) {
+ visitor.preVisitThread(this);
+ for (int i = 0; i < roots.size(); i++) {
+ MethodExecution root = roots.get(i);
+ root.traverseMethodExecutionsBackward(visitor);
+ }
+ visitor.postVisitThread(this);
+ }
+
+ public void traverseMarkedMethodExecutions(IMethodExecutionVisitor visitor, long markStart, long markEnd) {
+ visitor.preVisitThread(this);
+ for (int i = 0; i < roots.size(); i++) {
+ MethodExecution root = roots.get(i);
+ if (root.getEntryTime() <= markEnd) {
+ root.traverseMarkedMethodExecutions(visitor, markStart, markEnd);
+ } else {
+ break;
+ }
+ }
+ visitor.postVisitThread(this);
+ }
+
+ public void getUnmarkedMethodSignatures(HashSet signatures, long markStart, long markEnd) {
+ for (int i = 0; i < roots.size(); i++) {
+ MethodExecution root = roots.get(i);
+ root.getUnmarkedMethodSignatures(signatures, markStart, markEnd);
+ }
+ }
+
+ public void getUnmarkedMethodExecutions(HashMap> executions, long markStart, long markEnd) {
+ for (int i = 0; i < roots.size(); i++) {
+ MethodExecution root = roots.get(i);
+ root.getUnmarkedMethodExecutions(executions, markStart, markEnd);
+ }
+ }
+
+ public MethodExecution getCuurentMethodExecution() {
+ return curMethodExecution;
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/Trace.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/Trace.java
new file mode 100644
index 0000000..049e4ed
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/Trace.java
@@ -0,0 +1,1031 @@
+package org.ntlab.trace;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Stack;
+
+public class Trace {
+ protected static final boolean EAGER_DETECTION_OF_ARRAY_SET = false; // �z��v�f�ւ̑���̌��o�𑽂����ς��邩?(�������ς����False Positive�ɂȂ�\��������)
+
+ protected HashMap threads = new HashMap();
+
+ protected Trace() {
+ }
+
+ /**
+ * �w�肵��PlainText�̃g���[�X�t�@�C������ǂ��� Trace �I�u�W�F�N�g������
+ * @param traceFile �g���[�X�t�@�C���̃p�X
+ */
+ public Trace(String traceFile) {
+ BufferedReader file;
+ try {
+ file = new BufferedReader(new FileReader(traceFile));
+ // �g���[�X�t�@�C���ǂݍ���
+ String line, prevLine = null;
+ String signature;
+ String callerSideSignature;
+ String threadNo = null;
+ String[] methodData;
+ String[] argData;
+ String[] returnData;
+ String[] accessData;
+ String[] updateData;
+ String thisObjectId;
+ String thisClassName;
+ boolean isConstractor = false;
+ boolean isCollectionType = false;
+ boolean isStatic = false;
+ long timeStamp = 0L;
+ ThreadInstance thread = null;
+ HashMap> stacks = new HashMap>();
+ while ((line = file.readLine()) != null) {
+ // �g���[�X�t�@�C���̉��
+ if (line.startsWith("Method")) {
+ // ���\�b�h�Ăяo���i�R���X�g���N�^�Ăяo�����܂ށj
+ methodData = line.split(":");
+ int n = methodData[0].indexOf(',');
+ signature = methodData[0].substring(n + 1);
+ threadNo = methodData[methodData.length - 1].split(" ")[1];
+ thisObjectId = methodData[1];
+ thisClassName = methodData[0].substring(0, n).split(" ")[1];
+ isConstractor = false;
+ isStatic = false;
+ if (signature.contains("static ")) {
+ isStatic = true;
+ }
+ callerSideSignature = signature;
+ timeStamp = Long.parseLong(methodData[methodData.length - 2]);
+ if (prevLine != null) {
+ if (prevLine.startsWith("New")) {
+ isConstractor = true;
+ } else if (prevLine.startsWith("Invoke")) {
+ callerSideSignature = prevLine.split(":")[1];
+ }
+ }
+ thread = threads.get(threadNo);
+ Stack stack;
+ if (thread == null) {
+ thread = new ThreadInstance(threadNo);
+ threads.put(threadNo, thread);
+ stack = new Stack();
+ stacks.put(threadNo, stack);
+ } else {
+ stack = stacks.get(threadNo);
+ }
+ stack.push(line);
+ thread.callMethod(signature, callerSideSignature, thisClassName, thisObjectId, isConstractor, isStatic, timeStamp);
+ } else if (line.startsWith("Args")) {
+ // ���\�b�h�Ăяo���̈���
+ argData = line.split(":");
+ threadNo = argData[argData.length - 1].split(" ")[1];
+ thread = threads.get(threadNo);
+ ArrayList arguments = new ArrayList();
+ for (int k = 1; k < argData.length - 2; k += 2) {
+ arguments.add(new ObjectReference(argData[k+1], argData[k]));
+ }
+ thread.setArgments(arguments);
+ } else if (line.startsWith("Return")) {
+ // ���\�b�h����̕��A
+ returnData = line.split(":");
+ threadNo = returnData[returnData.length - 1].split(" ")[1];
+ Stack stack = stacks.get(threadNo);
+ if (!stack.isEmpty()) {
+ String line2 = stack.peek();
+ if (line2.split("\\(")[0].endsWith(line.split("\\(")[1])) {
+ stack.pop();
+ } else {
+ do {
+ line2 = stack.pop();
+ thread.terminateMethod();
+ } while (!stack.isEmpty() && !line2.split("\\(")[0].endsWith(line.split("\\(")[1]));
+ }
+ thread = threads.get(threadNo);
+ ObjectReference returnValue = new ObjectReference(returnData[2], returnData[1]);
+ thisObjectId = returnData[2];
+ isCollectionType = false;
+ String curLine = returnData[0];
+ if(curLine.contains("Return call(List")
+ || curLine.contains("Return call(Vector")
+ || curLine.contains("Return call(Iterator")
+ || curLine.contains("Return call(ListIterator")
+ || curLine.contains("Return call(ArrayList")
+ || curLine.contains("Return call(Stack")
+ || curLine.contains("Return call(Hash")
+ || curLine.contains("Return call(Map")
+ || curLine.contains("Return call(Set")
+ || curLine.contains("Return call(Linked")
+ || curLine.contains("Return call(Thread")) {
+ isCollectionType = true;
+ }
+ thread.returnMethod(returnValue, thisObjectId, isCollectionType);
+ }
+ } else if (line.startsWith("get")) {
+ // �t�B�[���h�A�N�Z�X
+ accessData = line.split(":");
+ threadNo = accessData[8].split(" ")[1];
+ thread = threads.get(threadNo);
+ if (thread != null) thread.fieldAccess(accessData[5], accessData[6], accessData[3], accessData[4], accessData[1], accessData[2]);
+ } else if (line.startsWith("set")) {
+ // �t�B�[���h�X�V
+ updateData = line.split(":");
+ threadNo = updateData[6].split(" ")[1];
+ thread = threads.get(threadNo);
+ if (thread != null) thread.fieldUpdate(updateData[3], updateData[4], updateData[1], updateData[2]);
+ }
+ prevLine = line;
+ }
+ file.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * �S�X���b�h���擾����
+ * @return �X���b�hID����X���b�h�C���X�^���X�ւ̃}�b�v
+ */
+ public HashMap getAllThreads() {
+ return threads;
+ }
+
+ /**
+ * �w�肵���X���b�h��Ō��ݎ��s���̃��\�b�h���s���擾����(�I�����C����͗p)
+ * @param thread �ΏۃX���b�h
+ * @return thread ��Ō��ݎ��s���̃��\�b�h���s
+ */
+ public MethodExecution getCurrentMethodExecution(Thread thread) {
+ ThreadInstance t = threads.get(thread.getId());
+ return t.getCuurentMethodExecution();
+ }
+
+ /**
+ * methodSignature �ɑO����v���郁�\�b�h���������\�b�h�̍Ō�̎��s
+ * @param methodSignature ���\�b�h��(�O����v��������)
+ * @return �Y������Ō�̃��\�b�h���s
+ */
+ public MethodExecution getLastMethodExecution(final String methodSignature) {
+ return traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() {
+ @Override
+ public boolean preVisitThread(ThreadInstance thread) { return false; }
+ @Override
+ public boolean postVisitThread(ThreadInstance thread) { return false; }
+ @Override
+ public boolean preVisitMethodExecution(MethodExecution methodExecution) { return false; }
+ @Override
+ public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) {
+ if (methodExecution.getSignature().startsWith(methodSignature)) return true;
+ return false;
+ }
+ });
+ }
+
+ public MethodExecution traverseMethodEntriesInTraceBackward(IMethodExecutionVisitor visitor) {
+ HashMap> threadRoots = new HashMap>();
+ HashMap threadLastPoints = new HashMap();
+ Iterator threadsIterator = threads.keySet().iterator();
+ // �e�X���b�h�ɂ����Ĉ�ԍŌ�ɊJ�n�������\�b�h���s��T��
+ long traceLastTime = 0;
+ String traceLastThread = null;
+ long traceLastTime2 = 0;
+ String traceLastThread2 = null;
+ for (; threadsIterator.hasNext();) {
+ String threadId = threadsIterator.next();
+ ThreadInstance thread = threads.get(threadId);
+ ArrayList rootExecutions = (ArrayList)thread.getRoot().clone();
+ threadRoots.put(threadId, rootExecutions);
+ TracePoint threadLastTp = getLastMethodEntryInThread(rootExecutions);
+ threadLastPoints.put(threadId, threadLastTp);
+ if (threadLastTp != null) {
+ long threadLastTime = threadLastTp.getMethodExecution().getEntryTime();
+ if (traceLastTime < threadLastTime) {
+ traceLastTime2 = traceLastTime;
+ traceLastThread2 = traceLastThread;
+ traceLastTime = threadLastTime;
+ traceLastThread = threadId;
+ }
+ }
+ }
+ return traverseMethodEntriesInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2);
+ }
+
+ /**
+ * methodSignature �ɑO����v���郁�\�b�h���������\�b�h�� before �ȑO�̍Ō�̎��s
+ * @param methodSignature ���\�b�h��(�O����v��������)
+ * @param before�@�T���J�n�g���[�X�|�C���g(������ȑO��T��)
+ * @return�@�Y������Ō�̃��\�b�h���s
+ */
+ public MethodExecution getLastMethodExecution(final String methodSignature, TracePoint before) {
+ return traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() {
+ @Override
+ public boolean preVisitThread(ThreadInstance thread) { return false; }
+ @Override
+ public boolean postVisitThread(ThreadInstance thread) { return false; }
+ @Override
+ public boolean preVisitMethodExecution(MethodExecution methodExecution) { return false; }
+ @Override
+ public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) {
+ if (methodExecution.getSignature().startsWith(methodSignature)) return true;
+ return false;
+ }
+ }, before);
+ }
+
+ public MethodExecution traverseMethodEntriesInTraceBackward(IMethodExecutionVisitor visitor, TracePoint before) {
+ HashMap> threadRoots = new HashMap>();
+ HashMap threadLastPoints = new HashMap();
+ Iterator threadsIterator = threads.keySet().iterator();
+ String traceLastThread = null;
+ long traceLastTime2 = 0;
+ String traceLastThread2 = null;
+ ThreadInstance thread = threads.get(before.getStatement().getThreadNo());
+ ArrayList rootExecutions = (ArrayList)thread.getRoot().clone();
+ for (int n = rootExecutions.size() - 1; n >= 0; n--) {
+ MethodExecution root = rootExecutions.get(n);
+ if (root.getEntryTime() > before.getMethodExecution().getEntryTime()) {
+ rootExecutions.remove(n);
+ } else {
+ break;
+ }
+ }
+ if (rootExecutions.size() > 0) {
+ rootExecutions.remove(rootExecutions.size() - 1);
+ }
+ before = getLastMethodEntryInThread(rootExecutions, before);
+ for (; threadsIterator.hasNext();) {
+ String threadId = threadsIterator.next();
+ ThreadInstance t = threads.get(threadId);
+ if (t == thread) {
+ threadRoots.put(threadId, rootExecutions);
+ traceLastThread = threadId;
+ threadLastPoints.put(threadId, before);
+ } else {
+ ArrayList rootExes = (ArrayList)t.getRoot().clone();
+ threadRoots.put(threadId, rootExes);
+ MethodExecution threadLastExecution = rootExes.remove(rootExes.size() - 1);
+ TracePoint threadBeforeTp = getLastMethodEntryInThread(rootExes, threadLastExecution.getExitOutPoint(), before.getMethodExecution().getEntryTime());
+ threadLastPoints.put(threadId, threadBeforeTp);
+ if (threadBeforeTp != null) {
+ long threadLastTime = threadBeforeTp.getMethodExecution().getEntryTime();
+ if (traceLastTime2 < threadLastTime) {
+ traceLastTime2 = threadLastTime;
+ traceLastThread2 = threadId;
+ }
+ }
+ }
+ }
+ return traverseMethodEntriesInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2);
+ }
+
+ private MethodExecution traverseMethodEntriesInTraceBackwardSub(
+ final IMethodExecutionVisitor visitor,
+ HashMap> threadRoots, HashMap threadLastPoints,
+ String traceLastThread, String traceLastThread2, long traceLastTime2) {
+ // �S�X���b�h�̓������Ƃ�Ȃ���t�����Ƀ��\�b�h���s��T������
+ for (;;) {
+ // �T���Ώۂ̃X���b�h���̋t�����T��
+ TracePoint threadLastTp = threadLastPoints.get(traceLastThread);
+ MethodExecution threadLastExecution = threadLastTp.getMethodExecution();
+ do {
+ threadLastTp.stepBackOver();
+ // ���̃X���b�h�̎��̃��\�b�h���s�J�n���_�܂ŒT������
+ threadLastTp = getLastMethodEntryInThread(threadRoots.get(traceLastThread), threadLastTp);
+ if (threadLastTp == null) break;
+ if (visitor.postVisitMethodExecution(threadLastExecution, threadLastExecution.getChildren())) {
+ // �Y�����郁�\�b�h���s��������
+ return threadLastExecution;
+ }
+ threadLastExecution = threadLastTp.getMethodExecution();
+ } while (threadLastExecution.getEntryTime() > traceLastTime2);
+ threadLastPoints.put(traceLastThread, threadLastTp);
+ traceLastThread = traceLastThread2;
+ // ���̎��ɒT�����ׂ��X���b�h(���T���̗̈悪��ԍŌ�܂Ŏc���Ă���X���b�h)�����肷��
+ traceLastTime2 = 0;
+ traceLastThread2 = null;
+ boolean continueTraverse = false;
+ Iterator threadIterator = threadLastPoints.keySet().iterator();
+ for (; threadIterator.hasNext();) {
+ String threadId = threadIterator.next();
+ if (!threadId.equals(traceLastThread)) {
+ TracePoint lastTp = threadLastPoints.get(threadId);
+ if (lastTp != null) {
+ continueTraverse = true;
+ long threadLastTime = lastTp.getMethodExecution().getEntryTime();
+ if (traceLastTime2 < threadLastTime) {
+ traceLastTime2 = threadLastTime;
+ traceLastThread2 = threadId;
+ }
+ }
+ }
+ }
+ if (!continueTraverse && threadLastPoints.get(traceLastThread) == null) break;
+ }
+ return null;
+ }
+
+ /**
+ * ���\�b�h���� methodSignature�@�ɑO����v���郁�\�b�h���s��S�ẴX���b�h������o��
+ * @param methodSignature ����������
+ * @return ��v�����S���\�b�h���s
+ */
+ public ArrayList getMethodExecutions(final String methodSignature) {
+ Iterator threadsIterator = threads.keySet().iterator();
+ final ArrayList results = new ArrayList();
+ for (; threadsIterator.hasNext();) {
+ ThreadInstance thread = threads.get(threadsIterator.next());
+ thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() {
+ @Override
+ public boolean preVisitThread(ThreadInstance thread) {
+ return false;
+ }
+ @Override
+ public boolean preVisitMethodExecution(MethodExecution methodExecution) {
+ if (methodExecution.getSignature().startsWith(methodSignature)) {
+ results.add(methodExecution);
+ }
+ return false;
+ }
+ @Override
+ public boolean postVisitThread(ThreadInstance thread) {
+ return false;
+ }
+ @Override
+ public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) {
+ return false;
+ }
+ });
+ }
+ return results;
+ }
+
+ /**
+ * ���\�b�h���ɑS���\�b�h���s��S�ẴX���b�h������o��
+ * @return ���\�b�h�V�O�j�`�����烁�\�b�h���s�̃��X�g�ւ�HashMap
+ */
+ public HashMap> getAllMethodExecutions() {
+ Iterator threadsIterator = threads.keySet().iterator();
+ final HashMap> results = new HashMap<>();
+ for (; threadsIterator.hasNext();) {
+ ThreadInstance thread = threads.get(threadsIterator.next());
+ thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() {
+ @Override
+ public boolean preVisitThread(ThreadInstance thread) {
+ return false;
+ }
+ @Override
+ public boolean preVisitMethodExecution(MethodExecution methodExecution) {
+ String signature = methodExecution.getSignature();
+ ArrayList executions = results.get(signature);
+ if (executions == null) {
+ executions = new ArrayList<>();
+ results.put(signature, executions);
+ }
+ executions.add(methodExecution);
+ return false;
+ }
+ @Override
+ public boolean postVisitThread(ThreadInstance thread) {
+ return false;
+ }
+ @Override
+ public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) {
+ return false;
+ }
+ });
+ }
+ return results;
+ }
+
+ /**
+ * �Ăяo�����̎����� markStart ���� markEnd �̊Ԃɂ���S�X���b�h���̑S���\�b�h���s��T������
+ * @param visitor�@�r�W�^�[
+ * @param markStart �J�n����
+ * @param markEnd �I������
+ */
+ public void traverseMarkedMethodExecutions(IMethodExecutionVisitor visitor, long markStart, long markEnd) {
+ Iterator threadsIterator = threads.keySet().iterator();
+ for (; threadsIterator.hasNext();) {
+ ThreadInstance thread = threads.get(threadsIterator.next());
+ thread.traverseMarkedMethodExecutions(visitor, markStart, markEnd);
+ }
+ }
+
+ /**
+ * �S���\�b�h�̃V�O�j�`�����擾����
+ * @return �S���\�b�h�V�O�j�`��
+ */
+ public HashSet getAllMethodSignatures() {
+ final HashSet signatures = new HashSet();
+ Iterator threadsIterator = threads.keySet().iterator();
+ for (; threadsIterator.hasNext();) {
+ ThreadInstance thread = threads.get(threadsIterator.next());
+ thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() {
+ @Override
+ public boolean preVisitThread(ThreadInstance thread) {
+ return false;
+ }
+ @Override
+ public boolean postVisitThread(ThreadInstance thread) {
+ return false;
+ }
+ @Override
+ public boolean preVisitMethodExecution(MethodExecution methodExecution) {
+ signatures.add(methodExecution.getSignature());
+ return false;
+ }
+ @Override
+ public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) {
+ return false;
+ }
+ });
+ }
+ return signatures;
+ }
+
+ /**
+ * �}�[�N���Ŏ��s���J�n���ꂽ�S���\�b�h�̃V�O�j�`�����擾����
+ * @param markStart �}�[�N�̊J�n����
+ * @param markEnd �}�[�N�̏I������
+ * @return �Y�����郁�\�b�h�V�O�j�`��
+ */
+ public HashSet getMarkedMethodSignatures(final long markStart, final long markEnd) {
+ final HashSet signatures = new HashSet();
+ Iterator threadsIterator = threads.keySet().iterator();
+ for (; threadsIterator.hasNext();) {
+ ThreadInstance thread = threads.get(threadsIterator.next());
+ thread.traverseMarkedMethodExecutions(new IMethodExecutionVisitor() {
+ @Override
+ public boolean preVisitThread(ThreadInstance thread) {
+ return false;
+ }
+ @Override
+ public boolean postVisitThread(ThreadInstance thread) {
+ return false;
+ }
+ @Override
+ public boolean preVisitMethodExecution(MethodExecution methodExecution) {
+ signatures.add(methodExecution.getSignature());
+ return false;
+ }
+ @Override
+ public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) {
+ return false;
+ }
+ }, markStart, markEnd);
+ }
+ return signatures;
+ }
+
+ /**
+ * �}�[�N���Ŏ��s���J�n���ꂽ�S���\�b�h���s�����\�b�h���Ɏ擾����
+ * @param markStart �}�[�N�̊J�n����
+ * @param markEnd �}�[�N�̏I������
+ * @return ���\�b�h�V�O�j�`������Y�����郁�\�b�h���s�̃��X�g�ւ�HashMap
+ */
+ public HashMap> getMarkedMethodExecutions(final long markStart, final long markEnd) {
+ final HashMap>allExecutions = new HashMap<>();
+ Iterator threadsIterator = threads.keySet().iterator();
+ for (; threadsIterator.hasNext();) {
+ ThreadInstance thread = threads.get(threadsIterator.next());
+ thread.traverseMarkedMethodExecutions(new IMethodExecutionVisitor() {
+ @Override
+ public boolean preVisitThread(ThreadInstance thread) {
+ return false;
+ }
+ @Override
+ public boolean postVisitThread(ThreadInstance thread) {
+ return false;
+ }
+ @Override
+ public boolean preVisitMethodExecution(MethodExecution methodExecution) {
+ ArrayList executions = allExecutions.get(methodExecution.getSignature());
+ if (executions == null) {
+ executions = new ArrayList<>();
+ allExecutions.put(methodExecution.getSignature(), executions);
+ }
+ executions.add(methodExecution);
+ return false;
+ }
+ @Override
+ public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) {
+ return false;
+ }
+ }, markStart, markEnd);
+ }
+ return allExecutions;
+ }
+
+ /**
+ * �}�[�N�O�Ŏ��s���J�n���ꂽ�S���\�b�h�̃V�O�j�`�����擾����
+ * @param markStart �}�[�N�̊J�n����
+ * @param markEnd �}�[�N�̏I������
+ * @return �Y�����郁�\�b�h�V�O�j�`��
+ */
+ public HashSet getUnmarkedMethodSignatures(long markStart, long markEnd) {
+ HashSet signatures = new HashSet();
+ Iterator threadsIterator = threads.keySet().iterator();
+ for (; threadsIterator.hasNext();) {
+ ThreadInstance thread = threads.get(threadsIterator.next());
+ thread.getUnmarkedMethodSignatures(signatures, markStart, markEnd);
+ }
+ return signatures;
+ }
+
+ /**
+ * �}�[�N�O�Ŏ��s���J�n���ꂽ�S���\�b�h���s���擾����
+ * @param markStart �}�[�N�̊J�n����
+ * @param markEnd �}�[�N�̏I������
+ * @return ���\�b�h�V�O�j�`������Y�����郁�\�b�h���s�̃��X�g�ւ�HashMap
+ */
+ public HashMap> getUnmarkedMethodExecutions(long markStart, long markEnd) {
+ HashMap> executions = new HashMap<>();
+ Iterator threadsIterator = threads.keySet().iterator();
+ for (; threadsIterator.hasNext();) {
+ ThreadInstance thread = threads.get(threadsIterator.next());
+ thread.getUnmarkedMethodExecutions(executions, markStart, markEnd);
+ }
+ return executions;
+ }
+
+ public TracePoint traverseStatementsInTraceBackward(IStatementVisitor visitor) {
+ HashMap> threadRoots = new HashMap>();
+ HashMap threadLastPoints = new HashMap();
+ Iterator threadsIterator = threads.keySet().iterator();
+ // �e�X���b�h�ɂ����Ĉ�ԍŌ�ɊJ�n�������\�b�h���s��T��
+ long traceLastTime = 0;
+ String traceLastThread = null;
+ long traceLastTime2 = 0;
+ String traceLastThread2 = null;
+ for (; threadsIterator.hasNext();) {
+ String threadId = threadsIterator.next();
+ ThreadInstance thread = threads.get(threadId);
+ ArrayList root = (ArrayList)thread.getRoot().clone();
+ threadRoots.put(threadId, root);
+ TracePoint threadLastTp;
+ do {
+ MethodExecution threadLastExecution = root.remove(root.size() - 1);
+ threadLastTp = threadLastExecution.getExitPoint();
+ } while (!threadLastTp.isValid() && root.size() > 0);
+ if (threadLastTp.isValid()) {
+ threadLastPoints.put(threadId, threadLastTp);
+ if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, threadLastTp)) return threadLastTp;
+ long methodEntry = threadLastTp.getMethodExecution().getEntryTime();
+ if (traceLastTime < methodEntry) {
+ traceLastTime2 = traceLastTime;
+ traceLastThread2 = traceLastThread;
+ traceLastTime = methodEntry;
+ traceLastThread = threadId;
+ }
+ } else {
+ threadLastPoints.put(threadId, null);
+ }
+ }
+ return traverseStatementsInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2);
+ }
+
+ public TracePoint traverseStatementsInTraceBackward(IStatementVisitor visitor, TracePoint before) {
+ if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, before)) return before;
+ HashMap> threadRoots = new HashMap>();
+ HashMap threadLastPoints = new HashMap();
+ Iterator threadsIterator = threads.keySet().iterator();
+ String traceLastThread = null;
+ long traceLastTime2 = 0;
+ String traceLastThread2 = null;
+ ThreadInstance thread = threads.get(before.getStatement().getThreadNo());
+ for (; threadsIterator.hasNext();) {
+ String threadId = threadsIterator.next();
+ ThreadInstance t = threads.get(threadId);
+ ArrayList rootExecutions = (ArrayList)t.getRoot().clone();
+ threadRoots.put(threadId, rootExecutions);
+ if (t == thread) {
+ traceLastThread = threadId;
+ threadLastPoints.put(threadId, before);
+ for (int n = rootExecutions.size() - 1; n >= 0; n--) {
+ MethodExecution root = rootExecutions.get(n);
+ if (root.getEntryTime() > before.getMethodExecution().getEntryTime()) {
+ rootExecutions.remove(n);
+ } else {
+ break;
+ }
+ }
+ if (rootExecutions.size() > 0) {
+ rootExecutions.remove(rootExecutions.size() - 1);
+ }
+ } else {
+ MethodExecution threadLastExecution = rootExecutions.remove(rootExecutions.size() - 1);
+ TracePoint threadBeforeTp = getLastMethodEntryInThread(rootExecutions, threadLastExecution.getExitOutPoint(), before.getMethodExecution().getEntryTime());
+ threadLastPoints.put(threadId, threadBeforeTp);
+ if (threadBeforeTp != null) {
+ long threadLastTime = threadBeforeTp.getMethodExecution().getEntryTime();
+ if (traceLastTime2 < threadLastTime) {
+ traceLastTime2 = threadLastTime;
+ traceLastThread2 = threadId;
+ }
+ }
+ }
+ }
+ return traverseStatementsInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2);
+ }
+
+ private TracePoint traverseStatementsInTraceBackwardSub(IStatementVisitor visitor,
+ HashMap> threadRoots,
+ HashMap threadLastPoints,
+ String traceLastThread, String traceLastThread2, long traceLastTime2) {
+ // �S�X���b�h�̓������Ƃ�Ȃ���t�����Ɏ��s����T������
+ for (;;) {
+ // �T���Ώۂ̃X���b�h���̋t�����T��
+ TracePoint lastTp = threadLastPoints.get(traceLastThread);
+ do {
+ if (lastTp.stepBackOver()) {
+ // ���̃X���b�h�̎��̃��\�b�h���s�J�n���_�܂ŒT������
+ if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, lastTp)) return lastTp;
+ } else {
+ // �Ăяo�����ɖ߂����ꍇ
+ if (!lastTp.isValid()) {
+ // �Ăяo���̊J�n���_�܂ŒT�����I�����ꍇ
+ ArrayList root = threadRoots.get(traceLastThread);
+ while (!lastTp.isValid() && root.size() > 0) {
+ // ���̌Ăяo�������������Ōォ��T��
+ MethodExecution lastExecution = root.remove(root.size() - 1);
+ lastTp = lastExecution.getExitPoint();
+ }
+ if (lastTp.isValid()) {
+ // ���̌Ăяo�������������Ōォ��T��
+ threadLastPoints.put(traceLastThread, lastTp);
+ if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, lastTp)) return lastTp;
+ } else {
+ // ���̃X���b�h�̒T�������ׂďI�������ꍇ
+ threadLastPoints.put(traceLastThread, null);
+ break;
+ }
+ }
+ }
+ } while (lastTp.getMethodExecution().getEntryTime() > traceLastTime2);
+ traceLastThread = traceLastThread2;
+ // ���̎��ɒT�����ׂ��X���b�h(���T���̗̈悪��ԍŌ�܂Ŏc���Ă���X���b�h)�����肷��
+ traceLastTime2 = 0;
+ traceLastThread2 = null;
+ boolean continueTraverse = false;
+ Iterator threadsIterator = threadLastPoints.keySet().iterator();
+ for (; threadsIterator.hasNext();) {
+ String threadId = threadsIterator.next();
+ if (!threadId.equals(traceLastThread)) {
+ TracePoint threadLastTp = threadLastPoints.get(threadId);
+ if (threadLastTp != null) {
+ continueTraverse = true;
+ long threadLastTime = threadLastTp.getMethodExecution().getEntryTime();
+ if (traceLastTime2 < threadLastTime) {
+ traceLastTime2 = threadLastTime;
+ traceLastThread2 = threadId;
+ }
+ }
+ }
+ }
+ if (!continueTraverse && threadLastPoints.get(traceLastThread) == null) break;
+ }
+ return null;
+ }
+
+ private TracePoint getLastMethodEntryInThread(ArrayList rootExecutions) {
+ MethodExecution lastExecution = rootExecutions.remove(rootExecutions.size() - 1);
+ return getLastMethodEntryInThread(rootExecutions, lastExecution.getExitOutPoint());
+ }
+
+ private TracePoint getLastMethodEntryInThread(ArrayList rootExecutions, TracePoint start) {
+ return getLastMethodEntryInThread(rootExecutions, start, -1L);
+ }
+
+ private TracePoint getLastMethodEntryInThread(ArrayList rootExecutions, TracePoint start, final long before) {
+ final TracePoint cp[] = new TracePoint[1];
+ cp[0] = start;
+ for (;;) {
+ if (!cp[0].isStepBackOut() && traverseMethodExecutionsInCallTreeBackward(
+ 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.getEntryTime() < before || before == -1L) {
+ cp[0] = methodExecution.getEntryPoint();
+ return true;
+ }
+ return false;
+ }
+ }, cp[0])) {
+ return cp[0];
+ }
+ if (rootExecutions.size() == 0) break;
+ MethodExecution lastExecution = rootExecutions.remove(rootExecutions.size() - 1);
+ cp[0] = lastExecution.getExitOutPoint();
+ }
+ return null;
+ }
+
+ /**
+ * before �Ŏw�肵���g���[�X�|�C���g�ȑO�̓���Ăяo���ؓ��̑S���s�����t�����ɒT������(�������Avisitor �� true ��Ԃ��܂�)
+ * @param visitor �r�W�^�[
+ * @param before �T���̊J�n�_(�T���ΏۃX���b�h���w�肵�Ă���)
+ * @return true -- �T���𒆒f����, false -- �Ō�܂ŒT������
+ */
+ public boolean traverseStatementsInCallTreeBackward(IStatementVisitor visitor, TracePoint before) {
+ for (;;) {
+ if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, before)) return true;
+ before.stepBackOver();
+ if (!before.isValid()) break;
+ }
+ return false;
+ }
+
+ private boolean traverseStatamentsInCallTreeBackwardNoReturn(IStatementVisitor visitor, TracePoint before) {
+ for (;;) {
+ Statement statement = before.getStatement();
+ if (statement instanceof MethodInvocation) {
+ // ���\�b�h�Ăяo�����̏ꍇ�́A�Ăяo���̑O��� preVisit �� postVisit ��ʁX�Ɏ��s����
+ if (visitor.preVisitStatement(statement)) return true;
+ before.stepBackNoReturn();
+ if (!before.isValid()) {
+ // �Ăяo����̃��\�b�h�Ŏ��s�����L�^����Ă��Ȃ��ꍇ
+ before.stepBackOver();
+ if (visitor.postVisitStatement(statement)) return true;
+ if (before.isMethodEntry()) return false;
+ before.stepBackOver();
+ }
+ } else {
+ if (visitor.preVisitStatement(statement)) return true;
+ if (visitor.postVisitStatement(statement)) return true;
+ if (before.isMethodEntry()) return false;
+ before.stepBackNoReturn();
+ }
+ }
+ }
+
+ /**
+ * before �Ŏw�肵���g���[�X�|�C���g�ȑO�̓���X���b�h���̑S���\�b�h���s���Ăяo���̒��ŋt�����ɒT������(�������Avisitor �� true ��Ԃ��܂�)
+ * @param visitor �r�W�^�[
+ * @param before �T���̊J�n�_(�T���ΏۃX���b�h���w�肵�Ă���)
+ * @return true -- �T���𒆒f����, false -- �Ō�܂ŒT������
+ */
+ public boolean traverseMethodExecutionsInCallTreeBackward(IMethodExecutionVisitor visitor, TracePoint before) {
+ ArrayList prevMethodExecutions = before.getPreviouslyCalledMethods();
+ for (int i = prevMethodExecutions.size() - 1; i >= 0; i--) {
+ MethodExecution child = prevMethodExecutions.get(i);
+ if (child.traverseMethodExecutionsBackward(visitor)) return true;
+ }
+ MethodExecution methodExecution = before.getMethodExecution();
+ if (visitor.postVisitMethodExecution(methodExecution, null)) return true;
+ TracePoint caller = methodExecution.getCallerTracePoint();
+ if (caller != null) {
+ if (traverseMethodExecutionsInCallTreeBackward(visitor, caller)) return true;
+ }
+ return false;
+ }
+
+ public TracePoint getCreationTracePoint(final ObjectReference newObjectId, TracePoint before) {
+ before = before.duplicate();
+ before = traverseStatementsInTraceBackward(
+ new IStatementVisitor() {
+ @Override
+ public boolean preVisitStatement(Statement statement) {
+ if (statement instanceof MethodInvocation) {
+ MethodInvocation mi = (MethodInvocation)statement;
+ if (mi.getCalledMethodExecution().isConstructor()
+ && mi.getCalledMethodExecution().getReturnValue().equals(newObjectId)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ @Override
+ public boolean postVisitStatement(Statement statement) { return false; }
+ }, before);
+ if (before != null) {
+ return before;
+ }
+ return null;
+ }
+
+ public TracePoint getFieldUpdateTracePoint(final Reference ref, TracePoint before) {
+ before = before.duplicate();
+ final String srcType = ref.getSrcClassName();
+ final String dstType = ref.getDstClassName();
+ final String srcObjId = ref.getSrcObjectId();
+ final String dstObjId = ref.getDstObjectId();
+
+ before = traverseStatementsInTraceBackward(new IStatementVisitor() {
+ @Override
+ public boolean preVisitStatement(Statement statement) {
+ if (statement instanceof FieldUpdate) {
+ FieldUpdate fu = (FieldUpdate)statement;
+ if (fu.getContainerObjId().equals(srcObjId)
+ && fu.getValueObjId().equals(dstObjId)) {
+ // �I�u�W�F�N�gID���݂��Ɉ�v�����ꍇ
+ return true;
+ } else if ((srcObjId == null || isNull(srcObjId)) && fu.getContainerClassName().equals(srcType)) {
+ if ((dstObjId == null || isNull(dstObjId)) && fu.getValueClassName().equals(dstType)) {
+ // ref �ɃI�u�W�F�N�gID���w�肵�Ă��Ȃ������ꍇ
+ ref.setSrcObjectId(fu.getContainerObjId());
+ ref.setDstObjectId(fu.getValueObjId());
+ return true;
+ } else if (fu.getValueObjId().equals(dstObjId)) {
+ // �N���X�ϐ��ւ̑���̏ꍇ
+ ref.setSrcObjectId(srcObjId);
+ ref.setDstClassName(dstType);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ @Override
+ public boolean postVisitStatement(Statement statement) { return false; }
+ }, before);
+ if (before != null) {
+ return before;
+ }
+ return null;
+ }
+
+ public TracePoint getCollectionAddTracePoint(final Reference ref, TracePoint before) {
+ final TracePoint[] result = new TracePoint[1];
+ if (traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() {
+ @Override
+ public boolean preVisitThread(ThreadInstance thread) {
+ return false;
+ }
+ @Override
+ public boolean postVisitThread(ThreadInstance thread) {
+ return false;
+ }
+ @Override
+ public boolean preVisitMethodExecution(MethodExecution methodExecution) {
+ return false;
+ }
+ @Override
+ public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) {
+ String srcType = ref.getSrcClassName();
+ String dstType = ref.getDstClassName();
+ String srcObjId = ref.getSrcObjectId();
+ String dstObjId = ref.getDstObjectId();
+ if (methodExecution.isCollectionType() && isCollectionAdd(methodExecution.getSignature())) {
+ if (dstObjId != null && methodExecution.getThisObjId().equals(srcObjId)) {
+ ArrayList args = methodExecution.getArguments();
+ for (int i = 0; i < args.size(); i++) {
+ ObjectReference arg = args.get(i);
+ if (arg.getId().equals(dstObjId)) {
+ ref.setSrcClassName(methodExecution.getThisClassName());
+ ref.setDstClassName(arg.getActualType());
+ result[0] = methodExecution.getCallerTracePoint();
+ return true;
+ }
+ }
+ } else if (dstObjId == null && methodExecution.getThisClassName().equals(srcType)) {
+ ArrayList args = methodExecution.getArguments();
+ for (int i = 0; i < args.size(); i++) {
+ ObjectReference arg = args.get(i);
+ if (arg.getActualType().equals(dstType)) {
+ ref.setSrcObjectId(methodExecution.getThisObjId());
+ ref.setDstObjectId(arg.getId());
+ result[0] = methodExecution.getCallerTracePoint();
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+ }, before) != null) {
+ return result[0];
+ }
+ return null;
+ }
+
+ private boolean isCollectionAdd(String methodSignature) {
+ return (methodSignature.contains("add(") || methodSignature.contains("set(") || methodSignature.contains("put(") || methodSignature.contains("push("));
+ }
+
+ public TracePoint getArraySetTracePoint(final Reference ref, TracePoint before) {
+ final TracePoint start = before.duplicate();
+ before = traverseStatementsInTraceBackward(new IStatementVisitor() {
+ @Override
+ public boolean preVisitStatement(Statement statement) {
+ if (statement instanceof FieldAccess) {
+ if (isArraySet(ref, start)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ @Override
+ public boolean postVisitStatement(Statement statement) { return false; }
+ }, start);
+ if (before != null) {
+ return before;
+ }
+ return null;
+ }
+
+ private boolean isArraySet(Reference ref, TracePoint fieldAccessPoint) {
+ FieldAccess fieldAccess = (FieldAccess)fieldAccessPoint.getStatement();
+ String srcObjId = ref.getSrcObjectId();
+ String dstObjId = ref.getDstObjectId();
+ if (fieldAccess.getValueClassName().startsWith("[L")
+ && fieldAccess.getValueObjId().equals(srcObjId)) {
+ // srcId �͔z��
+ // ���\�b�h���s�J�n���� fieldAccessPoint �܂ł̊Ԃ̃��\�b�h���s���� dstId ���o��������?
+ TracePoint p = fieldAccessPoint.duplicate();
+ while (p.stepBackOver()) {
+ Statement statement = p.getStatement();
+ if (statement instanceof MethodInvocation) {
+ MethodExecution calledMethod = ((MethodInvocation)statement).getCalledMethodExecution();
+ if (calledMethod.getReturnValue().getId().equals(dstObjId)) {
+ // dstId �͖߂�l�Ƃ��ďo��
+ ref.setSrcClassName(fieldAccess.getValueClassName());
+ ref.setDstClassName(calledMethod.getReturnValue().getActualType());
+ return true;
+ } else if (dstObjId == null || isNull(dstObjId) && calledMethod.getReturnValue().getActualType().equals(ref.getDstClassName())) {
+ // dstClassName �͖߂�l�̌^�Ƃ��ďo��
+ ref.setSrcObjectId(fieldAccess.getValueObjId());
+ ref.setDstObjectId(calledMethod.getReturnValue().getId());
+ return true;
+ }
+ }
+ if (EAGER_DETECTION_OF_ARRAY_SET) {
+ if (statement instanceof FieldAccess) {
+ if (((FieldAccess)statement).getContainerObjId().equals(dstObjId)) {
+ // dstId �̓t�B�[���h�ɏo��
+ ref.setSrcClassName(fieldAccess.getValueClassName());
+ ref.setDstClassName(((FieldAccess)statement).getContainerClassName());
+ return true;
+ } else if (dstObjId == null || isNull(dstObjId) && ((FieldAccess)statement).getContainerClassName().equals(ref.getDstClassName())) {
+ // dstClassName �̓t�B�[���h�̌^�Ƃ��ďo��
+ ref.setSrcObjectId(fieldAccess.getValueObjId());
+ ref.setDstObjectId(((FieldAccess)statement).getContainerObjId());
+ return true;
+ }
+ }
+ }
+ }
+ ArrayList args = fieldAccessPoint.getMethodExecution().getArguments();
+ int argindex = args.indexOf(new ObjectReference(dstObjId));
+ if (argindex != -1) {
+ // dstId �͈����ɏo��
+ ref.setSrcClassName(fieldAccess.getValueClassName());
+ ref.setDstClassName(args.get(argindex).getActualType());
+ return true;
+ } else if (dstObjId == null || isNull(dstObjId)) {
+ for (int j = 0; j < args.size(); j++) {
+ if (args.get(j).getActualType().equals(ref.getDstClassName())) {
+ // dstClassName �͈����̌^�ɏo��
+ ref.setSrcObjectId(fieldAccess.getValueObjId());
+ ref.setDstObjectId(args.get(j).getId());
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public static String getDeclaringType(String methodSignature, boolean isConstructor) {
+ if (isConstructor) {
+ String[] fragments = methodSignature.split("\\(");
+ return fragments[0].substring(fragments[0].lastIndexOf(' ') + 1);
+ }
+ String[] fragments = methodSignature.split("\\(");
+ return fragments[0].substring(fragments[0].lastIndexOf(' ') + 1, fragments[0].lastIndexOf('.'));
+ }
+
+ public static String getMethodName(String methodSignature) {
+ String[] fragments = methodSignature.split("\\(");
+ String[] fragments2 = fragments[0].split("\\.");
+ return fragments2[fragments2.length - 1];
+ }
+
+ public static String getReturnType(String methodSignature) {
+ String[] fragments = methodSignature.split(" ");
+ for (int i = 0; i < fragments.length; i++) {
+ if (!fragments[i].equals("public") && !fragments[i].equals("private") && !fragments[i].equals("protected")
+ && !fragments[i].equals("abstract") && !fragments[i].equals("final") && !fragments[i].equals("static")
+ && !fragments[i].equals("synchronized") && !fragments[i].equals("native")) {
+ return fragments[i];
+ }
+ }
+ return "";
+ }
+
+ public static boolean isNull(String objectId) {
+ return objectId.equals("0");
+ }
+
+ public static String getNull() {
+ return "0";
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TraceJSON.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TraceJSON.java
new file mode 100644
index 0000000..15f2324
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TraceJSON.java
@@ -0,0 +1,390 @@
+package org.ntlab.trace;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Stack;
+
+public class TraceJSON extends Trace {
+ private HashMap classes = new HashMap<>();
+
+ /**
+ * �w�肵��JSON�g���[�X�t�@�C������ǂ��� Trace �I�u�W�F�N�g������
+ * @param traceFile �g���[�X�t�@�C���̃p�X
+ */
+ public TraceJSON(String traceFile) {
+ super();
+ BufferedReader file;
+ try {
+ file = new BufferedReader(new FileReader(traceFile));
+ // �g���[�X�t�@�C���ǂݍ���
+ String line = null;
+ String[] type;
+ String[] classNameData;
+ String[] pathData;
+ String[] signature;
+ String[] receiver;
+ String[] arguments;
+ String[] lineData;
+ String[] threadId;
+ String[] thisObj;
+ String[] containerObj;
+ String[] valueObj;
+ String[] returnValue;
+ String[] arrayObj;
+ String[] thisData;
+ String[] containerData;
+ String[] valueData;
+ String[] returnData;
+ String[] arrayData;
+ String[] blockIdData;
+ String[] incomingsData;
+ String[] dimensionData;
+ String[] indexData;
+ String className;
+ String classPath;
+ String loaderPath;
+ String time;
+ String thisObjectId;
+ String thisClassName;
+ String containerObjectId;
+ String containerClassName;
+ String valueObjectId;
+ String valueClassName;
+ String returnClassName;
+ String returnObjectId;
+ String arrayObjectId;
+ String arrayClassName;
+ String shortSignature;
+ boolean isConstractor = false;
+ boolean isCollectionType = false;
+ boolean isStatic = false;
+ int dimension;
+ int index;
+ int blockId;
+ int incomings;
+ int lineNum;
+ long timeStamp = 0L;
+ ThreadInstance thread = null;
+ HashMap> stacks = new HashMap>();
+ while ((line = file.readLine()) != null) {
+ // �g���[�X�t�@�C���̉��
+ if (line.startsWith("{\"type\":\"classDef\"")) {
+ // �N���X��`
+ type = line.split(",\"name\":\"");
+ classNameData = type[1].split("\",\"path\":\"");
+ className = classNameData[0];
+ pathData = classNameData[1].split("\",\"loaderPath\":\"");
+ classPath = pathData[0].substring(1); // �擪�� / ����菜��
+ loaderPath = pathData[1].substring(1, pathData[1].length() - 3); // �擪�� / �ƁA������ "}, ����菜��
+ initializeClass(className, classPath, loaderPath);
+ } else if (line.startsWith("{\"type\":\"methodCall\"")) {
+ // ���\�b�h�Ăяo���̌Ăяo����
+ type = line.split(",\"callerSideSignature\":\"");
+ signature = type[1].split("\",\"threadId\":");
+ threadId = signature[1].split(",\"lineNum\":");
+ lineNum = Integer.parseInt(threadId[1].substring(0, threadId[1].length() - 2)); // ������ }, ����菜��
+ thread = threads.get(threadId[0]);
+ thread.preCallMethod(signature[0], lineNum);
+ } else if (line.startsWith("{\"type\":\"methodEntry\"")) {
+ // ���\�b�h�Ăяo��
+ type = line.split("\"signature\":\"");
+ signature = type[1].split("\",\"receiver\":");
+ receiver = signature[1].split(",\"args\":");
+ arguments = receiver[1].split(",\"threadId\":");
+ threadId = arguments[1].split(",\"time\":");
+ thisData = parseClassNameAndObjectId(receiver[0]);
+ thisClassName = thisData[0];
+ thisObjectId = thisData[1];
+ isConstractor = false;
+ isStatic = false;
+ if (signature[0].contains("static ")) {
+ isStatic = true;
+ }
+ thread = threads.get(threadId[0]);
+ time = threadId[1].substring(0, threadId[1].length() - 2); // ������ }, ����菜��
+ timeStamp = Long.parseLong(time);
+ Stack stack;
+ if (thread == null) {
+ thread = new ThreadInstance(threadId[0]);
+ threads.put(threadId[0], thread);
+ stack = new Stack();
+ stacks.put(threadId[0], stack);
+ } else {
+ stack = stacks.get(threadId[0]);
+ }
+ stack.push(signature[0]);
+ // ���\�b�h�Ăяo���̐ݒ�
+ thread.callMethod(signature[0], null, thisClassName, thisObjectId, isConstractor, isStatic, timeStamp);
+ // �����̐ݒ�
+ thread.setArgments(parseArguments(arguments));
+ } else if (line.startsWith("{\"type\":\"constructorEntry\"")) {
+ // �R���X�g���N�^�Ăяo��
+ type = line.split("\"signature\":\"");
+ signature = type[1].split("\",\"class\":\"");
+ receiver = signature[1].split("\",\"args\":");
+ arguments = receiver[1].split(",\"threadId\":");
+ threadId = arguments[1].split(",\"time\":");
+ thisClassName = receiver[0];
+ thisObjectId = "0";
+ isConstractor = true;
+ isStatic = false;
+ thread = threads.get(threadId[0]);
+ time = threadId[1].substring(0, threadId[1].length() - 2); // ������ }, ����菜��
+ timeStamp = Long.parseLong(time);
+ Stack stack;
+ if (thread == null) {
+ thread = new ThreadInstance(threadId[0]);
+ threads.put(threadId[0], thread);
+ stack = new Stack();
+ stacks.put(threadId[0], stack);
+ } else {
+ stack = stacks.get(threadId[0]);
+ }
+ stack.push(signature[0]);
+ // ���\�b�h�Ăяo���̐ݒ�
+ thread.callMethod(signature[0], null, thisClassName, thisObjectId, isConstractor, isStatic, timeStamp);
+ // �����̐ݒ�
+ thread.setArgments(parseArguments(arguments));
+ } else if (line.startsWith("{\"type\":\"methodExit\"")) {
+ // ���\�b�h����̕��A
+ type = line.split(",\"shortSignature\":\"");
+ signature = type[1].split("\",\"receiver\":");
+ receiver = signature[1].split(",\"returnValue\":");
+ returnValue = receiver[1].split(",\"threadId\":");
+ threadId = returnValue[1].split(",\"time\":");
+ thisData = parseClassNameAndObjectId(receiver[0]);
+ thisClassName = thisData[0];
+ thisObjectId = thisData[1];
+ returnData = parseClassNameAndObjectId(returnValue[0]);
+ returnClassName = returnData[0];
+ returnObjectId = returnData[1];
+ shortSignature = signature[0];
+ time = threadId[1].substring(0, threadId[1].length() - 2); // ������ }, ����菜��
+ timeStamp = Long.parseLong(time);
+ Stack stack = stacks.get(threadId[0]);
+ if (!stack.isEmpty()) {
+ String line2 = stack.peek();
+ if (line2.endsWith(shortSignature)) {
+ stack.pop();
+ } else {
+ do {
+ line2 = stack.pop();
+ thread.terminateMethod();
+ } while (!stack.isEmpty() && !line2.endsWith(shortSignature));
+ }
+ thread = threads.get(threadId[0]);
+ ObjectReference returnVal = new ObjectReference(returnObjectId, returnClassName);
+ isCollectionType = false;
+ if(thisClassName.contains("java.util.List")
+ || thisClassName.contains("java.util.Vector")
+ || thisClassName.contains("java.util.Iterator")
+ || thisClassName.contains("java.util.ListIterator")
+ || thisClassName.contains("java.util.ArrayList")
+ || thisClassName.contains("java.util.Stack")
+ || thisClassName.contains("java.util.Hash")
+ || thisClassName.contains("java.util.Map")
+ || thisClassName.contains("java.util.Set")
+ || thisClassName.contains("java.util.Linked")
+ || thisClassName.contains("java.lang.Thread")) {
+ isCollectionType = true;
+ }
+ // ���\�b�h����̕��A�̐ݒ�
+ thread.returnMethod(returnVal, thisObjectId, isCollectionType, timeStamp);
+ }
+ } else if (line.startsWith("{\"type\":\"constructorExit\"")) {
+ // �R���X�g���N�^����̕��A
+ type = line.split(",\"shortSignature\":\"");
+ signature = type[1].split("\",\"returnValue\":");
+ returnValue = signature[1].split(",\"threadId\":");
+ threadId = returnValue[1].split(",\"time\":");
+ returnData = parseClassNameAndObjectId(returnValue[0]);
+ thisClassName = returnClassName = returnData[0];
+ thisObjectId = returnObjectId = returnData[1];
+ time = threadId[1].substring(0, threadId[1].length() - 2); // ������ }, ����菜��
+ timeStamp = Long.parseLong(time);
+ Stack stack = stacks.get(threadId[0]);
+ shortSignature = signature[0];
+ if (!stack.isEmpty()) {
+ String line2 = stack.peek();
+ if (line2.endsWith(shortSignature)) {
+ stack.pop();
+ } else {
+ do {
+ line2 = stack.pop();
+ thread.terminateMethod();
+ } while (!stack.isEmpty() && !line2.endsWith(shortSignature));
+ }
+ thread = threads.get(threadId[0]);
+ ObjectReference returnVal = new ObjectReference(returnObjectId, returnClassName);
+ isCollectionType = false;
+ if(thisClassName.contains("java.util.List")
+ || thisClassName.contains("java.util.Vector")
+ || thisClassName.contains("java.util.Iterator")
+ || thisClassName.contains("java.util.ListIterator")
+ || thisClassName.contains("java.util.ArrayList")
+ || thisClassName.contains("java.util.Stack")
+ || thisClassName.contains("java.util.Hash")
+ || thisClassName.contains("java.util.Map")
+ || thisClassName.contains("java.util.Set")
+ || thisClassName.contains("java.util.Linked")
+ || thisClassName.contains("java.lang.Thread")) {
+ isCollectionType = true;
+ }
+ // ���\�b�h����̕��A�̐ݒ�
+ thread.returnMethod(returnVal, thisObjectId, isCollectionType, timeStamp);
+ }
+ } else if (line.startsWith("{\"type\":\"fieldGet\"")) {
+ // �t�B�[���h�A�N�Z�X
+ type = line.split("\"this\":");
+ thisObj = type[1].split(",\"container\":");
+ containerObj = thisObj[1].split(",\"value\":");
+ valueObj = containerObj[1].split(",\"threadId\":");
+ threadId = valueObj[1].split(",\"lineNum\":");
+ lineData = threadId[1].split(",\"time\":");
+ thisData = parseClassNameAndObjectId(thisObj[0]);
+ thisClassName = thisData[0];
+ thisObjectId = thisData[1];
+ containerData = parseClassNameAndObjectId(containerObj[0]);
+ containerClassName = containerData[0];
+ containerObjectId = containerData[1];
+ valueData = parseClassNameAndObjectId(valueObj[0]);
+ valueClassName = valueData[0];
+ valueObjectId = valueData[1];
+ thread = threads.get(threadId[0]);
+ lineNum = Integer.parseInt(lineData[0]);
+ time = lineData[1].substring(0, lineData[1].length() - 2); // ������ }, ����菜��
+ timeStamp = Long.parseLong(time);
+ // �t�B�[���h�A�N�Z�X�̐ݒ�
+ if (thread != null) thread.fieldAccess(valueClassName, valueObjectId, containerClassName, containerObjectId, thisClassName, thisObjectId, lineNum, timeStamp);
+ } else if (line.startsWith("{\"type\":\"fieldSet\"")) {
+ // �t�B�[���h�X�V
+ type = line.split(",\"container\":");
+ containerObj = type[1].split(",\"value\":");
+ valueObj = containerObj[1].split(",\"threadId\":");
+ threadId = valueObj[1].split(",\"lineNum\":");
+ lineData = threadId[1].split(",\"time\":");
+ containerData = parseClassNameAndObjectId(containerObj[0]);
+ containerClassName = containerData[0];
+ containerObjectId = containerData[1];
+ valueData = parseClassNameAndObjectId(valueObj[0]);
+ valueClassName = valueData[0];
+ valueObjectId = valueData[1];
+ thread = threads.get(threadId[0]);
+ lineNum = Integer.parseInt(lineData[0]);
+ time = lineData[1].substring(0, lineData[1].length() - 2); // ������ }, ����菜��
+ timeStamp = Long.parseLong(time);
+ // �t�B�[���h�X�V�̐ݒ�
+ if (thread != null) thread.fieldUpdate(valueClassName, valueObjectId, containerClassName, containerObjectId, lineNum, timeStamp);
+ } else if (line.startsWith("{\"type\":\"arrayCreate\"")) {
+ // �z��
+ type = line.split(",\"array\":");
+ arrayObj = type[1].split(",\"dimension\":");
+ arrayData = parseClassNameAndObjectId(arrayObj[0]);
+ arrayClassName = arrayData[0];
+ arrayObjectId = arrayData[1];
+ dimensionData = arrayObj[1].split(",\"threadId\":");
+ dimension = Integer.parseInt(dimensionData[0]);
+ threadId = dimensionData[1].split(",\"lineNum\":");
+ thread = threads.get(threadId[0]);
+ lineData = threadId[1].split(",\"time\":");
+ lineNum = Integer.parseInt(lineData[0]);
+ time = lineData[1].substring(0, lineData[1].length() - 2); // ������ }, ����菜��
+ timeStamp = Long.parseLong(time);
+ if (thread != null) thread.arrayCreate(arrayClassName, arrayObjectId, dimension, lineNum, timeStamp);
+ } else if (line.startsWith("{\"type\":\"arraySet\"")) {
+ // �z��v�f�ւ̑��
+ type = line.split(",\"array\":");
+ arrayObj = type[1].split(",\"index\":");
+ arrayData = parseClassNameAndObjectId(arrayObj[0]);
+ arrayClassName = arrayData[0];
+ arrayObjectId = arrayData[1];
+ indexData = arrayObj[1].split(",\"value\":");
+ index = Integer.parseInt(indexData[0]);
+ valueObj = indexData[1].split(",\"threadId\":");
+ valueData = parseClassNameAndObjectId(valueObj[0]);
+ valueClassName = valueData[0];
+ valueObjectId = valueData[1];
+ threadId = valueObj[1].split(",\"time\":");
+ thread = threads.get(threadId[0]);
+ time = threadId[1].substring(0, threadId[1].length() - 2); // ������ }, ����菜��
+ timeStamp = Long.parseLong(time);
+ if (thread != null) thread.arraySet(arrayClassName, arrayObjectId, index, valueClassName, valueObjectId, 0, timeStamp);
+ } else if (line.startsWith("{\"type\":\"arrayGet\"")) {
+ // �z��v�f�̎Q��
+ type = line.split(",\"array\":");
+ arrayObj = type[1].split(",\"index\":");
+ arrayData = parseClassNameAndObjectId(arrayObj[0]);
+ arrayClassName = arrayData[0];
+ arrayObjectId = arrayData[1];
+ indexData = arrayObj[1].split(",\"value\":");
+ index = Integer.parseInt(indexData[0]);
+ valueObj = indexData[1].split(",\"threadId\":");
+ valueData = parseClassNameAndObjectId(valueObj[0]);
+ valueClassName = valueData[0];
+ valueObjectId = valueData[1];
+ threadId = valueObj[1].split(",\"time\":");
+ thread = threads.get(threadId[0]);
+ time = threadId[1].substring(0, threadId[1].length() - 2); // ������ }, ����菜��
+ timeStamp = Long.parseLong(time);
+ if (thread != null) thread.arrayGet(arrayClassName, arrayObjectId, index, valueClassName, valueObjectId, 0, timeStamp);
+ } else if (line.startsWith("{\"type\":\"blockEntry\"")) {
+ // �u���b�N�̊J�n
+ type = line.split(",\"methodSignature\":\"");
+ signature = type[1].split("\",\"blockId\":");
+ blockIdData = signature[1].split(",\"incomings\":");
+ blockId = Integer.parseInt(blockIdData[0]);
+ incomingsData = blockIdData[1].split(",\"threadId\":");
+ incomings = Integer.parseInt(incomingsData[0]);
+ threadId = incomingsData[1].split(",\"lineNum\":");
+ thread = threads.get(threadId[0]);
+ lineData = threadId[1].split(",\"time\":");
+ lineNum = Integer.parseInt(lineData[0]);
+ time = lineData[1].substring(0, lineData[1].length() - 2); // ������ }, ����菜��
+ timeStamp = Long.parseLong(time);
+ if (thread != null) thread.blockEnter(blockId, incomings, lineNum, timeStamp);
+ }
+ }
+ file.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * �N���X���ƃI�u�W�F�N�gID��\��JSON�I�u�W�F�N�g����ǂ���
+ * @param classNameAndObjectIdJSON �g���[�X�t�@�C������JSON�I�u�W�F�N�g
+ * @return
+ */
+ protected String[] parseClassNameAndObjectId(String classNameAndObjectIdJSON) {
+ // �擪�� {"class":" ��10�����Ɩ����� } ����菜���ĕ���
+ return classNameAndObjectIdJSON.substring(10, classNameAndObjectIdJSON.length() - 1).split("\",\"id\":");
+ }
+
+ /**
+ * ������\��JSON�z�����ǂ���
+ * @param arguments
+ * @return
+ */
+ protected ArrayList parseArguments(String[] arguments) {
+ String[] argData;
+ argData = arguments[0].substring(1, arguments[0].length() - 1).split(","); // �擪�� [ �Ɩ����� ] ����菜��
+ ArrayList argumentsData = new ArrayList();
+ for (int k = 0; k < argData.length - 1; k += 2) {
+ argumentsData.add(new ObjectReference(argData[k+1].substring(5, argData[k+1].length() - 1), argData[k].substring(10, argData[k].length() - 1)));
+ }
+ return argumentsData;
+ }
+
+ public void initializeClass(String name, String path, String loaderPath) {
+ classes.put(name, new ClassInfo(name, path, loaderPath));
+ }
+
+ public ClassInfo getClassInfo(String className) {
+ return classes.get(className);
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TracePoint.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TracePoint.java
new file mode 100644
index 0000000..380b846
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TracePoint.java
@@ -0,0 +1,175 @@
+package org.ntlab.trace;
+
+import java.util.ArrayList;
+
+public class TracePoint {
+ private MethodExecution methodExecution;
+ private int order = 0;
+
+ public TracePoint(MethodExecution methodExecution, int order) {
+ this.methodExecution = methodExecution;
+ this.order = order;
+ }
+
+ public TracePoint duplicate() {
+ return new TracePoint(methodExecution, order);
+ }
+
+ public Statement getStatement() {
+ return methodExecution.getStatements().get(order);
+ }
+
+ public MethodExecution getMethodExecution() {
+ return methodExecution;
+ }
+
+ public ArrayList getPreviouslyCalledMethods() {
+ ArrayList children = new ArrayList();
+ ArrayList statements = methodExecution.getStatements();
+ for (int i = 0; i < order; i++) {
+ Statement statement = statements.get(i);
+ if (statement instanceof MethodInvocation) {
+ MethodExecution child = ((MethodInvocation)statement).getCalledMethodExecution();
+ children.add(child);
+ }
+ }
+ return children;
+ }
+
+ /**
+ * �������̑S�T��(�������A���s�����L�^����Ă��Ȃ����\�b�h���s�ɂ͐���Ȃ�)
+ * @return false: ����ȏ�H��Ȃ��ꍇ, true: ����ȊO
+ */
+ public boolean stepFull() {
+ if (getStatement() instanceof MethodInvocation) {
+ MethodExecution calledMethodExecution = ((MethodInvocation)getStatement()).getCalledMethodExecution();
+ if (calledMethodExecution.getStatements().size() > 0) {
+ methodExecution = calledMethodExecution;
+ order = 0;
+ return true;
+ }
+ }
+ while (order >= methodExecution.getStatements().size() - 1) {
+ order = methodExecution.getCallerStatementExecution();
+ methodExecution = methodExecution.getCallerMethodExecution();
+ if (methodExecution == null) {
+ order = -1;
+ return false;
+ }
+ }
+ order++;
+ return true;
+ }
+
+ /**
+ * �t�����̑S�T��(�������A���s�����L�^����Ă��Ȃ����\�b�h���s�ɂ͐���Ȃ��B�܂��A�Ăяo����̃��\�b�h���s����T��������ɁA�Ăяo�����̃��\�b�h�Ăяo������K�₷��̂Œ���!!)
+ * @return false: ����ȏ�H��Ȃ��ꍇ, true: ����ȊO
+ */
+ public boolean stepBackFull() {
+ if (order <= 0) {
+ order = methodExecution.getCallerStatementExecution();
+ methodExecution = methodExecution.getCallerMethodExecution();
+ if (methodExecution == null) {
+ order = -1;
+ return false;
+ }
+ return true;
+ }
+ order--;
+ while (getStatement() instanceof MethodInvocation) {
+ MethodExecution calledMethodExecution = ((MethodInvocation)getStatement()).getCalledMethodExecution();
+ if (calledMethodExecution.getStatements().size() == 0) break;
+ methodExecution = calledMethodExecution;
+ order = methodExecution.getStatements().size() - 1;
+ }
+ return true;
+ }
+
+ /**
+ * �������ɒT������B�Ăяo�����ɖ߂邪�Ăяo����ɂ͐���Ȃ��B
+ * @return false: �Ăяo�����ɖ߂����ꍇ�܂��͂���ȏ�H��Ȃ��ꍇ, true: ����ȊO
+ */
+ public boolean stepOver() {
+ if (order < methodExecution.getStatements().size() - 1) {
+ order++;
+ return true;
+ }
+ order = methodExecution.getCallerStatementExecution();
+ methodExecution = methodExecution.getCallerMethodExecution();
+ if (methodExecution == null) {
+ order = -1;
+ return false;
+ }
+ return false;
+ }
+
+ /**
+ * �t�����ɒT������B�Ăяo�����ɖ߂邪�Ăяo����ɂ͐���Ȃ��B
+ * @return false: �Ăяo�����ɖ߂����ꍇ�܂��͂���ȏ�H��Ȃ��ꍇ, true: ����ȊO
+ */
+ public boolean stepBackOver() {
+ if (order > 0) {
+ order--;
+ return true;
+ }
+ order = methodExecution.getCallerStatementExecution();
+ methodExecution = methodExecution.getCallerMethodExecution();
+ if (methodExecution == null) {
+ order = -1;
+ return false;
+ }
+ return false;
+ }
+
+ /**
+ * �������ɒT������B�Ăяo�����H�邪�Ăяo�����ɂ͖߂�Ȃ��B
+ * @return false: �Ăяo����Ɉڂ����ꍇ�܂��͂���ȏ�H��Ȃ��ꍇ, true: ����ȊO
+ */
+ public boolean stepNoReturn() {
+ if (getStatement() instanceof MethodInvocation) {
+ methodExecution = ((MethodInvocation)getStatement()).getCalledMethodExecution();
+ if (methodExecution.getStatements().size() > 0) {
+ order = 0;
+ } else {
+ order = -1; // �Ăяo����Ŏ��s�����L�^����Ă��Ȃ��ꍇ
+ }
+ return false;
+ }
+ order++;
+ if (order < methodExecution.getStatements().size()) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * �t�����ɒT������B�Ăяo�����H�邪�Ăяo�����ɂ͖߂�Ȃ��B(��ɌĂяo�����̃��\�b�h�Ăяo������K�₵�Ă���Ăяo����̃��\�b�h���s��K�₷��̂Œ���!!)
+ * @return�@false: �Ăяo����Ɉڂ����ꍇ�܂��͂���ȏ�H��Ȃ��ꍇ, true: ����ȊO
+ */
+ public boolean stepBackNoReturn() {
+ if (getStatement() instanceof MethodInvocation) {
+ methodExecution = ((MethodInvocation)getStatement()).getCalledMethodExecution();
+ order = methodExecution.getStatements().size() - 1; // -1 �ɂȂ�ꍇ������(�Ăяo����Ŏ��s�����L�^����Ă��Ȃ��ꍇ)
+ return false;
+ }
+ order--;
+ if (order >= 0) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isValid() {
+ if (methodExecution == null || order == -1 || order >= methodExecution.getStatements().size()) return false;
+ return true;
+ }
+
+ public boolean isMethodEntry() {
+ return (order == 0);
+ }
+
+ public boolean isStepBackOut() {
+ if (order < 0) return true;
+ return false;
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/Activator.java b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/Activator.java
new file mode 100644
index 0000000..72e18e2
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/Activator.java
@@ -0,0 +1,102 @@
+package org.ntlab.traceanalyzer;
+
+import java.util.Hashtable;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class Activator extends AbstractUIPlugin implements BundleActivator, ServiceListener {
+
+ public static final String PLUGIN_ID = "org.ntlab.traceAnalyzer"; //$NON-NLS-1$
+
+ private DictionaryService service;
+ private ServiceTracker dictionaryServiceTracker;
+ private BundleContext fContext;
+
+ private static Activator plugin;
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ fContext = context;
+ service = new DictionaryServiceImpl();
+
+ Hashtable props = new Hashtable();
+ // register the service
+ context.registerService(DictionaryService.class.getName(), service, props);
+
+ // create a tracker and track the service
+ dictionaryServiceTracker = new ServiceTracker(context, DictionaryService.class.getName(), null);
+ dictionaryServiceTracker.open();
+
+ // have a service listener to implement the whiteboard pattern
+ fContext.addServiceListener(this, "(objectclass=" + Dictionary.class.getName() + ")");
+
+ // grab the service
+ service = (DictionaryService) dictionaryServiceTracker.getService();
+
+ // register the dictionary
+ service.registerDictionary(new DictionaryImpl());
+
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ // close the service tracker
+ dictionaryServiceTracker.close();
+ dictionaryServiceTracker = null;
+
+ service = null;
+ fContext = null;
+ plugin = null;
+ }
+
+ public void serviceChanged(ServiceEvent ev) {
+ ServiceReference sr = ev.getServiceReference();
+ switch(ev.getType()) {
+ case ServiceEvent.REGISTERED:
+ {
+ Dictionary dictionary = (Dictionary) fContext.getService(sr);
+ service.registerDictionary(dictionary);
+ }
+ break;
+ case ServiceEvent.UNREGISTERING:
+ {
+ Dictionary dictionary = (Dictionary) fContext.getService(sr);
+ service.unregisterDictionary(dictionary);
+ }
+ break;
+ }
+ }
+
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ @Override
+ protected void initializeImageRegistry(ImageRegistry reg) {
+ reg.put("TraceAnalyzer.STACK_FRAME_IMAGE", getImageDescriptor("/icons/full/stckframe_obj.gif"));
+ reg.put("TraceAnalyzer.STACK_FRAME_IMAGE2", getImageDescriptor("/icons/full/stckframe_obj2.gif"));
+ reg.put("TraceAnalyzer.STACK_FRAME_IMAGE3", getImageDescriptor("/icons/full/stckframe_obj3.gif"));
+ reg.put("TraceAnalyzer.THREAD_IMAGE", getImageDescriptor("/icons/full/threads_obj.gif"));
+ reg.put("TraceAnalyzer.THREAD_IMAGE2", getImageDescriptor("/icons/full/threads_obj2.gif"));
+ reg.put("TraceAnalyzer.HIGHLIGHT_UNIQUE_IMAGE", getImageDescriptor("/icons/full/read_obj.gif"));
+ }
+
+ public static ImageDescriptor getImageDescriptor(String path) {
+ return imageDescriptorFromPlugin(PLUGIN_ID, path);
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/CallTreeContentProvider.java b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/CallTreeContentProvider.java
new file mode 100644
index 0000000..7a151f3
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/CallTreeContentProvider.java
@@ -0,0 +1,35 @@
+package org.ntlab.traceanalyzer;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+public class CallTreeContentProvider implements ITreeContentProvider {
+
+ public Object[] getChildren(Object parentElement) {
+ Object[] children = null;
+ if (parentElement instanceof MarkedThread) {
+ children = ((MarkedThread)parentElement).getChildren().toArray();
+ } else {
+ children = ((MarkedMethodExecution)parentElement).getChildren().toArray();
+ }
+ return children==null ? new Object[0] : children;
+ }
+
+ public Object getParent(Object element) {
+ return ((MarkedMethodExecution)element).getParent();
+ }
+
+ public boolean hasChildren(Object element) {
+ return getChildren(element).length == 0 ? false : true;
+ }
+
+ public Object[] getElements(Object inputElement) {
+ return ((MarkedTrace)inputElement).getMarkedThreads().toArray();
+ }
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/CallTreeLabelProvider.java b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/CallTreeLabelProvider.java
new file mode 100644
index 0000000..f1e33fe
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/CallTreeLabelProvider.java
@@ -0,0 +1,56 @@
+package org.ntlab.traceanalyzer;
+
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.views.ViewsPlugin;
+
+public class CallTreeLabelProvider extends LabelProvider {
+ public Image getImage(Object element) {
+ if (element instanceof MarkedMethodExecution){
+ int uniqueness = ((MarkedMethodExecution)element).isUniqueMethodInvokedFrom();
+ ImageRegistry registry = Activator.getDefault().getImageRegistry();
+ Image image;
+ switch (uniqueness) {
+ case 1:
+ image = registry.get("TraceAnalyzer.STACK_FRAME_IMAGE2");
+ break;
+ case 2:
+ image = registry.get("TraceAnalyzer.STACK_FRAME_IMAGE3");
+ break;
+ case 0:
+ default:
+ image = registry.get("TraceAnalyzer.STACK_FRAME_IMAGE");
+ }
+ return image;
+ } else if(element instanceof MarkedThread){
+ int uniqueness = ((MarkedThread)element).isUniqueMethodInvokedFrom();
+ ImageRegistry registry = Activator.getDefault().getImageRegistry();
+ Image image;
+ switch (uniqueness) {
+ case 1:
+ image = registry.get("TraceAnalyzer.THREAD_IMAGE2");
+ break;
+ case 0:
+ default:
+ image = registry.get("TraceAnalyzer.THREAD_IMAGE");
+ }
+ return image;
+ } else {
+ return null;
+ }
+ }
+
+ public String getText(Object element) {
+ String name = null;
+ if (element instanceof MarkedMethodExecution){
+ MarkedMethodExecution method = (MarkedMethodExecution)element;
+ name = method.getSignature();
+ } else if (element instanceof MarkedThread){
+ name = ((MarkedThread)element).getId();
+ }
+ return name;
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/CallTreeView.java b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/CallTreeView.java
new file mode 100644
index 0000000..38bfc95
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/CallTreeView.java
@@ -0,0 +1,258 @@
+package org.ntlab.traceanalyzer;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
+import org.ntlab.trace.ClassInfo;
+import org.ntlab.trace.Trace;
+
+public class CallTreeView extends ViewPart {
+ private TreeViewer viewer;
+ private IAction openAction;
+ private IAction markAction;
+ private IAction highlightAction;
+ private MarkedTrace markedTrace;
+ private Shell shell;
+
+ @Override
+ public void createPartControl(Composite parent) {
+ shell = parent.getShell();
+ viewer = new TreeViewer(parent);
+ viewer.setContentProvider(new CallTreeContentProvider());
+ viewer.setLabelProvider(new CallTreeLabelProvider());
+ viewer.setInput(null);
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ IStructuredSelection sel = (IStructuredSelection)event.getSelection();
+ Object element = sel.getFirstElement();
+ if (element instanceof MarkedMethodExecution) {
+ String className = ((MarkedMethodExecution)element).getDeclaringClassName();
+ String methodSignature = ((MarkedMethodExecution)element).getSignature();
+ ClassInfo classInfo = markedTrace.getClassInfo(className);
+ if (classInfo == null) {
+ className = ((MarkedMethodExecution)element).getReceiverClassName();
+ classInfo = markedTrace.getClassInfo(className);
+ }
+ if (classInfo != null) {
+ String projectPath = classInfo.getLoaderPath();
+ IJavaProject javaProject = findJavaProject(projectPath);
+ if (javaProject != null) {
+ openInJavaEditor(javaProject, className, methodSignature);
+ }
+ }
+ }
+ }
+ });
+ getSite().setSelectionProvider(viewer);
+ createActions();
+ createToolBar();
+ createMenuBar();
+ }
+
+ /** �A�N�V�������쐬 */
+ private void createActions(){
+ // �g���[�X�t�@�C�����J���A�N�V�������쐬
+ ImageDescriptor openIcon = PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER);
+ openAction = new Action("Open Trace File...", openIcon){
+ public void run(){
+ // �g���[�X�o�͐�Q�ƃE�B�U�[�h
+ FileDialog dialog = new FileDialog(shell, SWT.OPEN);
+ dialog.setText("Open Trace File");
+ dialog.setFilterExtensions(new String[]{"*.*"});
+ String path = dialog.open();
+ if (path == null) {
+ return;
+ }
+ markedTrace = new MarkedTrace(path);
+ viewer.setInput(markedTrace);
+ viewer.refresh();
+ highlightAction.setChecked(false);
+ }
+ };
+
+ // �g���[�X�Ƀ}�[�N����A�N�V�������쐬
+ ImageDescriptor markIcon = PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OPEN_MARKER);
+ markAction = new Action("Mark Trace...", markIcon){
+ public void run(){
+ final Shell traceMarkShell = new Shell(SWT.TITLE | SWT.ON_TOP | SWT.CLOSE); // �}�[�N�w����
+ traceMarkShell.setText("Mark Trace");
+ traceMarkShell.setSize(250, 150);
+ traceMarkShell.setLayout(new FormLayout());
+
+ // �J�n����(���x��)
+ Label startTimeLabel = new Label(traceMarkShell, SWT.NULL);
+ startTimeLabel.setText("Start Time:");
+ FormData startTimeLabelForm = new FormData();
+ startTimeLabelForm.top = new FormAttachment(10, 5);
+ startTimeLabelForm.left = new FormAttachment(5, 5);
+ startTimeLabel.setLayoutData(startTimeLabelForm);
+
+ // �J�n����(�e�L�X�g�{�b�N�X)
+ final Text startTimeText = new Text(traceMarkShell, SWT.BORDER | SWT.SINGLE | SWT.WRAP);
+ startTimeText.setText(Long.toString(markedTrace.getMarkStart()));
+ FormData startTimeTextForm = new FormData();
+ startTimeTextForm.top = new FormAttachment(10, 5);
+ startTimeTextForm.left = new FormAttachment(35, 10);
+ startTimeTextForm.right = new FormAttachment(95, -5);
+ startTimeText.setLayoutData(startTimeTextForm);
+
+ // �I������(���x��)
+ Label endTimeLabel = new Label(traceMarkShell, SWT.NULL);
+ endTimeLabel.setText("End Time:");
+ FormData endTimeLabelForm = new FormData();
+ endTimeLabelForm.top = new FormAttachment(30, 5);
+ endTimeLabelForm.left = new FormAttachment(5, 5);
+ endTimeLabel.setLayoutData(endTimeLabelForm);
+
+ // �I�����ԓ���(�e�L�X�g�{�b�N�X)
+ final Text endTimeText = new Text(traceMarkShell, SWT.BORDER | SWT.SINGLE | SWT.WRAP);
+ endTimeText.setText(Long.toString(markedTrace.getMarkEnd()));
+ FormData endTimeTextForm = new FormData();
+ endTimeTextForm.top = new FormAttachment(30, 5);
+ endTimeTextForm.left = new FormAttachment(35, 10);
+ endTimeTextForm.right = new FormAttachment(95, -5);
+ endTimeText.setLayoutData(endTimeTextForm);
+
+ //OK�{�^��
+ Button okButton = new Button(traceMarkShell, SWT.PUSH);
+ okButton.setText("OK");
+ FormData okButtonForm = new FormData();
+ okButtonForm.bottom = new FormAttachment(100, -5);
+ okButtonForm.right = new FormAttachment(95, -5);
+ okButton.setLayoutData(okButtonForm);
+ okButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e){
+ if (markedTrace != null) {
+ String startText = startTimeText.getText();
+ String endText = endTimeText.getText();
+ try {
+ long start = Long.parseLong(startText);
+ long end = Long.parseLong(endText);
+ traceMarkShell.close();
+ markedTrace.mark(start, end);
+ viewer.setInput(markedTrace);
+ viewer.refresh();
+ highlightAction.setChecked(false);
+ } catch (NumberFormatException ex) {
+ }
+ } else {
+ traceMarkShell.close();
+ }
+ }
+ });
+
+ traceMarkShell.open();
+ }
+ };
+
+ // �}�[�N�ŗL�̃��\�b�h����������A�N�V�������쐬
+ ImageRegistry registry = Activator.getDefault().getImageRegistry();
+ ImageDescriptor highlightIcon = registry.getDescriptor("TraceAnalyzer.HIGHLIGHT_UNIQUE_IMAGE");
+ highlightAction = new Action("Highlight Unique Methods", Action.AS_CHECK_BOX){
+ public void run(){
+ if (markedTrace != null) {
+ if (isChecked()) {
+ markedTrace.setHighlightUniqueMethods(true);
+ viewer.setInput(markedTrace);
+ viewer.refresh();
+ } else {
+ markedTrace.setHighlightUniqueMethods(false);
+ viewer.setInput(markedTrace);
+ viewer.refresh();
+ }
+ }
+ }
+ };
+ highlightAction.setImageDescriptor(highlightIcon);
+ }
+
+ /** �c�[���o�[�ɃA�N�V������lj� */
+ private void createToolBar(){
+ IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager();
+ mgr.add(openAction);
+ mgr.add(markAction);
+ mgr.add(highlightAction);
+ }
+
+ /** ���j���[�o�[�ɃA�N�V������lj� */
+ private void createMenuBar(){
+ IMenuManager mgr = getViewSite().getActionBars().getMenuManager();
+ mgr.add(openAction);
+ mgr.add(markAction);
+ }
+
+ public void setFocus() {
+ viewer.getTree().setFocus();
+ }
+
+ private IJavaProject findJavaProject(String projectPath) {
+ IJavaProject javaProject = null;
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ IProject[] projects = root.getProjects();
+ for (IProject project: projects) {
+ if (projectPath.startsWith(project.getLocation().toString())) {
+ javaProject = JavaCore.create(project);
+ break;
+ }
+ }
+ return javaProject;
+ }
+
+ private void openInJavaEditor(IJavaProject javaProject, String className, String methodSignature) {
+ try {
+ IType type = javaProject.findType(className);
+ if (type != null) {
+ IEditorPart editor = JavaUI.openInEditor(type);
+ if (!type.isLocal() && !type.isMember()) {
+ for (IMethod method: type.getMethods()) {
+ if (methodSignature.contains(method.getElementName())) {
+ JavaUI.revealInEditor(editor, (IJavaElement)method);
+ }
+ }
+ }
+ }
+ } catch (PartInitException | JavaModelException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/Dictionary.java b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/Dictionary.java
new file mode 100644
index 0000000..55dbad5
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/Dictionary.java
@@ -0,0 +1,21 @@
+package org.ntlab.traceanalyzer;
+
+public interface Dictionary {
+
+ /**
+ * Returns the language of the dictionary
+ *
+ * @return the language of the dictionary
+ */
+ public String getLanguage();
+
+ /**
+ * Check for the existence of a word in the dictionary
+ *
+ * @param word the word to be checked.
+ * @return true if the word is in the dictionary
+ */
+ public boolean check(String word);
+
+
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/DictionaryImpl.java b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/DictionaryImpl.java
new file mode 100644
index 0000000..897c991
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/DictionaryImpl.java
@@ -0,0 +1,24 @@
+package org.ntlab.traceanalyzer;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class DictionaryImpl implements Dictionary {
+
+ private List fWords = new ArrayList(Arrays.asList("osgi", "eclipse", "equinox"));
+ private String fLanguage = "en_US";
+
+ public String getLanguage() {
+ return fLanguage;
+ }
+
+ public boolean check(String word) {
+ return fWords.contains(word);
+ }
+
+ public String toString() {
+ return fLanguage;
+ }
+
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/DictionaryService.java b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/DictionaryService.java
new file mode 100644
index 0000000..86ba8ca
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/DictionaryService.java
@@ -0,0 +1,28 @@
+package org.ntlab.traceanalyzer;
+
+public interface DictionaryService {
+
+ /**
+ * Register a dictionary
+ *
+ * @param dictionary the dictionary to be added.
+ */
+ public void registerDictionary(Dictionary dictionary);
+
+ /**
+ * Remove a dictionary
+ *
+ * @param dictionary the dictionary to be removed.
+ */
+ public void unregisterDictionary(Dictionary dictionary);
+
+ /**
+ * Check for the existence of a word across all dictionaries
+ *
+ * @param word the word to be checked.
+ * @return true if the word is in any dictionary
+ */
+ public boolean check(String word);
+
+
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/DictionaryServiceImpl.java b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/DictionaryServiceImpl.java
new file mode 100644
index 0000000..50b8e08
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/DictionaryServiceImpl.java
@@ -0,0 +1,28 @@
+package org.ntlab.traceanalyzer;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class DictionaryServiceImpl implements DictionaryService {
+
+ private List fDictionaries = new ArrayList();
+
+ public void registerDictionary(Dictionary dictionary) {
+ fDictionaries.add(dictionary);
+ }
+
+ public void unregisterDictionary(Dictionary dictionary) {
+ fDictionaries.remove(dictionary);
+ }
+
+ public boolean check(String word) {
+ for (int i = 0; i < fDictionaries.size(); i++ ) {
+ Dictionary dictionary = (Dictionary) fDictionaries.get(i);
+ if(dictionary.check(word))
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/MarkedMethodExecution.java b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/MarkedMethodExecution.java
new file mode 100644
index 0000000..c439a65
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/MarkedMethodExecution.java
@@ -0,0 +1,91 @@
+package org.ntlab.traceanalyzer;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+import org.ntlab.trace.MethodExecution;
+
+public class MarkedMethodExecution {
+ private MethodExecution methodExecution;
+ private ArrayList children = null;
+ private int uniqueMethodInvokedFrom = 0;
+
+ public MarkedMethodExecution(MethodExecution methodExecution) {
+ this.methodExecution = methodExecution;
+ }
+
+ public void addChild(MarkedMethodExecution child) {
+ if (children == null) {
+ children = new ArrayList();
+ }
+ children.add(child);
+ }
+
+ public ArrayList getChildren() {
+ if (children == null) {
+ ArrayList rawChildren = methodExecution.getChildren();
+ children = new ArrayList();
+ for (int i = 0; i < rawChildren.size(); i++) {
+ children.add(0, new MarkedMethodExecution(rawChildren.get(i)));
+ }
+ }
+ return children;
+ }
+
+ public Object getParent() {
+ return methodExecution.getParent();
+ }
+
+ public String getSignature() {
+ return methodExecution.getSignature();
+ }
+
+ public String getDeclaringClassName() {
+ return methodExecution.getDeclaringClassName();
+ }
+
+ public String getReceiverClassName() {
+ return methodExecution.getThisClassName();
+ }
+
+ /**
+ * �}�[�N�ŗL�̃��\�b�h���Ăяo���ꂽ���ǂ����ׂ�
+ * @param commonMethodSignatures �}�[�N�O�ŌĂяo���ꂽ�S���\�b�h�̃V�O�j�`��
+ */
+ public int searchUniqueMethodInvocation(HashSet commonMethodSignatures) {
+ if (uniqueMethodInvokedFrom > 0) return uniqueMethodInvokedFrom;
+ if (isUniqueMethod(commonMethodSignatures)) uniqueMethodInvokedFrom = 2;
+ ArrayList children = getChildren();
+ for (int i = 0; i < children.size(); i++) {
+ int u = children.get(i).searchUniqueMethodInvocation(commonMethodSignatures);
+ if (uniqueMethodInvokedFrom == 0 && u > 0) uniqueMethodInvokedFrom = 1;
+ }
+ return uniqueMethodInvokedFrom;
+ }
+
+ /**
+ * �}�[�N�ŗL�̃��\�b�h���s�����ׂĎ擾����
+ * @param commonMethodSignatures �}�[�N�O�Ŏ��s���ꂽ�S���\�b�h�̃V�O�j�`��
+ * @return ���̃��\�b�h���s�ȉ��̃}�[�N�ŗL�̑S���\�b�h���s
+ */
+ public void getUniqueMethodExecutions(HashSet commonMethodSignatures, ArrayList uniqueMethodExecutions) {
+ if (isUniqueMethod(commonMethodSignatures)) {
+ uniqueMethodExecutions.add(this);
+ }
+ for (int n = 0; n < children.size(); n++) {
+ children.get(n).getUniqueMethodExecutions(commonMethodSignatures, uniqueMethodExecutions);
+ }
+ }
+
+ /**
+ * ���̃��\�b�h���s����}�[�N�ŗL�̃��\�b�h���Ăяo���ꂽ��?
+ * @return 0: �Ăяo����Ă��Ȃ�, 1: �Ăяo���ꂽ, 2: �������g���}�[�N�ŗL���\�b�h
+ */
+ public int isUniqueMethodInvokedFrom() {
+ return uniqueMethodInvokedFrom;
+ }
+
+ private boolean isUniqueMethod(HashSet commonMethodSignatures) {
+ return !commonMethodSignatures.contains(getSignature());
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/MarkedMethodExecutionVisitor.java b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/MarkedMethodExecutionVisitor.java
new file mode 100644
index 0000000..d2d74d1
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/MarkedMethodExecutionVisitor.java
@@ -0,0 +1,51 @@
+package org.ntlab.traceanalyzer;
+
+import java.util.ArrayList;
+import java.util.Stack;
+
+import org.ntlab.trace.IMethodExecutionVisitor;
+import org.ntlab.trace.MethodExecution;
+import org.ntlab.trace.ThreadInstance;
+
+public class MarkedMethodExecutionVisitor implements IMethodExecutionVisitor {
+ private ArrayList markedThreads = new ArrayList();
+ private ArrayList topMethodExecutions = null;
+ private Stack callStack = new Stack();
+
+ @Override
+ public boolean preVisitThread(ThreadInstance thread) {
+ topMethodExecutions = new ArrayList();
+ return false;
+ }
+
+ @Override
+ public boolean postVisitThread(ThreadInstance thread) {
+ if (topMethodExecutions.size() > 0) markedThreads.add(new MarkedThread(thread.getId(), topMethodExecutions));
+ return false;
+ }
+
+ @Override
+ public boolean preVisitMethodExecution(MethodExecution methodExecution) {
+ MarkedMethodExecution child = new MarkedMethodExecution(methodExecution);
+ if (!callStack.isEmpty()) {
+ MarkedMethodExecution parent = callStack.peek();
+ parent.addChild(child);
+ }
+ callStack.push(child);
+ return false;
+ }
+
+ @Override
+ public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) {
+ MarkedMethodExecution markedMethodExecution = callStack.pop();
+ if (callStack.isEmpty()) {
+ topMethodExecutions.add(markedMethodExecution);
+ }
+ return false;
+ }
+
+ public ArrayList getMarkedThreads() {
+ return markedThreads;
+ }
+
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/MarkedThread.java b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/MarkedThread.java
new file mode 100644
index 0000000..5123d7e
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/MarkedThread.java
@@ -0,0 +1,56 @@
+package org.ntlab.traceanalyzer;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+public class MarkedThread {
+ private String id;
+ private ArrayList methodExecutions;
+ private int uniqueMethodInvokedFrom = 0;
+
+ public MarkedThread(String id, ArrayList methodExecutions) {
+ this.id = id;
+ this.methodExecutions = methodExecutions;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public ArrayList getChildren() {
+ return methodExecutions;
+ }
+
+ /**
+ * �}�[�N�ŗL�̃��\�b�h���Ăяo���ꂽ���ǂ����ׂ�
+ * @param commonMethodSignatures �}�[�N�O�ŌĂяo���ꂽ�S���\�b�h�̃V�O�j�`��
+ */
+ public void searchUniqueMethodInvocation(HashSet commonMethodSignatures) {
+ if (uniqueMethodInvokedFrom > 0) return;
+ for (int i = 0; i < methodExecutions.size(); i++) {
+ int h = methodExecutions.get(i).searchUniqueMethodInvocation(commonMethodSignatures);
+ if (h > 0) uniqueMethodInvokedFrom = 1;
+ }
+ }
+
+ /**
+ * �}�[�N�ŗL�̃��\�b�h���s�����ׂĎ擾����
+ * @param unmarkedMethodSignatures �}�[�N�O�Ŏ��s���ꂽ�S���\�b�h�̃V�O�j�`��
+ * @return ���̃X���b�h���̃}�[�N�ŗL�̑S���\�b�h���s
+ */
+ public ArrayList getUniqueMethodExecutions(HashSet unmarkedMethodSignatures) {
+ ArrayList uniqueMethodExecutions = new ArrayList();
+ for (int i = 0; i < methodExecutions.size(); i++) {
+ methodExecutions.get(i).getUniqueMethodExecutions(unmarkedMethodSignatures, uniqueMethodExecutions);
+ }
+ return null;
+ }
+
+ /**
+ * ���̃X���b�h����}�[�N�ŗL�̃��\�b�h���Ăяo���ꂽ��?
+ * @return 0: �Ăяo����Ă��Ȃ�, 1: �Ăяo���ꂽ
+ */
+ public int isUniqueMethodInvokedFrom() {
+ return uniqueMethodInvokedFrom;
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/MarkedTrace.java b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/MarkedTrace.java
new file mode 100644
index 0000000..a650d6e
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/src/org/ntlab/traceanalyzer/MarkedTrace.java
@@ -0,0 +1,126 @@
+package org.ntlab.traceanalyzer;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+
+import org.ntlab.trace.ClassInfo;
+import org.ntlab.trace.MethodExecution;
+import org.ntlab.trace.ThreadInstance;
+import org.ntlab.trace.Trace;
+import org.ntlab.trace.TraceJSON;
+
+public class MarkedTrace {
+ private Trace trace;
+ private long markStart = -1L;
+ private long markEnd = -1L;
+ private ArrayList markedThreads = null;
+ private boolean bHighlightUniqueMethods = false;
+ /**
+ * �}�[�N�O�Ŏ��s���ꂽ�S���\�b�h���s
+ */
+ private HashSet unmarkedMethodSignatures = null;
+
+ public MarkedTrace(String traceFilePath) {
+ this.trace = new TraceJSON(traceFilePath);
+ markFull();
+ }
+
+ public void setTrace(Trace trace) {
+ this.trace = trace;
+ markFull();
+ }
+
+ public ClassInfo getClassInfo(String className) {
+ if (trace instanceof TraceJSON) {
+ return ((TraceJSON)trace).getClassInfo(className);
+ }
+ return null;
+ }
+
+ public void markFull() {
+ Collection threads = trace.getAllThreads().values();
+ long start = -1L;
+ long end = -1L;
+ for (ThreadInstance thread: threads) {
+ ArrayList roots = thread.getRoot();
+ for (MethodExecution m: roots) {
+ if (start == -1L || m.getEntryTime() < start) {
+ start = m.getEntryTime();
+ }
+ if (end == -1L || m.getExitTime() > end) {
+ end = m.getExitTime(); // JSON�g���[�X�̂ݑΉ�
+ }
+ }
+ }
+ if (end < start) {
+ end = start + 1;
+ }
+ mark(start, end);
+ }
+
+ public void mark(long start, long end) {
+ this.markStart = start;
+ this.markEnd = end;
+ updateMarkedThreads();
+ }
+
+ public long getMarkStart() {
+ return markStart;
+ }
+
+ public long getMarkEnd() {
+ return markEnd;
+ }
+
+ public ArrayList getMarkedThreads() {
+ if (markedThreads == null) {
+ updateMarkedThreads();
+ }
+ return markedThreads;
+ }
+
+ private void updateMarkedThreads() {
+ MarkedMethodExecutionVisitor visitor = new MarkedMethodExecutionVisitor();
+ trace.traverseMarkedMethodExecutions(visitor, markStart, markEnd);
+ markedThreads = visitor.getMarkedThreads();
+ }
+
+ /**
+ * �}�[�N�ŗL�̃��\�b�h����������
+ * @param bHighlightUniqueMethods �}�[�N�ŗL�̃��\�b�h���������邩?
+ */
+ public void setHighlightUniqueMethods(boolean bHighlightUniqueMethods) {
+ this.bHighlightUniqueMethods = bHighlightUniqueMethods;
+ if (bHighlightUniqueMethods) {
+ if (unmarkedMethodSignatures == null) unmarkedMethodSignatures = trace.getUnmarkedMethodSignatures(markStart, markEnd);
+ for (int i = 0; i < markedThreads.size(); i++) {
+ markedThreads.get(i).searchUniqueMethodInvocation(unmarkedMethodSignatures);
+ }
+ }
+ }
+
+ /**
+ * �}�[�N�ŗL�̃��\�b�h���������Ă��邩?
+ * @return
+ */
+ public boolean isbHighlightUniqueMethods() {
+ return bHighlightUniqueMethods;
+ }
+
+ /**
+ * �}�[�N�ŗL�̃��\�b�h���s�����ׂĎ擾����
+ * @return�@�}�[�N�ŗL�̑S���\�b�h���s
+ */
+ public ArrayList getUniqueMethodExecutions() {
+ ArrayList uniqueMethodExecutions = new ArrayList();
+ if (markedThreads == null) {
+ updateMarkedThreads();
+ }
+ if (unmarkedMethodSignatures == null) unmarkedMethodSignatures = trace.getUnmarkedMethodSignatures(markStart, markEnd);
+ for (int i = 0; i < markedThreads.size(); i++) {
+ uniqueMethodExecutions.addAll(markedThreads.get(i).getUniqueMethodExecutions(unmarkedMethodSignatures));
+ }
+ return uniqueMethodExecutions;
+ }
+}
diff --git a/org.ntlab.traceAnalyzer/traces/_arraySample.txt b/org.ntlab.traceAnalyzer/traces/_arraySample.txt
new file mode 100644
index 0000000..3b78a02
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/traces/_arraySample.txt
@@ -0,0 +1,47 @@
+{"type":"classDef","name":"arraySample.Main","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/arraySample/Main.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"methodEntry","signature":"public static void arraySample.Main.main(java.lang.String[])","receiver":{"class":"arraySample.Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":865101683}],"threadId":1,"time":1699149368296708},
+{"type":"blockEntry","methodSignature":"arraySample.Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":10,"time":1699149368313281},
+{"type":"methodCall","callerSideSignature":"arraySample.A()","threadId":1,"lineNum":10},
+{"type":"classDef","name":"arraySample.A","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/arraySample/A.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"public arraySample.A()","class":"arraySample.A","args":[],"threadId":1,"time":1699149368958570},
+{"type":"arrayCreate","array":{"class":"[LarraySample.B;","id":1484304002},"dimension":1,"threadId":1,"lineNum":5,"time":1699149369290735},
+{"type":"fieldSet","fieldName":"arraySample.A.array","container":{"class":"arraySample.A","id":1527318062},"value":{"class":"[LarraySample.B;","id":1484304002},"threadId":1,"lineNum":5,"time":1699149369313303},
+{"type":"methodCall","callerSideSignature":"arraySample.D()","threadId":1,"lineNum":6},
+{"type":"classDef","name":"arraySample.D","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/arraySample/D.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"public arraySample.D()","class":"arraySample.D","args":[],"threadId":1,"time":1699149369698361},
+{"type":"constructorExit","shortSignature":"arraySample.D()","returnValue":{"class":"arraySample.D","id":1642365377},"threadId":1,"time":1699149369729743},
+{"type":"fieldSet","fieldName":"arraySample.A.d","container":{"class":"arraySample.A","id":1527318062},"value":{"class":"arraySample.D","id":1642365377},"threadId":1,"lineNum":6,"time":1699149369744906},
+{"type":"constructorExit","shortSignature":"arraySample.A()","returnValue":{"class":"arraySample.A","id":1527318062},"threadId":1,"time":1699149369755132},
+{"type":"methodCall","callerSideSignature":"arraySample.A.init()","threadId":1,"lineNum":11},
+{"type":"methodEntry","signature":"public void arraySample.A.init()","receiver":{"class":"arraySample.A","id":1527318062},"args":[],"threadId":1,"time":1699149369774526},
+{"type":"blockEntry","methodSignature":"arraySample.A.init()","blockId":0,"incomings":0,"threadId":1,"lineNum":9,"time":1699149369783341},
+{"type":"fieldGet","fieldName":"arraySample.A.array","this":{"class":"arraySample.A","id":1527318062},"container":{"class":"arraySample.A","id":1527318062},"value":{"class":"[LarraySample.B;","id":1484304002},"threadId":1,"lineNum":9,"time":1699149369798856},
+{"type":"methodCall","callerSideSignature":"arraySample.B()","threadId":1,"lineNum":9},
+{"type":"classDef","name":"arraySample.B","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/arraySample/B.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"public arraySample.B()","class":"arraySample.B","args":[],"threadId":1,"time":1699149369928972},
+{"type":"methodCall","callerSideSignature":"arraySample.C()","threadId":1,"lineNum":5},
+{"type":"classDef","name":"arraySample.C","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/arraySample/C.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"public arraySample.C()","class":"arraySample.C","args":[],"threadId":1,"time":1699149370298162},
+{"type":"constructorExit","shortSignature":"arraySample.C()","returnValue":{"class":"arraySample.C","id":1558398402},"threadId":1,"time":1699149370320729},
+{"type":"fieldSet","fieldName":"arraySample.B.c","container":{"class":"arraySample.B","id":1291383602},"value":{"class":"arraySample.C","id":1558398402},"threadId":1,"lineNum":5,"time":1699149370343649},
+{"type":"constructorExit","shortSignature":"arraySample.B()","returnValue":{"class":"arraySample.B","id":1291383602},"threadId":1,"time":1699149370353875},
+{"type":"arraySet","array":{"class":"[LarraySample.B;","id":1484304002},"index":0,"value":{"class":"arraySample.B","id":1291383602},"threadId":1,"time":1699149370763616},
+{"type":"methodExit","shortSignature":"arraySample.A.init()","receiver":{"class":"arraySample.A","id":1527318062},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699149371705456},
+{"type":"methodCall","callerSideSignature":"arraySample.A.start()","threadId":1,"lineNum":12},
+{"type":"methodEntry","signature":"public void arraySample.A.start()","receiver":{"class":"arraySample.A","id":1527318062},"args":[],"threadId":1,"time":1699149371725202},
+{"type":"blockEntry","methodSignature":"arraySample.A.start()","blockId":0,"incomings":0,"threadId":1,"lineNum":13,"time":1699149371732960},
+{"type":"fieldGet","fieldName":"arraySample.A.d","this":{"class":"arraySample.A","id":1527318062},"container":{"class":"arraySample.A","id":1527318062},"value":{"class":"arraySample.D","id":1642365377},"threadId":1,"lineNum":13,"time":1699149371748475},
+{"type":"fieldGet","fieldName":"arraySample.A.array","this":{"class":"arraySample.A","id":1527318062},"container":{"class":"arraySample.A","id":1527318062},"value":{"class":"[LarraySample.B;","id":1484304002},"threadId":1,"lineNum":13,"time":1699149371762932},
+{"type":"arrayGet","array":{"class":"[LarraySample.B;","id":1484304002},"index":0,"value":{"class":"arraySample.B","id":1291383602},"threadId":1,"time":1699149371769632},
+{"type":"methodCall","callerSideSignature":"arraySample.B.getC()","threadId":1,"lineNum":13},
+{"type":"methodEntry","signature":"public arraySample.C arraySample.B.getC()","receiver":{"class":"arraySample.B","id":1291383602},"args":[],"threadId":1,"time":1699149371825346},
+{"type":"blockEntry","methodSignature":"arraySample.B.getC()","blockId":0,"incomings":0,"threadId":1,"lineNum":8,"time":1699149371834514},
+{"type":"fieldGet","fieldName":"arraySample.B.c","this":{"class":"arraySample.B","id":1291383602},"container":{"class":"arraySample.B","id":1291383602},"value":{"class":"arraySample.C","id":1558398402},"threadId":1,"lineNum":8,"time":1699149371848971},
+{"type":"methodExit","shortSignature":"arraySample.B.getC()","receiver":{"class":"arraySample.B","id":1291383602},"returnValue":{"class":"arraySample.C","id":1558398402},"threadId":1,"time":1699149371860960},
+{"type":"methodCall","callerSideSignature":"arraySample.D.setC(arraySample.C)","threadId":1,"lineNum":13},
+{"type":"methodEntry","signature":"void arraySample.D.setC(arraySample.C)","receiver":{"class":"arraySample.D","id":1642365377},"args":[{"class":"arraySample.C","id":1558398402}],"threadId":1,"time":1699149371881059},
+{"type":"blockEntry","methodSignature":"arraySample.D.setC(arraySample.C)","blockId":0,"incomings":0,"threadId":1,"lineNum":7,"time":1699149371889875},
+{"type":"fieldSet","fieldName":"arraySample.D.c","container":{"class":"arraySample.D","id":1642365377},"value":{"class":"arraySample.C","id":1558398402},"threadId":1,"lineNum":7,"time":1699149371904685},
+{"type":"methodExit","shortSignature":"arraySample.D.setC(arraySample.C)","receiver":{"class":"arraySample.D","id":1642365377},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699149371915968},
+{"type":"methodExit","shortSignature":"arraySample.A.start()","receiver":{"class":"arraySample.A","id":1527318062},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699149371926899},
+{"type":"methodExit","shortSignature":"arraySample.Main.main(java.lang.String[])","receiver":{"class":"arraySample.Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699149371936067},
diff --git a/org.ntlab.traceAnalyzer/traces/_finalLocal.txt b/org.ntlab.traceAnalyzer/traces/_finalLocal.txt
new file mode 100644
index 0000000..6036b77
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/traces/_finalLocal.txt
@@ -0,0 +1,31 @@
+2
+{"type":"classDef","name":"finalLocal.Main","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/finalLocal/Main.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"methodEntry","signature":"public static void finalLocal.Main.main(java.lang.String[])","receiver":{"class":"finalLocal.Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":1819586596}],"threadId":1,"time":1699409891667627},
+{"type":"blockEntry","methodSignature":"finalLocal.Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":9,"time":1699409891692663},
+{"type":"methodCall","callerSideSignature":"finalLocal.Main()","threadId":1,"lineNum":9},
+{"type":"constructorEntry","signature":"public finalLocal.Main()","class":"finalLocal.Main","args":[],"threadId":1,"time":1699409891713115},
+{"type":"constructorExit","shortSignature":"finalLocal.Main()","returnValue":{"class":"finalLocal.Main","id":1624785692},"threadId":1,"time":1699409891727925},
+{"type":"methodCall","callerSideSignature":"finalLocal.Main.coordinator()","threadId":1,"lineNum":10},
+{"type":"methodEntry","signature":"public void finalLocal.Main.coordinator()","receiver":{"class":"finalLocal.Main","id":1624785692},"args":[],"threadId":1,"time":1699409891754723},
+{"type":"blockEntry","methodSignature":"finalLocal.Main.coordinator()","blockId":0,"incomings":0,"threadId":1,"lineNum":20,"time":1699409891766713},
+{"type":"methodCall","callerSideSignature":"finalLocal.Main.A()","threadId":1,"lineNum":20},
+{"type":"classDef","name":"finalLocal.Main$A","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/finalLocal/Main$A.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"finalLocal.Main.A()","class":"finalLocal.Main$A","args":[],"threadId":1,"time":1699409892360519},
+{"type":"constructorExit","shortSignature":"finalLocal.Main.A()","returnValue":{"class":"finalLocal.Main$A","id":1656301910},"threadId":1,"time":1699409892401070},
+{"type":"methodCall","callerSideSignature":"finalLocal.Main.1Test(finalLocal.Main,finalLocal.Main.A)","threadId":1,"lineNum":29},
+{"type":"classDef","name":"finalLocal.Main$1Test","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/finalLocal/Main$1Test.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"finalLocal.Main.1Test(finalLocal.Main,finalLocal.Main.A)","class":"finalLocal.Main$1Test","args":[{"class":"finalLocal.Main","id":1624785692},{"class":"finalLocal.Main$A","id":1656301910}],"threadId":1,"time":1699409893076332},
+{"type":"constructorExit","shortSignature":"finalLocal.Main.1Test(finalLocal.Main,finalLocal.Main.A)","returnValue":{"class":"finalLocal.Main$1Test","id":1437150522},"threadId":1,"time":1699409893104894},
+{"type":"methodCall","callerSideSignature":"finalLocal.Main.1Test.test()","threadId":1,"lineNum":30},
+{"type":"methodEntry","signature":"public void finalLocal.Main.1Test.test()","receiver":{"class":"finalLocal.Main$1Test","id":1437150522},"args":[],"threadId":1,"time":1699409893132045},
+{"type":"blockEntry","methodSignature":"finalLocal.Main.1Test.test()","blockId":0,"incomings":0,"threadId":1,"lineNum":25,"time":1699409893145092},
+{"type":"fieldSet","fieldName":"finalLocal.Main$1Test.a2","container":{"class":"finalLocal.Main$1Test","id":1437150522},"value":{"class":"finalLocal.Main$A","id":1656301910},"threadId":1,"lineNum":25,"time":1699409893165191},
+{"type":"fieldGet","fieldName":"java.lang.System.out","this":{"class":"finalLocal.Main$1Test","id":1437150522},"container":{"class":"---","id":0},"value":{"class":"java.io.PrintStream","id":1440245445},"threadId":1,"lineNum":26,"time":1699409893193048},
+{"type":"fieldGet","fieldName":"finalLocal.Main$1Test.a2","this":{"class":"finalLocal.Main$1Test","id":1437150522},"container":{"class":"finalLocal.Main$1Test","id":1437150522},"value":{"class":"finalLocal.Main$A","id":1656301910},"threadId":1,"lineNum":26,"time":1699409893215263},
+{"type":"methodCall","callerSideSignature":"finalLocal.Main.A.get()","threadId":1,"lineNum":26},
+{"type":"methodEntry","signature":"int finalLocal.Main.A.get()","receiver":{"class":"finalLocal.Main$A","id":1656301910},"args":[],"threadId":1,"time":1699409893243472},
+{"type":"blockEntry","methodSignature":"finalLocal.Main.A.get()","blockId":0,"incomings":0,"threadId":1,"lineNum":15,"time":1699409893255814},
+{"type":"methodExit","shortSignature":"finalLocal.Main.A.get()","receiver":{"class":"finalLocal.Main$A","id":1656301910},"returnValue":{"class":"int","id":2},"threadId":1,"time":1699409893273797},
+{"type":"methodExit","shortSignature":"finalLocal.Main.1Test.test()","receiver":{"class":"finalLocal.Main$1Test","id":1437150522},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699409893469852},
+{"type":"methodExit","shortSignature":"finalLocal.Main.coordinator()","receiver":{"class":"finalLocal.Main","id":1624785692},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699409893492420},
+{"type":"methodExit","shortSignature":"finalLocal.Main.main(java.lang.String[])","receiver":{"class":"finalLocal.Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699409893520982},
diff --git a/org.ntlab.traceAnalyzer/traces/_threadSample.txt b/org.ntlab.traceAnalyzer/traces/_threadSample.txt
new file mode 100644
index 0000000..8eb859a
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/traces/_threadSample.txt
@@ -0,0 +1,62 @@
+{"type":"classDef","name":"threadSample.Main","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/threadSample/Main.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"methodEntry","signature":"public static void threadSample.Main.main(java.lang.String[])","receiver":{"class":"threadSample.Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":1588438933}],"threadId":1,"time":1699487713263226},
+{"type":"blockEntry","methodSignature":"threadSample.Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":11,"time":1699487713280504},
+{"type":"methodCall","callerSideSignature":"threadSample.ThreadSample()","threadId":1,"lineNum":11},
+{"type":"classDef","name":"threadSample.ThreadSample","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/threadSample/ThreadSample.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"public threadSample.ThreadSample()","class":"threadSample.ThreadSample","args":[],"threadId":1,"time":1699487713462454},
+{"type":"constructorExit","shortSignature":"threadSample.ThreadSample()","returnValue":{"class":"threadSample.ThreadSample","id":1523931074},"threadId":1,"time":1699487713495248},
+{"type":"methodCall","callerSideSignature":"java.lang.Thread.start()","threadId":1,"lineNum":12},
+{"type":"methodEntry","signature":"public synchronized void java.lang.Thread.start()","receiver":{"class":"threadSample.ThreadSample","id":1523931074},"args":[],"threadId":1,"time":1699487713514289},
+{"type":"methodExit","shortSignature":"java.lang.Thread.start()","receiver":{"class":"threadSample.ThreadSample","id":1523931074},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699487713590454},
+{"type":"methodExit","shortSignature":"threadSample.Main.main(java.lang.String[])","receiver":{"class":"threadSample.Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699487713603148},
+{"type":"methodEntry","signature":"public void threadSample.ThreadSample.run()","receiver":{"class":"threadSample.ThreadSample","id":1523931074},"args":[],"threadId":10,"time":1699487713707876},
+{"type":"blockEntry","methodSignature":"threadSample.ThreadSample.run()","blockId":0,"incomings":0,"threadId":10,"lineNum":5,"time":1699487713725154},
+{"type":"methodCall","callerSideSignature":"threadSample.ThreadSample.1(threadSample.ThreadSample)","threadId":10,"lineNum":5},
+{"type":"classDef","name":"threadSample.ThreadSample$1","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/threadSample/ThreadSample$1.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"threadSample.ThreadSample.1(threadSample.ThreadSample)","class":"threadSample.ThreadSample$1","args":[{"class":"threadSample.ThreadSample","id":1523931074}],"threadId":10,"time":1699487714260779},
+{"type":"constructorExit","shortSignature":"threadSample.ThreadSample.1(threadSample.ThreadSample)","returnValue":{"class":"threadSample.ThreadSample$1","id":1484491751},"threadId":10,"time":1699487714281583},
+{"type":"methodCall","callerSideSignature":"java.lang.Thread(java.lang.Runnable)","threadId":10,"lineNum":5},
+{"type":"constructorEntry","signature":"public java.lang.Thread(java.lang.Runnable)","class":"java.lang.Thread","args":[{"class":"threadSample.ThreadSample$1","id":1484491751}],"threadId":10,"time":1699487714301330},
+{"type":"constructorExit","shortSignature":"java.lang.Thread(java.lang.Runnable)","returnValue":{"class":"java.lang.Thread","id":387848211},"threadId":10,"time":1699487714322839},
+{"type":"methodCall","callerSideSignature":"java.lang.Thread.start()","threadId":10,"lineNum":12},
+{"type":"methodEntry","signature":"public synchronized void java.lang.Thread.start()","receiver":{"class":"java.lang.Thread","id":387848211},"args":[],"threadId":10,"time":1699487714339060},
+{"type":"methodExit","shortSignature":"java.lang.Thread.start()","receiver":{"class":"java.lang.Thread","id":387848211},"returnValue":{"class":"void","id":0},"threadId":10,"time":1699487714397242},
+{"type":"methodExit","shortSignature":"threadSample.ThreadSample.run()","receiver":{"class":"threadSample.ThreadSample","id":1523931074},"returnValue":{"class":"void","id":0},"threadId":10,"time":1699487714418399},
+{"type":"methodEntry","signature":"public void threadSample.ThreadSample.1.run()","receiver":{"class":"threadSample.ThreadSample$1","id":1484491751},"args":[],"threadId":12,"time":1699487714499853},
+{"type":"blockEntry","methodSignature":"threadSample.ThreadSample.1.run()","blockId":0,"incomings":0,"threadId":12,"lineNum":8,"time":1699487714518542},
+{"type":"methodCall","callerSideSignature":"threadSample.A()","threadId":12,"lineNum":8},
+{"type":"classDef","name":"threadSample.A","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/threadSample/A.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"public threadSample.A()","class":"threadSample.A","args":[],"threadId":12,"time":1699487715148668},
+{"type":"methodCall","callerSideSignature":"threadSample.B()","threadId":12,"lineNum":4},
+{"type":"classDef","name":"threadSample.B","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/threadSample/B.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"public threadSample.B()","class":"threadSample.B","args":[],"threadId":12,"time":1699487715599313},
+{"type":"methodCall","callerSideSignature":"threadSample.C()","threadId":12,"lineNum":4},
+{"type":"classDef","name":"threadSample.C","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/threadSample/C.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"public threadSample.C()","class":"threadSample.C","args":[],"threadId":12,"time":1699487715910673},
+{"type":"constructorExit","shortSignature":"threadSample.C()","returnValue":{"class":"threadSample.C","id":2022437173},"threadId":12,"time":1699487715935004},
+{"type":"fieldSet","fieldName":"threadSample.B.c","container":{"class":"threadSample.B","id":730401895},"value":{"class":"threadSample.C","id":2022437173},"threadId":12,"lineNum":4,"time":1699487715959334},
+{"type":"constructorExit","shortSignature":"threadSample.B()","returnValue":{"class":"threadSample.B","id":730401895},"threadId":12,"time":1699487715968503},
+{"type":"fieldSet","fieldName":"threadSample.A.b","container":{"class":"threadSample.A","id":848123013},"value":{"class":"threadSample.B","id":730401895},"threadId":12,"lineNum":4,"time":1699487715989659},
+{"type":"methodCall","callerSideSignature":"threadSample.D()","threadId":12,"lineNum":5},
+{"type":"classDef","name":"threadSample.D","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/threadSample/D.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"public threadSample.D()","class":"threadSample.D","args":[],"threadId":12,"time":1699487716356028},
+{"type":"constructorExit","shortSignature":"threadSample.D()","returnValue":{"class":"threadSample.D","id":289975132},"threadId":12,"time":1699487716377891},
+{"type":"fieldSet","fieldName":"threadSample.A.d","container":{"class":"threadSample.A","id":848123013},"value":{"class":"threadSample.D","id":289975132},"threadId":12,"lineNum":5,"time":1699487716392701},
+{"type":"constructorExit","shortSignature":"threadSample.A()","returnValue":{"class":"threadSample.A","id":848123013},"threadId":12,"time":1699487716402574},
+{"type":"methodCall","callerSideSignature":"threadSample.A.m()","threadId":12,"lineNum":9},
+{"type":"methodEntry","signature":"public void threadSample.A.m()","receiver":{"class":"threadSample.A","id":848123013},"args":[],"threadId":12,"time":1699487716421262},
+{"type":"blockEntry","methodSignature":"threadSample.A.m()","blockId":0,"incomings":0,"threadId":12,"lineNum":8,"time":1699487716428668},
+{"type":"fieldGet","fieldName":"threadSample.A.d","this":{"class":"threadSample.A","id":848123013},"container":{"class":"threadSample.A","id":848123013},"value":{"class":"threadSample.D","id":289975132},"threadId":12,"lineNum":8,"time":1699487716444183},
+{"type":"fieldGet","fieldName":"threadSample.A.b","this":{"class":"threadSample.A","id":848123013},"container":{"class":"threadSample.A","id":848123013},"value":{"class":"threadSample.B","id":730401895},"threadId":12,"lineNum":8,"time":1699487716458993},
+{"type":"methodCall","callerSideSignature":"threadSample.B.getC()","threadId":12,"lineNum":8},
+{"type":"methodEntry","signature":"public threadSample.C threadSample.B.getC()","receiver":{"class":"threadSample.B","id":730401895},"args":[],"threadId":12,"time":1699487716478034},
+{"type":"blockEntry","methodSignature":"threadSample.B.getC()","blockId":0,"incomings":0,"threadId":12,"lineNum":7,"time":1699487716485791},
+{"type":"fieldGet","fieldName":"threadSample.B.c","this":{"class":"threadSample.B","id":730401895},"container":{"class":"threadSample.B","id":730401895},"value":{"class":"threadSample.C","id":2022437173},"threadId":12,"lineNum":7,"time":1699487716502717},
+{"type":"methodExit","shortSignature":"threadSample.B.getC()","receiver":{"class":"threadSample.B","id":730401895},"returnValue":{"class":"threadSample.C","id":2022437173},"threadId":12,"time":1699487716518585},
+{"type":"methodCall","callerSideSignature":"threadSample.D.setC(threadSample.C)","threadId":12,"lineNum":8},
+{"type":"methodEntry","signature":"public void threadSample.D.setC(threadSample.C)","receiver":{"class":"threadSample.D","id":289975132},"args":[{"class":"threadSample.C","id":2022437173}],"threadId":12,"time":1699487716538684},
+{"type":"blockEntry","methodSignature":"threadSample.D.setC(threadSample.C)","blockId":0,"incomings":0,"threadId":12,"lineNum":7,"time":1699487716547147},
+{"type":"fieldSet","fieldName":"threadSample.D.c","container":{"class":"threadSample.D","id":289975132},"value":{"class":"threadSample.C","id":2022437173},"threadId":12,"lineNum":7,"time":1699487716560194},
+{"type":"methodExit","shortSignature":"threadSample.D.setC(threadSample.C)","receiver":{"class":"threadSample.D","id":289975132},"returnValue":{"class":"void","id":0},"threadId":12,"time":1699487716575356},
+{"type":"methodExit","shortSignature":"threadSample.A.m()","receiver":{"class":"threadSample.A","id":848123013},"returnValue":{"class":"void","id":0},"threadId":12,"time":1699487716590871},
+{"type":"methodExit","shortSignature":"threadSample.ThreadSample.1.run()","receiver":{"class":"threadSample.ThreadSample$1","id":1484491751},"returnValue":{"class":"void","id":0},"threadId":12,"time":1699487716609207},
diff --git a/org.ntlab.traceAnalyzer/traces/_worstCase.txt b/org.ntlab.traceAnalyzer/traces/_worstCase.txt
new file mode 100644
index 0000000..860ecd7
--- /dev/null
+++ b/org.ntlab.traceAnalyzer/traces/_worstCase.txt
@@ -0,0 +1,159 @@
+{"type":"classDef","name":"worstCase.main","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/main.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"methodEntry","signature":"public static void worstCase.main.main(java.lang.String[])","receiver":{"class":"worstCase.main","id":0},"args":[{"class":"[Ljava.lang.String;","id":1457398981}],"threadId":1,"time":1699552992964235},
+{"type":"blockEntry","methodSignature":"worstCase.main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":10,"time":1699552992988213},
+{"type":"methodCall","callerSideSignature":"worstCase.A()","threadId":1,"lineNum":10},
+{"type":"classDef","name":"worstCase.A","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/A.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"worstCase.A()","class":"worstCase.A","args":[],"threadId":1,"time":1699552993730471},
+{"type":"methodCall","callerSideSignature":"worstCase.B()","threadId":1,"lineNum":4},
+{"type":"classDef","name":"worstCase.B","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/B.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"worstCase.B()","class":"worstCase.B","args":[],"threadId":1,"time":1699552994339441},
+{"type":"methodCall","callerSideSignature":"worstCase.C()","threadId":1,"lineNum":4},
+{"type":"classDef","name":"worstCase.C","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/C.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"worstCase.C()","class":"worstCase.C","args":[],"threadId":1,"time":1699552994979793},
+{"type":"methodCall","callerSideSignature":"worstCase.D()","threadId":1,"lineNum":4},
+{"type":"classDef","name":"worstCase.D","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/D.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"worstCase.D()","class":"worstCase.D","args":[],"threadId":1,"time":1699552995575363},
+{"type":"methodCall","callerSideSignature":"worstCase.E()","threadId":1,"lineNum":4},
+{"type":"classDef","name":"worstCase.E","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/E.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"worstCase.E()","class":"worstCase.E","args":[],"threadId":1,"time":1699552996163881},
+{"type":"methodCall","callerSideSignature":"worstCase.F()","threadId":1,"lineNum":4},
+{"type":"classDef","name":"worstCase.F","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/F.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"worstCase.F()","class":"worstCase.F","args":[],"threadId":1,"time":1699552996774613},
+{"type":"methodCall","callerSideSignature":"worstCase.G()","threadId":1,"lineNum":4},
+{"type":"classDef","name":"worstCase.G","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/G.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"worstCase.G()","class":"worstCase.G","args":[],"threadId":1,"time":1699552997363836},
+{"type":"methodCall","callerSideSignature":"worstCase.H()","threadId":1,"lineNum":4},
+{"type":"classDef","name":"worstCase.H","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/H.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"worstCase.H()","class":"worstCase.H","args":[],"threadId":1,"time":1699552997949532},
+{"type":"methodCall","callerSideSignature":"worstCase.I()","threadId":1,"lineNum":4},
+{"type":"classDef","name":"worstCase.I","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/I.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"worstCase.I()","class":"worstCase.I","args":[],"threadId":1,"time":1699552998548628},
+{"type":"methodCall","callerSideSignature":"worstCase.J()","threadId":1,"lineNum":4},
+{"type":"classDef","name":"worstCase.J","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/J.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"worstCase.J()","class":"worstCase.J","args":[],"threadId":1,"time":1699552999050402},
+{"type":"methodCall","callerSideSignature":"worstCase.K()","threadId":1,"lineNum":4},
+{"type":"classDef","name":"worstCase.K","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/K.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"worstCase.K()","class":"worstCase.K","args":[],"threadId":1,"time":1699552999466490},
+{"type":"methodCall","callerSideSignature":"worstCase.L()","threadId":1,"lineNum":4},
+{"type":"classDef","name":"worstCase.L","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/L.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"worstCase.L()","class":"worstCase.L","args":[],"threadId":1,"time":1699552999875526},
+{"type":"methodCall","callerSideSignature":"worstCase.M()","threadId":1,"lineNum":4},
+{"type":"classDef","name":"worstCase.M","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/M.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"public worstCase.M()","class":"worstCase.M","args":[],"threadId":1,"time":1699553000173135},
+{"type":"constructorExit","shortSignature":"worstCase.M()","returnValue":{"class":"worstCase.M","id":1289325312},"threadId":1,"time":1699553000199581},
+{"type":"fieldSet","fieldName":"worstCase.L.m","container":{"class":"worstCase.L","id":1580520554},"value":{"class":"worstCase.M","id":1289325312},"threadId":1,"lineNum":4,"time":1699553000225322},
+{"type":"constructorExit","shortSignature":"worstCase.L()","returnValue":{"class":"worstCase.L","id":1580520554},"threadId":1,"time":1699553000234842},
+{"type":"fieldSet","fieldName":"worstCase.K.l","container":{"class":"worstCase.K","id":1583721335},"value":{"class":"worstCase.L","id":1580520554},"threadId":1,"lineNum":4,"time":1699553000259878},
+{"type":"constructorExit","shortSignature":"worstCase.K()","returnValue":{"class":"worstCase.K","id":1583721335},"threadId":1,"time":1699553000268694},
+{"type":"fieldSet","fieldName":"worstCase.J.k","container":{"class":"worstCase.J","id":1692156427},"value":{"class":"worstCase.K","id":1583721335},"threadId":1,"lineNum":4,"time":1699553000290908},
+{"type":"constructorExit","shortSignature":"worstCase.J()","returnValue":{"class":"worstCase.J","id":1692156427},"threadId":1,"time":1699553000300782},
+{"type":"fieldSet","fieldName":"worstCase.I.j","container":{"class":"worstCase.I","id":947131368},"value":{"class":"worstCase.J","id":1692156427},"threadId":1,"lineNum":4,"time":1699553000331107},
+{"type":"constructorExit","shortSignature":"worstCase.I()","returnValue":{"class":"worstCase.I","id":947131368},"threadId":1,"time":1699553000348033},
+{"type":"fieldSet","fieldName":"worstCase.H.i","container":{"class":"worstCase.H","id":1288110412},"value":{"class":"worstCase.I","id":947131368},"threadId":1,"lineNum":4,"time":1699553000376947},
+{"type":"constructorExit","shortSignature":"worstCase.H()","returnValue":{"class":"worstCase.H","id":1288110412},"threadId":1,"time":1699553000390346},
+{"type":"fieldSet","fieldName":"worstCase.G.h","container":{"class":"worstCase.G","id":489049077},"value":{"class":"worstCase.H","id":1288110412},"threadId":1,"lineNum":4,"time":1699553000422435},
+{"type":"constructorExit","shortSignature":"worstCase.G()","returnValue":{"class":"worstCase.G","id":489049077},"threadId":1,"time":1699553000433718},
+{"type":"fieldSet","fieldName":"worstCase.F.g","container":{"class":"worstCase.F","id":1027920070},"value":{"class":"worstCase.G","id":489049077},"threadId":1,"lineNum":4,"time":1699553000463691},
+{"type":"constructorExit","shortSignature":"worstCase.F()","returnValue":{"class":"worstCase.F","id":1027920070},"threadId":1,"time":1699553000475327},
+{"type":"fieldSet","fieldName":"worstCase.E.f","container":{"class":"worstCase.E","id":1894160022},"value":{"class":"worstCase.F","id":1027920070},"threadId":1,"lineNum":4,"time":1699553000508121},
+{"type":"constructorExit","shortSignature":"worstCase.E()","returnValue":{"class":"worstCase.E","id":1894160022},"threadId":1,"time":1699553000520462},
+{"type":"fieldSet","fieldName":"worstCase.D.e","container":{"class":"worstCase.D","id":849906626},"value":{"class":"worstCase.E","id":1894160022},"threadId":1,"lineNum":4,"time":1699553000551845},
+{"type":"constructorExit","shortSignature":"worstCase.D()","returnValue":{"class":"worstCase.D","id":849906626},"threadId":1,"time":1699553000565597},
+{"type":"fieldSet","fieldName":"worstCase.C.d","container":{"class":"worstCase.C","id":1466926985},"value":{"class":"worstCase.D","id":849906626},"threadId":1,"lineNum":4,"time":1699553000596627},
+{"type":"constructorExit","shortSignature":"worstCase.C()","returnValue":{"class":"worstCase.C","id":1466926985},"threadId":1,"time":1699553000610732},
+{"type":"fieldSet","fieldName":"worstCase.B.c","container":{"class":"worstCase.B","id":1529569335},"value":{"class":"worstCase.C","id":1466926985},"threadId":1,"lineNum":4,"time":1699553000640352},
+{"type":"constructorExit","shortSignature":"worstCase.B()","returnValue":{"class":"worstCase.B","id":1529569335},"threadId":1,"time":1699553000654457},
+{"type":"fieldSet","fieldName":"worstCase.A.b","container":{"class":"worstCase.A","id":2092558755},"value":{"class":"worstCase.B","id":1529569335},"threadId":1,"lineNum":4,"time":1699553000682666},
+{"type":"methodCall","callerSideSignature":"worstCase.N()","threadId":1,"lineNum":5},
+{"type":"classDef","name":"worstCase.N","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/N.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"worstCase.N()","class":"worstCase.N","args":[],"threadId":1,"time":1699553001472175},
+{"type":"methodCall","callerSideSignature":"worstCase.O()","threadId":1,"lineNum":4},
+{"type":"classDef","name":"worstCase.O","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/O.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"worstCase.O()","class":"worstCase.O","args":[],"threadId":1,"time":1699553002201034},
+{"type":"methodCall","callerSideSignature":"worstCase.P()","threadId":1,"lineNum":4},
+{"type":"classDef","name":"worstCase.P","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/P.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"},
+{"type":"constructorEntry","signature":"worstCase.P()","class":"worstCase.P","args":[],"threadId":1,"time":1699553003026510},
+{"type":"constructorExit","shortSignature":"worstCase.P()","returnValue":{"class":"worstCase.P","id":1386559816},"threadId":1,"time":1699553003062477},
+{"type":"fieldSet","fieldName":"worstCase.O.p","container":{"class":"worstCase.O","id":1565773915},"value":{"class":"worstCase.P","id":1386559816},"threadId":1,"lineNum":4,"time":1699553003101618},
+{"type":"constructorExit","shortSignature":"worstCase.O()","returnValue":{"class":"worstCase.O","id":1565773915},"threadId":1,"time":1699553003115017},
+{"type":"fieldSet","fieldName":"worstCase.N.o","container":{"class":"worstCase.N","id":697579067},"value":{"class":"worstCase.O","id":1565773915},"threadId":1,"lineNum":4,"time":1699553003149926},
+{"type":"constructorExit","shortSignature":"worstCase.N()","returnValue":{"class":"worstCase.N","id":697579067},"threadId":1,"time":1699553003164031},
+{"type":"fieldSet","fieldName":"worstCase.A.n","container":{"class":"worstCase.A","id":2092558755},"value":{"class":"worstCase.N","id":697579067},"threadId":1,"lineNum":5,"time":1699553003190477},
+{"type":"constructorExit","shortSignature":"worstCase.A()","returnValue":{"class":"worstCase.A","id":2092558755},"threadId":1,"time":1699553003215866},
+{"type":"methodCall","callerSideSignature":"worstCase.A.m()","threadId":1,"lineNum":11},
+{"type":"methodEntry","signature":"void worstCase.A.m()","receiver":{"class":"worstCase.A","id":2092558755},"args":[],"threadId":1,"time":1699553003253243},
+{"type":"blockEntry","methodSignature":"worstCase.A.m()","blockId":0,"incomings":0,"threadId":1,"lineNum":7,"time":1699553003273695},
+{"type":"fieldGet","fieldName":"worstCase.A.n","this":{"class":"worstCase.A","id":2092558755},"container":{"class":"worstCase.A","id":2092558755},"value":{"class":"worstCase.N","id":697579067},"threadId":1,"lineNum":7,"time":1699553003299083},
+{"type":"fieldGet","fieldName":"worstCase.A.b","this":{"class":"worstCase.A","id":2092558755},"container":{"class":"worstCase.A","id":2092558755},"value":{"class":"worstCase.B","id":1529569335},"threadId":1,"lineNum":7,"time":1699553003355502},
+{"type":"methodCall","callerSideSignature":"worstCase.B.getI()","threadId":1,"lineNum":7},
+{"type":"methodEntry","signature":"worstCase.I worstCase.B.getI()","receiver":{"class":"worstCase.B","id":1529569335},"args":[],"threadId":1,"time":1699553003386885},
+{"type":"blockEntry","methodSignature":"worstCase.B.getI()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553003400637},
+{"type":"fieldGet","fieldName":"worstCase.B.c","this":{"class":"worstCase.B","id":1529569335},"container":{"class":"worstCase.B","id":1529569335},"value":{"class":"worstCase.C","id":1466926985},"threadId":1,"lineNum":6,"time":1699553003436956},
+{"type":"methodCall","callerSideSignature":"worstCase.C.getF()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.F worstCase.C.getF()","receiver":{"class":"worstCase.C","id":1466926985},"args":[],"threadId":1,"time":1699553003482444},
+{"type":"blockEntry","methodSignature":"worstCase.C.getF()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553003500427},
+{"type":"fieldGet","fieldName":"worstCase.C.d","this":{"class":"worstCase.C","id":1466926985},"container":{"class":"worstCase.C","id":1466926985},"value":{"class":"worstCase.D","id":849906626},"threadId":1,"lineNum":6,"time":1699553003526169},
+{"type":"methodCall","callerSideSignature":"worstCase.D.getE()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.E worstCase.D.getE()","receiver":{"class":"worstCase.D","id":849906626},"args":[],"threadId":1,"time":1699553003556141},
+{"type":"blockEntry","methodSignature":"worstCase.D.getE()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553003570951},
+{"type":"fieldGet","fieldName":"worstCase.D.e","this":{"class":"worstCase.D","id":849906626},"container":{"class":"worstCase.D","id":849906626},"value":{"class":"worstCase.E","id":1894160022},"threadId":1,"lineNum":6,"time":1699553003599513},
+{"type":"methodExit","shortSignature":"worstCase.D.getE()","receiver":{"class":"worstCase.D","id":849906626},"returnValue":{"class":"worstCase.E","id":1894160022},"threadId":1,"time":1699553003626664},
+{"type":"methodCall","callerSideSignature":"worstCase.E.getF()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.F worstCase.E.getF()","receiver":{"class":"worstCase.E","id":1894160022},"args":[],"threadId":1,"time":1699553003668273},
+{"type":"blockEntry","methodSignature":"worstCase.E.getF()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553003688020},
+{"type":"fieldGet","fieldName":"worstCase.E.f","this":{"class":"worstCase.E","id":1894160022},"container":{"class":"worstCase.E","id":1894160022},"value":{"class":"worstCase.F","id":1027920070},"threadId":1,"lineNum":6,"time":1699553003715876},
+{"type":"methodExit","shortSignature":"worstCase.E.getF()","receiver":{"class":"worstCase.E","id":1894160022},"returnValue":{"class":"worstCase.F","id":1027920070},"threadId":1,"time":1699553003743381},
+{"type":"methodExit","shortSignature":"worstCase.C.getF()","receiver":{"class":"worstCase.C","id":1466926985},"returnValue":{"class":"worstCase.F","id":1027920070},"threadId":1,"time":1699553003767006},
+{"type":"methodCall","callerSideSignature":"worstCase.F.getI()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.I worstCase.F.getI()","receiver":{"class":"worstCase.F","id":1027920070},"args":[],"threadId":1,"time":1699553003805088},
+{"type":"blockEntry","methodSignature":"worstCase.F.getI()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553003818135},
+{"type":"fieldGet","fieldName":"worstCase.F.g","this":{"class":"worstCase.F","id":1027920070},"container":{"class":"worstCase.F","id":1027920070},"value":{"class":"worstCase.G","id":489049077},"threadId":1,"lineNum":6,"time":1699553003846345},
+{"type":"methodCall","callerSideSignature":"worstCase.G.getH()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.H worstCase.G.getH()","receiver":{"class":"worstCase.G","id":489049077},"args":[],"threadId":1,"time":1699553003896769},
+{"type":"blockEntry","methodSignature":"worstCase.G.getH()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553003912989},
+{"type":"fieldGet","fieldName":"worstCase.G.h","this":{"class":"worstCase.G","id":489049077},"container":{"class":"worstCase.G","id":489049077},"value":{"class":"worstCase.H","id":1288110412},"threadId":1,"lineNum":6,"time":1699553003944020},
+{"type":"methodExit","shortSignature":"worstCase.G.getH()","receiver":{"class":"worstCase.G","id":489049077},"returnValue":{"class":"worstCase.H","id":1288110412},"threadId":1,"time":1699553003969761},
+{"type":"methodCall","callerSideSignature":"worstCase.H.getI()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.I worstCase.H.getI()","receiver":{"class":"worstCase.H","id":1288110412},"args":[],"threadId":1,"time":1699553004012075},
+{"type":"blockEntry","methodSignature":"worstCase.H.getI()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553004029706},
+{"type":"fieldGet","fieldName":"worstCase.H.i","this":{"class":"worstCase.H","id":1288110412},"container":{"class":"worstCase.H","id":1288110412},"value":{"class":"worstCase.I","id":947131368},"threadId":1,"lineNum":6,"time":1699553004082951},
+{"type":"methodExit","shortSignature":"worstCase.H.getI()","receiver":{"class":"worstCase.H","id":1288110412},"returnValue":{"class":"worstCase.I","id":947131368},"threadId":1,"time":1699553004119623},
+{"type":"methodExit","shortSignature":"worstCase.F.getI()","receiver":{"class":"worstCase.F","id":1027920070},"returnValue":{"class":"worstCase.I","id":947131368},"threadId":1,"time":1699553004147480},
+{"type":"methodExit","shortSignature":"worstCase.B.getI()","receiver":{"class":"worstCase.B","id":1529569335},"returnValue":{"class":"worstCase.I","id":947131368},"threadId":1,"time":1699553004170752},
+{"type":"methodCall","callerSideSignature":"worstCase.N.passI(worstCase.I)","threadId":1,"lineNum":7},
+{"type":"methodEntry","signature":"void worstCase.N.passI(worstCase.I)","receiver":{"class":"worstCase.N","id":697579067},"args":[{"class":"worstCase.I","id":947131368}],"threadId":1,"time":1699553004208835},
+{"type":"blockEntry","methodSignature":"worstCase.N.passI(worstCase.I)","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553004228229},
+{"type":"fieldGet","fieldName":"worstCase.N.o","this":{"class":"worstCase.N","id":697579067},"container":{"class":"worstCase.N","id":697579067},"value":{"class":"worstCase.O","id":1565773915},"threadId":1,"lineNum":6,"time":1699553004257849},
+{"type":"methodCall","callerSideSignature":"worstCase.I.getL()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.L worstCase.I.getL()","receiver":{"class":"worstCase.I","id":947131368},"args":[],"threadId":1,"time":1699553004302631},
+{"type":"blockEntry","methodSignature":"worstCase.I.getL()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553004326962},
+{"type":"fieldGet","fieldName":"worstCase.I.j","this":{"class":"worstCase.I","id":947131368},"container":{"class":"worstCase.I","id":947131368},"value":{"class":"worstCase.J","id":1692156427},"threadId":1,"lineNum":6,"time":1699553004373507},
+{"type":"methodCall","callerSideSignature":"worstCase.J.getK()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.K worstCase.J.getK()","receiver":{"class":"worstCase.J","id":1692156427},"args":[],"threadId":1,"time":1699553004418995},
+{"type":"blockEntry","methodSignature":"worstCase.J.getK()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553004434510},
+{"type":"fieldGet","fieldName":"worstCase.J.k","this":{"class":"worstCase.J","id":1692156427},"container":{"class":"worstCase.J","id":1692156427},"value":{"class":"worstCase.K","id":1583721335},"threadId":1,"lineNum":6,"time":1699553004461661},
+{"type":"methodExit","shortSignature":"worstCase.J.getK()","receiver":{"class":"worstCase.J","id":1692156427},"returnValue":{"class":"worstCase.K","id":1583721335},"threadId":1,"time":1699553004482466},
+{"type":"methodCall","callerSideSignature":"worstCase.K.getL()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.L worstCase.K.getL()","receiver":{"class":"worstCase.K","id":1583721335},"args":[],"threadId":1,"time":1699553004515964},
+{"type":"blockEntry","methodSignature":"worstCase.K.getL()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553004526543},
+{"type":"fieldGet","fieldName":"worstCase.K.l","this":{"class":"worstCase.K","id":1583721335},"container":{"class":"worstCase.K","id":1583721335},"value":{"class":"worstCase.L","id":1580520554},"threadId":1,"lineNum":6,"time":1699553004546994},
+{"type":"methodExit","shortSignature":"worstCase.K.getL()","receiver":{"class":"worstCase.K","id":1583721335},"returnValue":{"class":"worstCase.L","id":1580520554},"threadId":1,"time":1699553004564273},
+{"type":"methodExit","shortSignature":"worstCase.I.getL()","receiver":{"class":"worstCase.I","id":947131368},"returnValue":{"class":"worstCase.L","id":1580520554},"threadId":1,"time":1699553004582256},
+{"type":"methodCall","callerSideSignature":"worstCase.O.passL(worstCase.L)","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"void worstCase.O.passL(worstCase.L)","receiver":{"class":"worstCase.O","id":1565773915},"args":[{"class":"worstCase.L","id":1580520554}],"threadId":1,"time":1699553004606587},
+{"type":"blockEntry","methodSignature":"worstCase.O.passL(worstCase.L)","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553004615402},
+{"type":"fieldGet","fieldName":"worstCase.O.p","this":{"class":"worstCase.O","id":1565773915},"container":{"class":"worstCase.O","id":1565773915},"value":{"class":"worstCase.P","id":1386559816},"threadId":1,"lineNum":6,"time":1699553004629507},
+{"type":"methodCall","callerSideSignature":"worstCase.L.getM()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.M worstCase.L.getM()","receiver":{"class":"worstCase.L","id":1580520554},"args":[],"threadId":1,"time":1699553004648195},
+{"type":"blockEntry","methodSignature":"worstCase.L.getM()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553004655953},
+{"type":"fieldGet","fieldName":"worstCase.L.m","this":{"class":"worstCase.L","id":1580520554},"container":{"class":"worstCase.L","id":1580520554},"value":{"class":"worstCase.M","id":1289325312},"threadId":1,"lineNum":6,"time":1699553004670763},
+{"type":"methodExit","shortSignature":"worstCase.L.getM()","receiver":{"class":"worstCase.L","id":1580520554},"returnValue":{"class":"worstCase.M","id":1289325312},"threadId":1,"time":1699553004682752},
+{"type":"methodCall","callerSideSignature":"worstCase.P.setM(worstCase.M)","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"void worstCase.P.setM(worstCase.M)","receiver":{"class":"worstCase.P","id":1386559816},"args":[{"class":"worstCase.M","id":1289325312}],"threadId":1,"time":1699553004703556},
+{"type":"blockEntry","methodSignature":"worstCase.P.setM(worstCase.M)","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553004712019},
+{"type":"fieldSet","fieldName":"worstCase.P.m","container":{"class":"worstCase.P","id":1386559816},"value":{"class":"worstCase.M","id":1289325312},"threadId":1,"lineNum":6,"time":1699553004728240},
+{"type":"methodExit","shortSignature":"worstCase.P.setM(worstCase.M)","receiver":{"class":"worstCase.P","id":1386559816},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699553004739523},
+{"type":"methodExit","shortSignature":"worstCase.O.passL(worstCase.L)","receiver":{"class":"worstCase.O","id":1565773915},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699553004751512},
+{"type":"methodExit","shortSignature":"worstCase.N.passI(worstCase.I)","receiver":{"class":"worstCase.N","id":697579067},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699553004764207},
+{"type":"methodExit","shortSignature":"worstCase.A.m()","receiver":{"class":"worstCase.A","id":2092558755},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699553004776548},
+{"type":"methodExit","shortSignature":"worstCase.main.main(java.lang.String[])","receiver":{"class":"worstCase.main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699553004787479},