diff --git a/DeltaExtractor/.classpath b/DeltaExtractor/.classpath
new file mode 100644
index 0000000..91ee9a5
--- /dev/null
+++ b/DeltaExtractor/.classpath
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/DeltaExtractor/.project b/DeltaExtractor/.project
new file mode 100644
index 0000000..c1bc1ab
--- /dev/null
+++ b/DeltaExtractor/.project
@@ -0,0 +1,17 @@
+
+
+ DeltaExtractor
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/DeltaExtractor/.settings/org.eclipse.jdt.core.prefs b/DeltaExtractor/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..838bd9d
--- /dev/null
+++ b/DeltaExtractor/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+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.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+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/DeltaExtractor/src/org/ntlab/deltaExtractor/Delta.java b/DeltaExtractor/src/org/ntlab/deltaExtractor/Delta.java
new file mode 100644
index 0000000..7964f23
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/deltaExtractor/DeltaAugmentationInfo.java b/DeltaExtractor/src/org/ntlab/deltaExtractor/DeltaAugmentationInfo.java
new file mode 100644
index 0000000..d887b4f
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/deltaExtractor/DeltaExtractor.java b/DeltaExtractor/src/org/ntlab/deltaExtractor/DeltaExtractor.java
new file mode 100644
index 0000000..08cc21d
--- /dev/null
+++ b/DeltaExtractor/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.isConstractor()), Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstractor()));
+
+ 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.isConstractor()) {
+ // �Ăя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.isConstractor()) {
+ // �ǐՑΏۂ�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.isConstractor()),
+ Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstractor()));
+
+ ((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.isConstractor()) {
+ // �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.isConstractor()), Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstractor()));
+ 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/DeltaExtractor/src/org/ntlab/deltaExtractor/ExtractedStructure.java b/DeltaExtractor/src/org/ntlab/deltaExtractor/ExtractedStructure.java
new file mode 100644
index 0000000..6e47f75
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/deltaExtractor/Test.java b/DeltaExtractor/src/org/ntlab/deltaExtractor/Test.java
new file mode 100644
index 0000000..e5d14f7
--- /dev/null
+++ b/DeltaExtractor/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("traces\\_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("traces\\_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("traces\\_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("traces\\_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/DeltaExtractor/src/org/ntlab/trace/ArrayAccess.java b/DeltaExtractor/src/org/ntlab/trace/ArrayAccess.java
new file mode 100644
index 0000000..1e1e903
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/trace/ArrayCreate.java b/DeltaExtractor/src/org/ntlab/trace/ArrayCreate.java
new file mode 100644
index 0000000..18a6acd
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/trace/ArrayUpdate.java b/DeltaExtractor/src/org/ntlab/trace/ArrayUpdate.java
new file mode 100644
index 0000000..f447718
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/trace/AugmentationInfo.java b/DeltaExtractor/src/org/ntlab/trace/AugmentationInfo.java
new file mode 100644
index 0000000..55bfbbe
--- /dev/null
+++ b/DeltaExtractor/src/org/ntlab/trace/AugmentationInfo.java
@@ -0,0 +1,5 @@
+package org.ntlab.trace;
+
+abstract public class AugmentationInfo {
+
+}
diff --git a/DeltaExtractor/src/org/ntlab/trace/BlockEnter.java b/DeltaExtractor/src/org/ntlab/trace/BlockEnter.java
new file mode 100644
index 0000000..0d4ccf5
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/trace/FieldAccess.java b/DeltaExtractor/src/org/ntlab/trace/FieldAccess.java
new file mode 100644
index 0000000..02e6e54
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/trace/FieldUpdate.java b/DeltaExtractor/src/org/ntlab/trace/FieldUpdate.java
new file mode 100644
index 0000000..b7d8443
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/trace/IBoundaryChecker.java b/DeltaExtractor/src/org/ntlab/trace/IBoundaryChecker.java
new file mode 100644
index 0000000..f5860a1
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/trace/IMethodExecutionVisitor.java b/DeltaExtractor/src/org/ntlab/trace/IMethodExecutionVisitor.java
new file mode 100644
index 0000000..54d368f
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/trace/IStatementVisitor.java b/DeltaExtractor/src/org/ntlab/trace/IStatementVisitor.java
new file mode 100644
index 0000000..aac4f2a
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/trace/MethodExecution.java b/DeltaExtractor/src/org/ntlab/trace/MethodExecution.java
new file mode 100644
index 0000000..e89d4e7
--- /dev/null
+++ b/DeltaExtractor/src/org/ntlab/trace/MethodExecution.java
@@ -0,0 +1,259 @@
+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 isConstractor;
+ 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 isConstractor,
+ boolean isStatic, long enterTime) {
+ this.signature = signature;
+ this.callerSideSignature = callerSideSignature;
+ this.thisClassName = thisClassName;
+ this.thisObjId = thisObjId;
+ this.isConstractor = isConstractor;
+ 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 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 isConstractor() {
+ return isConstractor;
+ }
+
+ 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/DeltaExtractor/src/org/ntlab/trace/MethodInvocation.java b/DeltaExtractor/src/org/ntlab/trace/MethodInvocation.java
new file mode 100644
index 0000000..b815b2d
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/trace/ObjectReference.java b/DeltaExtractor/src/org/ntlab/trace/ObjectReference.java
new file mode 100644
index 0000000..50dc6fc
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/trace/Reference.java b/DeltaExtractor/src/org/ntlab/trace/Reference.java
new file mode 100644
index 0000000..ac61644
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/trace/Statement.java b/DeltaExtractor/src/org/ntlab/trace/Statement.java
new file mode 100644
index 0000000..a6473d6
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/trace/TestTrace.java b/DeltaExtractor/src/org/ntlab/trace/TestTrace.java
new file mode 100644
index 0000000..89fa699
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/trace/ThreadInstance.java b/DeltaExtractor/src/org/ntlab/trace/ThreadInstance.java
new file mode 100644
index 0000000..272a062
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/src/org/ntlab/trace/Trace.java b/DeltaExtractor/src/org/ntlab/trace/Trace.java
new file mode 100644
index 0000000..2760009
--- /dev/null
+++ b/DeltaExtractor/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().isConstractor()
+ && 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 isContructor) {
+ if (isContructor) {
+ 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/DeltaExtractor/src/org/ntlab/trace/TraceJSON.java b/DeltaExtractor/src/org/ntlab/trace/TraceJSON.java
new file mode 100644
index 0000000..1562381
--- /dev/null
+++ b/DeltaExtractor/src/org/ntlab/trace/TraceJSON.java
@@ -0,0 +1,366 @@
+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 {
+ /**
+ * �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[] 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 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\":\"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;
+ }
+}
diff --git a/DeltaExtractor/src/org/ntlab/trace/TracePoint.java b/DeltaExtractor/src/org/ntlab/trace/TracePoint.java
new file mode 100644
index 0000000..380b846
--- /dev/null
+++ b/DeltaExtractor/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/DeltaExtractor/traces/_arraySample.txt b/DeltaExtractor/traces/_arraySample.txt
new file mode 100644
index 0000000..bd3b580
--- /dev/null
+++ b/DeltaExtractor/traces/_arraySample.txt
@@ -0,0 +1,42 @@
+{"type":"methodEntry","signature":"public static void arraySample.Main.main(java.lang.String[])","receiver":{"class":"arraySample.Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":1921964932}],"threadId":1,"time":1612422448371822},
+{"type":"blockEntry","methodSignature":"arraySample.Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":10,"time":1612422449617602},
+{"type":"methodCall","callerSideSignature":"arraySample.A()","threadId":1,"lineNum":10},
+{"type":"constructorEntry","signature":"public arraySample.A()","class":"arraySample.A","args":[],"threadId":1,"time":1612422450525902},
+{"type":"arrayCreate","array":{"class":"[LarraySample.B;","id":1041287558},"dimension":1,"threadId":1,"lineNum":5,"time":1612422451112719},
+{"type":"fieldSet","fieldName":"arraySample.A.array","container":{"class":"arraySample.A","id":1075747903},"value":{"class":"[LarraySample.B;","id":1041287558},"threadId":1,"lineNum":5,"time":1612422451142302},
+{"type":"methodCall","callerSideSignature":"arraySample.D()","threadId":1,"lineNum":6},
+{"type":"constructorEntry","signature":"public arraySample.D()","class":"arraySample.D","args":[],"threadId":1,"time":1612422451938611},
+{"type":"constructorExit","shortSignature":"arraySample.D()","returnValue":{"class":"arraySample.D","id":1626380693},"threadId":1,"time":1612422451975136},
+{"type":"fieldSet","fieldName":"arraySample.A.d","container":{"class":"arraySample.A","id":1075747903},"value":{"class":"arraySample.D","id":1626380693},"threadId":1,"lineNum":6,"time":1612422451998983},
+{"type":"constructorExit","shortSignature":"arraySample.A()","returnValue":{"class":"arraySample.A","id":1075747903},"threadId":1,"time":1612422452014982},
+{"type":"methodCall","callerSideSignature":"arraySample.A.init()","threadId":1,"lineNum":11},
+{"type":"methodEntry","signature":"public void arraySample.A.init()","receiver":{"class":"arraySample.A","id":1075747903},"args":[],"threadId":1,"time":1612422452057242},
+{"type":"blockEntry","methodSignature":"arraySample.A.init()","blockId":0,"incomings":0,"threadId":1,"lineNum":9,"time":1612422452070222},
+{"type":"fieldGet","fieldName":"arraySample.A.array","this":{"class":"arraySample.A","id":1075747903},"container":{"class":"arraySample.A","id":1075747903},"value":{"class":"[LarraySample.B;","id":1041287558},"threadId":1,"lineNum":9,"time":1612422452096182},
+{"type":"methodCall","callerSideSignature":"arraySample.B()","threadId":1,"lineNum":9},
+{"type":"constructorEntry","signature":"public arraySample.B()","class":"arraySample.B","args":[],"threadId":1,"time":1612422452270356},
+{"type":"methodCall","callerSideSignature":"arraySample.C()","threadId":1,"lineNum":5},
+{"type":"constructorEntry","signature":"public arraySample.C()","class":"arraySample.C","args":[],"threadId":1,"time":1612422452911509},
+{"type":"constructorExit","shortSignature":"arraySample.C()","returnValue":{"class":"arraySample.C","id":863719801},"threadId":1,"time":1612422452944411},
+{"type":"fieldSet","fieldName":"arraySample.B.c","container":{"class":"arraySample.B","id":1696725334},"value":{"class":"arraySample.C","id":863719801},"threadId":1,"lineNum":5,"time":1612422452979427},
+{"type":"constructorExit","shortSignature":"arraySample.B()","returnValue":{"class":"arraySample.B","id":1696725334},"threadId":1,"time":1612422452996030},
+{"type":"arraySet","array":{"class":"[LarraySample.B;","id":1041287558},"index":0,"value":{"class":"arraySample.B","id":1696725334},"threadId":1,"time":1612422453801093},
+{"type":"methodExit","shortSignature":"arraySample.A.init()","receiver":{"class":"arraySample.A","id":1075747903},"returnValue":{"class":"void","id":0},"threadId":1,"time":1612422455723041},
+{"type":"methodCall","callerSideSignature":"arraySample.A.start()","threadId":1,"lineNum":12},
+{"type":"methodEntry","signature":"public void arraySample.A.start()","receiver":{"class":"arraySample.A","id":1075747903},"args":[],"threadId":1,"time":1612422455755340},
+{"type":"blockEntry","methodSignature":"arraySample.A.start()","blockId":0,"incomings":0,"threadId":1,"lineNum":13,"time":1612422455768622},
+{"type":"fieldGet","fieldName":"arraySample.A.d","this":{"class":"arraySample.A","id":1075747903},"container":{"class":"arraySample.A","id":1075747903},"value":{"class":"arraySample.D","id":1626380693},"threadId":1,"lineNum":13,"time":1612422455795186},
+{"type":"fieldGet","fieldName":"arraySample.A.array","this":{"class":"arraySample.A","id":1075747903},"container":{"class":"arraySample.A","id":1075747903},"value":{"class":"[LarraySample.B;","id":1041287558},"threadId":1,"lineNum":13,"time":1612422455819335},
+{"type":"arrayGet","array":{"class":"[LarraySample.B;","id":1041287558},"index":0,"value":{"class":"arraySample.B","id":1696725334},"threadId":1,"time":1612422455827787},
+{"type":"methodCall","callerSideSignature":"arraySample.B.getC()","threadId":1,"lineNum":13},
+{"type":"methodEntry","signature":"public arraySample.C arraySample.B.getC()","receiver":{"class":"arraySample.B","id":1696725334},"args":[],"threadId":1,"time":1612422455954568},
+{"type":"blockEntry","methodSignature":"arraySample.B.getC()","blockId":0,"incomings":0,"threadId":1,"lineNum":8,"time":1612422455968454},
+{"type":"fieldGet","fieldName":"arraySample.B.c","this":{"class":"arraySample.B","id":1696725334},"container":{"class":"arraySample.B","id":1696725334},"value":{"class":"arraySample.C","id":863719801},"threadId":1,"lineNum":8,"time":1612422456008602},
+{"type":"methodExit","shortSignature":"arraySample.B.getC()","receiver":{"class":"arraySample.B","id":1696725334},"returnValue":{"class":"arraySample.C","id":863719801},"threadId":1,"time":1612422456034863},
+{"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":1626380693},"args":[{"class":"arraySample.C","id":863719801}],"threadId":1,"time":1612422456071690},
+{"type":"blockEntry","methodSignature":"arraySample.D.setC(arraySample.C)","blockId":0,"incomings":0,"threadId":1,"lineNum":7,"time":1612422456086180},
+{"type":"fieldSet","fieldName":"arraySample.D.c","container":{"class":"arraySample.D","id":1626380693},"value":{"class":"arraySample.C","id":863719801},"threadId":1,"lineNum":7,"time":1612422456110631},
+{"type":"methodExit","shortSignature":"arraySample.D.setC(arraySample.C)","receiver":{"class":"arraySample.D","id":1626380693},"returnValue":{"class":"void","id":0},"threadId":1,"time":1612422456130855},
+{"type":"methodExit","shortSignature":"arraySample.A.start()","receiver":{"class":"arraySample.A","id":1075747903},"returnValue":{"class":"void","id":0},"threadId":1,"time":1612422456160437},
+{"type":"methodExit","shortSignature":"arraySample.Main.main(java.lang.String[])","receiver":{"class":"arraySample.Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":1612422456182171},
diff --git a/DeltaExtractor/traces/_finalLocal.txt b/DeltaExtractor/traces/_finalLocal.txt
new file mode 100644
index 0000000..f5f478e
--- /dev/null
+++ b/DeltaExtractor/traces/_finalLocal.txt
@@ -0,0 +1,28 @@
+2
+{"type":"methodEntry","signature":"public static void finalLocal.Main.main(java.lang.String[])","receiver":{"class":"finalLocal.Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":281035435}],"threadId":1,"time":1612668092421661},
+{"type":"blockEntry","methodSignature":"finalLocal.Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":9,"time":1612668094179095},
+{"type":"methodCall","callerSideSignature":"finalLocal.Main()","threadId":1,"lineNum":9},
+{"type":"constructorEntry","signature":"public finalLocal.Main()","class":"finalLocal.Main","args":[],"threadId":1,"time":1612668094220450},
+{"type":"constructorExit","shortSignature":"finalLocal.Main()","returnValue":{"class":"finalLocal.Main","id":706099045},"threadId":1,"time":1612668094248523},
+{"type":"methodCall","callerSideSignature":"finalLocal.Main.coordinator()","threadId":1,"lineNum":10},
+{"type":"methodEntry","signature":"public void finalLocal.Main.coordinator()","receiver":{"class":"finalLocal.Main","id":706099045},"args":[],"threadId":1,"time":1612668094295010},
+{"type":"blockEntry","methodSignature":"finalLocal.Main.coordinator()","blockId":0,"incomings":0,"threadId":1,"lineNum":20,"time":1612668094317347},
+{"type":"methodCall","callerSideSignature":"finalLocal.Main.A()","threadId":1,"lineNum":20},
+{"type":"constructorEntry","signature":"finalLocal.Main.A()","class":"finalLocal.Main$A","args":[],"threadId":1,"time":1612668095262776},
+{"type":"constructorExit","shortSignature":"finalLocal.Main.A()","returnValue":{"class":"finalLocal.Main$A","id":1248633254},"threadId":1,"time":1612668095320129},
+{"type":"methodCall","callerSideSignature":"finalLocal.Main.1Test(finalLocal.Main,finalLocal.Main.A)","threadId":1,"lineNum":29},
+{"type":"constructorEntry","signature":"finalLocal.Main.1Test(finalLocal.Main,finalLocal.Main.A)","class":"finalLocal.Main$1Test","args":[{"class":"finalLocal.Main","id":706099045},{"class":"finalLocal.Main$A","id":1248633254}],"threadId":1,"time":1612668096453013},
+{"type":"constructorExit","shortSignature":"finalLocal.Main.1Test(finalLocal.Main,finalLocal.Main.A)","returnValue":{"class":"finalLocal.Main$1Test","id":641502649},"threadId":1,"time":1612668096501915},
+{"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":641502649},"args":[],"threadId":1,"time":1612668096557759},
+{"type":"blockEntry","methodSignature":"finalLocal.Main.1Test.test()","blockId":0,"incomings":0,"threadId":1,"lineNum":25,"time":1612668096585832},
+{"type":"fieldSet","fieldName":"finalLocal.Main$1Test.a2","container":{"class":"finalLocal.Main$1Test","id":641502649},"value":{"class":"finalLocal.Main$A","id":1248633254},"threadId":1,"lineNum":25,"time":1612668096622659},
+{"type":"fieldGet","fieldName":"java.lang.System.out","this":{"class":"finalLocal.Main$1Test","id":641502649},"container":{"class":"---","id":0},"value":{"class":"java.io.PrintStream","id":1367113803},"threadId":1,"lineNum":26,"time":1612668096699030},
+{"type":"fieldGet","fieldName":"finalLocal.Main$1Test.a2","this":{"class":"finalLocal.Main$1Test","id":641502649},"container":{"class":"finalLocal.Main$1Test","id":641502649},"value":{"class":"finalLocal.Main$A","id":1248633254},"threadId":1,"lineNum":26,"time":1612668096751554},
+{"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":1248633254},"args":[],"threadId":1,"time":1612668096805889},
+{"type":"blockEntry","methodSignature":"finalLocal.Main.A.get()","blockId":0,"incomings":0,"threadId":1,"lineNum":15,"time":1612668096829736},
+{"type":"methodExit","shortSignature":"finalLocal.Main.A.get()","receiver":{"class":"finalLocal.Main$A","id":1248633254},"returnValue":{"class":"int","id":2},"threadId":1,"time":1612668096870487},
+{"type":"methodExit","shortSignature":"finalLocal.Main.1Test.test()","receiver":{"class":"finalLocal.Main$1Test","id":641502649},"returnValue":{"class":"void","id":0},"threadId":1,"time":1612668097181102},
+{"type":"methodExit","shortSignature":"finalLocal.Main.coordinator()","receiver":{"class":"finalLocal.Main","id":706099045},"returnValue":{"class":"void","id":0},"threadId":1,"time":1612668097224871},
+{"type":"methodExit","shortSignature":"finalLocal.Main.main(java.lang.String[])","receiver":{"class":"finalLocal.Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":1612668097241776},
diff --git a/DeltaExtractor/traces/_threadSample.txt b/DeltaExtractor/traces/_threadSample.txt
new file mode 100644
index 0000000..b408e5c
--- /dev/null
+++ b/DeltaExtractor/traces/_threadSample.txt
@@ -0,0 +1,55 @@
+{"type":"methodEntry","signature":"public static void threadSample.Main.main(java.lang.String[])","receiver":{"class":"threadSample.Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":137014984}],"threadId":1,"time":1612704867585390},
+{"type":"blockEntry","methodSignature":"threadSample.Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":11,"time":1612704868759025},
+{"type":"methodCall","callerSideSignature":"threadSample.ThreadSample()","threadId":1,"lineNum":11},
+{"type":"constructorEntry","signature":"public threadSample.ThreadSample()","class":"threadSample.ThreadSample","args":[],"threadId":1,"time":1612704868973045},
+{"type":"constructorExit","shortSignature":"threadSample.ThreadSample()","returnValue":{"class":"threadSample.ThreadSample","id":2087347332},"threadId":1,"time":1612704869015003},
+{"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":2087347332},"args":[],"threadId":1,"time":1612704869043076},
+{"type":"methodExit","shortSignature":"java.lang.Thread.start()","receiver":{"class":"threadSample.ThreadSample","id":2087347332},"returnValue":{"class":"void","id":0},"threadId":1,"time":1612704869146917},
+{"type":"methodExit","shortSignature":"threadSample.Main.main(java.lang.String[])","receiver":{"class":"threadSample.Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":1612704869162311},
+{"type":"methodEntry","signature":"public void threadSample.ThreadSample.run()","receiver":{"class":"threadSample.ThreadSample","id":2087347332},"args":[],"threadId":10,"time":1612704869277320},
+{"type":"blockEntry","methodSignature":"threadSample.ThreadSample.run()","blockId":0,"incomings":0,"threadId":10,"lineNum":5,"time":1612704869304488},
+{"type":"methodCall","callerSideSignature":"threadSample.ThreadSample.1(threadSample.ThreadSample)","threadId":10,"lineNum":5},
+{"type":"constructorEntry","signature":"threadSample.ThreadSample.1(threadSample.ThreadSample)","class":"threadSample.ThreadSample$1","args":[{"class":"threadSample.ThreadSample","id":2087347332}],"threadId":10,"time":1612704870231201},
+{"type":"constructorExit","shortSignature":"threadSample.ThreadSample.1(threadSample.ThreadSample)","returnValue":{"class":"threadSample.ThreadSample$1","id":682976601},"threadId":10,"time":1612704870278593},
+{"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":682976601}],"threadId":10,"time":1612704870325381},
+{"type":"constructorExit","shortSignature":"java.lang.Thread(java.lang.Runnable)","returnValue":{"class":"java.lang.Thread","id":487639792},"threadId":10,"time":1612704870376396},
+{"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":487639792},"args":[],"threadId":10,"time":1612704870417147},
+{"type":"methodExit","shortSignature":"java.lang.Thread.start()","receiver":{"class":"java.lang.Thread","id":487639792},"returnValue":{"class":"void","id":0},"threadId":10,"time":1612704870527025},
+{"type":"methodExit","shortSignature":"threadSample.ThreadSample.run()","receiver":{"class":"threadSample.ThreadSample","id":2087347332},"returnValue":{"class":"void","id":0},"threadId":10,"time":1612704870558418},
+{"type":"methodEntry","signature":"public void threadSample.ThreadSample.1.run()","receiver":{"class":"threadSample.ThreadSample$1","id":682976601},"args":[],"threadId":12,"time":1612704870578341},
+{"type":"blockEntry","methodSignature":"threadSample.ThreadSample.1.run()","blockId":0,"incomings":0,"threadId":12,"lineNum":8,"time":1612704870592830},
+{"type":"methodCall","callerSideSignature":"threadSample.A()","threadId":12,"lineNum":8},
+{"type":"constructorEntry","signature":"public threadSample.A()","class":"threadSample.A","args":[],"threadId":12,"time":1612704871611611},
+{"type":"methodCall","callerSideSignature":"threadSample.B()","threadId":12,"lineNum":4},
+{"type":"constructorEntry","signature":"public threadSample.B()","class":"threadSample.B","args":[],"threadId":12,"time":1612704872320380},
+{"type":"methodCall","callerSideSignature":"threadSample.C()","threadId":12,"lineNum":4},
+{"type":"constructorEntry","signature":"public threadSample.C()","class":"threadSample.C","args":[],"threadId":12,"time":1612704872876710},
+{"type":"constructorExit","shortSignature":"threadSample.C()","returnValue":{"class":"threadSample.C","id":1191632942},"threadId":12,"time":1612704872913839},
+{"type":"fieldSet","fieldName":"threadSample.B.c","container":{"class":"threadSample.B","id":342364272},"value":{"class":"threadSample.C","id":1191632942},"threadId":12,"lineNum":4,"time":1612704872948553},
+{"type":"constructorExit","shortSignature":"threadSample.B()","returnValue":{"class":"threadSample.B","id":342364272},"threadId":12,"time":1612704872963344},
+{"type":"fieldSet","fieldName":"threadSample.A.b","container":{"class":"threadSample.A","id":1007629191},"value":{"class":"threadSample.B","id":342364272},"threadId":12,"lineNum":4,"time":1612704872995341},
+{"type":"methodCall","callerSideSignature":"threadSample.D()","threadId":12,"lineNum":5},
+{"type":"constructorEntry","signature":"public threadSample.D()","class":"threadSample.D","args":[],"threadId":12,"time":1612704873620797},
+{"type":"constructorExit","shortSignature":"threadSample.D()","returnValue":{"class":"threadSample.D","id":1851889404},"threadId":12,"time":1612704873653398},
+{"type":"fieldSet","fieldName":"threadSample.A.d","container":{"class":"threadSample.A","id":1007629191},"value":{"class":"threadSample.D","id":1851889404},"threadId":12,"lineNum":5,"time":1612704873675132},
+{"type":"constructorExit","shortSignature":"threadSample.A()","returnValue":{"class":"threadSample.A","id":1007629191},"threadId":12,"time":1612704873690527},
+{"type":"methodCall","callerSideSignature":"threadSample.A.m()","threadId":12,"lineNum":9},
+{"type":"methodEntry","signature":"public void threadSample.A.m()","receiver":{"class":"threadSample.A","id":1007629191},"args":[],"threadId":12,"time":1612704873719808},
+{"type":"blockEntry","methodSignature":"threadSample.A.m()","blockId":0,"incomings":0,"threadId":12,"lineNum":8,"time":1612704873731882},
+{"type":"fieldGet","fieldName":"threadSample.A.d","this":{"class":"threadSample.A","id":1007629191},"container":{"class":"threadSample.A","id":1007629191},"value":{"class":"threadSample.D","id":1851889404},"threadId":12,"lineNum":8,"time":1612704873758748},
+{"type":"fieldGet","fieldName":"threadSample.A.b","this":{"class":"threadSample.A","id":1007629191},"container":{"class":"threadSample.A","id":1007629191},"value":{"class":"threadSample.B","id":342364272},"threadId":12,"lineNum":8,"time":1612704873784104},
+{"type":"methodCall","callerSideSignature":"threadSample.B.getC()","threadId":12,"lineNum":8},
+{"type":"methodEntry","signature":"public threadSample.C threadSample.B.getC()","receiver":{"class":"threadSample.B","id":342364272},"args":[],"threadId":12,"time":1612704873813686},
+{"type":"blockEntry","methodSignature":"threadSample.B.getC()","blockId":0,"incomings":0,"threadId":12,"lineNum":7,"time":1612704873826063},
+{"type":"fieldGet","fieldName":"threadSample.B.c","this":{"class":"threadSample.B","id":342364272},"container":{"class":"threadSample.B","id":342364272},"value":{"class":"threadSample.C","id":1191632942},"threadId":12,"lineNum":7,"time":1612704873849910},
+{"type":"methodExit","shortSignature":"threadSample.B.getC()","receiver":{"class":"threadSample.B","id":342364272},"returnValue":{"class":"threadSample.C","id":1191632942},"threadId":12,"time":1612704873869832},
+{"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":1851889404},"args":[{"class":"threadSample.C","id":1191632942}],"threadId":12,"time":1612704873909376},
+{"type":"blockEntry","methodSignature":"threadSample.D.setC(threadSample.C)","blockId":0,"incomings":0,"threadId":12,"lineNum":7,"time":1612704873925677},
+{"type":"fieldSet","fieldName":"threadSample.D.c","container":{"class":"threadSample.D","id":1851889404},"value":{"class":"threadSample.C","id":1191632942},"threadId":12,"lineNum":7,"time":1612704873947411},
+{"type":"methodExit","shortSignature":"threadSample.D.setC(threadSample.C)","receiver":{"class":"threadSample.D","id":1851889404},"returnValue":{"class":"void","id":0},"threadId":12,"time":1612704873966428},
+{"type":"methodExit","shortSignature":"threadSample.A.m()","receiver":{"class":"threadSample.A","id":1007629191},"returnValue":{"class":"void","id":0},"threadId":12,"time":1612704873986652},
+{"type":"methodExit","shortSignature":"threadSample.ThreadSample.1.run()","receiver":{"class":"threadSample.ThreadSample$1","id":682976601},"returnValue":{"class":"void","id":0},"threadId":12,"time":1612704874005670},
diff --git a/DeltaExtractor/traces/_worstCase.txt b/DeltaExtractor/traces/_worstCase.txt
new file mode 100644
index 0000000..51b25ad
--- /dev/null
+++ b/DeltaExtractor/traces/_worstCase.txt
@@ -0,0 +1,142 @@
+{"type":"methodEntry","signature":"public static void worstCase.main.main(java.lang.String[])","receiver":{"class":"worstCase.main","id":0},"args":[{"class":"[Ljava.lang.String;","id":1176526329}],"threadId":1,"time":1612737807295616},
+{"type":"blockEntry","methodSignature":"worstCase.main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":10,"time":1612737808605088},
+{"type":"methodCall","callerSideSignature":"worstCase.A()","threadId":1,"lineNum":10},
+{"type":"constructorEntry","signature":"worstCase.A()","class":"worstCase.A","args":[],"threadId":1,"time":1612737809391738},
+{"type":"methodCall","callerSideSignature":"worstCase.B()","threadId":1,"lineNum":4},
+{"type":"constructorEntry","signature":"worstCase.B()","class":"worstCase.B","args":[],"threadId":1,"time":1612737810080282},
+{"type":"methodCall","callerSideSignature":"worstCase.C()","threadId":1,"lineNum":4},
+{"type":"constructorEntry","signature":"worstCase.C()","class":"worstCase.C","args":[],"threadId":1,"time":1612737810881422},
+{"type":"methodCall","callerSideSignature":"worstCase.D()","threadId":1,"lineNum":4},
+{"type":"constructorEntry","signature":"worstCase.D()","class":"worstCase.D","args":[],"threadId":1,"time":1612737811649356},
+{"type":"methodCall","callerSideSignature":"worstCase.E()","threadId":1,"lineNum":4},
+{"type":"constructorEntry","signature":"worstCase.E()","class":"worstCase.E","args":[],"threadId":1,"time":1612737812445967},
+{"type":"methodCall","callerSideSignature":"worstCase.F()","threadId":1,"lineNum":4},
+{"type":"constructorEntry","signature":"worstCase.F()","class":"worstCase.F","args":[],"threadId":1,"time":1612737813345512},
+{"type":"methodCall","callerSideSignature":"worstCase.G()","threadId":1,"lineNum":4},
+{"type":"constructorEntry","signature":"worstCase.G()","class":"worstCase.G","args":[],"threadId":1,"time":1612737814022284},
+{"type":"methodCall","callerSideSignature":"worstCase.H()","threadId":1,"lineNum":4},
+{"type":"constructorEntry","signature":"worstCase.H()","class":"worstCase.H","args":[],"threadId":1,"time":1612737814683963},
+{"type":"methodCall","callerSideSignature":"worstCase.I()","threadId":1,"lineNum":4},
+{"type":"constructorEntry","signature":"worstCase.I()","class":"worstCase.I","args":[],"threadId":1,"time":1612737815370697},
+{"type":"methodCall","callerSideSignature":"worstCase.J()","threadId":1,"lineNum":4},
+{"type":"constructorEntry","signature":"worstCase.J()","class":"worstCase.J","args":[],"threadId":1,"time":1612737816032980},
+{"type":"methodCall","callerSideSignature":"worstCase.K()","threadId":1,"lineNum":4},
+{"type":"constructorEntry","signature":"worstCase.K()","class":"worstCase.K","args":[],"threadId":1,"time":1612737816720317},
+{"type":"methodCall","callerSideSignature":"worstCase.L()","threadId":1,"lineNum":4},
+{"type":"constructorEntry","signature":"worstCase.L()","class":"worstCase.L","args":[],"threadId":1,"time":1612737817439652},
+{"type":"methodCall","callerSideSignature":"worstCase.M()","threadId":1,"lineNum":4},
+{"type":"constructorEntry","signature":"public worstCase.M()","class":"worstCase.M","args":[],"threadId":1,"time":1612737817971832},
+{"type":"constructorExit","shortSignature":"worstCase.M()","returnValue":{"class":"worstCase.M","id":1590384136},"threadId":1,"time":1612737818007452},
+{"type":"fieldSet","fieldName":"worstCase.L.m","container":{"class":"worstCase.L","id":2004703190},"value":{"class":"worstCase.M","id":1590384136},"threadId":1,"lineNum":4,"time":1612737818044581},
+{"type":"constructorExit","shortSignature":"worstCase.L()","returnValue":{"class":"worstCase.L","id":2004703190},"threadId":1,"time":1612737818059372},
+{"type":"fieldSet","fieldName":"worstCase.K.l","container":{"class":"worstCase.K","id":1175576547},"value":{"class":"worstCase.L","id":2004703190},"threadId":1,"lineNum":4,"time":1612737818091973},
+{"type":"constructorExit","shortSignature":"worstCase.K()","returnValue":{"class":"worstCase.K","id":1175576547},"threadId":1,"time":1612737818106462},
+{"type":"fieldSet","fieldName":"worstCase.J.k","container":{"class":"worstCase.J","id":1065473029},"value":{"class":"worstCase.K","id":1175576547},"threadId":1,"lineNum":4,"time":1612737818138762},
+{"type":"constructorExit","shortSignature":"worstCase.J()","returnValue":{"class":"worstCase.J","id":1065473029},"threadId":1,"time":1612737818156873},
+{"type":"fieldSet","fieldName":"worstCase.I.j","container":{"class":"worstCase.I","id":1686549717},"value":{"class":"worstCase.J","id":1065473029},"threadId":1,"lineNum":4,"time":1612737818188870},
+{"type":"constructorExit","shortSignature":"worstCase.I()","returnValue":{"class":"worstCase.I","id":1686549717},"threadId":1,"time":1612737818204869},
+{"type":"fieldSet","fieldName":"worstCase.H.i","container":{"class":"worstCase.H","id":1204436866},"value":{"class":"worstCase.I","id":1686549717},"threadId":1,"lineNum":4,"time":1612737818235659},
+{"type":"constructorExit","shortSignature":"worstCase.H()","returnValue":{"class":"worstCase.H","id":1204436866},"threadId":1,"time":1612737818251356},
+{"type":"fieldSet","fieldName":"worstCase.G.h","container":{"class":"worstCase.G","id":789550240},"value":{"class":"worstCase.H","id":1204436866},"threadId":1,"lineNum":4,"time":1612737818282145},
+{"type":"constructorExit","shortSignature":"worstCase.G()","returnValue":{"class":"worstCase.G","id":789550240},"threadId":1,"time":1612737818336178},
+{"type":"fieldSet","fieldName":"worstCase.F.g","container":{"class":"worstCase.F","id":669428867},"value":{"class":"worstCase.G","id":789550240},"threadId":1,"lineNum":4,"time":1612737818408927},
+{"type":"constructorExit","shortSignature":"worstCase.F()","returnValue":{"class":"worstCase.F","id":669428867},"threadId":1,"time":1612737818434585},
+{"type":"fieldSet","fieldName":"worstCase.E.f","container":{"class":"worstCase.E","id":424141036},"value":{"class":"worstCase.F","id":669428867},"threadId":1,"lineNum":4,"time":1612737818500693},
+{"type":"constructorExit","shortSignature":"worstCase.E()","returnValue":{"class":"worstCase.E","id":424141036},"threadId":1,"time":1612737818525445},
+{"type":"fieldSet","fieldName":"worstCase.D.e","container":{"class":"worstCase.D","id":1040167659},"value":{"class":"worstCase.E","id":424141036},"threadId":1,"lineNum":4,"time":1612737818584308},
+{"type":"constructorExit","shortSignature":"worstCase.D()","returnValue":{"class":"worstCase.D","id":1040167659},"threadId":1,"time":1612737818608155},
+{"type":"fieldSet","fieldName":"worstCase.C.d","container":{"class":"worstCase.C","id":1580958233},"value":{"class":"worstCase.D","id":1040167659},"threadId":1,"lineNum":4,"time":1612737818665811},
+{"type":"constructorExit","shortSignature":"worstCase.C()","returnValue":{"class":"worstCase.C","id":1580958233},"threadId":1,"time":1612737818691469},
+{"type":"fieldSet","fieldName":"worstCase.B.c","container":{"class":"worstCase.B","id":349857700},"value":{"class":"worstCase.C","id":1580958233},"threadId":1,"lineNum":4,"time":1612737818746407},
+{"type":"constructorExit","shortSignature":"worstCase.B()","returnValue":{"class":"worstCase.B","id":349857700},"threadId":1,"time":1612737818775990},
+{"type":"fieldSet","fieldName":"worstCase.A.b","container":{"class":"worstCase.A","id":248138414},"value":{"class":"worstCase.B","id":349857700},"threadId":1,"lineNum":4,"time":1612737818831230},
+{"type":"methodCall","callerSideSignature":"worstCase.N()","threadId":1,"lineNum":5},
+{"type":"constructorEntry","signature":"worstCase.N()","class":"worstCase.N","args":[],"threadId":1,"time":1612737819869934},
+{"type":"methodCall","callerSideSignature":"worstCase.O()","threadId":1,"lineNum":4},
+{"type":"constructorEntry","signature":"worstCase.O()","class":"worstCase.O","args":[],"threadId":1,"time":1612737820953614},
+{"type":"methodCall","callerSideSignature":"worstCase.P()","threadId":1,"lineNum":4},
+{"type":"constructorEntry","signature":"worstCase.P()","class":"worstCase.P","args":[],"threadId":1,"time":1612737821906891},
+{"type":"constructorExit","shortSignature":"worstCase.P()","returnValue":{"class":"worstCase.P","id":1495547765},"threadId":1,"time":1612737821969377},
+{"type":"fieldSet","fieldName":"worstCase.O.p","container":{"class":"worstCase.O","id":1522681867},"value":{"class":"worstCase.P","id":1495547765},"threadId":1,"lineNum":4,"time":1612737822032767},
+{"type":"constructorExit","shortSignature":"worstCase.O()","returnValue":{"class":"worstCase.O","id":1522681867},"threadId":1,"time":1612737822056916},
+{"type":"fieldSet","fieldName":"worstCase.N.o","container":{"class":"worstCase.N","id":151517370},"value":{"class":"worstCase.O","id":1522681867},"threadId":1,"lineNum":4,"time":1612737822114873},
+{"type":"constructorExit","shortSignature":"worstCase.N()","returnValue":{"class":"worstCase.N","id":151517370},"threadId":1,"time":1612737822138419},
+{"type":"fieldSet","fieldName":"worstCase.A.n","container":{"class":"worstCase.A","id":248138414},"value":{"class":"worstCase.N","id":151517370},"threadId":1,"lineNum":5,"time":1612737822175246},
+{"type":"constructorExit","shortSignature":"worstCase.A()","returnValue":{"class":"worstCase.A","id":248138414},"threadId":1,"time":1612737822199998},
+{"type":"methodCall","callerSideSignature":"worstCase.A.m()","threadId":1,"lineNum":11},
+{"type":"methodEntry","signature":"void worstCase.A.m()","receiver":{"class":"worstCase.A","id":248138414},"args":[],"threadId":1,"time":1612737822247994},
+{"type":"blockEntry","methodSignature":"worstCase.A.m()","blockId":0,"incomings":0,"threadId":1,"lineNum":7,"time":1612737822271841},
+{"type":"fieldGet","fieldName":"worstCase.A.n","this":{"class":"worstCase.A","id":248138414},"container":{"class":"worstCase.A","id":248138414},"value":{"class":"worstCase.N","id":151517370},"threadId":1,"lineNum":7,"time":1612737822312592},
+{"type":"fieldGet","fieldName":"worstCase.A.b","this":{"class":"worstCase.A","id":248138414},"container":{"class":"worstCase.A","id":248138414},"value":{"class":"worstCase.B","id":349857700},"threadId":1,"lineNum":7,"time":1612737822352740},
+{"type":"methodCall","callerSideSignature":"worstCase.B.getI()","threadId":1,"lineNum":7},
+{"type":"methodEntry","signature":"worstCase.I worstCase.B.getI()","receiver":{"class":"worstCase.B","id":349857700},"args":[],"threadId":1,"time":1612737822399830},
+{"type":"blockEntry","methodSignature":"worstCase.B.getI()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1612737822421262},
+{"type":"fieldGet","fieldName":"worstCase.B.c","this":{"class":"worstCase.B","id":349857700},"container":{"class":"worstCase.B","id":349857700},"value":{"class":"worstCase.C","id":1580958233},"threadId":1,"lineNum":6,"time":1612737822459297},
+{"type":"methodCall","callerSideSignature":"worstCase.C.getF()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.F worstCase.C.getF()","receiver":{"class":"worstCase.C","id":1580958233},"args":[],"threadId":1,"time":1612737822513934},
+{"type":"blockEntry","methodSignature":"worstCase.C.getF()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1612737822537479},
+{"type":"fieldGet","fieldName":"worstCase.C.d","this":{"class":"worstCase.C","id":1580958233},"container":{"class":"worstCase.C","id":1580958233},"value":{"class":"worstCase.D","id":1040167659},"threadId":1,"lineNum":6,"time":1612737822576721},
+{"type":"methodCall","callerSideSignature":"worstCase.D.getE()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.E worstCase.D.getE()","receiver":{"class":"worstCase.D","id":1040167659},"args":[],"threadId":1,"time":1612737822627735},
+{"type":"blockEntry","methodSignature":"worstCase.D.getE()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1612737822651582},
+{"type":"fieldGet","fieldName":"worstCase.D.e","this":{"class":"worstCase.D","id":1040167659},"container":{"class":"worstCase.D","id":1040167659},"value":{"class":"worstCase.E","id":424141036},"threadId":1,"lineNum":6,"time":1612737822693541},
+{"type":"methodExit","shortSignature":"worstCase.D.getE()","receiver":{"class":"worstCase.D","id":1040167659},"returnValue":{"class":"worstCase.E","id":424141036},"threadId":1,"time":1612737822729462},
+{"type":"methodCall","callerSideSignature":"worstCase.E.getF()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.F worstCase.E.getF()","receiver":{"class":"worstCase.E","id":424141036},"args":[],"threadId":1,"time":1612737822781382},
+{"type":"blockEntry","methodSignature":"worstCase.E.getF()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1612737822804927},
+{"type":"fieldGet","fieldName":"worstCase.E.f","this":{"class":"worstCase.E","id":424141036},"container":{"class":"worstCase.E","id":424141036},"value":{"class":"worstCase.F","id":669428867},"threadId":1,"lineNum":6,"time":1612737822845377},
+{"type":"methodExit","shortSignature":"worstCase.E.getF()","receiver":{"class":"worstCase.E","id":424141036},"returnValue":{"class":"worstCase.F","id":669428867},"threadId":1,"time":1612737822887939},
+{"type":"methodExit","shortSignature":"worstCase.C.getF()","receiver":{"class":"worstCase.C","id":1580958233},"returnValue":{"class":"worstCase.F","id":669428867},"threadId":1,"time":1612737822925370},
+{"type":"methodCall","callerSideSignature":"worstCase.F.getI()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.I worstCase.F.getI()","receiver":{"class":"worstCase.F","id":669428867},"args":[],"threadId":1,"time":1612737822977290},
+{"type":"blockEntry","methodSignature":"worstCase.F.getI()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1612737822998420},
+{"type":"fieldGet","fieldName":"worstCase.F.g","this":{"class":"worstCase.F","id":669428867},"container":{"class":"worstCase.F","id":669428867},"value":{"class":"worstCase.G","id":789550240},"threadId":1,"lineNum":6,"time":1612737823040681},
+{"type":"methodCall","callerSideSignature":"worstCase.G.getH()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.H worstCase.G.getH()","receiver":{"class":"worstCase.G","id":789550240},"args":[],"threadId":1,"time":1612737823100751},
+{"type":"blockEntry","methodSignature":"worstCase.G.getH()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1612737823129126},
+{"type":"fieldGet","fieldName":"worstCase.G.h","this":{"class":"worstCase.G","id":789550240},"container":{"class":"worstCase.G","id":789550240},"value":{"class":"worstCase.H","id":1204436866},"threadId":1,"lineNum":6,"time":1612737823171085},
+{"type":"methodExit","shortSignature":"worstCase.G.getH()","receiver":{"class":"worstCase.G","id":789550240},"returnValue":{"class":"worstCase.H","id":1204436866},"threadId":1,"time":1612737823212741},
+{"type":"methodCall","callerSideSignature":"worstCase.H.getI()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.I worstCase.H.getI()","receiver":{"class":"worstCase.H","id":1204436866},"args":[],"threadId":1,"time":1612737823267680},
+{"type":"blockEntry","methodSignature":"worstCase.H.getI()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1612737823289112},
+{"type":"fieldGet","fieldName":"worstCase.H.i","this":{"class":"worstCase.H","id":1204436866},"container":{"class":"worstCase.H","id":1204436866},"value":{"class":"worstCase.I","id":1686549717},"threadId":1,"lineNum":6,"time":1612737823338014},
+{"type":"methodExit","shortSignature":"worstCase.H.getI()","receiver":{"class":"worstCase.H","id":1204436866},"returnValue":{"class":"worstCase.I","id":1686549717},"threadId":1,"time":1612737823368502},
+{"type":"methodExit","shortSignature":"worstCase.F.getI()","receiver":{"class":"worstCase.F","id":669428867},"returnValue":{"class":"worstCase.I","id":1686549717},"threadId":1,"time":1612737823400197},
+{"type":"methodExit","shortSignature":"worstCase.B.getI()","receiver":{"class":"worstCase.B","id":349857700},"returnValue":{"class":"worstCase.I","id":1686549717},"threadId":1,"time":1612737823432194},
+{"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":151517370},"args":[{"class":"worstCase.I","id":1686549717}],"threadId":1,"time":1612737823483813},
+{"type":"blockEntry","methodSignature":"worstCase.N.passI(worstCase.I)","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1612737823503736},
+{"type":"fieldGet","fieldName":"worstCase.N.o","this":{"class":"worstCase.N","id":151517370},"container":{"class":"worstCase.N","id":151517370},"value":{"class":"worstCase.O","id":1522681867},"threadId":1,"lineNum":6,"time":1612737823551128},
+{"type":"methodCall","callerSideSignature":"worstCase.I.getL()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.L worstCase.I.getL()","receiver":{"class":"worstCase.I","id":1686549717},"args":[],"threadId":1,"time":1612737823602142},
+{"type":"blockEntry","methodSignature":"worstCase.I.getL()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1612737823623272},
+{"type":"fieldGet","fieldName":"worstCase.I.j","this":{"class":"worstCase.I","id":1686549717},"container":{"class":"worstCase.I","id":1686549717},"value":{"class":"worstCase.J","id":1065473029},"threadId":1,"lineNum":6,"time":1612737823669759},
+{"type":"methodCall","callerSideSignature":"worstCase.J.getK()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.K worstCase.J.getK()","receiver":{"class":"worstCase.J","id":1065473029},"args":[],"threadId":1,"time":1612737823731640},
+{"type":"blockEntry","methodSignature":"worstCase.J.getK()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1612737823761525},
+{"type":"fieldGet","fieldName":"worstCase.J.k","this":{"class":"worstCase.J","id":1065473029},"container":{"class":"worstCase.J","id":1065473029},"value":{"class":"worstCase.K","id":1175576547},"threadId":1,"lineNum":6,"time":1612737823801370},
+{"type":"methodExit","shortSignature":"worstCase.J.getK()","receiver":{"class":"worstCase.J","id":1065473029},"returnValue":{"class":"worstCase.K","id":1175576547},"threadId":1,"time":1612737823851479},
+{"type":"methodCall","callerSideSignature":"worstCase.K.getL()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.L worstCase.K.getL()","receiver":{"class":"worstCase.K","id":1175576547},"args":[],"threadId":1,"time":1612737823912153},
+{"type":"blockEntry","methodSignature":"worstCase.K.getL()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1612737823943245},
+{"type":"fieldGet","fieldName":"worstCase.K.l","this":{"class":"worstCase.K","id":1175576547},"container":{"class":"worstCase.K","id":1175576547},"value":{"class":"worstCase.L","id":2004703190},"threadId":1,"lineNum":6,"time":1612737823983091},
+{"type":"methodExit","shortSignature":"worstCase.K.getL()","receiver":{"class":"worstCase.K","id":1175576547},"returnValue":{"class":"worstCase.L","id":2004703190},"threadId":1,"time":1612737824017201},
+{"type":"methodExit","shortSignature":"worstCase.I.getL()","receiver":{"class":"worstCase.I","id":1686549717},"returnValue":{"class":"worstCase.L","id":2004703190},"threadId":1,"time":1612737824052821},
+{"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":1522681867},"args":[{"class":"worstCase.L","id":2004703190}],"threadId":1,"time":1612737824119834},
+{"type":"blockEntry","methodSignature":"worstCase.O.passL(worstCase.L)","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1612737824140058},
+{"type":"fieldGet","fieldName":"worstCase.O.p","this":{"class":"worstCase.O","id":1522681867},"container":{"class":"worstCase.O","id":1522681867},"value":{"class":"worstCase.P","id":1495547765},"threadId":1,"lineNum":6,"time":1612737824183526},
+{"type":"methodCall","callerSideSignature":"worstCase.L.getM()","threadId":1,"lineNum":6},
+{"type":"methodEntry","signature":"worstCase.M worstCase.L.getM()","receiver":{"class":"worstCase.L","id":2004703190},"args":[],"threadId":1,"time":1612737824234239},
+{"type":"blockEntry","methodSignature":"worstCase.L.getM()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1612737824253256},
+{"type":"fieldGet","fieldName":"worstCase.L.m","this":{"class":"worstCase.L","id":2004703190},"container":{"class":"worstCase.L","id":2004703190},"value":{"class":"worstCase.M","id":1590384136},"threadId":1,"lineNum":6,"time":1612737824302761},
+{"type":"methodExit","shortSignature":"worstCase.L.getM()","receiver":{"class":"worstCase.L","id":2004703190},"returnValue":{"class":"worstCase.M","id":1590384136},"threadId":1,"time":1612737824345022},
+{"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":1495547765},"args":[{"class":"worstCase.M","id":1590384136}],"threadId":1,"time":1612737824403281},
+{"type":"blockEntry","methodSignature":"worstCase.P.setM(worstCase.M)","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1612737824425015},
+{"type":"fieldSet","fieldName":"worstCase.P.m","container":{"class":"worstCase.P","id":1495547765},"value":{"class":"worstCase.M","id":1590384136},"threadId":1,"lineNum":6,"time":1612737824472709},
+{"type":"methodExit","shortSignature":"worstCase.P.setM(worstCase.M)","receiver":{"class":"worstCase.P","id":1495547765},"returnValue":{"class":"void","id":0},"threadId":1,"time":1612737824505310},
+{"type":"methodExit","shortSignature":"worstCase.O.passL(worstCase.L)","receiver":{"class":"worstCase.O","id":1522681867},"returnValue":{"class":"void","id":0},"threadId":1,"time":1612737824535194},
+{"type":"methodExit","shortSignature":"worstCase.N.passI(worstCase.I)","receiver":{"class":"worstCase.N","id":151517370},"returnValue":{"class":"void","id":0},"threadId":1,"time":1612737824582284},
+{"type":"methodExit","shortSignature":"worstCase.A.m()","receiver":{"class":"worstCase.A","id":248138414},"returnValue":{"class":"void","id":0},"threadId":1,"time":1612737824616093},
+{"type":"methodExit","shortSignature":"worstCase.main.main(java.lang.String[])","receiver":{"class":"worstCase.main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":1612737824655939},