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