diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/DeltaAlias.java b/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/DeltaAlias.java new file mode 100644 index 0000000..e1de2be --- /dev/null +++ b/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/DeltaAlias.java @@ -0,0 +1,16 @@ +package org.ntlab.deltaExtractor; + +import org.ntlab.trace.TracePoint; + +public class DeltaAlias extends Alias { + boolean bSrcSide = false; + + public DeltaAlias(AliasType aliasType, int index, String objectId, TracePoint occurrencePoint, boolean isSrcSide) { + super(aliasType, index, objectId, occurrencePoint); + bSrcSide = isSrcSide; + } + + public boolean isSrcSide() { + return bSrcSide; + } +} diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/DeltaExtractor.java b/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/DeltaExtractor.java index f687c55..2a3b809 100644 --- a/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/DeltaExtractor.java +++ b/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/DeltaExtractor.java @@ -1,6 +1,7 @@ package org.ntlab.deltaExtractor; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import org.ntlab.trace.FieldAccess; @@ -46,6 +47,7 @@ } @Override public List getAliasList() { + // TODO Auto-generated method stub return null; } }; @@ -102,12 +104,13 @@ /** * �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 methodExecution �T�����n�߂郁�\�b�h���s + * @param objList�@�ǐՒ��̃I�u�W�F�N�g�̃��X�g * @param child�@���O�ɒT�����Ă����Ăяo����̃��\�b�h���s + * @param aliasCollector �G�C���A�X�����W���邽�߂̃r�W�^�[ * @return ���‚������R�[�f�B�l�[�^ - * @throws TraceFileException */ + @Deprecated protected MethodExecution callerSearch(Trace trace, TracePoint tracePoint, ArrayList objList, MethodExecution childMethodExecution, IAliasTracker aliasCollector) { MethodExecution methodExecution = tracePoint.getMethodExecution(); methodExecution.setAugmentation(new DeltaAugmentationInfo()); @@ -123,6 +126,9 @@ ObjectReference thisObj = new ObjectReference(thisObjectId, methodExecution.getThisClassName(), Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor()), Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstructor())); + HashMap srcAliasList = new HashMap<>(); + HashMap dstAliasList = new HashMap<>(); + if (childMethodExecution == null) { // �T���J�n���͈�U�폜���A�Ăяo�����̒T���𑱂���ۂɕ��������� removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� @@ -135,6 +141,19 @@ // �I�u�W�F�N�g���Ăяo���̂Ƃ��݈̂�U�폜���A�Ăяo�����̒T���𑱂���ۂɕ��������� removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� isTrackingThis = true; // �Ăяo�����T���O�ɕ��� + // �I�u�W�F�N�g���Ăяo���̏ꍇ [case 1] + aliasCollector.addAlias(new Alias(Alias.AliasType.RECEIVER, 0, childMethodExecution.getThisObjId(), tracePoint.duplicate())); + } else if (!childMethodExecution.isConstructor()) { + // �I�u�W�F�N�g�Ԃ̔�R���X�g���N�^�Ăяo���̏ꍇ [case 2] + aliasCollector.addAlias(new Alias(Alias.AliasType.RECEIVER, 0, childMethodExecution.getThisObjId(), tracePoint.duplicate())); + } + } + + if (childMethodExecution != null) { + for (String objId : objList) { + if (!objId.equals(childMethodExecution.getThisObjId())) { + aliasCollector.addAlias(new Alias(Alias.AliasType.ACTUAL_ARGUMENT, -1, objId, tracePoint.duplicate())); // �����ԍ����킩��Ȃ� + } } } @@ -146,6 +165,14 @@ removeList.add(childMethodExecution.getThisObjId()); existsInFields++; removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + if (!thisObjectId.equals(childMethodExecution.getThisObjId())) { + // �I�u�W�F�N�g�Ԃ̃R���X�g���N�^�Ăяo���̏ꍇl [case 3] + if (childMethodExecution.getThisObjId().equals(srcObject.getId())) { + srcAliasList.put(childMethodExecution.getThisObjId(), new DeltaAlias(Alias.AliasType.RECEIVER, 0, childMethodExecution.getThisObjId(), tracePoint.duplicate(), true)); + } else if (childMethodExecution.getThisObjId().equals(dstObject.getId())) { + dstAliasList.put(childMethodExecution.getThisObjId(), new DeltaAlias(Alias.AliasType.RECEIVER, 0, childMethodExecution.getThisObjId(), tracePoint.duplicate(), false)); + } + } } } @@ -160,34 +187,46 @@ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� } } - + + // callerSearch �̃��C�����[�v�D���݂̃��\�b�h�̃X�e�[�g�����g�̎��s�����s�Ƌt�����ɒT�������D // �߂�l�ɒT���Ώۂ��܂܂�Ă����calleeSearch���ċA�Ăяo�� while (tracePoint.stepBackOver()) { Statement statement = tracePoint.getStatement(); - // ���ڎQ�Ƃ���уt�B�[���h�Q�Ƃ̒T�� if (statement instanceof FieldAccess) { + // ���s�����t�B�[���h�Q�Ƃ������ꍇ 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�Ƃ̏ꍇ + // �����̃t�B�[���h�̎Q�Ƃ̏ꍇ removeList.add(refObjectId); - existsInFields++; // set�������get�����o���Ă���”\�������� removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + if (refObjectId.equals(srcObject.getId())) { + srcAliasList.put(refObjectId, new DeltaAlias(Alias.AliasType.FIELD, 0, refObjectId, tracePoint.duplicate(), true)); + } else if (refObjectId.equals(dstObject.getId())) { + dstAliasList.put(refObjectId, new DeltaAlias(Alias.AliasType.FIELD, 0, refObjectId, tracePoint.duplicate(), false)); + } + existsInFields++; // set�������get�����o���Ă���”\�������� } else { - // ���ڎQ�Ƃ̏ꍇ + // ���̃I�u�W�F�N�g�̃t�B�[���h�̎Q�Ƃ̏ꍇ + boolean isSrcSideChanged = false; if (refObjectId.equals(srcObject.getId())) { eStructure.addSrcSide(new Reference(ownerObjectId, refObjectId, fs.getContainerClassName(), srcObject.getActualType())); srcObject = new ObjectReference(ownerObjectId, fs.getContainerClassName()); + isSrcSideChanged = true; } else if(refObjectId.equals(dstObject.getId())) { eStructure.addDstSide(new Reference(ownerObjectId, refObjectId, fs.getContainerClassName(), dstObject.getActualType())); dstObject = new ObjectReference(ownerObjectId, fs.getContainerClassName()); + isSrcSideChanged = false; } objList.set(index, ownerObjectId); + aliasCollector.addAlias(new Alias(Alias.AliasType.FIELD, 0, refObjectId, tracePoint.duplicate())); + aliasCollector.changeTrackingObject(refObjectId, ownerObjectId, isSrcSideChanged); // �ǐՑΏۂ��t�B�[���h�ɂ��Q�Ɛ�I�u�W�F�N�g����Q�ƌ��I�u�W�F�N�g�i�R���e�i�j�ɒu������ + aliasCollector.addAlias(new Alias(Alias.AliasType.CONTAINER, 0, ownerObjectId, tracePoint.duplicate())); } } else { // �ŏI�I�ɃI�u�W�F�N�g�̗R�������‚���Ȃ������ꍇ�ɁA�����ŎQ�Ƃ����z������̗v�f�ɗR�����Ă���”\�������� @@ -211,6 +250,11 @@ // �t�B�[���h�Q�Ƃ̏ꍇ�i���ɗR���̉”\�����Ȃ��Ƃ킩�������_�ŁA���̔z��̗v�f�ɗR�����Ă�����̂Ɛ�������B�j fieldArrays.add(new ObjectReference(refObjectId, refObjType)); fieldArrayElements.add(trackingObj); + if (trackingObj.getId().equals(srcObject.getId())) { + srcAliasList.put(trackingObj.getId(), new DeltaAlias(Alias.AliasType.ARRAY_ELEMENT, 0, trackingObj.getId(), tracePoint.duplicate(), true)); + } else if (trackingObj.getId().equals(dstObject.getId())) { + dstAliasList.put(trackingObj.getId(), new DeltaAlias(Alias.AliasType.ARRAY_ELEMENT, 0, trackingObj.getId(), tracePoint.duplicate(), false)); + } } else { // ���ڎQ�Ƃ̏ꍇ(�{���ɂ��̔z��̗v�f����擾���ꂽ���̂Ȃ炱���ŒǐՑΏۂ�u��������ׂ������A // ���̎��_�ő��̗R���̉”\����r���ł��Ȃ��B�����ŒǐՑΏۂ�u�������Ă��܂��ƁA��ŕʂɗR�������邱�Ƃ��킩�����ꍇ�� @@ -220,6 +264,7 @@ } } } else if (statement instanceof MethodInvocation) { + // ���s�������\�b�h�Ăяo���������ꍇ MethodExecution prevChildMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution(); if (!prevChildMethodExecution.equals(childMethodExecution)) { // �߂�l @@ -236,13 +281,23 @@ 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 + ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(newObjId)); // �ǐՑΏ� + ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setSetterSide(false); // �Q�Ƒ��̌Ăяo���Ɠ��l + if (newObjId.equals(srcObject.getId())) { + srcAliasList.put(newObjId, new DeltaAlias(Alias.AliasType.CONSTRACTOR_INVOCATION, 0, newObjId, tracePoint.duplicate(), true)); + } else if (newObjId.equals(dstObject.getId())) { + dstAliasList.put(newObjId, new DeltaAlias(Alias.AliasType.CONSTRACTOR_INVOCATION, 0, newObjId, tracePoint.duplicate(), false)); + } continue; } String retObj = objList.get(retIndex); + if (retObj.equals(srcObject.getId())) { + isSrcSide = true; + } else if (retObj.equals(dstObject.getId())) { + isSrcSide = false; + } + aliasCollector.addAlias(new Alias(Alias.AliasType.METHOD_INVOCATION, 0, retObj, tracePoint.duplicate())); if (removeList.contains(retObj)) { // ��xget�Ō��o���ăt�B�[���h�Ɉˑ����Ă���Ɣ��f�������{���̗R�����߂�l���������Ƃ����������̂ŁA�t�B�[���h�ւ̈ˑ����L�����Z������ removeList.remove(retObj); @@ -251,15 +306,21 @@ removeList.remove(thisObjectId); } } - ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(retObj)); // �ǐՑΏ� + ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(retObj)); // �ǐՑΏ� TracePoint prevChildTracePoint = tracePoint.duplicate(); prevChildTracePoint.stepBackNoReturn(); - calleeSearch(trace, prevChildTracePoint, objList, prevChildMethodExecution.isStatic(), retIndex, aliasCollector); // �Ăя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�ɕ��� + calleeSearch(trace, prevChildTracePoint, objList, prevChildMethodExecution.isStatic(), retIndex, aliasCollector); // �Ăяo���惁�\�b�h���s�̒T���̂��ߍċA�Ăяo�� + if (objList.get(retIndex) != null && objList.get(retIndex).equals(prevChildMethodExecution.getThisObjId())) { + if (thisObjectId.equals(prevChildMethodExecution.getThisObjId())) { + // �Ăяo����Ńt�B�[���h�Ɉˑ����Ă����ꍇ�̏��� + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + isTrackingThis = true; // �Ăяo�����T���O�ɕ��� + } + if (isSrcSide) { + aliasCollector.addAlias(new DeltaAlias(Alias.AliasType.RECEIVER, 0, objList.get(retIndex), tracePoint.duplicate(), true)); + } else { + aliasCollector.addAlias(new DeltaAlias(Alias.AliasType.RECEIVER, 0, objList.get(retIndex), tracePoint.duplicate(), false)); + } } if (isLost) { checkList.add(objList.get(retIndex)); @@ -297,16 +358,16 @@ // �R���N�V�����^�Ή� if (methodExecution.isCollectionType()) { objList.add(thisObjectId); - } - + } + // �����̎擾 - ArrayList argments = methodExecution.getArguments(); + ArrayList arguments = methodExecution.getArguments(); - // �����ƃt�B�[���h�ɓ���ID�̃I�u�W�F�N�g������ꍇ��z�� + // �����ƃt�B�[���h�ɓ���ID�̃I�u�W�F�N�g������ꍇ��z��i�R���Ƃ��Ĉ����ƃt�B�[���h�̗������^����ꍇ�j Reference r; for (int i = 0; i < removeList.size(); i++) { String removeId = removeList.get(i); - if (argments.contains(new ObjectReference(removeId))) { + if (arguments.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�Ɉ���) @@ -319,28 +380,41 @@ eStructure.addSrcSide(r); srcObject = thisObj; isSrcSide = true; + if (srcAliasList.containsKey(removeId)) { + aliasCollector.addAlias(srcAliasList.get(removeId)); + aliasCollector.changeTrackingObject(removeId, thisObjectId, isSrcSide); + aliasCollector.addAlias(new Alias(Alias.AliasType.THIS, 0, thisObjectId, srcAliasList.get(removeId).getOccurrencePoint())); + srcAliasList.remove(removeId); + } } 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; + if (dstAliasList.containsKey(removeId)) { + aliasCollector.addAlias(dstAliasList.get(removeId)); + aliasCollector.changeTrackingObject(removeId, thisObjectId, isSrcSide); + aliasCollector.addAlias(new Alias(Alias.AliasType.THIS, 0, thisObjectId, dstAliasList.get(removeId).getOccurrencePoint())); + dstAliasList.remove(removeId); + } } } } } // --- ���̎��_�� this ���ǐՑΏۂł������Ƃ��Ă� objList �̒����炢������폜����Ă��� --- - // �����T�� + // �R���Ƃ��Ĉ�����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)) { + if (arguments.contains(trackingObj)) { // �������R�������� existsInAnArgument = true; ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(objectId)); + aliasCollector.addAlias(new Alias(Alias.AliasType.FORMAL_PARAMETER, arguments.indexOf(trackingObj), trackingObj.getId(), methodExecution.getEntryPoint())); } else { // �R�����ǂ��ɂ����‚���Ȃ����� boolean isSrcSide2 = true; @@ -354,8 +428,8 @@ } if (trackingObj != null) { // �܂��z������̗v�f��R���Ƃ��ċ^��(������D��) - for (int j = 0; j < argments.size(); j++) { - ObjectReference argArray = argments.get(j); + for (int j = 0; j < arguments.size(); j++) { + ObjectReference argArray = arguments.get(j); if (argArray.getActualType().startsWith("[L") && (trackingObj.getActualType() != null && (argArray.getActualType().endsWith(trackingObj.getActualType() + ";")) || (trackingObj.getCalleeType() != null && argArray.getActualType().endsWith(trackingObj.getCalleeType() + ";")) @@ -376,6 +450,10 @@ dstObject = new ObjectReference(argArray.getId(), argArray.getActualType()); } objectId = null; + aliasCollector.addAlias(new Alias(Alias.AliasType.ARRAY_ELEMENT, 0, trackingObj.getId(), methodExecution.getEntryPoint())); // �z��v�f�̓��\�b�h�̐擪�Ŏ擾���ꂽ�Ɖ��肷�� + aliasCollector.changeTrackingObject(trackingObj.getId(), argArray.getId(), isSrcSide2); // �ǐՑΏۂ�z��v�f����z��ɒu������ + aliasCollector.addAlias(new Alias(Alias.AliasType.ARRAY, 0, argArray.getId(), methodExecution.getEntryPoint())); // �z��̓��\�b�h�̐擪�ŃA�N�Z�X���ꂽ�Ɖ��肷�� + aliasCollector.addAlias(new Alias(Alias.AliasType.FORMAL_PARAMETER, arguments.indexOf(argArray), trackingObj.getId(), methodExecution.getEntryPoint())); break; } } @@ -395,13 +473,27 @@ eStructure.addSrcSide(new Reference(thisObjectId, fieldArray.getId(), methodExecution.getThisClassName(), fieldArray.getActualType())); srcObject = thisObj; - isSrcSide = true; + if (srcAliasList.containsKey(trackingObj.getId())) { + aliasCollector.addAlias(srcAliasList.get(trackingObj.getId())); + aliasCollector.changeTrackingObject(trackingObj.getId(), fieldArray.getId(), isSrcSide2); // �ǐՑΏۂ�z��v�f����z��t�B�[���h�ɒu������ + aliasCollector.addAlias(new Alias(Alias.AliasType.ARRAY, 0, fieldArray.getId(), srcAliasList.get(trackingObj.getId()).getOccurrencePoint())); + aliasCollector.changeTrackingObject(fieldArray.getId(), thisObjectId, isSrcSide2); // �ǐՑΏۂ�z��t�B�[���h����this�I�u�W�F�N�g�ɒu������ + aliasCollector.addAlias(new Alias(Alias.AliasType.THIS, 0, thisObjectId, srcAliasList.get(trackingObj.getId()).getOccurrencePoint())); + srcAliasList.remove(trackingObj.getId()); + } } else { eStructure.addDstSide(r); eStructure.addDstSide(new Reference(thisObjectId, fieldArray.getId(), methodExecution.getThisClassName(), fieldArray.getActualType())); dstObject = thisObj; - isSrcSide = false; + if (dstAliasList.containsKey(trackingObj.getId())) { + aliasCollector.addAlias(dstAliasList.get(trackingObj.getId())); + aliasCollector.changeTrackingObject(trackingObj.getId(), fieldArray.getId(), isSrcSide2); // �ǐՑΏۂ�z��v�f����z��t�B�[���h�ɒu������ + aliasCollector.addAlias(new Alias(Alias.AliasType.ARRAY, 0, fieldArray.getId(), dstAliasList.get(trackingObj.getId()).getOccurrencePoint())); + aliasCollector.changeTrackingObject(fieldArray.getId(), thisObjectId, isSrcSide2); // �ǐՑΏۂ�z��t�B�[���h����this�I�u�W�F�N�g�ɒu������ + aliasCollector.addAlias(new Alias(Alias.AliasType.THIS, 0, thisObjectId, dstAliasList.get(trackingObj.getId()).getOccurrencePoint())); + dstAliasList.remove(trackingObj.getId()); + } } } } @@ -412,13 +504,14 @@ 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; } + aliasCollector.addAlias(new Alias(Alias.AliasType.ARRAY_CREATE, 0, trackingObj.getId(), methodExecution.getEntryPoint())); // �z��̓��\�b�h�̐擪�Ő������ꂽ���̂Ɖ��肷�� + aliasCollector.changeTrackingObject(trackingObj.getId(), thisObjectId, isSrcSide2); // �ǐՑΏۂ�z�񂩂�this�I�u�W�F�N�g�ɒu������ + aliasCollector.addAlias(new Alias(Alias.AliasType.THIS, 0, thisObjectId, methodExecution.getEntryPoint())); // �z��̓��\�b�h�̐擪�Ő������ꂽ���̂Ɖ��肷�� } } } @@ -444,7 +537,7 @@ // } if (tracePoint.isValid()) { finalCount = 0; - return callerSearch(trace, tracePoint, objList, methodExecution, aliasCollector); // �Ăяo����������ɒT�� + return callerSearch(trace, tracePoint, objList, methodExecution, aliasCollector); // �Ăяo����������ɒT�����邽�ߍċA�Ăяo�� } } @@ -459,8 +552,8 @@ finalCount++; if (finalCount <= LOST_DECISION_EXTENSION) { // final�ϐ����Q�Ƃ��Ă���ꍇ�R���������ł��Ȃ��”\��������̂ŁA�ǐՂ������I�������P�\���Ԃ�݂��� - if (tracePoint.isValid()) { - MethodExecution c = callerSearch(trace, tracePoint, objList, methodExecution, aliasCollector); // �Ăяo����������ɒT�� + if (tracePoint.isValid()) { + MethodExecution c = callerSearch(trace, tracePoint, objList, methodExecution, aliasCollector); // �Ăяo����������ɒT�����邽�ߍċA�Ăяo�� if (((DeltaAugmentationInfo)c.getAugmentation()).isCoodinator()) { methodExecution = c; // �ǐՂ𑱂������ʃR�[�f�B�l�[�^�����‚����� } @@ -505,7 +598,7 @@ finalCount = 0; return methodExecution; } - + /** * �f���^���o�A���S���Y���̌Ăяo����T������(�ċA�Ăяo���ɂȂ��Ă���) * @param trace ��͑Ώۃg���[�X @@ -513,8 +606,9 @@ * @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 + * @param aliasCollector �G�C���A�X�����W���邽�߂̃r�W�^�[ */ + @Deprecated protected void calleeSearch(Trace trace, TracePoint tracePoint, ArrayList objList, Boolean isStatic, int index, IAliasTracker aliasCollector) { MethodExecution methodExecution = tracePoint.getMethodExecution(); Boolean isResolved = false; @@ -526,9 +620,14 @@ 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(); + ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setSetterSide(false); // ��{�I�ɎQ�Ɛ摤�̌Ăяo���̂͂������A���� + ArrayList arguments = methodExecution.getArguments(); ObjectReference trackingObj = null; + + HashMap srcAliasList = new HashMap<>(); + HashMap dstAliasList = new HashMap<>(); + + aliasCollector.addAlias(new Alias(Alias.AliasType.RETURN_VALUE, 0, objectId, tracePoint.duplicate())); //static���o�R�����null�������Ă��鎞������ if (objectId != null) { String returnType = Trace.getReturnType(methodExecution.getSignature()); @@ -543,42 +642,55 @@ } Reference r; + // calleeSearch �̃��C�����[�v�D���݂̃��\�b�h�̃X�e�[�g�����g�̎��s�����s�Ƌt�����ɒT�������D // �߂�l�ɒT���Ώۂ��܂܂�Ă����calleeSearch�Ăяo�� do { if (!tracePoint.isValid()) break; Statement statement = tracePoint.getStatement(); - // ���ڎQ�Ƃ���уt�B�[���h�Q�Ƃ̒T�� if (statement instanceof FieldAccess) { + // ���s�����t�B�[���h�Q�Ƃ������ꍇ FieldAccess fs = (FieldAccess)statement; if (objectId != null && objectId.equals(fs.getValueObjId())) { String ownerObjectId = fs.getContainerObjId(); - if (ownerObjectId.equals(thisObjectId)) { - // �t�B�[���h�Q�Ƃ̏ꍇ + if (ownerObjectId.equals(thisObjectId)) { + // �����̃t�B�[���h�̎Q�Ƃ̏ꍇ + boolean isSrcSideChanged = false; if (objectId.equals(srcObject.getId())) { eStructure.addSrcSide(new Reference(thisObj, srcObject)); srcObject = thisObj; trackingObj = srcObject; + isSrcSideChanged = true; } else if(objectId.equals(dstObject.getId())) { eStructure.addDstSide(new Reference(thisObj, dstObject)); dstObject = thisObj; trackingObj = dstObject; + isSrcSideChanged = false; } + aliasCollector.addAlias(new Alias(Alias.AliasType.FIELD, 0, objectId, tracePoint.duplicate())); + aliasCollector.changeTrackingObject(objectId, ownerObjectId, isSrcSideChanged); + aliasCollector.addAlias(new Alias(Alias.AliasType.THIS, 0, ownerObjectId, tracePoint.duplicate())); if (Trace.isNull(thisObjectId)) objectId = null; // static�ϐ��̏ꍇ else objectId = thisObjectId; objList.set(index, objectId); } else { - // ���ڎQ�Ƃ̏ꍇ + // ���̃I�u�W�F�N�g�̃t�B�[���h�̎Q�Ƃ̏ꍇ + boolean isSrcSideChanged = false; if (objectId.equals(srcObject.getId())) { eStructure.addSrcSide(new Reference(ownerObjectId, objectId, fs.getContainerClassName(), srcObject.getActualType())); srcObject = new ObjectReference(ownerObjectId, fs.getContainerClassName()); trackingObj = srcObject; + isSrcSideChanged = true; } else if(objectId.equals(dstObject.getId())) { eStructure.addDstSide(new Reference(ownerObjectId, objectId, fs.getContainerClassName(), dstObject.getActualType())); dstObject = new ObjectReference(ownerObjectId, fs.getContainerClassName()); trackingObj = dstObject; + isSrcSideChanged = false; } + aliasCollector.addAlias(new Alias(Alias.AliasType.FIELD, 0, objectId, tracePoint.duplicate())); + aliasCollector.changeTrackingObject(objectId, ownerObjectId, isSrcSideChanged); + aliasCollector.addAlias(new Alias(Alias.AliasType.CONTAINER, 0, ownerObjectId, tracePoint.duplicate())); if (Trace.isNull(ownerObjectId)) objectId = null; // static�ϐ��̏ꍇ else objectId = ownerObjectId; objList.set(index, objectId); @@ -598,6 +710,11 @@ // �t�B�[���h�Q�Ƃ̏ꍇ�i���ɗR���̉”\�����Ȃ��Ƃ킩�������_�ŁA���̔z��̗v�f�ɗR�����Ă�����̂Ɛ�������B�j fieldArrays.add(new ObjectReference(fs.getValueObjId(), refObjType)); fieldArrayElements.add(trackingObj); + if (objectId.equals(srcObject.getId())) { + srcAliasList.put(objectId, new DeltaAlias(Alias.AliasType.ARRAY_ELEMENT, 0, objectId, tracePoint.duplicate(), true)); + } else if(objectId.equals(dstObject.getId())) { + dstAliasList.put(objectId, new DeltaAlias(Alias.AliasType.ARRAY_ELEMENT, 0, objectId, tracePoint.duplicate(), false)); + } } else { // ���ڎQ�Ƃ̏ꍇ(�{���ɂ��̔z��̗v�f����擾���ꂽ���̂Ȃ炱���ŒǐՑΏۂ�u��������ׂ������A // ���̎��_�ő��̗R���̉”\����r���ł��Ȃ��B�����ŒǐՑΏۂ�u�������Ă��܂��ƁA��ŕʂɗR�������邱�Ƃ��킩�����ꍇ�� @@ -607,7 +724,7 @@ } } } else if (statement instanceof MethodInvocation) { - // �߂�l + // ���s�������\�b�h�Ăяo���������ꍇ MethodExecution childMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution(); ObjectReference ret = childMethodExecution.getReturnValue(); if (ret != null && objectId != null && objectId.equals(ret.getId())) { @@ -615,7 +732,12 @@ ((DeltaAugmentationInfo)childMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(objectId)); TracePoint childTracePoint = tracePoint.duplicate(); childTracePoint.stepBackNoReturn(); - calleeSearch(trace, childTracePoint, objList, childMethodExecution.isStatic(), index, aliasCollector); // �Ăяo���������ɒT�� + if (!childMethodExecution.isConstructor()) { + aliasCollector.addAlias(new Alias(Alias.AliasType.METHOD_INVOCATION, 0, ret.getId(), tracePoint.duplicate())); + calleeSearch(trace, childTracePoint, objList, childMethodExecution.isStatic(), index, aliasCollector); // �Ăяo���������ɒT�����邽�ߍċA�Ăяo�� + } else { + aliasCollector.addAlias(new Alias(Alias.AliasType.CONSTRACTOR_INVOCATION, 0, ret.getId(), tracePoint.duplicate())); + } if (childMethodExecution.isConstructor()) { // �R���X�g���N�^�Ăяo���������ꍇ if (objectId.equals(srcObject.getId())) { @@ -624,12 +746,16 @@ eStructure.addSrcSide(r); srcObject = thisObj; trackingObj = srcObject; + aliasCollector.changeTrackingObject(objectId, thisObjectId, true); + aliasCollector.addAlias(new Alias(Alias.AliasType.THIS, 0, thisObjectId, tracePoint.duplicate())); } else if (objectId.equals(dstObject.getId())) { r = new Reference(thisObj, dstObject); r.setCreation(true); eStructure.addDstSide(r); dstObject = thisObj; trackingObj = dstObject; + aliasCollector.changeTrackingObject(objectId, thisObjectId, false); + aliasCollector.addAlias(new Alias(Alias.AliasType.THIS, 0, thisObjectId, tracePoint.duplicate())); } if (Trace.isNull(thisObjectId)) objectId = null; // static�ϐ��̏ꍇ else objectId = thisObjectId; @@ -652,6 +778,11 @@ checkList.add(objList.get(index)); isLost = false; } + if (objectId != null) { + if (childMethodExecution.getThisObjId().equals(objectId)) { + aliasCollector.addAlias(new Alias(Alias.AliasType.RECEIVER, 0, objectId, tracePoint.duplicate())); + } + } } else { // �I�u�W�F�N�g�̗R�������ڌ��‚���Ȃ������ꍇ�ł��A�ǂ����̔z��̗v�f�ɗR�����Ă���”\�������� String retType = ret.getActualType(); @@ -669,14 +800,15 @@ } } while (tracePoint.stepBackOver()); - //�����T�� - if (argments.contains(new ObjectReference(objectId))) { + // �����T�� + if (arguments.contains(new ObjectReference(objectId))) { ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setSetterSide(true); // �������K�v? isResolved = true; + aliasCollector.addAlias(new Alias(Alias.AliasType.FORMAL_PARAMETER, arguments.indexOf(new ObjectReference(objectId)), objectId, methodExecution.getEntryPoint())); } } - //�R���N�V�����^�Ή� + // �R���N�V�����^�Ή� Reference r; if (methodExecution.isCollectionType()) { if (objectId != null) { @@ -686,11 +818,15 @@ r.setCollection(true); eStructure.addSrcSide(r); srcObject = thisObj; + aliasCollector.changeTrackingObject(objectId, thisObjectId, true); + aliasCollector.addAlias(new Alias(Alias.AliasType.THIS, 0, thisObjectId, tracePoint.duplicate())); } else if(objectId.equals(dstObject.getId())) { r = new Reference(thisObj, dstObject); r.setCollection(true); eStructure.addDstSide(r); dstObject =thisObj; + aliasCollector.changeTrackingObject(objectId, thisObjectId, false); + aliasCollector.addAlias(new Alias(Alias.AliasType.THIS, 0, thisObjectId, tracePoint.duplicate())); } } objList.set(index, methodExecution.getThisObjId()); @@ -707,8 +843,8 @@ } if (trackingObj != null) { // �܂��z������̗v�f��R���Ƃ��ċ^��(�������D��) - for (int i = 0; i < argments.size(); i++) { - ObjectReference argArray = argments.get(i); + for (int i = 0; i < arguments.size(); i++) { + ObjectReference argArray = arguments.get(i); if (argArray.getActualType().startsWith("[L") && ((trackingObj.getActualType() != null && argArray.getActualType().endsWith(trackingObj.getActualType() + ";")) || (trackingObj.getCalleeType() != null && argArray.getActualType().endsWith(trackingObj.getCalleeType() + ";")) @@ -728,6 +864,10 @@ dstObject = new ObjectReference(argArray.getId(), argArray.getActualType()); } objectId = null; + aliasCollector.addAlias(new Alias(Alias.AliasType.ARRAY_ELEMENT, 0, trackingObj.getId(), methodExecution.getEntryPoint())); // �z��v�f�̓��\�b�h�̐擪�Ŏ擾���ꂽ���̂Ɖ��肷�� + aliasCollector.changeTrackingObject(trackingObj.getId(), argArray.getId(), isSrcSide); // �ǐՑΏۂ�z��v�f����z��ɒu������ + aliasCollector.addAlias(new Alias(Alias.AliasType.ARRAY, 0, argArray.getId(), methodExecution.getEntryPoint())); // �z��̓��\�b�h�̐擪�ŃA�N�Z�X���ꂽ���̂Ɖ��肷�� + aliasCollector.addAlias(new Alias(Alias.AliasType.FORMAL_PARAMETER, arguments.indexOf(argArray), trackingObj.getId(), methodExecution.getEntryPoint())); break; } } @@ -747,11 +887,23 @@ eStructure.addSrcSide(new Reference(thisObjectId, fieldArray.getId(), methodExecution.getThisClassName(), fieldArray.getActualType())); srcObject = thisObj; + aliasCollector.addAlias(srcAliasList.get(trackingObj.getId())); + aliasCollector.changeTrackingObject(trackingObj.getId(), fieldArray.getId(), isSrcSide); // �ǐՑΏۂ�z��v�f����z��t�B�[���h�ɒu������ + aliasCollector.addAlias(new Alias(Alias.AliasType.ARRAY, 0, fieldArray.getId(), srcAliasList.get(trackingObj.getId()).getOccurrencePoint())); + aliasCollector.changeTrackingObject(fieldArray.getId(), thisObjectId, isSrcSide); // �ǐՑΏۂ�z��t�B�[���h����this�I�u�W�F�N�g�ɒu������ + aliasCollector.addAlias(new Alias(Alias.AliasType.THIS, 0, thisObjectId, srcAliasList.get(trackingObj.getId()).getOccurrencePoint())); + srcAliasList.remove(trackingObj.getId()); } else { eStructure.addDstSide(r); eStructure.addDstSide(new Reference(thisObjectId, fieldArray.getId(), methodExecution.getThisClassName(), fieldArray.getActualType())); dstObject = thisObj; + aliasCollector.addAlias(dstAliasList.get(trackingObj.getId())); + aliasCollector.changeTrackingObject(trackingObj.getId(), fieldArray.getId(), isSrcSide); // �ǐՑΏۂ�z��v�f����z��t�B�[���h�ɒu������ + aliasCollector.addAlias(new Alias(Alias.AliasType.ARRAY, 0, fieldArray.getId(), dstAliasList.get(trackingObj.getId()).getOccurrencePoint())); + aliasCollector.changeTrackingObject(fieldArray.getId(), thisObjectId, isSrcSide); // �ǐՑΏۂ�z��t�B�[���h����this�I�u�W�F�N�g�ɒu������ + aliasCollector.addAlias(new Alias(Alias.AliasType.THIS, 0, thisObjectId, dstAliasList.get(trackingObj.getId()).getOccurrencePoint())); + dstAliasList.remove(trackingObj.getId()); } } } @@ -768,6 +920,9 @@ methodExecution.getThisClassName(), trackingObj.getActualType())); dstObject = thisObj; } + aliasCollector.addAlias(new Alias(Alias.AliasType.ARRAY_CREATE, 0, trackingObj.getId(), methodExecution.getEntryPoint())); // �z��̓��\�b�h�̐擪�Ő������ꂽ���̂Ɖ��肷�� + aliasCollector.changeTrackingObject(trackingObj.getId(), thisObjectId, isSrcSide); // �ǐՑΏۂ�z�񂩂�this�I�u�W�F�N�g�ɒu������ + aliasCollector.addAlias(new Alias(Alias.AliasType.THIS, 0, thisObjectId, methodExecution.getEntryPoint())); // �z��̓��\�b�h�̐擪�Ő������ꂽ���̂Ɖ��肷�� } } } diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/Test.java b/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/Test.java index 03efdaa..9233229 100644 --- a/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/Test.java +++ b/org.ntlab.traceAnalyzer/src/org/ntlab/deltaExtractor/Test.java @@ -21,25 +21,25 @@ public static void main(String[] args) { // TODO Auto-generated method stub long time = System.nanoTime(); - TraceJSON trace = new TraceJSON("traces\\sampleCollection.trace"); - DeltaExtractorJSON s = new DeltaExtractorJSON(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, "sampleCollection.D", "sampleCollection.C"), tp, new IAliasTracker() { - @Override - public void addAlias(Alias alias) { - System.out.println(alias.getAliasType().toString() + ":" + alias.getObjectId() +"," + alias.getIndex() + "," + alias.getMethodSignature() + "," + alias.getLineNo()); - } - @Override - public void changeTrackingObject(String from, String to, boolean isSrcSide) { - System.out.println("Change:" + from + "�@=>�@" + to); - } - @Override - public List getAliasList() { - return null; - } - }); +// TraceJSON trace = new TraceJSON("traces\\sampleCollection.trace"); +// DeltaExtractorJSON s = new DeltaExtractorJSON(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, "sampleCollection.D", "sampleCollection.C"), tp, new IAliasTracker() { +// @Override +// public void addAlias(Alias alias) { +// System.out.println(alias.getAliasType().toString() + ":" + alias.getObjectId() +"," + alias.getIndex() + "," + alias.getMethodSignature() + "," + alias.getLineNo()); +// } +// @Override +// public void changeTrackingObject(String from, String to, boolean isSrcSide) { +// System.out.println("Change:" + from + "�@=>�@" + to); +// } +// @Override +// public List getAliasList() { +// return null; +// } +// }); // TraceJSON trace = new TraceJSON("traces\\_finalLocal.txt"); // DeltaExtractorJSON s = new DeltaExtractorJSON(trace); @@ -175,7 +175,8 @@ // // --------------- ArgoUML (2014/12/19-20 �v���O�����������؎��� �ۑ�3, �ȉ���1��ڂ̃f���^) --------------- -// DeltaExtractor s = new DeltaExtractor("documents\\ArgoUML-3.txt"); +//// DeltaExtractor s = new DeltaExtractor("documents\\ArgoUML-3.txt"); +// DeltaExtractorJSON s = new DeltaExtractorJSON("traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace"); // MethodExecution m = null; // ExtractedStructure e = null; // do { @@ -183,7 +184,9 @@ // 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()); +// TracePoint tp = m.getEntryPoint(); +// tp.stepBackOver(); +// m = s.getLastMethodExecution("protected void org.tigris.gef.base.SelectionManager.addFig(", tp); // } // if (m != null) { // ArrayList argments = m.getArguments(); @@ -198,28 +201,33 @@ // } while (m != null); -// // --------------- ArgoUML (2014/12/19-20 �v���O�����������؎��� �ۑ�4, �ȉ���3��ڂ̃f���^) --------------- + // --------------- 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) { + DeltaExtractorJSON s = new DeltaExtractorJSON("traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace"); + 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); + m = s.getLastMethodExecution("public boolean java.util.List.add("); + } else { + TracePoint tp = m.getEntryPoint(); + tp.stepBackOver(); +// m = s.getLastMethodExecution("public abstract interface boolean java.util.List.add(", tp); + m = s.getLastMethodExecution("public boolean java.util.List.add(", tp); + } + 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); /////////////////////////////////////////////////////////////////////////////////// // // diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/AbstractTracePointVisitor.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/AbstractTracePointVisitor.java new file mode 100644 index 0000000..b12c12c --- /dev/null +++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/AbstractTracePointVisitor.java @@ -0,0 +1,14 @@ +package org.ntlab.trace; + +abstract public class AbstractTracePointVisitor implements IStatementVisitor { + @Override + public boolean preVisitStatement(Statement statement) { // not called + return false; + } + @Override + public boolean postVisitStatement(Statement statement) { // not called + return false; + } + abstract public boolean preVisitStatement(Statement statement, TracePoint tp); + abstract public boolean postVisitStatement(Statement statement, TracePoint tp); +} diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ThreadInstance.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ThreadInstance.java index 0d46569..03f0341 100644 --- a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ThreadInstance.java +++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/ThreadInstance.java @@ -174,4 +174,8 @@ public TracePoint getCurrentTracePoint() { return new TracePoint(curMethodExecution, curMethodExecution.getStatements().size() - 1); } + + public TracePoint getLastTracePoint() { + return roots.get(roots.size() - 1).getExitPoint(); + } } diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/Trace.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/Trace.java index aa938f2..53f12e1 100644 --- a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/Trace.java +++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/Trace.java @@ -71,101 +71,139 @@ 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]; + threadNo = getThreadNo(line); +// threadNo = methodData[methodData.length - 1].split(" ")[1]; + if (threadNo != null) { + 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); } - 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])); + threadNo = getThreadNo(line); +// threadNo = argData[argData.length - 1].split(" ")[1]; + if (threadNo != null) { + 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); } - 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 { + threadNo = getThreadNo(line); +// threadNo = returnData[returnData.length - 1].split(" ")[1]; + if (threadNo != null) { + Stack stack = stacks.get(threadNo); + if (!stack.isEmpty()) { + String line2 = stack.peek(); + if (line2.split("\\(")[0].endsWith(line.split("\\(")[1])) { stack.pop(); - thread.terminateMethod(); - line2 = stack.peek(); - } while (!stack.isEmpty() && !line2.split("\\(")[0].endsWith(line.split("\\(")[1])); - if (!stack.isEmpty()) stack.pop(); + } else { + do { + stack.pop(); + thread.terminateMethod(); + if (!stack.isEmpty()) line2 = stack.peek(); + } while (!stack.isEmpty() && !line2.split("\\(")[0].endsWith(line.split("\\(")[1])); + if (!stack.isEmpty()) stack.pop(); + } + 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(Collection") + || curLine.contains("Return call(Arrays") + || curLine.contains("Return call(Thread")) { + isCollectionType = true; + } + thread.returnMethod(returnValue, thisObjectId, isCollectionType); } - 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(Collection") - || curLine.contains("Return call(Arrays") - || 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]); + if (accessData.length >= 9) { + threadNo = getThreadNo(line); +// threadNo = accessData[8].split(" ")[1]; + if (threadNo != null) { + 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]); - } + if (updateData.length >= 7) { + threadNo = getThreadNo(line); +// threadNo = updateData[6].split(" ")[1]; + if (threadNo != null) { + thread = threads.get(threadNo); + if (thread != null) thread.fieldUpdate(updateData[3], updateData[4], updateData[1], updateData[2]); + } + } + } else continue; prevLine = line; } } + private String getThreadNo(String line) { + int tidx = line.indexOf("ThreadNo "); + if (tidx == -1) return null; + String threadNo = line.substring(tidx + 9); + try { + Integer.parseInt(threadNo); + } catch (NumberFormatException e) { + for (int i = 1; i <= threadNo.length(); i++) { + try { + Integer.parseInt(threadNo.substring(0, i)); + } catch (NumberFormatException e2) { + threadNo = threadNo.substring(0, i - 1); + break; + } + } + } + return threadNo; + } + /** * �I�����C����͗p�V���O���g���̎擾 * @return �I�����C����͗p�g���[�X @@ -557,9 +595,19 @@ start[0] = null; return false; } + + public TracePoint getLastTracePoint() { + TracePoint tp = null; + for (ThreadInstance thread: threads.values()) { + if (tp == null || thread.getLastTracePoint().getStatement().getTimeStamp() > tp.getStatement().getTimeStamp()) { + tp = thread.getLastTracePoint(); + } + } + return tp; + } public TracePoint getCreationTracePoint(final ObjectReference newObjectId, TracePoint before) { - before = before.duplicate(); + if (before != null) before = before.duplicate(); before = traverseStatementsInTraceBackward( new IStatementVisitor() { @Override @@ -583,7 +631,7 @@ } public TracePoint getFieldUpdateTracePoint(final Reference ref, TracePoint before) { - before = before.duplicate(); + if (before != null) before = before.duplicate(); final String srcType = ref.getSrcClassName(); final String dstType = ref.getDstClassName(); final String srcObjId = ref.getSrcObjectId(); @@ -678,7 +726,7 @@ } public TracePoint getArraySetTracePoint(final Reference ref, TracePoint before) { - final TracePoint start = before.duplicate(); + final TracePoint start = (before == null) ? null : before.duplicate(); before = traverseStatementsInTraceBackward(new IStatementVisitor() { @Override public boolean preVisitStatement(Statement statement) { @@ -699,7 +747,7 @@ } private boolean isCollectionAdd(String methodSignature) { - return (methodSignature.contains("add(") || methodSignature.contains("set(") || methodSignature.contains("put(") || methodSignature.contains("push(")); + return (methodSignature.contains("add(") || methodSignature.contains("set(") || methodSignature.contains("put(") || methodSignature.contains("push(") || methodSignature.contains("addElement(")); } private boolean isArraySet(Reference ref, TracePoint fieldAccessPoint) { @@ -790,6 +838,9 @@ traceLastThread2 = traceLastThread; traceLastTime = threadLastTime; traceLastThread = threadId; + } else if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; } } } @@ -803,12 +854,19 @@ * @return ���f�������\�b�h���s */ public MethodExecution traverseMethodEntriesInTraceBackward(IMethodExecutionVisitor visitor, TracePoint before) { + if (before == null) { + return traverseMethodEntriesInTraceBackward(visitor); + } HashMap> threadRoots = new HashMap>(); HashMap threadLastPoints = new HashMap(); String traceLastThread = null; long traceLastTime2 = 0; String traceLastThread2 = null; - ThreadInstance thread = threads.get(before.getStatement().getThreadNo()); + Statement st = before.getStatement(); + if (st == null) { + st = before.getMethodExecution().getCallerTracePoint().getStatement(); + } + ThreadInstance thread = threads.get(st.getThreadNo()); ArrayList rootExecutions = (ArrayList)thread.getRoot().clone(); for (int n = rootExecutions.size() - 1; n >= 0; n--) { MethodExecution root = rootExecutions.get(n); @@ -956,9 +1014,17 @@ while (curTp != null && (curTp.getStatement().getTimeStamp() <= nextThreadTime || nextThreadTime == -1)) { Statement statement = curTp.getStatement(); - if (visitor.preVisitStatement(statement)) return curTp; - if (!(statement instanceof MethodInvocation)) { - if (visitor.postVisitStatement(statement)) return curTp; + if (!(visitor instanceof AbstractTracePointVisitor)) { + if (visitor.preVisitStatement(statement)) return curTp; + if (!(statement instanceof MethodInvocation)) { + if (visitor.postVisitStatement(statement)) return curTp; + } + } else { + // �g���[�X�|�C���g�̏����K�v�ȏꍇ + if (((AbstractTracePointVisitor) visitor).preVisitStatement(statement, curTp)) return curTp; + if (!(statement instanceof MethodInvocation)) { + if (((AbstractTracePointVisitor) visitor).postVisitStatement(statement, curTp)) return curTp; + } } curTp.stepNoReturn(); // ���A�����ɌĂяo���؂�����Ă��� if (!curTp.isValid()) { @@ -966,7 +1032,12 @@ while (!curTp.stepOver()) { // ���x�͕��A�͂��邪���炸�ɒT�� if (curTp.isValid()) { // �Ăяo����T���O�Ɉ�x�K��ς݂̃��\�b�h�Ăяo���s���A�T���������x�K�₷�� - if (visitor.postVisitStatement(curTp.getStatement())) return curTp; + if (!(visitor instanceof AbstractTracePointVisitor)) { + if (visitor.postVisitStatement(curTp.getStatement())) return curTp; + } else { + // �g���[�X�|�C���g�̏����K�v�ȏꍇ + if (((AbstractTracePointVisitor) visitor).postVisitStatement(curTp.getStatement(), curTp)) return curTp; + } } else { // �Ăяo���؂̊J�n���_�܂ŒT�����I�����ꍇ ArrayList roots = threadRoots.get(curThreadId); @@ -1071,7 +1142,11 @@ String traceLastThread = null; long traceLastTime2 = 0; String traceLastThread2 = null; - ThreadInstance thread = threads.get(before.getStatement().getThreadNo()); + Statement st = before.getStatement(); + if (st == null) { + st = before.getMethodExecution().getCallerTracePoint().getStatement(); + } + ThreadInstance thread = threads.get(st.getThreadNo()); for (String threadId: threads.keySet()) { ThreadInstance t = threads.get(threadId); ArrayList rootExecutions = (ArrayList)t.getRoot().clone(); diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TraceJSON.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TraceJSON.java index 01c99db..a397549 100644 --- a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TraceJSON.java +++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TraceJSON.java @@ -1,935 +1,939 @@ -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<>(); - - private TraceJSON() { - - } - - /** - * �w�肵��JSON�̃g���[�X�t�@�C������ǂ��� Trace �I�u�W�F�N�g�𐶐����� - * @param file �g���[�X�t�@�C�� - */ - public TraceJSON(BufferedReader file) { - try { - readJSON(file); - file.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * �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) { - BufferedReader file; - try { - file = new BufferedReader(new FileReader(traceFile)); - readJSON(file); - file.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private void readJSON(BufferedReader file) throws IOException { - // �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[] fieldData; - 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 { - stack.pop(); - thread.terminateMethod(); - line2 = stack.peek(); - } while (!stack.isEmpty() && !line2.endsWith(shortSignature)); - if (!stack.isEmpty()) stack.pop(); - } - 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.util.Collection") - || thisClassName.contains("java.util.Arrays") - || 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 { - stack.pop(); - thread.terminateMethod(); - line2 = stack.peek(); - } while (!stack.isEmpty() && !line2.endsWith(shortSignature)); - if (!stack.isEmpty()) stack.pop(); - } - 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(",\"fieldName\":\""); - fieldData = type[1].split("\",\"this\":"); - thisObj = fieldData[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(fieldData[0], valueClassName, valueObjectId, containerClassName, containerObjectId, thisClassName, thisObjectId, lineNum, timeStamp); - } else if (line.startsWith("{\"type\":\"fieldSet\"")) { - // �t�B�[���h�X�V - type = line.split(",\"fieldName\":\""); - fieldData = type[1].split("\",\"container\":"); - containerObj = fieldData[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(fieldData[0], 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); - } - } - } - - /** - * �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; - } - - /** - * �I�����C����͗p�V���O���g���̎擾 - * @return �I�����C����͗p�g���[�X - */ - public static TraceJSON getInstance() { - if (theTrace == null) { - theTrace = new TraceJSON(); - } - return (TraceJSON)theTrace; - } - - /** - * �X���b�hID���w�肵�ăX���b�h�C���X�^���X���擾����(�I�����C����͗p) - * @param threadId - * @return �X���b�h�C���X�^���X - */ - public static ThreadInstance getThreadInstance(String threadId) { - return getInstance().threads.get(threadId); - } - - /** - * �w�肵���X���b�h��Ō��ݎ��s���̃��\�b�h���s���擾���� - * @param thread �ΏۃX���b�h - * @return thread ��Ō��ݎ��s���̃��\�b�h���s - */ - public static MethodExecution getCurrentMethodExecution(Thread thread) { - ThreadInstance t = getInstance().threads.get(String.valueOf(thread.getId())); - return t.getCurrentMethodExecution(); - } - - /** - * �w�肵���X���b�h��Ō��ݎ��s���̃g���[�X�|�C���g���擾���� - * @param thread �ΏۃX���b�h - * @return thread ��Ō��ݎ��s���̎��s���̃g���[�X�|�C���g - */ - public static TracePoint getCurrentTracePoint(Thread thread) { - ThreadInstance t = getInstance().threads.get(String.valueOf(thread.getId())); - return t.getCurrentTracePoint(); - } - - 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); - } - - 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 ArrayUpdate) { - ArrayUpdate arraySet = (ArrayUpdate)start.getStatement(); - String srcObjId = ref.getSrcObjectId(); - String dstObjId = ref.getDstObjectId(); - String srcClassName = ref.getSrcClassName(); - String dstClassName = ref.getDstClassName(); - if ((srcObjId != null && srcObjId.equals(arraySet.getArrayObjectId())) - || (srcObjId == null || isNull(srcObjId)) && srcClassName.equals(arraySet.getArrayClassName())) { - if ((dstObjId != null && dstObjId.equals(arraySet.getValueObjectId())) - || ((dstObjId == null || isNull(dstObjId)) && dstClassName.equals(arraySet.getValueClassName()))) { - if (srcObjId == null) { - ref.setSrcObjectId(arraySet.getArrayObjectId()); - } else if (srcClassName == null) { - ref.setSrcClassName(arraySet.getArrayClassName()); - } - if (dstObjId == null) { - ref.setDstObjectId(arraySet.getValueObjectId()); - } else if (dstClassName == null) { - ref.setDstClassName(arraySet.getValueClassName()); - } - return true; - } - } - } - return false; - } - @Override - public boolean postVisitStatement(Statement statement) { return false; } - }, start); - if (before != null) { - return before; - } - return null; - } - - /** - * ���s���ꂽ�S�u���b�N���擾���� - * @return �S�u���b�N(���\�b�h��:�u���b�NID) - */ - public HashSet getAllBlocks() { - final HashSet blocks = 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) { - for (Statement s: methodExecution.getStatements()) { - if (s instanceof BlockEnter) { - blocks.add(methodExecution.getSignature() + ":" + ((BlockEnter)s).getBlockId()); - } - } - return false; - } - @Override - public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { - return false; - } - }); - } - return blocks; - } - - /** - * �}�[�N���Ŏ��s���J�n���ꂽ�u���b�N���擾���� - * @param markStart �}�[�N�̊J�n���� - * @param markEnd �}�[�N�̏I������ - * @return �Y������u���b�N(���\�b�h��:�u���b�NID) - */ - public HashSet getMarkedBlocks(final long markStart, final long markEnd) { - final HashSet blocks = 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) { - if (!methodExecution.isTerminated() && methodExecution.getExitTime() < markStart) return true; // �T���I�� - if (methodExecution.getEntryTime() > markEnd) return false; - for (Statement s: methodExecution.getStatements()) { - if (s instanceof BlockEnter) { - long entryTime = ((BlockEnter)s).getTimeStamp(); - if (entryTime >= markStart && entryTime <= markEnd) { - blocks.add(methodExecution.getSignature() + ":" + ((BlockEnter)s).getBlockId()); - } - } - } - return false; - } - @Override - public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { - return false; - } - }); - } - return blocks; - } - - /** - * ���s���ꂽ�S�t���[���擾���� - * @return �S�t���[(���\�b�h��:�t���[���u���b�NID:�t���[��u���b�NID) - */ - public HashSet getAllFlows() { - final HashSet flows = 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) { - int prevBlockId = -1; - for (Statement s: methodExecution.getStatements()) { - if (s instanceof BlockEnter) { - int curBlockID = ((BlockEnter)s).getBlockId(); - if (prevBlockId != -1) { - flows.add(methodExecution.getSignature() + ":" + prevBlockId + ":" + curBlockID); - } else { - flows.add(methodExecution.getSignature() + ":" + curBlockID); - } - prevBlockId = curBlockID; - } - } - return false; - } - @Override - public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { - return false; - } - }); - } - return flows; - } - - /** - * �}�[�N���Ŏ��s���ꂽ�t���[���擾���� - * @param markStart �}�[�N�̊J�n���� - * @param markEnd �}�[�N�̏I������ - * @return �Y������t���[(���\�b�h��:�t���[���u���b�NID:�t���[��u���b�NID) - */ - public HashSet getMarkedFlows(final long markStart, final long markEnd) { - final HashSet flows = 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) { - if (!methodExecution.isTerminated() && methodExecution.getExitTime() < markStart) return true; // �T���I�� - if (methodExecution.getEntryTime() > markEnd) return false; - int prevBlockId = -1; - for (Statement s: methodExecution.getStatements()) { - if (s instanceof BlockEnter) { - long entryTime = ((BlockEnter)s).getTimeStamp(); - int curBlockID = ((BlockEnter)s).getBlockId(); - if (entryTime >= markStart && entryTime <= markEnd) { - if (prevBlockId != -1) { - flows.add(methodExecution.getSignature() + ":" + prevBlockId + ":" + curBlockID); - } else { - flows.add(methodExecution.getSignature() + ":" + curBlockID); - } - } - prevBlockId = curBlockID; - } - } - return false; - } - @Override - public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { - return false; - } - }); - } - return flows; - } - - /** - * �g���[�X���̑S�X���b�h�𓯊������Ȃ���S���s�����t�����ɒT������ - * - * @param visitor ���s���̃r�W�^�[ - * @return ���f�����g���[�X�|�C���g - */ - public TracePoint traverseStatementsInTraceBackward(IStatementVisitor visitor) { - HashMap> threadRoots = new HashMap>(); - HashMap threadLastPoints = new HashMap(); - // �e�X���b�h�ɂ����Ĉ�ԍŌ�ɊJ�n�������\�b�h���s��T�� - long traceLastTime = 0; - String traceLastThread = null; - long traceLastTime2 = 0; - String traceLastThread2 = null; - for (String threadId: threads.keySet()) { - ThreadInstance thread = threads.get(threadId); - ArrayList roots = (ArrayList)thread.getRoot().clone(); - threadRoots.put(threadId, roots); - TracePoint threadLastTp; - do { - MethodExecution threadLastExecution = roots.remove(roots.size() - 1); - threadLastTp = threadLastExecution.getExitPoint(); - } while (!threadLastTp.isValid() && roots.size() > 0); - if (threadLastTp.isValid()) { - threadLastPoints.put(threadId, threadLastTp); - long threadLastTime; - if (threadLastTp.getStatement() instanceof MethodInvocation) { - threadLastTime = ((MethodInvocation) threadLastTp.getStatement()).getCalledMethodExecution().getExitTime(); - } else { - threadLastTime = threadLastTp.getStatement().getTimeStamp(); - } - if (traceLastTime < threadLastTime) { - traceLastTime2 = traceLastTime; - traceLastThread2 = traceLastThread; - traceLastTime = threadLastTime; - traceLastThread = threadId; - } else if (traceLastTime2 < threadLastTime) { - traceLastTime2 = threadLastTime; - traceLastThread2 = threadId; - } - } else { - threadLastPoints.put(threadId, null); - } - } - return traverseStatementsInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); - } - - /** - * �g���[�X���̑S�X���b�h�𓯊������Ȃ���w�肵���g���[�X�|�C���g����t�����ɒT������ - * - * @param visitor�@���s���̃r�W�^�[ - * @param before �T���J�n�g���[�X�|�C���g - * @return�@���f�����g���[�X�|�C���g - */ - public TracePoint traverseStatementsInTraceBackward(IStatementVisitor visitor, TracePoint before) { - if (before == null) { - return traverseStatementsInTraceBackward(visitor); - } - // �S�ẴX���b�h�̃g���[�X�|�C���g�� before �̑O�܂Ŋ����߂� - HashMap> threadRoots = new HashMap>(); - HashMap threadLastPoints = new HashMap(); - String traceLastThread = null; - long traceLastTime2 = 0; - String traceLastThread2 = null; - ThreadInstance thread = threads.get(before.getStatement().getThreadNo()); - for (String threadId: threads.keySet()) { - 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.getStatement().getTimeStamp()) { - rootExecutions.remove(n); - } else { - break; - } - } - if (rootExecutions.size() > 0) { - rootExecutions.remove(rootExecutions.size() - 1); - } - } else { - TracePoint threadBeforeTp; - do { - MethodExecution threadLastExecution = rootExecutions.remove(rootExecutions.size() - 1); - threadBeforeTp = threadLastExecution.getExitPoint(); - } while (!threadBeforeTp.isValid() && rootExecutions.size() > 0); - if (threadBeforeTp.isValid()) { - TracePoint[] tp = new TracePoint[] {threadBeforeTp}; - long threadLastTime; - if (before.getStatement() instanceof MethodInvocation) { - threadLastTime = ((MethodInvocation) before.getStatement()).getCalledMethodExecution().getExitTime(); - } else { - threadLastTime = before.getStatement().getTimeStamp(); - } - getLastStatementInThread(rootExecutions, tp, threadLastTime, new IStatementVisitor() { - @Override - public boolean preVisitStatement(Statement statement) { return false; } - @Override - public boolean postVisitStatement(Statement statement) { return false; } - }); - threadLastPoints.put(threadId, tp[0]); - if (tp[0] != null) { - if (tp[0].getStatement() instanceof MethodInvocation) { - threadLastTime = ((MethodInvocation) tp[0].getStatement()).getCalledMethodExecution().getExitTime(); // ��Exception �����������ꍇ�͍l���Ȃ��Ă悢? - } else { - threadLastTime = tp[0].getStatement().getTimeStamp(); - } - if (traceLastTime2 < threadLastTime) { - traceLastTime2 = threadLastTime; - traceLastThread2 = threadId; - } - } - } else { - threadLastPoints.put(threadId, null); - } - } - } - return traverseStatementsInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); - } - - /** - * �g���[�X���̑S�X���b�h�𓯊������Ȃ���w�肵���g���[�X�|�C���g����t�����ɒT������ - * - * @param visitor�@���s���̃r�W�^�[ - * @param before �T���J�n���� - * @return�@���f�����g���[�X�|�C���g - */ - public TracePoint traverseStatementsInTraceBackward(IStatementVisitor visitor, long before) { - if (before <= 0L) { - return traverseStatementsInTraceBackward(visitor); - } - // �S�ẴX���b�h�̃g���[�X�|�C���g�� before �̑O�܂Ŋ����߂� - HashMap> threadRoots = new HashMap>(); - HashMap threadLastPoints = new HashMap(); - long traceLastTime = 0; - String traceLastThread = null; - long traceLastTime2 = 0; - String traceLastThread2 = null; - for (String threadId: threads.keySet()) { - ThreadInstance t = threads.get(threadId); - ArrayList rootExecutions = (ArrayList)t.getRoot().clone(); - threadRoots.put(threadId, rootExecutions); - TracePoint threadBeforeTp; - do { - MethodExecution threadLastExecution = rootExecutions.remove(rootExecutions.size() - 1); - threadBeforeTp = threadLastExecution.getExitPoint(); - } while (!threadBeforeTp.isValid() && rootExecutions.size() > 0); - if (threadBeforeTp.isValid()) { - TracePoint[] tp = new TracePoint[] {threadBeforeTp}; - getLastStatementInThread(rootExecutions, tp, before, new IStatementVisitor() { - @Override - public boolean preVisitStatement(Statement statement) { return false; } - @Override - public boolean postVisitStatement(Statement statement) { return false; } - }); - threadLastPoints.put(threadId, tp[0]); - if (tp[0] != null) { - long threadLastTime; - if (tp[0].getStatement() instanceof MethodInvocation) { - threadLastTime = ((MethodInvocation) tp[0].getStatement()).getCalledMethodExecution().getExitTime(); // ��Exception �����������ꍇ�͍l���Ȃ��Ă悢? - } else { - threadLastTime = tp[0].getStatement().getTimeStamp(); - } - if (traceLastTime < threadLastTime) { - traceLastTime2 = traceLastTime; - traceLastThread2 = traceLastThread; - traceLastTime = threadLastTime; - traceLastThread = threadId; - } else if (traceLastTime2 < threadLastTime) { - traceLastTime2 = threadLastTime; - traceLastThread2 = threadId; - } - } - } else { - threadLastPoints.put(threadId, null); - } - } - 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); - while (lastTp != null) { - Statement statement = lastTp.getStatement(); - if (visitor.preVisitStatement(statement)) return lastTp; - if (statement instanceof MethodInvocation) { - // �Ăяo���悪����ꍇ�A�Ăяo����ɐ��� - lastTp.stepBackNoReturn(); - if (lastTp.isValid()) { - // ���ʂɌĂяo����Ɉڂ����ꍇ - MethodExecution methodExecution = ((MethodInvocation) statement).getCalledMethodExecution(); - if (!methodExecution.isTerminated() && methodExecution.getExitTime() < traceLastTime2) { - break; - } - continue; - } - // ��̃��\�b�h���s�̏ꍇ - } else { - if (visitor.postVisitStatement(statement)) return lastTp; - } - if (lastTp.isValid() && lastTp.getStatement().getTimeStamp() < traceLastTime2) break; - // 1�X�e�b�v�����߂� - while (!lastTp.stepBackOver() && lastTp.isValid()) { - // �Ăяo�����ɖ߂����ꍇ(���\�b�h�Ăяo�����ɕ��A) - statement = lastTp.getStatement(); - if (visitor.postVisitStatement(statement)) return lastTp; - } - if (!lastTp.isValid()) { - // �Ăяo���؂̊J�n���_�܂ŒT�����I�����ꍇ - ArrayList roots = threadRoots.get(traceLastThread); - while (!lastTp.isValid() && roots.size() > 0) { - // ���̌Ăяo���؂�T�� - MethodExecution lastExecution = roots.remove(roots.size() - 1); - lastTp = lastExecution.getExitPoint(); - } - if (lastTp.isValid()) { - // ���̌Ăяo���؂�����΂�����Ōォ��T�� - threadLastPoints.put(traceLastThread, lastTp); - if (lastTp.getStatement().getTimeStamp() < traceLastTime2) break; - } else { - // ���̃X���b�h�̒T�������ׂďI�������ꍇ - threadLastPoints.put(traceLastThread, null); - break; - } - } - } - traceLastThread = traceLastThread2; - // ���̎��ɒT�����ׂ��X���b�h(���T���̗̈悪��ԍŌ�܂Ŏc���Ă���X���b�h)�����肷�� - traceLastTime2 = 0; - traceLastThread2 = null; - boolean continueTraverse = false; - for (String threadId: threadLastPoints.keySet()) { - if (!threadId.equals(traceLastThread)) { - TracePoint threadLastTp = threadLastPoints.get(threadId); - if (threadLastTp != null) { - continueTraverse = true; - long threadLastTime; - if (threadLastTp.getStatement() instanceof MethodInvocation) { - threadLastTime = ((MethodInvocation) threadLastTp.getStatement()).getCalledMethodExecution().getExitTime(); - } else { - threadLastTime = threadLastTp.getStatement().getTimeStamp(); - } - if (traceLastTime2 < threadLastTime) { - traceLastTime2 = threadLastTime; - traceLastThread2 = threadId; - } - } - } - } - if (traceLastThread == null && traceLastThread2 == null) break; - if (!continueTraverse && threadLastPoints.get(traceLastThread) == null) break; - } - return null; - } +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<>(); + + private TraceJSON() { + + } + + /** + * �w�肵��JSON�̃g���[�X�t�@�C������ǂ��� Trace �I�u�W�F�N�g�𐶐����� + * @param file �g���[�X�t�@�C�� + */ + public TraceJSON(BufferedReader file) { + try { + readJSON(file); + file.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * �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) { + BufferedReader file; + try { + file = new BufferedReader(new FileReader(traceFile)); + readJSON(file); + file.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void readJSON(BufferedReader file) throws IOException { + // �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[] fieldData; + 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 { + stack.pop(); + thread.terminateMethod(); + if (!stack.isEmpty()) line2 = stack.peek(); + } while (!stack.isEmpty() && !line2.endsWith(shortSignature)); + if (!stack.isEmpty()) stack.pop(); + } + 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.util.Collection") + || thisClassName.contains("java.util.Arrays") + || 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 { + stack.pop(); + thread.terminateMethod(); + line2 = stack.peek(); + } while (!stack.isEmpty() && !line2.endsWith(shortSignature)); + if (!stack.isEmpty()) stack.pop(); + } + 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(",\"fieldName\":\""); + fieldData = type[1].split("\",\"this\":"); + thisObj = fieldData[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(fieldData[0], valueClassName, valueObjectId, containerClassName, containerObjectId, thisClassName, thisObjectId, lineNum, timeStamp); + } else if (line.startsWith("{\"type\":\"fieldSet\"")) { + // �t�B�[���h�X�V + type = line.split(",\"fieldName\":\""); + fieldData = type[1].split("\",\"container\":"); + containerObj = fieldData[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(fieldData[0], 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); + } + } + } + + /** + * �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; + } + + /** + * �I�����C����͗p�V���O���g���̎擾 + * @return �I�����C����͗p�g���[�X + */ + public static TraceJSON getInstance() { + if (theTrace == null) { + theTrace = new TraceJSON(); + } + return (TraceJSON)theTrace; + } + + /** + * �X���b�hID���w�肵�ăX���b�h�C���X�^���X���擾����(�I�����C����͗p) + * @param threadId + * @return �X���b�h�C���X�^���X + */ + public static ThreadInstance getThreadInstance(String threadId) { + return getInstance().threads.get(threadId); + } + + /** + * �w�肵���X���b�h��Ō��ݎ��s���̃��\�b�h���s���擾���� + * @param thread �ΏۃX���b�h + * @return thread ��Ō��ݎ��s���̃��\�b�h���s + */ + public static MethodExecution getCurrentMethodExecution(Thread thread) { + ThreadInstance t = getInstance().threads.get(String.valueOf(thread.getId())); + return t.getCurrentMethodExecution(); + } + + /** + * �w�肵���X���b�h��Ō��ݎ��s���̃g���[�X�|�C���g���擾���� + * @param thread �ΏۃX���b�h + * @return thread ��Ō��ݎ��s���̎��s���̃g���[�X�|�C���g + */ + public static TracePoint getCurrentTracePoint(Thread thread) { + ThreadInstance t = getInstance().threads.get(String.valueOf(thread.getId())); + return t.getCurrentTracePoint(); + } + + 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); + } + + 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 ArrayUpdate) { + ArrayUpdate arraySet = (ArrayUpdate)start.getStatement(); + String srcObjId = ref.getSrcObjectId(); + String dstObjId = ref.getDstObjectId(); + String srcClassName = ref.getSrcClassName(); + String dstClassName = ref.getDstClassName(); + if ((srcObjId != null && srcObjId.equals(arraySet.getArrayObjectId())) + || (srcObjId == null || isNull(srcObjId)) && srcClassName.equals(arraySet.getArrayClassName())) { + if ((dstObjId != null && dstObjId.equals(arraySet.getValueObjectId())) + || ((dstObjId == null || isNull(dstObjId)) && dstClassName.equals(arraySet.getValueClassName()))) { + if (srcObjId == null) { + ref.setSrcObjectId(arraySet.getArrayObjectId()); + } else if (srcClassName == null) { + ref.setSrcClassName(arraySet.getArrayClassName()); + } + if (dstObjId == null) { + ref.setDstObjectId(arraySet.getValueObjectId()); + } else if (dstClassName == null) { + ref.setDstClassName(arraySet.getValueClassName()); + } + return true; + } + } + } + return false; + } + @Override + public boolean postVisitStatement(Statement statement) { return false; } + }, start); + if (before != null) { + return before; + } + return null; + } + + /** + * ���s���ꂽ�S�u���b�N���擾���� + * @return �S�u���b�N(���\�b�h��:�u���b�NID) + */ + public HashSet getAllBlocks() { + final HashSet blocks = 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) { + for (Statement s: methodExecution.getStatements()) { + if (s instanceof BlockEnter) { + blocks.add(methodExecution.getSignature() + ":" + ((BlockEnter)s).getBlockId()); + } + } + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }); + } + return blocks; + } + + /** + * �}�[�N���Ŏ��s���J�n���ꂽ�u���b�N���擾���� + * @param markStart �}�[�N�̊J�n���� + * @param markEnd �}�[�N�̏I������ + * @return �Y������u���b�N(���\�b�h��:�u���b�NID) + */ + public HashSet getMarkedBlocks(final long markStart, final long markEnd) { + final HashSet blocks = 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) { + if (!methodExecution.isTerminated() && methodExecution.getExitTime() < markStart) return true; // �T���I�� + if (methodExecution.getEntryTime() > markEnd) return false; + for (Statement s: methodExecution.getStatements()) { + if (s instanceof BlockEnter) { + long entryTime = ((BlockEnter)s).getTimeStamp(); + if (entryTime >= markStart && entryTime <= markEnd) { + blocks.add(methodExecution.getSignature() + ":" + ((BlockEnter)s).getBlockId()); + } + } + } + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }); + } + return blocks; + } + + /** + * ���s���ꂽ�S�t���[���擾���� + * @return �S�t���[(���\�b�h��:�t���[���u���b�NID:�t���[��u���b�NID) + */ + public HashSet getAllFlows() { + final HashSet flows = 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) { + int prevBlockId = -1; + for (Statement s: methodExecution.getStatements()) { + if (s instanceof BlockEnter) { + int curBlockID = ((BlockEnter)s).getBlockId(); + if (prevBlockId != -1) { + flows.add(methodExecution.getSignature() + ":" + prevBlockId + ":" + curBlockID); + } else { + flows.add(methodExecution.getSignature() + ":" + curBlockID); + } + prevBlockId = curBlockID; + } + } + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }); + } + return flows; + } + + /** + * �}�[�N���Ŏ��s���ꂽ�t���[���擾���� + * @param markStart �}�[�N�̊J�n���� + * @param markEnd �}�[�N�̏I������ + * @return �Y������t���[(���\�b�h��:�t���[���u���b�NID:�t���[��u���b�NID) + */ + public HashSet getMarkedFlows(final long markStart, final long markEnd) { + final HashSet flows = 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) { + if (!methodExecution.isTerminated() && methodExecution.getExitTime() < markStart) return true; // �T���I�� + if (methodExecution.getEntryTime() > markEnd) return false; + int prevBlockId = -1; + for (Statement s: methodExecution.getStatements()) { + if (s instanceof BlockEnter) { + long entryTime = ((BlockEnter)s).getTimeStamp(); + int curBlockID = ((BlockEnter)s).getBlockId(); + if (entryTime >= markStart && entryTime <= markEnd) { + if (prevBlockId != -1) { + flows.add(methodExecution.getSignature() + ":" + prevBlockId + ":" + curBlockID); + } else { + flows.add(methodExecution.getSignature() + ":" + curBlockID); + } + } + prevBlockId = curBlockID; + } + } + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }); + } + return flows; + } + + /** + * �g���[�X���̑S�X���b�h�𓯊������Ȃ���S���s�����t�����ɒT������ + * + * @param visitor ���s���̃r�W�^�[ + * @return ���f�����g���[�X�|�C���g + */ + public TracePoint traverseStatementsInTraceBackward(IStatementVisitor visitor) { + HashMap> threadRoots = new HashMap>(); + HashMap threadLastPoints = new HashMap(); + // �e�X���b�h�ɂ����Ĉ�ԍŌ�ɊJ�n�������\�b�h���s��T�� + long traceLastTime = 0; + String traceLastThread = null; + long traceLastTime2 = 0; + String traceLastThread2 = null; + for (String threadId: threads.keySet()) { + ThreadInstance thread = threads.get(threadId); + ArrayList roots = (ArrayList)thread.getRoot().clone(); + threadRoots.put(threadId, roots); + TracePoint threadLastTp; + do { + MethodExecution threadLastExecution = roots.remove(roots.size() - 1); + threadLastTp = threadLastExecution.getExitPoint(); + } while (!threadLastTp.isValid() && roots.size() > 0); + if (threadLastTp.isValid()) { + threadLastPoints.put(threadId, threadLastTp); + long threadLastTime; + if (threadLastTp.getStatement() instanceof MethodInvocation) { + threadLastTime = ((MethodInvocation) threadLastTp.getStatement()).getCalledMethodExecution().getExitTime(); + } else { + threadLastTime = threadLastTp.getStatement().getTimeStamp(); + } + if (traceLastTime < threadLastTime) { + traceLastTime2 = traceLastTime; + traceLastThread2 = traceLastThread; + traceLastTime = threadLastTime; + traceLastThread = threadId; + } else if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; + } + } else { + threadLastPoints.put(threadId, null); + } + } + return traverseStatementsInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); + } + + /** + * �g���[�X���̑S�X���b�h�𓯊������Ȃ���w�肵���g���[�X�|�C���g����t�����ɒT������ + * + * @param visitor�@���s���̃r�W�^�[ + * @param before �T���J�n�g���[�X�|�C���g + * @return�@���f�����g���[�X�|�C���g + */ + public TracePoint traverseStatementsInTraceBackward(IStatementVisitor visitor, TracePoint before) { + if (before == null) { + return traverseStatementsInTraceBackward(visitor); + } + // �S�ẴX���b�h�̃g���[�X�|�C���g�� before �̑O�܂Ŋ����߂� + HashMap> threadRoots = new HashMap>(); + HashMap threadLastPoints = new HashMap(); + String traceLastThread = null; + long traceLastTime2 = 0; + String traceLastThread2 = null; + Statement st = before.getStatement(); + if (st == null) { + st = before.getMethodExecution().getCallerTracePoint().getStatement(); + } + ThreadInstance thread = threads.get(st.getThreadNo()); + for (String threadId: threads.keySet()) { + 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.getStatement().getTimeStamp()) { + rootExecutions.remove(n); + } else { + break; + } + } + if (rootExecutions.size() > 0) { + rootExecutions.remove(rootExecutions.size() - 1); + } + } else { + TracePoint threadBeforeTp; + do { + MethodExecution threadLastExecution = rootExecutions.remove(rootExecutions.size() - 1); + threadBeforeTp = threadLastExecution.getExitPoint(); + } while (!threadBeforeTp.isValid() && rootExecutions.size() > 0); + if (threadBeforeTp.isValid()) { + TracePoint[] tp = new TracePoint[] {threadBeforeTp}; + long threadLastTime; + if (before.getStatement() instanceof MethodInvocation) { + threadLastTime = ((MethodInvocation) before.getStatement()).getCalledMethodExecution().getExitTime(); + } else { + threadLastTime = before.getStatement().getTimeStamp(); + } + getLastStatementInThread(rootExecutions, tp, threadLastTime, new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { return false; } + @Override + public boolean postVisitStatement(Statement statement) { return false; } + }); + threadLastPoints.put(threadId, tp[0]); + if (tp[0] != null) { + if (tp[0].getStatement() instanceof MethodInvocation) { + threadLastTime = ((MethodInvocation) tp[0].getStatement()).getCalledMethodExecution().getExitTime(); // ��Exception �����������ꍇ�͍l���Ȃ��Ă悢? + } else { + threadLastTime = tp[0].getStatement().getTimeStamp(); + } + if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; + } + } + } else { + threadLastPoints.put(threadId, null); + } + } + } + return traverseStatementsInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); + } + + /** + * �g���[�X���̑S�X���b�h�𓯊������Ȃ���w�肵���g���[�X�|�C���g����t�����ɒT������ + * + * @param visitor�@���s���̃r�W�^�[ + * @param before �T���J�n���� + * @return�@���f�����g���[�X�|�C���g + */ + public TracePoint traverseStatementsInTraceBackward(IStatementVisitor visitor, long before) { + if (before <= 0L) { + return traverseStatementsInTraceBackward(visitor); + } + // �S�ẴX���b�h�̃g���[�X�|�C���g�� before �̑O�܂Ŋ����߂� + HashMap> threadRoots = new HashMap>(); + HashMap threadLastPoints = new HashMap(); + long traceLastTime = 0; + String traceLastThread = null; + long traceLastTime2 = 0; + String traceLastThread2 = null; + for (String threadId: threads.keySet()) { + ThreadInstance t = threads.get(threadId); + ArrayList rootExecutions = (ArrayList)t.getRoot().clone(); + threadRoots.put(threadId, rootExecutions); + TracePoint threadBeforeTp; + do { + MethodExecution threadLastExecution = rootExecutions.remove(rootExecutions.size() - 1); + threadBeforeTp = threadLastExecution.getExitPoint(); + } while (!threadBeforeTp.isValid() && rootExecutions.size() > 0); + if (threadBeforeTp.isValid()) { + TracePoint[] tp = new TracePoint[] {threadBeforeTp}; + getLastStatementInThread(rootExecutions, tp, before, new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { return false; } + @Override + public boolean postVisitStatement(Statement statement) { return false; } + }); + threadLastPoints.put(threadId, tp[0]); + if (tp[0] != null) { + long threadLastTime; + if (tp[0].getStatement() instanceof MethodInvocation) { + threadLastTime = ((MethodInvocation) tp[0].getStatement()).getCalledMethodExecution().getExitTime(); // ��Exception �����������ꍇ�͍l���Ȃ��Ă悢? + } else { + threadLastTime = tp[0].getStatement().getTimeStamp(); + } + if (traceLastTime < threadLastTime) { + traceLastTime2 = traceLastTime; + traceLastThread2 = traceLastThread; + traceLastTime = threadLastTime; + traceLastThread = threadId; + } else if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; + } + } + } else { + threadLastPoints.put(threadId, null); + } + } + 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); + while (lastTp != null) { + Statement statement = lastTp.getStatement(); + if (visitor.preVisitStatement(statement)) return lastTp; + if (statement instanceof MethodInvocation) { + // �Ăяo���悪����ꍇ�A�Ăяo����ɐ��� + lastTp.stepBackNoReturn(); + if (lastTp.isValid()) { + // ���ʂɌĂяo����Ɉڂ����ꍇ + MethodExecution methodExecution = ((MethodInvocation) statement).getCalledMethodExecution(); + if (!methodExecution.isTerminated() && methodExecution.getExitTime() < traceLastTime2) { + break; + } + continue; + } + // ��̃��\�b�h���s�̏ꍇ + } else { + if (visitor.postVisitStatement(statement)) return lastTp; + } + if (lastTp.isValid() && lastTp.getStatement().getTimeStamp() < traceLastTime2) break; + // 1�X�e�b�v�����߂� + while (!lastTp.stepBackOver() && lastTp.isValid()) { + // �Ăяo�����ɖ߂����ꍇ(���\�b�h�Ăяo�����ɕ��A) + statement = lastTp.getStatement(); + if (visitor.postVisitStatement(statement)) return lastTp; + } + if (!lastTp.isValid()) { + // �Ăяo���؂̊J�n���_�܂ŒT�����I�����ꍇ + ArrayList roots = threadRoots.get(traceLastThread); + while (!lastTp.isValid() && roots.size() > 0) { + // ���̌Ăяo���؂�T�� + MethodExecution lastExecution = roots.remove(roots.size() - 1); + lastTp = lastExecution.getExitPoint(); + } + if (lastTp.isValid()) { + // ���̌Ăяo���؂�����΂�����Ōォ��T�� + threadLastPoints.put(traceLastThread, lastTp); + if (lastTp.getStatement().getTimeStamp() < traceLastTime2) break; + } else { + // ���̃X���b�h�̒T�������ׂďI�������ꍇ + threadLastPoints.put(traceLastThread, null); + break; + } + } + } + traceLastThread = traceLastThread2; + // ���̎��ɒT�����ׂ��X���b�h(���T���̗̈悪��ԍŌ�܂Ŏc���Ă���X���b�h)�����肷�� + traceLastTime2 = 0; + traceLastThread2 = null; + boolean continueTraverse = false; + for (String threadId: threadLastPoints.keySet()) { + if (!threadId.equals(traceLastThread)) { + TracePoint threadLastTp = threadLastPoints.get(threadId); + if (threadLastTp != null) { + continueTraverse = true; + long threadLastTime; + if (threadLastTp.getStatement() instanceof MethodInvocation) { + threadLastTime = ((MethodInvocation) threadLastTp.getStatement()).getCalledMethodExecution().getExitTime(); + } else { + threadLastTime = threadLastTp.getStatement().getTimeStamp(); + } + if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; + } + } + } + } + if (traceLastThread == null && traceLastThread2 == null) break; + if (!continueTraverse && threadLastPoints.get(traceLastThread) == null) break; + } + return null; + } } \ No newline at end of file diff --git a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TracePoint.java b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TracePoint.java index ae65e14..11b8f57 100644 --- a/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TracePoint.java +++ b/org.ntlab.traceAnalyzer/src/org/ntlab/trace/TracePoint.java @@ -1,192 +1,193 @@ -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; - } - - /** - * �������\�b�h���ŏ�������1�i�߂�B�Ăяo����ɂ��Ăяo�����ɂ��s���Ȃ��B - * @return false:���\�b�h�𔲂��o���ꍇ, true: ����ȊO - */ - public boolean stepNext() { - order++; - return (order < methodExecution.getStatements().size()); - } - - 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; - } - - public boolean equals(Object other) { - if (this == other) return true; - if (!(other instanceof TracePoint)) return false; - if (methodExecution != ((TracePoint) other).methodExecution) return false; - if (order != ((TracePoint) other).order) return false; - return true; - } -} +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() { + if (methodExecution.getStatements().size() <= order) return null; + 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; + } + + /** + * �������\�b�h���ŏ�������1�i�߂�B�Ăяo����ɂ��Ăяo�����ɂ��s���Ȃ��B + * @return false:���\�b�h�𔲂��o���ꍇ, true: ����ȊO + */ + public boolean stepNext() { + order++; + return (order < methodExecution.getStatements().size()); + } + + 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; + } + + public boolean equals(Object other) { + if (this == other) return true; + if (!(other instanceof TracePoint)) return false; + if (methodExecution != ((TracePoint) other).methodExecution) return false; + if (order != ((TracePoint) other).order) return false; + return true; + } +} diff --git a/org.ntlab.traceAnalyzer/traces/ArgoUMLBenchmarkWithMoreStandardClasses.trace b/org.ntlab.traceAnalyzer/traces/ArgoUMLBenchmarkWithMoreStandardClasses.trace new file mode 100644 index 0000000..e7fe043 --- /dev/null +++ b/org.ntlab.traceAnalyzer/traces/ArgoUMLBenchmarkWithMoreStandardClasses.trace Binary files differ diff --git a/org.ntlab.traceAnalyzer/traces/jEditBenchmarkWithMoreStandardClasses.trace b/org.ntlab.traceAnalyzer/traces/jEditBenchmarkWithMoreStandardClasses.trace new file mode 100644 index 0000000..6f8285c --- /dev/null +++ b/org.ntlab.traceAnalyzer/traces/jEditBenchmarkWithMoreStandardClasses.trace Binary files differ diff --git a/org.ntlab.traceAnalyzer/traces/jHotDrawBenchmarkWithMoreStandardClasses.trace b/org.ntlab.traceAnalyzer/traces/jHotDrawBenchmarkWithMoreStandardClasses.trace new file mode 100644 index 0000000..97ee36b --- /dev/null +++ b/org.ntlab.traceAnalyzer/traces/jHotDrawBenchmarkWithMoreStandardClasses.trace Binary files differ