diff --git a/src/org/ntlab/deltaExtractor/DeltaExtractor.java b/src/org/ntlab/deltaExtractor/DeltaExtractor.java index 23fc536..47cb66d 100644 --- a/src/org/ntlab/deltaExtractor/DeltaExtractor.java +++ b/src/org/ntlab/deltaExtractor/DeltaExtractor.java @@ -14,7 +14,7 @@ /** * �f���^���o�A���S���Y��(�z��ւ̃A�N�Z�X�𐄑�����]���̃o�[�W����) - * extract(...)���\�b�h�Q�Œ��o����Bcd + * extract(...)���\�b�h�Q�Œ��o����B * * @author Nitta * @@ -785,7 +785,7 @@ } /** - * �݌v�ύX��̃A���S���Y���̋N�����\�b�h(������) + * �Q�ƌ��I�u�W�F�N�g�ƎQ�Ɛ�I�u�W�F�N�g���֘A�t�����f���^���A�Q�Ƃ��w�肵�Ē��o���� * @param targetRef �ΏۂƂȂ�Q�� * @param before �T���J�n�g���[�X�|�C���g(������ȑO��T��) * @return ���o���� @@ -795,7 +795,7 @@ } /** - * �݌v�ύX��̃A���S���Y���̋N�����\�b�h(������) + * �Q�ƌ��I�u�W�F�N�g�ƎQ�Ɛ�I�u�W�F�N�g���֘A�t�����f���^���A�Q�Ƃ��w�肵�Ē��o���� * @param targetRef �ΏۂƂȂ�Q�� * @param before �T���J�n�g���[�X�|�C���g(������ȑO��T��) * @param aliasCollector �f���^���o���ɒǐՂ����I�u�W�F�N�g�̑S�G�C���A�X�����W���郊�X�i @@ -824,7 +824,7 @@ } /** - * �݌v�ύX��̃A���S���Y���̋N�����\�b�h(������) + * �Q�ƌ��I�u�W�F�N�g�ƎQ�Ɛ�I�u�W�F�N�g���֘A�t�����f���^���A�I�u�W�F�N�g�ԎQ�Ƃ��������ꂽ�g���[�X�|�C���g���w�肵�Ē��o���� * @param creationTracePoint �I�u�W�F�N�g�ԎQ�Ɛ����g���[�X�|�C���g(�t�B�[���h�ւ̑��) * @return ���o���� */ @@ -840,7 +840,7 @@ } /** - * �݌v�ύX��̃A���S���Y���̋N�����\�b�h(������) + * �Q�ƌ��I�u�W�F�N�g�ƎQ�Ɛ�I�u�W�F�N�g���֘A�t�����f���^���A�I�u�W�F�N�g�ԎQ�Ƃ��������ꂽ�g���[�X�|�C���g���w�肵�Ē��o���� * @param creationTracePoint �I�u�W�F�N�g�ԎQ�Ɛ����g���[�X�|�C���g(�t�B�[���h�ւ̑��) * @param aliasCollector �f���^���o���ɒǐՂ����I�u�W�F�N�g�̑S�G�C���A�X�����W���郊�X�i * @return ���o���� @@ -877,29 +877,65 @@ return extractSub2(creationTracePoint, objList, aliasCollector); } - public ExtractedStructure extract(TracePoint tracePoint, ObjectReference argObj) { - return extract(tracePoint, argObj, defaultAliasCollector); + /** + * �Ăяo�����I�u�W�F�N�g�ƌĂяo����I�u�W�F�N�g���֘A�t�����f���^���A�Ăяo���惁�\�b�h���s���w�肵�Ē��o���� + * @param calledMethodExecution �Ăяo���惁�\�b�h���s + * @return�@���o���� + */ + public ExtractedStructure extract(MethodExecution calledMethodExecution) { + return extract(calledMethodExecution, defaultAliasCollector); + } + + /** + * �Ăяo�����I�u�W�F�N�g�ƌĂяo����I�u�W�F�N�g���֘A�t�����f���^���A�Ăяo���惁�\�b�h���s���w�肵�Ē��o���� + * @param calledMethodExecution �Ăяo���惁�\�b�h���s + * @param aliasCollector �f���^���o���ɒǐՂ����I�u�W�F�N�g�̑S�G�C���A�X�����W���郊�X�i + * @return�@���o���� + */ + public ExtractedStructure extract(MethodExecution calledMethodExecution, IAliasCollector aliasCollector) { + ObjectReference callee = new ObjectReference(calledMethodExecution.getThisObjId(), calledMethodExecution.getThisClassName()); + return extract(calledMethodExecution.getCallerTracePoint(), callee, aliasCollector); } - public ExtractedStructure extract(TracePoint tracePoint, ObjectReference argObj, IAliasCollector aliasCollector) { - MethodExecution methodExecution = tracePoint.getMethodExecution(); + /** + * �����ithis�I�u�W�F�N�g�j�Ǝ��������\�b�h���ŎQ�Ƃ����I�u�W�F�N�g���֘A�t�����f���^�𒊏o���� + * @param thisTracePoint �Q�Ƃ������������_ + * @param anotherObj �Q�Ƃ����I�u�W�F�N�g + * @return ���o���� + */ + public ExtractedStructure extract(TracePoint thisTracePoint, ObjectReference anotherObj) { + return extract(thisTracePoint, anotherObj, defaultAliasCollector); + } + + /** + * �����ithis�I�u�W�F�N�g�j�ƃ��\�b�h���ŎQ�Ƃ��ꂽ�I�u�W�F�N�g���֘A�t�����f���^�𒊏o���� + * @param thisTracePoint �Q�Ƃ������������_ + * @param anotherObj �Q�Ƃ����I�u�W�F�N�g + * @param aliasCollector �f���^���o���ɒǐՂ����I�u�W�F�N�g�̑S�G�C���A�X�����W���郊�X�i + * @return ���o���� + */ + public ExtractedStructure extract(TracePoint thisTracePoint, ObjectReference anotherObj, IAliasCollector aliasCollector) { + MethodExecution methodExecution = thisTracePoint.getMethodExecution(); + if (!thisTracePoint.isMethodEntry()) { + thisTracePoint.stepNext(); + } eStructure = new ExtractedStructure(); ArrayList objList = new ArrayList(); String thisObjectId = methodExecution.getThisObjId(); objList.add(thisObjectId); - objList.add(argObj.getId()); + objList.add(anotherObj.getId()); srcObject = new ObjectReference(thisObjectId, methodExecution.getThisClassName(), Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor()), Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstructor())); - dstObject = argObj; + dstObject = anotherObj; if (DEBUG1) { - System.out.println("extract delta of:" + methodExecution.getSignature() + " -> " + argObj.getActualType() + "(" + argObj.getId() + ")"); + System.out.println("extract delta of:" + methodExecution.getSignature() + " -> " + anotherObj.getActualType() + "(" + anotherObj.getId() + ")"); } - return extractSub2(tracePoint, objList, aliasCollector); + return extractSub2(thisTracePoint, objList, aliasCollector); } - private ExtractedStructure extractSub2(TracePoint creationTracePoint, ArrayList objList, IAliasCollector aliasCollector) { - eStructure.setCreationMethodExecution(creationTracePoint.getMethodExecution()); - MethodExecution coordinator = callerSearch(trace, creationTracePoint, objList, null, aliasCollector); + private ExtractedStructure extractSub2(TracePoint tracePoint, ArrayList objList, IAliasCollector aliasCollector) { + eStructure.setCreationMethodExecution(tracePoint.getMethodExecution()); + MethodExecution coordinator = callerSearch(trace, tracePoint, objList, null, aliasCollector); eStructure.setCoordinator(coordinator); if (DEBUG2) { if (((DeltaAugmentationInfo)coordinator.getAugmentation()).isCoodinator()) { diff --git a/src/org/ntlab/deltaExtractor/DeltaExtractorJSON.java b/src/org/ntlab/deltaExtractor/DeltaExtractorJSON.java index 16be00d..ff9da6a 100644 --- a/src/org/ntlab/deltaExtractor/DeltaExtractorJSON.java +++ b/src/org/ntlab/deltaExtractor/DeltaExtractorJSON.java @@ -120,10 +120,13 @@ if (ownerObjectId.equals(thisObjectId)) { // �t�B�[���h�Q�Ƃ̏ꍇ - removeList.add(refObjectId); - existsInFields++; // set�������get�����o���Ă���”\�������� - removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� - aliasList.put(refObjectId, new Alias(Alias.AliasType.FIELD, 0, refObjectId, tracePoint.duplicate())); + if (!removeList.contains(refObjectId)) { + // ��ԋ߂��t�B�[���h�Q�Ƃ�D�悷�� + removeList.add(refObjectId); + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + aliasList.put(refObjectId, new Alias(Alias.AliasType.FIELD, 0, refObjectId, tracePoint.duplicate())); + existsInFields++; // set�������get�����o���Ă���”\�������� + } } else { // ���ڎQ�Ƃ̏ꍇ boolean isSrcSideChanged = false; @@ -592,24 +595,50 @@ Reference r; if (methodExecution.isCollectionType()) { if (objectId != null) { - // �R���N�V�����^�̏ꍇ�A�����ԁX�̗v�f�𒼐ڕێ����Ă���Ɖ��肷�� - if (objectId.equals(srcObject.getId())) { - r = new Reference(thisObj, srcObject); - r.setCollection(true); - eStructure.addSrcSide(r); - srcObject = thisObj; - 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())); + if (methodExecution.getSignature().contains("Collections.unmodifiable") + || methodExecution.getSignature().contains("Collections.checked") + || methodExecution.getSignature().contains("Collections.synchronized") + || methodExecution.getSignature().contains("Arrays.asList") + || methodExecution.getSignature().contains("Arrays.copyOf")) { + // �z���R���N�V�����̊Ԃ̕ϊ��̏ꍇ�A�ϊ����̑������Ɉˑ����� + if (arguments.size() > 0) { + if (objectId.equals(srcObject.getId())) { + r = new Reference(arguments.get(0), srcObject); + r.setCollection(true); + eStructure.addSrcSide(r); + srcObject = arguments.get(0); + aliasCollector.changeTrackingObject(objectId, arguments.get(0).getId(), true); + aliasCollector.addAlias(new Alias(Alias.AliasType.FORMAL_PARAMETER, 0, arguments.get(0).getId(), tracePoint.duplicate())); + } else if(objectId.equals(dstObject.getId())) { + r = new Reference(arguments.get(0), dstObject); + r.setCollection(true); + eStructure.addDstSide(r); + dstObject =arguments.get(0); + aliasCollector.changeTrackingObject(objectId, arguments.get(0).getId(), false); + aliasCollector.addAlias(new Alias(Alias.AliasType.FORMAL_PARAMETER, 0, arguments.get(0).getId(), tracePoint.duplicate())); + } + } + objList.set(index, arguments.get(0).getId()); + } else { + // �R���N�V�����^�̏ꍇ�A�����ԁX�̗v�f�𒼐ڕێ����Ă���Ɖ��肷�� + if (objectId.equals(srcObject.getId())) { + r = new Reference(thisObj, srcObject); + r.setCollection(true); + eStructure.addSrcSide(r); + srcObject = thisObj; + 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()); } } - objList.set(index, methodExecution.getThisObjId()); isResolved = true; // �K�v�Ȃ̂ł�? } diff --git a/src/org/ntlab/deltaViewer/DeltaViewerSample.java b/src/org/ntlab/deltaViewer/DeltaViewerSample.java index 93f67b4..3d682eb 100644 --- a/src/org/ntlab/deltaViewer/DeltaViewerSample.java +++ b/src/org/ntlab/deltaViewer/DeltaViewerSample.java @@ -14,6 +14,7 @@ import org.ntlab.trace.IStatementVisitor; import org.ntlab.trace.MethodExecution; import org.ntlab.trace.MethodInvocation; +import org.ntlab.trace.ObjectReference; import org.ntlab.trace.Reference; import org.ntlab.trace.Statement; import org.ntlab.trace.ThreadInstance; @@ -114,53 +115,65 @@ Map argsMap = new HashMap<>(); setArgmentsForDeltaExtract(argsMap); //���o�������f���^�̈������i�[����Map��key -// String argsKey = "ArgoUMLPlace1_1"; -// String argsKey = "ArgoUMLSelect0_1"; -// String argsKey = "ArgoUMLSelect1_2"; + String argsKey = "ArgoUMLSelect"; +// String argsKey = "ArgoUMLDelete1"; +// String argsKey = "JHotDrawTransform"; +// String argsKey = "JHotDrawSelect1"; // String argsKey = "sampleArray"; // String argsKey = "sampleCollection"; // String argsKey = "sampleCreate"; // String argsKey = "sampleStatic"; // String argsKey = "delta_eg1"; - String argsKey = "pre_Exp1"; +// String argsKey = "pre_Exp3"; // String argsKey = "worstCase"; // String argsKey = "sample1"; long time = System.nanoTime(); TraceJSON trace = new TraceJSON(argsMap.get(argsKey)[4]); DeltaExtractorJSON s = new DeltaExtractorJSON(trace); - HashMap threads = trace.getAllThreads(); + if (argsMap.get(argsKey)[5] == null) { + HashMap threads = trace.getAllThreads(); - List eList = new ArrayList<>(); - List dacList = new ArrayList<>(); - if (threads.values().size() == 1) { - ThreadInstance thread = threads.values().iterator().next(); // �Ō�̃X���b�h�����Ă��邾���c - TracePoint tp = thread.getRoot().get(thread.getRoot().size() - 1).getExitPoint(); - Reference reference = new Reference(argsMap.get(argsKey)[0], argsMap.get(argsKey)[1], argsMap.get(argsKey)[2], argsMap.get(argsKey)[3]); - DeltaAliasCollector dac = new DeltaAliasCollector(); - ExtractedStructure e = s.extract(reference, tp, dac); - eList.add(e); - dacList.add(dac); - } else { - for (ThreadInstance thread: threads.values()) { + List eList = new ArrayList<>(); + List dacList = new ArrayList<>(); + if (threads.values().size() == 1) { + ThreadInstance thread = threads.values().iterator().next(); // �Ō�̃X���b�h�����Ă��邾���c TracePoint tp = thread.getRoot().get(thread.getRoot().size() - 1).getExitPoint(); Reference reference = new Reference(argsMap.get(argsKey)[0], argsMap.get(argsKey)[1], argsMap.get(argsKey)[2], argsMap.get(argsKey)[3]); - reference.setCollection(true); + DeltaAliasCollector dac = new DeltaAliasCollector(); + ExtractedStructure e = s.extract(reference, tp, dac); + eList.add(e); + dacList.add(dac); + } else { + for (ThreadInstance thread: threads.values()) { + TracePoint tp = thread.getRoot().get(thread.getRoot().size() - 1).getExitPoint(); + Reference reference = new Reference(argsMap.get(argsKey)[0], argsMap.get(argsKey)[1], argsMap.get(argsKey)[2], argsMap.get(argsKey)[3]); + reference.setCollection(true); // reference.setArray(true); // reference.setFinalLocal(true); // reference.setCreation(true); - DeltaAliasCollector dac = new DeltaAliasCollector(); - ExtractedStructure e = s.extract(reference, tp, dac); - System.out.println(e); - if (e != null) { - eList.add(e); - dacList.add(dac); - System.out.println("add" + eList.size() + ", " + dacList.size()); + DeltaAliasCollector dac = new DeltaAliasCollector(); + ExtractedStructure e = s.extract(reference, tp, dac); + System.out.println(e); + if (e != null) { + eList.add(e); + dacList.add(dac); + System.out.println("add" + eList.size() + ", " + dacList.size()); + } + System.out.println("---------------------------"); } - System.out.println("---------------------------"); } - } - startDeltaViewer(eList.get(0), dacList.get(0)); + startDeltaViewer(eList.get(0), dacList.get(0)); + } else { + DeltaAliasCollector dac = new DeltaAliasCollector(); + MethodExecution me = trace.getLastMethodExecution(argsMap.get(argsKey)[2]); + Map refs = me.getObjectReferences(argsMap.get(argsKey)[3]); + ObjectReference ref = refs.keySet().iterator().next(); + ExtractedStructure e = s.extract(refs.get(ref), ref, dac); + + startDeltaViewer(e, dac); + + } } private static void startDeltaViewer(ExtractedStructure e, DeltaAliasCollector dac) { @@ -176,7 +189,7 @@ dv.stepToAnimation(i); } } - + private static void setArgmentsForDeltaExtract(Map map){ // one delta extract @@ -195,33 +208,44 @@ String[] testTrace3 = {null, null, "","", "traces/testTrace3.txt"}; map.put("testTrace3", testTrace3); // �\�������̂Ƃ��ɗp����Toy program - String[] pre_Exp1 = {null, null, "E","C", "traces/pre_Exp1.txt"}; map.put("pre_Exp1", pre_Exp1); - String[] pre_Exp2 = {null, null, "E","C", "traces/pre_Exp2.txt"}; map.put("pre_Exp2", pre_Exp2); - String[] pre_Exp3 = {null, null, "E","C", "traces/pre_Exp3.txt"}; map.put("pre_Exp3", pre_Exp3); - String[] pre_Exp4 = {null, null, "E","C", "traces/pre_Exp4.txt"}; map.put("pre_Exp4", pre_Exp4); - String[] pre_Exp5 = {null, null, "E","C", "traces/pre_Exp5.txt"}; map.put("pre_Exp5", pre_Exp5); - String[] pre_Exp6 = {null, null, "E","C", "traces/pre_Exp6.txt"}; map.put("pre_Exp6", pre_Exp6); - String[] pre_Exp7 = {null, null, "E","C", "traces/pre_Exp7.txt"}; map.put("pre_Exp7", pre_Exp7); + String[] pre_Exp1 = {null, null, "E","C", "traces/pre_Exp1.txt", null}; map.put("pre_Exp1", pre_Exp1); + String[] pre_Exp2 = {null, null, "E","C", "traces/pre_Exp2.txt", null}; map.put("pre_Exp2", pre_Exp2); + String[] pre_Exp3 = {null, null, "E","C", "traces/pre_Exp3.txt", null}; map.put("pre_Exp3", pre_Exp3); + String[] pre_Exp4 = {null, null, "E","C", "traces/pre_Exp4.txt", null}; map.put("pre_Exp4", pre_Exp4); + String[] pre_Exp5 = {null, null, "E","C", "traces/pre_Exp5.txt", null}; map.put("pre_Exp5", pre_Exp5); + String[] pre_Exp6 = {null, null, "E","C", "traces/pre_Exp6.txt", null}; map.put("pre_Exp6", pre_Exp6); + String[] pre_Exp7 = {null, null, "E","C", "traces/pre_Exp7.txt", null}; map.put("pre_Exp7", pre_Exp7); - String[] test = {null, null, "org.argouml.uml.diagram.static_structure.ui.FigClass","org.tigris.gef.base.LayerPerspectiveMutable", "traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace"}; map.put("test", test); - String[] testVectorAddElement = {null, null, "java.util.Vector", "org.tigris.gef.base.LayerPerspective", "traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace"}; map.put("testVectorAddElement", testVectorAddElement);//trace.java��"addElement("�ɑΉ�����悤�ɒlj� - String[] ArgoUMLBenchmark = {"", "", "", "", "traces/ArgoUMLBenchmark.trace"}; map.put("ArgoUMLBenchmark", ArgoUMLBenchmark); - String[] ArgoUMLBenchmarkWithMoreStandardClasses = {"", "", "", "", "traces/ArgoUMLBenchmarkWithMoreStandardClasses.trace"}; map.put("ArgoUMLBenchmarkWithMoreStandardClasses", ArgoUMLBenchmarkWithMoreStandardClasses); -// String[] ArgoUMLSelect0_1 = {"1994249754", "1141430801", "java.util.ArrayList", "org.argouml.uml.diagram.static_structure.ui.SelectionClass","traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace"}; map.put("ArgoUMLSelect0_1", ArgoUMLSelect0_1); - String[] ArgoUMLSelect0_1 = {"1994249754", "1141430801", null, null,"traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace"}; map.put("ArgoUMLSelect0_1", ArgoUMLSelect0_1); - /*Vector.addElemnt()�ɑΉ��ς�*/String[] ArgoUMLDelete0_2 = {"1784213708", "1337038091", "java.util.Vector", "org.argouml.uml.diagram.static_structure.ui.FigClass", "traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace"}; map.put("ArgoUMLDelete0_2", ArgoUMLDelete0_2); - /*�X�ɉߋ�mouse.Pressed(), mouseReleased()*/String[] ArgoUMLPlace1_1 = {null, null, "java.util.ArrayList", "org.argouml.uml.diagram.static_structure.ui.FigClass", "traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace"}; map.put("ArgoUMLPlace1_1", ArgoUMLPlace1_1); - String[] ArgoUMLSelect1_2 = {"1994249754", "1141430801", "java.util.ArrayList", "org.argouml.uml.diagram.static_structure.ui.SelectionClass", "traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace"}; map.put("ArgoUMLSelect1_2", ArgoUMLSelect1_2); - String[] jEditBenchmark = {"", "", "", "", "traces/jEditBenchmark.trace"}; map.put("jEditBenchmark", jEditBenchmark); - String[] jEditSelect2_1 = {"932187140", "1572482885", "java.util.ArrayList", "org.gjt.sp.jedit.textarea.Selection$Range", "traces\\jEditBenchmarkWithMoreStandardClasses.trace"}; map.put("jEditSelect2_1", jEditSelect2_1); - String[] jHotDrawBenchmark = {"", "", "", "", "traces/jHotDrawBenchmark.trace"}; map.put("jHotDrawBenchmark", jHotDrawBenchmark); - String[] jHotDrawBenchmarkWithMoreStandardClasses = {"", "", "", "", "traces/jHotDrawBenchmarkWithMoreStandardClasses.trace"}; map.put("jHotDrawBenchmarkWithMoreStandardClasses", jHotDrawBenchmarkWithMoreStandardClasses); - /*List.toArray()�ɑΉ�������K�v������H*/String[] jEditDelete2_2 = {null, null, "org.gjt.sp.jedit.buffer.ContentManager", "java.util.ArrayList", "traces\\jEditBenchmarkWithMoreStandardClasses.trace"}; map.put("jEditDelete2_2", jEditDelete2_2); - String[] jHotDrawSelect3_1 = {"361298449", "212532447", "java.util.LinkedHashSet", "org.jhotdraw.draw.RectangleFigure", "traces\\jHotDrawBenchmarkWithMoreStandardClasses.trace"}; map.put("jHotDrawSelect3_1", jHotDrawSelect3_1); - String[] jHotDrawMove3_2 = {"778703711", "212532447", "org.jhotdraw.draw.tool.DefaultDragTracker", "org.jhotdraw.draw.RectangleFigure", "traces\\jHotDrawBenchmarkWithMoreStandardClasses.trace"}; map.put("jHotDrawMove3_2", jHotDrawMove3_2); - /*�s��*/String[] jHotDrawMove3_2_1 = {null, null, "java.util.ArrayList", "org.jhotdraw.draw.RectangleFigure", "traces\\jHotDrawBenchmarkWithMoreStandardClasses.trace"}; map.put("jHotDrawMove3_2_1", jHotDrawMove3_2_1); - String[] jHotDrawPlace4_1 = {"1284329882", "212532447", "java.util.HashMap", "org.jhotdraw.draw.RectangleFigure", "traces\\jHotDrawBenchmarkWithMoreStandardClasses.trace"}; map.put("jHotDrawPlace4_1", jHotDrawPlace4_1); - String[] jHotDrawSelect4_2 = {"361298449", "212532447", "java.util.LinkedHashSet", "org.jhotdraw.draw.RectangleFigure", "traces\\jHotDrawBenchmarkWithMoreStandardClasses.trace"}; map.put("jHotDrawSelect4_2", jHotDrawSelect4_2); + String[] test = {null, null, "org.argouml.uml.diagram.static_structure.ui.FigClass","org.tigris.gef.base.LayerPerspectiveMutable", "traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace", null}; map.put("test", test); + String[] testVectorAddElement = {null, null, "java.util.Vector", "org.tigris.gef.base.LayerPerspective", "traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace", null}; map.put("testVectorAddElement", testVectorAddElement);//trace.java��"addElement("�ɑΉ�����悤�ɒlj� + String[] ArgoUMLBenchmark = {"", "", "", "", "traces/ArgoUMLBenchmark.trace", null}; map.put("ArgoUMLBenchmark", ArgoUMLBenchmark); + String[] ArgoUMLBenchmarkWithMoreStandardClasses = {"", "", "", "", "traces/ArgoUMLBenchmarkWithMoreStandardClasses.trace", null}; map.put("ArgoUMLBenchmarkWithMoreStandardClasses", ArgoUMLBenchmarkWithMoreStandardClasses); +// String[] ArgoUMLSelect0_1 = {"1994249754", "1141430801", "java.util.ArrayList", "org.argouml.uml.diagram.static_structure.ui.SelectionClass","traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace", null}; map.put("ArgoUMLSelect0_1", ArgoUMLSelect0_1); + String[] ArgoUMLSelect0_1 = {"1994249754", "1141430801", null, null,"traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace", null}; map.put("ArgoUMLSelect0_1", ArgoUMLSelect0_1); + /*Vector.addElemnt()�ɑΉ��ς�*/String[] ArgoUMLDelete0_2 = {"1784213708", "1337038091", "java.util.Vector", "org.argouml.uml.diagram.static_structure.ui.FigClass", "traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace", null}; map.put("ArgoUMLDelete0_2", ArgoUMLDelete0_2); + /*�X�ɉߋ�mouse.Pressed(), mouseReleased()*/String[] ArgoUMLPlace1_1 = {null, null, "java.util.ArrayList", "org.argouml.uml.diagram.static_structure.ui.FigClass", "traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace", null}; map.put("ArgoUMLPlace1_1", ArgoUMLPlace1_1); +// String[] ArgoUMLSelect1_2 = {"1994249754", "1141430801", "java.util.ArrayList", "org.argouml.uml.diagram.static_structure.ui.SelectionClass", "traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace", null}; map.put("ArgoUMLSelect1_2", ArgoUMLSelect1_2); +// String[] ArgoUMLSelect1_2 = {"125345735", "1672744985", "java.util.ArrayList", "org.argouml.uml.diagram.static_structure.ui.SelectionClass", "traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace", null}; map.put("ArgoUMLSelect1_2", ArgoUMLSelect1_2); + String[] jEditBenchmark = {"", "", "", "", "traces/jEditBenchmark.trace", null}; map.put("jEditBenchmark", jEditBenchmark); + String[] jEditSelect2_1 = {"932187140", "1572482885", "java.util.ArrayList", "org.gjt.sp.jedit.textarea.Selection$Range", "traces\\jEditBenchmarkWithMoreStandardClasses.trace", null}; map.put("jEditSelect2_1", jEditSelect2_1); + String[] jHotDrawBenchmark = {"", "", "", "", "traces/jHotDrawBenchmark.trace", null}; map.put("jHotDrawBenchmark", jHotDrawBenchmark); + String[] jHotDrawBenchmarkWithMoreStandardClasses = {"", "", "", "", "traces/jHotDrawBenchmarkWithMoreStandardClasses.trace", null}; map.put("jHotDrawBenchmarkWithMoreStandardClasses", jHotDrawBenchmarkWithMoreStandardClasses); + /*List.toArray()�ɑΉ�������K�v������H*/String[] jEditDelete2_2 = {null, null, "org.gjt.sp.jedit.buffer.ContentManager", "java.util.ArrayList", "traces\\jEditBenchmarkWithMoreStandardClasses.trace", null}; map.put("jEditDelete2_2", jEditDelete2_2); + String[] jHotDrawSelect3_1 = {"361298449", "212532447", "java.util.LinkedHashSet", "org.jhotdraw.draw.RectangleFigure", "traces\\jHotDrawBenchmarkWithMoreStandardClasses.trace", null}; map.put("jHotDrawSelect3_1", jHotDrawSelect3_1); + String[] jHotDrawMove3_2 = {"778703711", "212532447", "org.jhotdraw.draw.tool.DefaultDragTracker", "org.jhotdraw.draw.RectangleFigure", "traces\\jHotDrawBenchmarkWithMoreStandardClasses.trace", null}; map.put("jHotDrawMove3_2", jHotDrawMove3_2); + /*�s��*/String[] jHotDrawMove3_2_1 = {null, null, "java.util.ArrayList", "org.jhotdraw.draw.RectangleFigure", "traces\\jHotDrawBenchmarkWithMoreStandardClasses.trace", null}; map.put("jHotDrawMove3_2_1", jHotDrawMove3_2_1); + String[] jHotDrawPlace4_1 = {"1284329882", "212532447", "java.util.HashMap", "org.jhotdraw.draw.RectangleFigure", "traces\\jHotDrawBenchmarkWithMoreStandardClasses.trace", null}; map.put("jHotDrawPlace4_1", jHotDrawPlace4_1); +// String[] jHotDrawSelect4_2 = {"361298449", "212532447", "java.util.LinkedHashSet", "org.jhotdraw.draw.RectangleFigure", "traces\\jHotDrawBenchmarkWithMoreStandardClasses.trace", null}; map.put("jHotDrawSelect4_2", jHotDrawSelect4_2); + String[] jHotDrawSelect4_2 = {null, null, "java.util.LinkedHashSet", "org.jhotdraw.draw.RectangleFigure", "traces\\jHotDrawBenchmarkWithMoreStandardClasses.trace", null}; map.put("jHotDrawSelect4_2", jHotDrawSelect4_2); + + // MagnetRON Experiment + String[] ArgoUMLSelect = {"125345735", "1672744985", "java.util.ArrayList", "org.argouml.uml.diagram.static_structure.ui.SelectionClass", "traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace", null}; map.put("ArgoUMLSelect", ArgoUMLSelect); // ArgoUML �I���@�\ (collection) + String[] ArgoUMLDelete1 = {null, null, "public void org.argouml.uml.diagram.ui.ActionRemoveFromDiagram.actionPerformed(", "org.argouml.uml.diagram.static_structure.ui.FigClass", "traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace", "this to another"}; map.put("ArgoUMLDelete1", ArgoUMLDelete1);// ArgoUML �폜�@�\1 (this to another) + String[] ArgoUMLDelete2 = {"450474599", "1675174935", "java.util.Vector", "org.argouml.uml.diagram.static_structure.ui.FigClass", "traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace", null}; map.put("ArgoUMLDelete2", ArgoUMLDelete2); // ArgoUML �폜�@�\2 (collection) + String[] JHotDrawTransform = {"176893671", "1952912699", "java.util.HashSet", "org.jhotdraw.draw.RectangleFigure", "traces\\jHotDrawBenchmarkWithMoreStandardClasses.trace", null}; map.put("JHotDrawTransform", JHotDrawTransform); // JHotDraw �ړ��@�\ (collection) + String[] JHotDrawSelect1 = {"758826749", "1952912699", "org.jhotdraw.draw.tool.DefaultDragTracker", "org.jhotdraw.draw.RectangleFigure", "traces\\jHotDrawBenchmarkWithMoreStandardClasses.trace", null}; map.put("JHotDrawSelect1", JHotDrawSelect1); // JHotDraw �I���@�\1 + String[] JHotDrawSelect2 = {"1378082106", "1952912699", "java.util.HashSet", "org.jhotdraw.draw.RectangleFigure", "traces\\jHotDrawBenchmarkWithMoreStandardClasses.trace", null}; map.put("JHotDrawSelect2", JHotDrawSelect2); // JHotDraw �I���@�\2 (collection) + String[] JHotDrawSelect3 = {"1787265837", "1952912699", "java.util.LinkedHashSet", "org.jhotdraw.draw.RectangleFigure", "traces\\jHotDrawBenchmarkWithMoreStandardClasses.trace", null}; map.put("JHotDrawSelect3", JHotDrawSelect3); // JHotDraw �I���@�\3 (collection) } private static void traverseMethodExecution(MethodExecution m) { diff --git a/src/org/ntlab/trace/MethodExecution.java b/src/org/ntlab/trace/MethodExecution.java index 4658073..d1797de 100644 --- a/src/org/ntlab/trace/MethodExecution.java +++ b/src/org/ntlab/trace/MethodExecution.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.Map; public class MethodExecution { private String signature; @@ -175,6 +176,49 @@ } /** + * ���̃��\�b�h���ŎQ�Ƃ��ꂽ�I�u�W�F�N�g�Ƃ��̃I�u�W�F�N�g�����\�b�h���ōŏ��ɎQ�Ƃ������s���_�̃��X�g���A�I�u�W�F�N�g�̌^���w�肵�Ď擾���� + * @param actualTypeName �I�u�W�F�N�g�̌^ + * @return ���̃��\�b�h���ŎQ�Ƃ��ꂽ actualTypeName �̃C���X�^���X�Ƃ��̃C���X�^���X���ŏ��ɎQ�Ƃ������s���_�̃��X�g + */ + public Map getObjectReferences(String actualTypeName) { + Map objectRefMap = new HashMap<>(); + TracePoint tp = getExitPoint(); + if (tp != null) { + do { + Statement s = tp.getStatement(); + if (s instanceof FieldAccess) { + FieldAccess f = (FieldAccess) s; + if (f.getValueClassName().equals(actualTypeName)) { + objectRefMap.put(new ObjectReference(f.getValueObjId(), f.getValueClassName()), tp.duplicate()); + } + } else if (s instanceof ArrayAccess) { + ArrayAccess a = (ArrayAccess) s; + if (a.getValueClassName().equals(actualTypeName)) { + objectRefMap.put(new ObjectReference(a.getValueObjectId(), a.getValueClassName()), tp.duplicate()); + } + } else if (s instanceof ArrayCreate) { + ArrayCreate a = (ArrayCreate) s; + if (a.getArrayClassName().equals(actualTypeName)) { + objectRefMap.put(new ObjectReference(a.getArrayObjectId(), a.getArrayClassName()), tp.duplicate()); + } + } else if (s instanceof MethodInvocation) { + MethodInvocation m = (MethodInvocation) s; + ObjectReference ret = m.getCalledMethodExecution().getReturnValue(); + if (ret.getActualType().equals(actualTypeName)) { + objectRefMap.put(ret, tp.duplicate()); + } + } + } while (tp.stepBackOver()); + } + for (ObjectReference arg: getArguments()) { + if (arg.getActualType().equals(actualTypeName)) { + objectRefMap.put(arg, getEntryPoint().duplicate()); + } + } + return objectRefMap; + } + + /** * ���̃��\�b�h���s����т��̑S�Ăяo������Ăяo���؂̒��ŋt�����ɒT������(�������Avisitor �� true ��Ԃ��܂�) * @param visitor �r�W�^�[ * @return�@true -- �T���𒆒f����, false -- �Ō�܂ŒT������ diff --git a/src/org/ntlab/trace/ThreadInstance.java b/src/org/ntlab/trace/ThreadInstance.java index 627f410..03f0341 100644 --- a/src/org/ntlab/trace/ThreadInstance.java +++ b/src/org/ntlab/trace/ThreadInstance.java @@ -1,177 +1,181 @@ -package org.ntlab.trace; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; - -public class ThreadInstance { - private ArrayList roots = new ArrayList(); - private MethodExecution curMethodExecution = null; - private MethodInvocation curMethodInvocation = null; - private String id; - - public ThreadInstance(String id) { - this.id = id; - } - - public void addRoot(MethodExecution root) { - this.roots.add(root); - curMethodExecution = root; - } - - public ArrayList getRoot() { - return roots; - } - - public String getId() { - return id; - } - - public void preCallMethod(String callerSideSignature, int lineNumOfInvocationStatement) { - if (curMethodExecution != null) { - curMethodInvocation = new MethodInvocation(callerSideSignature, curMethodExecution.getThisClassName(), curMethodExecution.getThisObjId(), lineNumOfInvocationStatement, id); - } - } - - public void callMethod(String signature, String callerSideSignature, String receiverClassName, String receiverObjId, - boolean isConstractor, boolean isStatic, long timeStamp) { - if (callerSideSignature == null && curMethodInvocation != null) { - callerSideSignature = curMethodInvocation.getCallerSideMethodName(); - } - MethodExecution newMethodExecution = new MethodExecution(signature, callerSideSignature, receiverClassName, receiverObjId, isConstractor, isStatic, timeStamp); - if (curMethodExecution != null) { - if (curMethodInvocation == null) { - curMethodExecution.addStatement(new MethodInvocation(newMethodExecution, curMethodExecution.getThisClassName(), curMethodExecution.getThisObjId(), 0, id)); - } else { - curMethodInvocation.setCalledMethodExecution(newMethodExecution); - curMethodExecution.addStatement(curMethodInvocation); - curMethodInvocation = null; - } - newMethodExecution.setCaller(curMethodExecution, curMethodExecution.getStatements().size() - 1); - curMethodExecution = newMethodExecution; - } else { - addRoot(newMethodExecution); - } - } - - public void setArgments(ArrayList arguments) { - curMethodExecution.setArguments(arguments); - } - - public void returnMethod(ObjectReference returnValue, String thisObjId, boolean isCollectionType) { - if (curMethodExecution == null) return; - curMethodExecution.setReturnValue(returnValue); - if (curMethodExecution.getThisObjId().equals("0")) { - curMethodExecution.setThisObjeId(thisObjId); - } - curMethodExecution.setCollectionType(isCollectionType); - curMethodExecution = curMethodExecution.getParent(); - curMethodInvocation = null; // �O�̂��� - } - - public void returnMethod(ObjectReference returnValue, String thisObjId, boolean isCollectionType, long exitTime) { - if (curMethodExecution != null) curMethodExecution.setExitTime(exitTime); - returnMethod(returnValue, thisObjId, isCollectionType); - } - - public void terminateMethod() { - if (curMethodExecution == null) return; - curMethodExecution.setTerminated(true); - curMethodExecution = curMethodExecution.getParent(); - } - - public void fieldAccess(String valueClassName, String valueObjId, String containerClassName, String containerObjId, String thisClassName, String thisId) { - FieldAccess fieldAccess = new FieldAccess(valueClassName, valueObjId, containerClassName, containerObjId, thisClassName, thisId, 0, id); - if (curMethodExecution != null) curMethodExecution.addStatement(fieldAccess); - } - - public void fieldAccess(String valueClassName, String valueObjId, String containerClassName, String containerObjId, String thisClassName, String thisId, int lineNo, long timeStamp) { - FieldAccess fieldAccess = new FieldAccess(valueClassName, valueObjId, containerClassName, containerObjId, thisClassName, thisId, lineNo, id, timeStamp); - if (curMethodExecution != null) curMethodExecution.addStatement(fieldAccess); - } - - public void fieldAccess(String fieldName, String valueClassName, String valueObjId, String containerClassName, String containerObjId, String thisClassName, String thisId, int lineNo, long timeStamp) { - FieldAccess fieldAccess = new FieldAccess(fieldName, valueClassName, valueObjId, containerClassName, containerObjId, thisClassName, thisId, lineNo, id, timeStamp); - if (curMethodExecution != null) curMethodExecution.addStatement(fieldAccess); - } - - public void fieldUpdate(String valueClassName, String valueObjId, String containerClassName, String containerObjId) { - FieldUpdate fieldUpdate = new FieldUpdate(valueClassName, valueObjId, containerClassName, containerObjId, 0, id); - if (curMethodExecution != null) curMethodExecution.addStatement(fieldUpdate); - } - - public void fieldUpdate(String valueClassName, String valueObjId, String containerClassName, String containerObjId, int lineNo, long timeStamp) { - FieldUpdate fieldUpdate = new FieldUpdate(valueClassName, valueObjId, containerClassName, containerObjId, lineNo, id, timeStamp); - if (curMethodExecution != null) curMethodExecution.addStatement(fieldUpdate); - } - - public void fieldUpdate(String fieldName, String valueClassName, String valueObjId, String containerClassName, String containerObjId, int lineNo, long timeStamp) { - FieldUpdate fieldUpdate = new FieldUpdate(fieldName, valueClassName, valueObjId, containerClassName, containerObjId, lineNo, id, timeStamp); - if (curMethodExecution != null) curMethodExecution.addStatement(fieldUpdate); - } - - public void arrayCreate(String arrayClassName, String arrayObjectId, int dimension, int lineNo, long timeStamp) { - ArrayCreate arrayCreate = new ArrayCreate(arrayClassName, arrayObjectId, dimension, lineNo, id, timeStamp); - if (curMethodExecution != null) curMethodExecution.addStatement(arrayCreate); - } - - public void arraySet(String arrayClassName, String arrayObjectId, int index, String valueClassName, String valueObjectId, int lineNo, long timeStamp) { - ArrayUpdate arraySet = new ArrayUpdate(arrayClassName, arrayObjectId, index, valueClassName, valueObjectId, lineNo, id, timeStamp); - if (curMethodExecution != null) curMethodExecution.addStatement(arraySet); - } - - public void arrayGet(String arrayClassName, String arrayObjectId, int index, String valueClassName, String valueObjectId, int lineNo, long timeStamp) { - ArrayAccess arrayGet = new ArrayAccess(arrayClassName, arrayObjectId, index, valueClassName, valueObjectId, lineNo, id, timeStamp); - if (curMethodExecution != null) curMethodExecution.addStatement(arrayGet); - } - - public void blockEnter(int blockId, int incomings, int lineNo, long timeStamp) { - BlockEnter blockEnter = new BlockEnter(blockId, incomings, lineNo, id, timeStamp); - if (curMethodExecution != null) curMethodExecution.addStatement(blockEnter); - } - - public void traverseMethodExecutionsBackward(IMethodExecutionVisitor visitor) { - visitor.preVisitThread(this); - for (int i = 0; i < roots.size(); i++) { - MethodExecution root = roots.get(i); - root.traverseMethodExecutionsBackward(visitor); - } - visitor.postVisitThread(this); - } - - public void traverseMarkedMethodExecutions(IMethodExecutionVisitor visitor, long markStart, long markEnd) { - visitor.preVisitThread(this); - for (int i = 0; i < roots.size(); i++) { - MethodExecution root = roots.get(i); - if (root.getEntryTime() <= markEnd) { - root.traverseMarkedMethodExecutions(visitor, markStart, markEnd); - } else { - break; - } - } - visitor.postVisitThread(this); - } - - public void getUnmarkedMethodSignatures(HashSet signatures, long markStart, long markEnd) { - for (int i = 0; i < roots.size(); i++) { - MethodExecution root = roots.get(i); - root.getUnmarkedMethodSignatures(signatures, markStart, markEnd); - } - } - - public void getUnmarkedMethodExecutions(HashMap> executions, long markStart, long markEnd) { - for (int i = 0; i < roots.size(); i++) { - MethodExecution root = roots.get(i); - root.getUnmarkedMethodExecutions(executions, markStart, markEnd); - } - } - - public MethodExecution getCurrentMethodExecution() { - return curMethodExecution; - } - - public TracePoint getCurrentTracePoint() { - return new TracePoint(curMethodExecution, curMethodExecution.getStatements().size() - 1); - } -} +package org.ntlab.trace; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; + +public class ThreadInstance { + private ArrayList roots = new ArrayList(); + private MethodExecution curMethodExecution = null; + private MethodInvocation curMethodInvocation = null; + private String id; + + public ThreadInstance(String id) { + this.id = id; + } + + public void addRoot(MethodExecution root) { + this.roots.add(root); + curMethodExecution = root; + } + + public ArrayList getRoot() { + return roots; + } + + public String getId() { + return id; + } + + public void preCallMethod(String callerSideSignature, int lineNumOfInvocationStatement) { + if (curMethodExecution != null) { + curMethodInvocation = new MethodInvocation(callerSideSignature, curMethodExecution.getThisClassName(), curMethodExecution.getThisObjId(), lineNumOfInvocationStatement, id); + } + } + + public void callMethod(String signature, String callerSideSignature, String receiverClassName, String receiverObjId, + boolean isConstractor, boolean isStatic, long timeStamp) { + if (callerSideSignature == null && curMethodInvocation != null) { + callerSideSignature = curMethodInvocation.getCallerSideMethodName(); + } + MethodExecution newMethodExecution = new MethodExecution(signature, callerSideSignature, receiverClassName, receiverObjId, isConstractor, isStatic, timeStamp); + if (curMethodExecution != null) { + if (curMethodInvocation == null) { + curMethodExecution.addStatement(new MethodInvocation(newMethodExecution, curMethodExecution.getThisClassName(), curMethodExecution.getThisObjId(), 0, id)); + } else { + curMethodInvocation.setCalledMethodExecution(newMethodExecution); + curMethodExecution.addStatement(curMethodInvocation); + curMethodInvocation = null; + } + newMethodExecution.setCaller(curMethodExecution, curMethodExecution.getStatements().size() - 1); + curMethodExecution = newMethodExecution; + } else { + addRoot(newMethodExecution); + } + } + + public void setArgments(ArrayList arguments) { + curMethodExecution.setArguments(arguments); + } + + public void returnMethod(ObjectReference returnValue, String thisObjId, boolean isCollectionType) { + if (curMethodExecution == null) return; + curMethodExecution.setReturnValue(returnValue); + if (curMethodExecution.getThisObjId().equals("0")) { + curMethodExecution.setThisObjeId(thisObjId); + } + curMethodExecution.setCollectionType(isCollectionType); + curMethodExecution = curMethodExecution.getParent(); + curMethodInvocation = null; // �O�̂��� + } + + public void returnMethod(ObjectReference returnValue, String thisObjId, boolean isCollectionType, long exitTime) { + if (curMethodExecution != null) curMethodExecution.setExitTime(exitTime); + returnMethod(returnValue, thisObjId, isCollectionType); + } + + public void terminateMethod() { + if (curMethodExecution == null) return; + curMethodExecution.setTerminated(true); + curMethodExecution = curMethodExecution.getParent(); + } + + public void fieldAccess(String valueClassName, String valueObjId, String containerClassName, String containerObjId, String thisClassName, String thisId) { + FieldAccess fieldAccess = new FieldAccess(valueClassName, valueObjId, containerClassName, containerObjId, thisClassName, thisId, 0, id); + if (curMethodExecution != null) curMethodExecution.addStatement(fieldAccess); + } + + public void fieldAccess(String valueClassName, String valueObjId, String containerClassName, String containerObjId, String thisClassName, String thisId, int lineNo, long timeStamp) { + FieldAccess fieldAccess = new FieldAccess(valueClassName, valueObjId, containerClassName, containerObjId, thisClassName, thisId, lineNo, id, timeStamp); + if (curMethodExecution != null) curMethodExecution.addStatement(fieldAccess); + } + + public void fieldAccess(String fieldName, String valueClassName, String valueObjId, String containerClassName, String containerObjId, String thisClassName, String thisId, int lineNo, long timeStamp) { + FieldAccess fieldAccess = new FieldAccess(fieldName, valueClassName, valueObjId, containerClassName, containerObjId, thisClassName, thisId, lineNo, id, timeStamp); + if (curMethodExecution != null) curMethodExecution.addStatement(fieldAccess); + } + + public void fieldUpdate(String valueClassName, String valueObjId, String containerClassName, String containerObjId) { + FieldUpdate fieldUpdate = new FieldUpdate(valueClassName, valueObjId, containerClassName, containerObjId, 0, id); + if (curMethodExecution != null) curMethodExecution.addStatement(fieldUpdate); + } + + public void fieldUpdate(String valueClassName, String valueObjId, String containerClassName, String containerObjId, int lineNo, long timeStamp) { + FieldUpdate fieldUpdate = new FieldUpdate(valueClassName, valueObjId, containerClassName, containerObjId, lineNo, id, timeStamp); + if (curMethodExecution != null) curMethodExecution.addStatement(fieldUpdate); + } + + public void fieldUpdate(String fieldName, String valueClassName, String valueObjId, String containerClassName, String containerObjId, int lineNo, long timeStamp) { + FieldUpdate fieldUpdate = new FieldUpdate(fieldName, valueClassName, valueObjId, containerClassName, containerObjId, lineNo, id, timeStamp); + if (curMethodExecution != null) curMethodExecution.addStatement(fieldUpdate); + } + + public void arrayCreate(String arrayClassName, String arrayObjectId, int dimension, int lineNo, long timeStamp) { + ArrayCreate arrayCreate = new ArrayCreate(arrayClassName, arrayObjectId, dimension, lineNo, id, timeStamp); + if (curMethodExecution != null) curMethodExecution.addStatement(arrayCreate); + } + + public void arraySet(String arrayClassName, String arrayObjectId, int index, String valueClassName, String valueObjectId, int lineNo, long timeStamp) { + ArrayUpdate arraySet = new ArrayUpdate(arrayClassName, arrayObjectId, index, valueClassName, valueObjectId, lineNo, id, timeStamp); + if (curMethodExecution != null) curMethodExecution.addStatement(arraySet); + } + + public void arrayGet(String arrayClassName, String arrayObjectId, int index, String valueClassName, String valueObjectId, int lineNo, long timeStamp) { + ArrayAccess arrayGet = new ArrayAccess(arrayClassName, arrayObjectId, index, valueClassName, valueObjectId, lineNo, id, timeStamp); + if (curMethodExecution != null) curMethodExecution.addStatement(arrayGet); + } + + public void blockEnter(int blockId, int incomings, int lineNo, long timeStamp) { + BlockEnter blockEnter = new BlockEnter(blockId, incomings, lineNo, id, timeStamp); + if (curMethodExecution != null) curMethodExecution.addStatement(blockEnter); + } + + public void traverseMethodExecutionsBackward(IMethodExecutionVisitor visitor) { + visitor.preVisitThread(this); + for (int i = 0; i < roots.size(); i++) { + MethodExecution root = roots.get(i); + root.traverseMethodExecutionsBackward(visitor); + } + visitor.postVisitThread(this); + } + + public void traverseMarkedMethodExecutions(IMethodExecutionVisitor visitor, long markStart, long markEnd) { + visitor.preVisitThread(this); + for (int i = 0; i < roots.size(); i++) { + MethodExecution root = roots.get(i); + if (root.getEntryTime() <= markEnd) { + root.traverseMarkedMethodExecutions(visitor, markStart, markEnd); + } else { + break; + } + } + visitor.postVisitThread(this); + } + + public void getUnmarkedMethodSignatures(HashSet signatures, long markStart, long markEnd) { + for (int i = 0; i < roots.size(); i++) { + MethodExecution root = roots.get(i); + root.getUnmarkedMethodSignatures(signatures, markStart, markEnd); + } + } + + public void getUnmarkedMethodExecutions(HashMap> executions, long markStart, long markEnd) { + for (int i = 0; i < roots.size(); i++) { + MethodExecution root = roots.get(i); + root.getUnmarkedMethodExecutions(executions, markStart, markEnd); + } + } + + public MethodExecution getCurrentMethodExecution() { + return curMethodExecution; + } + + public TracePoint getCurrentTracePoint() { + return new TracePoint(curMethodExecution, curMethodExecution.getStatements().size() - 1); + } + + public TracePoint getLastTracePoint() { + return roots.get(roots.size() - 1).getExitPoint(); + } +} diff --git a/src/org/ntlab/trace/Trace.java b/src/org/ntlab/trace/Trace.java index b46d7e4..c0308ad 100644 --- a/src/org/ntlab/trace/Trace.java +++ b/src/org/ntlab/trace/Trace.java @@ -1,1282 +1,1303 @@ -package org.ntlab.trace; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Stack; - -public class Trace { - protected static final boolean EAGER_DETECTION_OF_ARRAY_SET = false; // �z��v�f�ւ̑���̌��o�𑽂����ς��邩?(�������ς����False Positive�ɂȂ�”\��������) - protected static Trace theTrace = null; - protected HashMap threads = new HashMap(); - - protected Trace() { - } - - /** - * �w�肵��PlainText�̃g���[�X�t�@�C������ǂ��� Trace �I�u�W�F�N�g�𐶐����� - * @param file �g���[�X�t�@�C�� - */ - public Trace(BufferedReader file) { - try { - read(file); - file.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * �w�肵��PlainText�̃g���[�X�t�@�C������ǂ��� Trace �I�u�W�F�N�g�𐶐����� - * @param traceFile �g���[�X�t�@�C���̃p�X - */ - public Trace(String traceFile) { - BufferedReader file; - try { - file = new BufferedReader(new FileReader(traceFile)); - read(file); - file.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private void read(BufferedReader file) throws IOException { - // �g���[�X�t�@�C���ǂݍ��� - String line, prevLine = null; - String signature; - String callerSideSignature; - String threadNo = null; - String[] methodData; - String[] argData; - String[] returnData; - String[] accessData; - String[] updateData; - String thisObjectId; - String thisClassName; - boolean isConstractor = false; - boolean isCollectionType = false; - boolean isStatic = false; - long timeStamp = 0L; - ThreadInstance thread = null; - HashMap> stacks = new HashMap>(); - while ((line = file.readLine()) != null) { - // �g���[�X�t�@�C���̉�� - if (line.startsWith("Method")) { - // ���\�b�h�Ăяo���i�R���X�g���N�^�Ăяo�����܂ށj - methodData = line.split(":"); - int n = methodData[0].indexOf(','); - signature = methodData[0].substring(n + 1); - threadNo = methodData[methodData.length - 1].split(" ")[1]; - thisObjectId = methodData[1]; - thisClassName = methodData[0].substring(0, n).split(" ")[1]; - isConstractor = false; - isStatic = false; - if (signature.contains("static ")) { - isStatic = true; - } - callerSideSignature = signature; - timeStamp = Long.parseLong(methodData[methodData.length - 2]); - if (prevLine != null) { - if (prevLine.startsWith("New")) { - isConstractor = true; - } else if (prevLine.startsWith("Invoke")) { - callerSideSignature = prevLine.split(":")[1]; - } - } - thread = threads.get(threadNo); - Stack stack; - if (thread == null) { - thread = new ThreadInstance(threadNo); - threads.put(threadNo, thread); - stack = new Stack(); - stacks.put(threadNo, stack); - } else { - stack = stacks.get(threadNo); - } - stack.push(line); - thread.callMethod(signature, callerSideSignature, thisClassName, thisObjectId, isConstractor, isStatic, timeStamp); - } else if (line.startsWith("Args")) { - // ���\�b�h�Ăяo���̈��� - argData = line.split(":"); - threadNo = argData[argData.length - 1].split(" ")[1]; - thread = threads.get(threadNo); - ArrayList arguments = new ArrayList(); - for (int k = 1; k < argData.length - 2; k += 2) { - arguments.add(new ObjectReference(argData[k+1], argData[k])); - } - thread.setArgments(arguments); - } else if (line.startsWith("Return")) { - // ���\�b�h����̕��A - returnData = line.split(":"); - threadNo = returnData[returnData.length - 1].split(" ")[1]; - Stack stack = stacks.get(threadNo); - if (!stack.isEmpty()) { - String line2 = stack.peek(); - if (line2.split("\\(")[0].endsWith(line.split("\\(")[1])) { - stack.pop(); - } else { - do { - stack.pop(); - thread.terminateMethod(); - 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(Thread")) { - isCollectionType = true; - } - thread.returnMethod(returnValue, thisObjectId, isCollectionType); - } - } else if (line.startsWith("get")) { - // �t�B�[���h�A�N�Z�X - accessData = line.split(":"); - threadNo = accessData[8].split(" ")[1]; - thread = threads.get(threadNo); - if (thread != null) thread.fieldAccess(accessData[5], accessData[6], accessData[3], accessData[4], accessData[1], accessData[2]); - } else if (line.startsWith("set")) { - // �t�B�[���h�X�V - updateData = line.split(":"); - threadNo = updateData[6].split(" ")[1]; - thread = threads.get(threadNo); - if (thread != null) thread.fieldUpdate(updateData[3], updateData[4], updateData[1], updateData[2]); - } - prevLine = line; - } - } - - /** - * �I�����C����͗p�V���O���g���̎擾 - * @return �I�����C����͗p�g���[�X - */ - public static Trace getInstance() { - if (theTrace == null) { - theTrace = new Trace(); - } - return 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���擾����(�I�����C����͗p) - * @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���擾����(�I�����C����͗p) - * @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(); - } - - /** - * �S�X���b�h���擾���� - * @return �X���b�hID����X���b�h�C���X�^���X�ւ̃}�b�v - */ - public HashMap getAllThreads() { - return threads; - } - - /** - * ���\�b�h���ɑS���\�b�h���s��S�ẴX���b�h������o�� - * @return ���\�b�h�V�O�j�`�����烁�\�b�h���s�̃��X�g�ւ�HashMap - */ - public HashMap> getAllMethodExecutions() { - Iterator threadsIterator = threads.keySet().iterator(); - final HashMap> results = new HashMap<>(); - for (; threadsIterator.hasNext();) { - ThreadInstance thread = threads.get(threadsIterator.next()); - thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { - @Override - public boolean preVisitThread(ThreadInstance thread) { - return false; - } - @Override - public boolean preVisitMethodExecution(MethodExecution methodExecution) { - String signature = methodExecution.getSignature(); - ArrayList executions = results.get(signature); - if (executions == null) { - executions = new ArrayList<>(); - results.put(signature, executions); - } - executions.add(methodExecution); - return false; - } - @Override - public boolean postVisitThread(ThreadInstance thread) { - return false; - } - @Override - public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { - return false; - } - }); - } - return results; - } - - /** - * �S���\�b�h�̃V�O�j�`�����擾���� - * @return �S���\�b�h�V�O�j�`�� - */ - public HashSet getAllMethodSignatures() { - final HashSet signatures = new HashSet(); - Iterator threadsIterator = threads.keySet().iterator(); - for (; threadsIterator.hasNext();) { - ThreadInstance thread = threads.get(threadsIterator.next()); - thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { - @Override - public boolean preVisitThread(ThreadInstance thread) { - return false; - } - @Override - public boolean postVisitThread(ThreadInstance thread) { - return false; - } - @Override - public boolean preVisitMethodExecution(MethodExecution methodExecution) { - signatures.add(methodExecution.getSignature()); - return false; - } - @Override - public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { - return false; - } - }); - } - return signatures; - } - - /** - * ���\�b�h���� methodSignature�@�ɑO����v���郁�\�b�h���s��S�ẴX���b�h������o�� - * @param methodSignature ���������� - * @return ��v�����S���\�b�h���s - */ - public ArrayList getMethodExecutions(final String methodSignature) { - Iterator threadsIterator = threads.keySet().iterator(); - final ArrayList results = new ArrayList(); - for (; threadsIterator.hasNext();) { - ThreadInstance thread = threads.get(threadsIterator.next()); - thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { - @Override - public boolean preVisitThread(ThreadInstance thread) { - return false; - } - @Override - public boolean preVisitMethodExecution(MethodExecution methodExecution) { - if (methodExecution.getSignature().startsWith(methodSignature)) { - results.add(methodExecution); - } - return false; - } - @Override - public boolean postVisitThread(ThreadInstance thread) { - return false; - } - @Override - public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { - return false; - } - }); - } - return results; - } - - /** - * methodSignature �ɑO����v���郁�\�b�h�������ƒ��\�b�h�̍Ō�̎��s - * @param methodSignature ���\�b�h��(�O����v�Ō�������) - * @return �Y������Ō�̃��\�b�h���s - */ - public MethodExecution getLastMethodExecution(final String methodSignature) { - return traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() { - @Override - public boolean preVisitThread(ThreadInstance thread) { return false; } - @Override - public boolean postVisitThread(ThreadInstance thread) { return false; } - @Override - public boolean preVisitMethodExecution(MethodExecution methodExecution) { return false; } - @Override - public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { - if (methodExecution.getSignature().startsWith(methodSignature)) return true; - return false; - } - }); - } - - /** - * methodSignature �ɑO����v���郁�\�b�h�������ƒ��\�b�h�� before �ȑO�̍Ō�̎��s - * @param methodSignature ���\�b�h��(�O����v�Ō�������) - * @param before�@�T���J�n�g���[�X�|�C���g(������ȑO��T��) - * @return�@�Y������Ō�̃��\�b�h���s - */ - public MethodExecution getLastMethodExecution(final String methodSignature, TracePoint before) { - return traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() { - @Override - public boolean preVisitThread(ThreadInstance thread) { return false; } - @Override - public boolean postVisitThread(ThreadInstance thread) { return false; } - @Override - public boolean preVisitMethodExecution(MethodExecution methodExecution) { return false; } - @Override - public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { - if (methodExecution.getSignature().startsWith(methodSignature)) return true; - return false; - } - }, before); - } - - /** - * �}�[�N���Ŏ��s���J�n���ꂽ�S���\�b�h�̃V�O�j�`�����擾���� - * @param markStart �}�[�N�̊J�n���� - * @param markEnd �}�[�N�̏I������ - * @return �Y�����郁�\�b�h�V�O�j�`�� - */ - public HashSet getMarkedMethodSignatures(final long markStart, final long markEnd) { - final HashSet signatures = new HashSet(); - Iterator threadsIterator = threads.keySet().iterator(); - for (; threadsIterator.hasNext();) { - ThreadInstance thread = threads.get(threadsIterator.next()); - thread.traverseMarkedMethodExecutions(new IMethodExecutionVisitor() { - @Override - public boolean preVisitThread(ThreadInstance thread) { - return false; - } - @Override - public boolean postVisitThread(ThreadInstance thread) { - return false; - } - @Override - public boolean preVisitMethodExecution(MethodExecution methodExecution) { - signatures.add(methodExecution.getSignature()); - return false; - } - @Override - public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { - return false; - } - }, markStart, markEnd); - } - return signatures; - } - - /** - * �}�[�N���Ŏ��s���J�n���ꂽ�S���\�b�h���s�����\�b�h���Ɏ擾���� - * @param markStart �}�[�N�̊J�n���� - * @param markEnd �}�[�N�̏I������ - * @return ���\�b�h�V�O�j�`������Y�����郁�\�b�h���s�̃��X�g�ւ�HashMap - */ - public HashMap> getMarkedMethodExecutions(final long markStart, final long markEnd) { - final HashMap>allExecutions = new HashMap<>(); - Iterator threadsIterator = threads.keySet().iterator(); - for (; threadsIterator.hasNext();) { - ThreadInstance thread = threads.get(threadsIterator.next()); - thread.traverseMarkedMethodExecutions(new IMethodExecutionVisitor() { - @Override - public boolean preVisitThread(ThreadInstance thread) { - return false; - } - @Override - public boolean postVisitThread(ThreadInstance thread) { - return false; - } - @Override - public boolean preVisitMethodExecution(MethodExecution methodExecution) { - ArrayList executions = allExecutions.get(methodExecution.getSignature()); - if (executions == null) { - executions = new ArrayList<>(); - allExecutions.put(methodExecution.getSignature(), executions); - } - executions.add(methodExecution); - return false; - } - @Override - public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { - return false; - } - }, markStart, markEnd); - } - return allExecutions; - } - - /** - * �}�[�N�O�Ŏ��s���J�n���ꂽ�S���\�b�h�̃V�O�j�`�����擾���� - * @param markStart �}�[�N�̊J�n���� - * @param markEnd �}�[�N�̏I������ - * @return �Y�����郁�\�b�h�V�O�j�`�� - */ - public HashSet getUnmarkedMethodSignatures(long markStart, long markEnd) { - HashSet signatures = new HashSet(); - Iterator threadsIterator = threads.keySet().iterator(); - for (; threadsIterator.hasNext();) { - ThreadInstance thread = threads.get(threadsIterator.next()); - thread.getUnmarkedMethodSignatures(signatures, markStart, markEnd); - } - return signatures; - } - - /** - * �}�[�N�O�Ŏ��s���J�n���ꂽ�S���\�b�h���s���擾���� - * @param markStart �}�[�N�̊J�n���� - * @param markEnd �}�[�N�̏I������ - * @return ���\�b�h�V�O�j�`������Y�����郁�\�b�h���s�̃��X�g�ւ�HashMap - */ - public HashMap> getUnmarkedMethodExecutions(long markStart, long markEnd) { - HashMap> executions = new HashMap<>(); - Iterator threadsIterator = threads.keySet().iterator(); - for (; threadsIterator.hasNext();) { - ThreadInstance thread = threads.get(threadsIterator.next()); - thread.getUnmarkedMethodExecutions(executions, markStart, markEnd); - } - return executions; - } - - - protected TracePoint getLastMethodEntryInThread(ArrayList rootExecutions) { - MethodExecution lastExecution = rootExecutions.remove(rootExecutions.size() - 1); - return getLastMethodEntryInThread(rootExecutions, lastExecution.getExitOutPoint()); - } - - protected TracePoint getLastMethodEntryInThread(ArrayList rootExecutions, TracePoint start) { - return getLastMethodEntryInThread(rootExecutions, start, -1L); - } - - /** - * - * @param rootExecutions - * @param start - * @param before - * @return - */ - protected TracePoint getLastMethodEntryInThread(ArrayList rootExecutions, TracePoint start, final long before) { - final TracePoint cp[] = new TracePoint[1]; - cp[0] = start; - for (;;) { - if (!cp[0].isStepBackOut() && traverseMethodExecutionsInCallTreeBackward ( - new IMethodExecutionVisitor() { - @Override - public boolean preVisitThread(ThreadInstance thread) { return false; } - @Override - public boolean preVisitMethodExecution(MethodExecution methodExecution) { return false; } - @Override - public boolean postVisitThread(ThreadInstance thread) { return false; } - @Override - public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { - if (methodExecution.getEntryTime() < before || before == -1L) { - cp[0] = methodExecution.getEntryPoint(); - return true; - } - return false; - } - }, cp[0])) { - return cp[0]; - } - if (rootExecutions.size() == 0) break; - MethodExecution lastExecution = rootExecutions.remove(rootExecutions.size() - 1); - cp[0] = lastExecution.getExitOutPoint(); - } - return null; - } - - public boolean getLastStatementInThread(String threadId, final TracePoint[] start, final IStatementVisitor visitor) { - return getLastStatementInThread((ArrayList) threads.get(threadId).getRoot().clone(), start, start[0].getStatement().getTimeStamp(), visitor); - } - - protected boolean getLastStatementInThread(ArrayList rootExecutions, final TracePoint[] start, final long before, final IStatementVisitor visitor) { - final boolean[] bArrived = new boolean[] { - false - }; - for (;;) { - if (start[0].isValid() && traverseStatementsInCallTreeBackward( - new IStatementVisitor() { - @Override - public boolean preVisitStatement(Statement statement) { - if (statement instanceof MethodInvocation) { - MethodExecution methodExecution = ((MethodInvocation) statement).getCalledMethodExecution(); - if ((!methodExecution.isTerminated() && methodExecution.getExitTime() < before) || before == -1L) { - if (visitor.preVisitStatement(statement)) return true; - bArrived[0] = true; - return true; - } - } else { - if (statement.getTimeStamp() < before || before == -1L) { - if (visitor.preVisitStatement(statement)) return true; - bArrived[0] = true; - return true; - } - } - return visitor.preVisitStatement(statement); - } - @Override - public boolean postVisitStatement(Statement statement) { - return visitor.postVisitStatement(statement); - } - }, start[0])) { - return !bArrived[0]; - } - if (rootExecutions.size() == 0) break; - MethodExecution lastExecution = rootExecutions.remove(rootExecutions.size() - 1); - start[0] = lastExecution.getExitPoint(); - } - start[0] = null; - return false; - } - - public TracePoint getCreationTracePoint(final ObjectReference newObjectId, TracePoint before) { - before = before.duplicate(); - before = traverseStatementsInTraceBackward( - new IStatementVisitor() { - @Override - public boolean preVisitStatement(Statement statement) { - if (statement instanceof MethodInvocation) { - MethodInvocation mi = (MethodInvocation)statement; - if (mi.getCalledMethodExecution().isConstructor() - && mi.getCalledMethodExecution().getReturnValue().equals(newObjectId)) { - return true; - } - } - return false; - } - @Override - public boolean postVisitStatement(Statement statement) { return false; } - }, before); - if (before != null) { - return before; - } - return null; - } - - public TracePoint getFieldUpdateTracePoint(final Reference ref, TracePoint before) { - before = before.duplicate(); - final String srcType = ref.getSrcClassName(); - final String dstType = ref.getDstClassName(); - final String srcObjId = ref.getSrcObjectId(); - final String dstObjId = ref.getDstObjectId(); - - before = traverseStatementsInTraceBackward(new IStatementVisitor() { - @Override - public boolean preVisitStatement(Statement statement) { - if (statement instanceof FieldUpdate) { - FieldUpdate fu = (FieldUpdate)statement; - if (fu.getContainerObjId().equals(srcObjId) - && fu.getValueObjId().equals(dstObjId)) { - // �I�u�W�F�N�gID���݂��Ɉ�v�����ꍇ - return true; - } else if ((srcObjId == null || isNull(srcObjId)) && fu.getContainerClassName().equals(srcType)) { - if ((dstObjId == null || isNull(dstObjId)) && fu.getValueClassName().equals(dstType)) { - // ref �ɃI�u�W�F�N�gID���w�肵�Ă��Ȃ������ꍇ - ref.setSrcObjectId(fu.getContainerObjId()); - ref.setDstObjectId(fu.getValueObjId()); - return true; - } else if (fu.getValueObjId().equals(dstObjId)) { - // �N���X�ϐ��ւ̑���̏ꍇ - ref.setSrcObjectId(srcObjId); - ref.setDstClassName(dstType); - return true; - } - } - } - return false; - } - @Override - public boolean postVisitStatement(Statement statement) { return false; } - }, before); - if (before != null) { - return before; - } - return null; - } - - public TracePoint getCollectionAddTracePoint(final Reference ref, TracePoint before) { - final TracePoint[] result = new TracePoint[1]; - if (traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() { - @Override - public boolean preVisitThread(ThreadInstance thread) { - return false; - } - @Override - public boolean postVisitThread(ThreadInstance thread) { - return false; - } - @Override - public boolean preVisitMethodExecution(MethodExecution methodExecution) { - return false; - } - @Override - public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { - String srcType = ref.getSrcClassName(); - String dstType = ref.getDstClassName(); - String srcObjId = ref.getSrcObjectId(); - String dstObjId = ref.getDstObjectId(); - if (methodExecution.isCollectionType() && isCollectionAdd(methodExecution.getSignature())) { - if (dstObjId != null && methodExecution.getThisObjId().equals(srcObjId)) { - ArrayList args = methodExecution.getArguments(); - for (int i = 0; i < args.size(); i++) { - ObjectReference arg = args.get(i); - if (arg.getId().equals(dstObjId)) { - ref.setSrcClassName(methodExecution.getThisClassName()); - ref.setDstClassName(arg.getActualType()); - result[0] = methodExecution.getCallerTracePoint(); - return true; - } - } - } else if (dstObjId == null && methodExecution.getThisClassName().equals(srcType)) { - ArrayList args = methodExecution.getArguments(); - for (int i = 0; i < args.size(); i++) { - ObjectReference arg = args.get(i); - if (arg.getActualType().equals(dstType)) { - ref.setSrcObjectId(methodExecution.getThisObjId()); - ref.setDstObjectId(arg.getId()); - result[0] = methodExecution.getCallerTracePoint(); - return true; - } - } - } - } - return false; - } - }, before) != null) { - return result[0]; - } - return null; - } - - public TracePoint getArraySetTracePoint(final Reference ref, TracePoint before) { - final TracePoint start = before.duplicate(); - before = traverseStatementsInTraceBackward(new IStatementVisitor() { - @Override - public boolean preVisitStatement(Statement statement) { - if (statement instanceof FieldAccess) { - if (isArraySet(ref, start)) { - return true; - } - } - return false; - } - @Override - public boolean postVisitStatement(Statement statement) { return false; } - }, start); - if (before != null) { - return before; - } - return null; - } - - private boolean isCollectionAdd(String methodSignature) { - return (methodSignature.contains("add(") || methodSignature.contains("set(") || methodSignature.contains("put(") || methodSignature.contains("push(")); - } - - private boolean isArraySet(Reference ref, TracePoint fieldAccessPoint) { - FieldAccess fieldAccess = (FieldAccess)fieldAccessPoint.getStatement(); - String srcObjId = ref.getSrcObjectId(); - String dstObjId = ref.getDstObjectId(); - if (fieldAccess.getValueClassName().startsWith("[L") - && fieldAccess.getValueObjId().equals(srcObjId)) { - // srcId �͔z�� - // ���\�b�h���s�J�n���� fieldAccessPoint �܂ł̊Ԃ̃��\�b�h���s���� dstId ���o��������? - TracePoint p = fieldAccessPoint.duplicate(); - while (p.stepBackOver()) { - Statement statement = p.getStatement(); - if (statement instanceof MethodInvocation) { - MethodExecution calledMethod = ((MethodInvocation)statement).getCalledMethodExecution(); - if (calledMethod.getReturnValue().getId().equals(dstObjId)) { - // dstId �͖߂�l�Ƃ��ďo�� - ref.setSrcClassName(fieldAccess.getValueClassName()); - ref.setDstClassName(calledMethod.getReturnValue().getActualType()); - return true; - } else if (dstObjId == null || isNull(dstObjId) && calledMethod.getReturnValue().getActualType().equals(ref.getDstClassName())) { - // dstClassName �͖߂�l�̌^�Ƃ��ďo�� - ref.setSrcObjectId(fieldAccess.getValueObjId()); - ref.setDstObjectId(calledMethod.getReturnValue().getId()); - return true; - } - } - if (EAGER_DETECTION_OF_ARRAY_SET) { - if (statement instanceof FieldAccess) { - if (((FieldAccess)statement).getContainerObjId().equals(dstObjId)) { - // dstId �̓t�B�[���h�ɏo�� - ref.setSrcClassName(fieldAccess.getValueClassName()); - ref.setDstClassName(((FieldAccess)statement).getContainerClassName()); - return true; - } else if (dstObjId == null || isNull(dstObjId) && ((FieldAccess)statement).getContainerClassName().equals(ref.getDstClassName())) { - // dstClassName �̓t�B�[���h�̌^�Ƃ��ďo�� - ref.setSrcObjectId(fieldAccess.getValueObjId()); - ref.setDstObjectId(((FieldAccess)statement).getContainerObjId()); - return true; - } - } - } - } - ArrayList args = fieldAccessPoint.getMethodExecution().getArguments(); - int argindex = args.indexOf(new ObjectReference(dstObjId)); - if (argindex != -1) { - // dstId �͈����ɏo�� - ref.setSrcClassName(fieldAccess.getValueClassName()); - ref.setDstClassName(args.get(argindex).getActualType()); - return true; - } else if (dstObjId == null || isNull(dstObjId)) { - for (int j = 0; j < args.size(); j++) { - if (args.get(j).getActualType().equals(ref.getDstClassName())) { - // dstClassName �͈����̌^�ɏo�� - ref.setSrcObjectId(fieldAccess.getValueObjId()); - ref.setDstObjectId(args.get(j).getId()); - return true; - } - } - } - } - return false; - } - - /** - * �g���[�X���̑S���\�b�h���s�̊J�n�n�_���t�����ɒT������ - * @param visitor ���\�b�h���s�̃r�W�^�[(postVisitMethodExecution()�����ĂѕԂ��Ȃ��̂Œ���) - * @return ���f�������\�b�h���s - */ - public MethodExecution traverseMethodEntriesInTraceBackward(IMethodExecutionVisitor 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 rootExecutions = (ArrayList)thread.getRoot().clone(); - threadRoots.put(threadId, rootExecutions); - TracePoint threadLastTp = getLastMethodEntryInThread(rootExecutions); - threadLastPoints.put(threadId, threadLastTp); - if (threadLastTp != null) { - long threadLastTime = threadLastTp.getMethodExecution().getEntryTime(); - if (traceLastTime < threadLastTime) { - traceLastTime2 = traceLastTime; - traceLastThread2 = traceLastThread; - traceLastTime = threadLastTime; - traceLastThread = threadId; - } - } - } - return traverseMethodEntriesInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); - } - - /** - * �w�肵�����s���_�ȑO�Ɏ��s���J�n���ꂽ���\�b�h���s�̊J�n���_���t�����ɒT������ - * @param visitor ���\�b�h���s�̃r�W�^�[(postVisitMethodExecution()�����ĂѕԂ��Ȃ��̂Œ���) - * @param before �T���J�n���_ - * @return ���f�������\�b�h���s - */ - public MethodExecution traverseMethodEntriesInTraceBackward(IMethodExecutionVisitor visitor, TracePoint before) { - HashMap> threadRoots = new HashMap>(); - HashMap threadLastPoints = new HashMap(); - String traceLastThread = null; - long traceLastTime2 = 0; - String traceLastThread2 = null; - ThreadInstance thread = threads.get(before.getStatement().getThreadNo()); - ArrayList rootExecutions = (ArrayList)thread.getRoot().clone(); - for (int n = rootExecutions.size() - 1; n >= 0; n--) { - MethodExecution root = rootExecutions.get(n); - if (root.getEntryTime() > before.getMethodExecution().getEntryTime()) { - rootExecutions.remove(n); - } else { - break; - } - } - if (rootExecutions.size() > 0) { - rootExecutions.remove(rootExecutions.size() - 1); - } - before = getLastMethodEntryInThread(rootExecutions, before); - for (String threadId: threads.keySet()) { - ThreadInstance t = threads.get(threadId); - if (t == thread) { - threadRoots.put(threadId, rootExecutions); - traceLastThread = threadId; - threadLastPoints.put(threadId, before); - } else { - ArrayList rootExes = (ArrayList)t.getRoot().clone(); - threadRoots.put(threadId, rootExes); - MethodExecution threadLastExecution = rootExes.remove(rootExes.size() - 1); - TracePoint threadBeforeTp = getLastMethodEntryInThread(rootExes, threadLastExecution.getExitOutPoint(), before.getMethodExecution().getEntryTime()); - threadLastPoints.put(threadId, threadBeforeTp); - if (threadBeforeTp != null) { - long threadLastTime = threadBeforeTp.getMethodExecution().getEntryTime(); - if (traceLastTime2 < threadLastTime) { - traceLastTime2 = threadLastTime; - traceLastThread2 = threadId; - } - } - } - } - return traverseMethodEntriesInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); - } - - private MethodExecution traverseMethodEntriesInTraceBackwardSub( - final IMethodExecutionVisitor visitor, - HashMap> threadRoots, HashMap threadLastPoints, - String traceLastThread, String traceLastThread2, long traceLastTime2) { - // �S�X���b�h�̓������Ƃ�Ȃ���t�����Ƀ��\�b�h���s��T������ - for (;;) { - // �T���Ώۂ̃X���b�h���̋t�����T�� - TracePoint threadLastTp = threadLastPoints.get(traceLastThread); - MethodExecution threadLastExecution = threadLastTp.getMethodExecution(); - do { - threadLastTp.stepBackOver(); - // ���̃X���b�h�̎��̃��\�b�h���s�J�n���_�܂ŒT������ - threadLastTp = getLastMethodEntryInThread(threadRoots.get(traceLastThread), threadLastTp); - if (threadLastTp == null) break; - if (visitor.postVisitMethodExecution(threadLastExecution, threadLastExecution.getChildren())) { - // �Y�����郁�\�b�h���s�����‚��� - return threadLastExecution; - } - threadLastExecution = threadLastTp.getMethodExecution(); - } while (threadLastExecution.getEntryTime() > traceLastTime2); - threadLastPoints.put(traceLastThread, threadLastTp); - traceLastThread = traceLastThread2; - // ���̎��ɒT�����ׂ��X���b�h(���T���̗̈悪��ԍŌ�܂Ŏc���Ă���X���b�h)�����肷�� - traceLastTime2 = 0; - traceLastThread2 = null; - boolean continueTraverse = false; - for (String threadId: threadLastPoints.keySet()) { - if (!threadId.equals(traceLastThread)) { - TracePoint lastTp = threadLastPoints.get(threadId); - if (lastTp != null) { - continueTraverse = true; - long threadLastTime = lastTp.getMethodExecution().getEntryTime(); - if (traceLastTime2 < threadLastTime) { - traceLastTime2 = threadLastTime; - traceLastThread2 = threadId; - } - } - } - } - if (!continueTraverse && threadLastPoints.get(traceLastThread) == null) break; - } - return null; - } - - /** - * �Ăяo�����̎����� markStart ���� markEnd �̊Ԃɂ���S�X���b�h���̑S���\�b�h���s��T������ - * @param visitor�@�r�W�^�[ - * @param markStart �J�n���� - * @param markEnd �I������ - */ - public void traverseMarkedMethodExecutions(IMethodExecutionVisitor visitor, long markStart, long markEnd) { - for (String threadId: threads.keySet()) { - ThreadInstance thread = threads.get(threadId); - thread.traverseMarkedMethodExecutions(visitor, markStart, markEnd); - } - } - - /** - * �g���[�X���̑S�X���b�h�𓯊������Ȃ炪�S���s�����������ɒT������ - * - * @param visitor ���s���̃r�W�^�[ - * @return ���f�����g���[�X�|�C���g - */ - public TracePoint traverseStatementsInTrace(IStatementVisitor visitor) { - HashMap> threadRoots = new HashMap>(); - HashMap threadCurPoints = new HashMap(); - // �e�X���b�h�ɂ����Ĉ�ԍŏ��ɊJ�n�������\�b�h���s��T�� - long traceCurTime = -1; - String traceCurThread = null; - long traceCurTime2 = -1; - String traceCurThread2 = null; - for (String threadId: threads.keySet()) { - ThreadInstance thread = threads.get(threadId); - ArrayList roots = (ArrayList)thread.getRoot().clone(); - threadRoots.put(threadId, roots); - TracePoint threadCurTp; - do { - MethodExecution threadCurExecution = roots.remove(0); - threadCurTp = threadCurExecution.getEntryPoint(); - } while (!threadCurTp.isValid() && roots.size() > 0); - if (threadCurTp.isValid()) { - threadCurPoints.put(threadId, threadCurTp); - long methodEntry = threadCurTp.getMethodExecution().getEntryTime(); - if (traceCurTime == -1 || traceCurTime > methodEntry) { - traceCurTime2 = traceCurTime; - traceCurThread2 = traceCurThread; - traceCurTime = methodEntry; - traceCurThread = threadId; - } - } else { - threadCurPoints.put(threadId, null); - } - } - return traverseStatementsInTraceSub(visitor, threadRoots, threadCurPoints, traceCurThread, traceCurThread2, traceCurTime2); - } - - private TracePoint traverseStatementsInTraceSub(IStatementVisitor visitor, - HashMap> threadRoots, - HashMap threadCurPoints, - String curThreadId, String nextThreadId, long nextThreadTime) { - // �S�X���b�h�̓������Ƃ�Ȃ��珇�����Ɏ��s����T������ - for (;;) { - // �T���Ώۂ̃X���b�h���̏������T�� - TracePoint curTp = threadCurPoints.get(curThreadId); - 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; - } - curTp.stepNoReturn(); // ���A�����ɌĂяo���؂�����Ă��� - if (!curTp.isValid()) { - // ���A���Ȃ��Ƃ���ȏ�T���ł��Ȃ� - 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; - } else { - // �Ăяo���؂̊J�n���_�܂ŒT�����I�����ꍇ - ArrayList roots = threadRoots.get(curThreadId); - while (!curTp.isValid() && roots.size() > 0) { - // ���̌Ăяo���؂�����΂�����ŏ�����T�� - MethodExecution firstExecution = roots.remove(0); - curTp = firstExecution.getEntryPoint(); - } - if (curTp.isValid()) { - // ���̌Ăяo���؂�����΂�����ŏ�����T�� - threadCurPoints.put(curThreadId, curTp); - } else { - // ���̃X���b�h�̒T�������ׂďI�������ꍇ - threadCurPoints.put(curThreadId, null); - curTp = null; - } - break; - } - } - } - } - curThreadId = nextThreadId; - if (curThreadId == null) break; - // ���̎��ɒT�����ׂ��X���b�h(���T���̗̈悪��ԍŏ��Ɏn�܂�X���b�h)�����肷�� - nextThreadTime = -1; - nextThreadId = null; - boolean continueTraverse = false; - for (String threadId: threadCurPoints.keySet()) { - if (!threadId.equals(curThreadId)) { - TracePoint threadTp = threadCurPoints.get(threadId); - if (threadTp != null) { - continueTraverse = true; - long threadTime = threadTp.getStatement().getTimeStamp(); - if (threadTime > 0 && (nextThreadTime == -1 || nextThreadTime > threadTime)) { - nextThreadTime = threadTime; - nextThreadId = threadId; - } - } - } - } - if (!continueTraverse && threadCurPoints.get(curThreadId) == null) break; - } - return null; - } - - /** - * �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 root = (ArrayList)thread.getRoot().clone(); - threadRoots.put(threadId, root); - TracePoint threadLastTp; - do { - MethodExecution threadLastExecution = root.remove(root.size() - 1); - threadLastTp = threadLastExecution.getExitPoint(); - } while (!threadLastTp.isValid() && root.size() > 0); - if (threadLastTp.isValid()) { - threadLastPoints.put(threadId, threadLastTp); - if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, threadLastTp)) return threadLastTp; - long methodEntry = threadLastTp.getMethodExecution().getEntryTime(); - if (traceLastTime < methodEntry) { - traceLastTime2 = traceLastTime; - traceLastThread2 = traceLastThread; - traceLastTime = methodEntry; - traceLastThread = threadId; - } - } else { - threadLastPoints.put(threadId, null); - } - } - return traverseStatementsInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); - } - - /** - * - * @param visitor - * @param before - * @return - */ - public TracePoint traverseStatementsInTraceBackward(IStatementVisitor visitor, TracePoint before) { - if (before == null) { - return traverseStatementsInTraceBackward(visitor); - } - if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, before)) return before; - 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.getMethodExecution().getEntryTime()) { - rootExecutions.remove(n); - } else { - break; - } - } - if (rootExecutions.size() > 0) { - rootExecutions.remove(rootExecutions.size() - 1); - } - } else { - MethodExecution threadLastExecution = rootExecutions.remove(rootExecutions.size() - 1); - TracePoint threadBeforeTp = getLastMethodEntryInThread(rootExecutions, threadLastExecution.getExitOutPoint(), before.getMethodExecution().getEntryTime()); - threadLastPoints.put(threadId, threadBeforeTp); - if (threadBeforeTp != null) { - long threadLastTime = threadBeforeTp.getMethodExecution().getEntryTime(); - if (traceLastTime2 < threadLastTime) { - traceLastTime2 = threadLastTime; - traceLastThread2 = threadId; - } - } - } - } - return traverseStatementsInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); - } - - private TracePoint traverseStatementsInTraceBackwardSub(IStatementVisitor visitor, - HashMap> threadRoots, - HashMap threadLastPoints, - String traceLastThread, String traceLastThread2, long traceLastTime2) { - // �S�X���b�h�̓������Ƃ�Ȃ���t�����Ɏ��s����T������ - for (;;) { - // �T���Ώۂ̃X���b�h���̋t�����T�� - TracePoint lastTp = threadLastPoints.get(traceLastThread); - do { - if (lastTp.stepBackOver()) { - // ���̃X���b�h�̎��̃��\�b�h���s�J�n���_�܂ŒT������ - if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, lastTp)) return lastTp; - } else { - // �Ăяo�����ɖ߂����ꍇ - if (lastTp.isValid()) { - if (visitor.postVisitStatement(lastTp.getStatement())) return lastTp; - } else { - // �Ăяo���؂̊J�n���_�܂ŒT�����I�����ꍇ - ArrayList root = threadRoots.get(traceLastThread); - while (!lastTp.isValid() && root.size() > 0) { - // ���̌Ăяo���؂�����΂�����Ōォ��T�� - MethodExecution lastExecution = root.remove(root.size() - 1); - lastTp = lastExecution.getExitPoint(); - } - if (lastTp.isValid()) { - // ���̌Ăяo���؂�����΂�����Ōォ��T�� - threadLastPoints.put(traceLastThread, lastTp); - if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, lastTp)) return lastTp; - } else { - // ���̃X���b�h�̒T�������ׂďI�������ꍇ - threadLastPoints.put(traceLastThread, null); - break; - } - } - } - } while (lastTp.getMethodExecution().getEntryTime() >= traceLastTime2); - traceLastThread = traceLastThread2; - // ���̎��ɒT�����ׂ��X���b�h(���T���̗̈悪��ԍŌ�܂Ŏc���Ă���X���b�h)�����肷�� - traceLastTime2 = 0; - traceLastThread2 = null; - boolean continueTraverse = false; - for (String threadId: threadLastPoints.keySet()) { - if (!threadId.equals(traceLastThread)) { - TracePoint threadLastTp = threadLastPoints.get(threadId); - if (threadLastTp != null) { - continueTraverse = true; - long threadLastTime = threadLastTp.getMethodExecution().getEntryTime(); - if (traceLastTime2 < threadLastTime) { - traceLastTime2 = threadLastTime; - traceLastThread2 = threadId; - } - } - } - } - if (!continueTraverse && threadLastPoints.get(traceLastThread) == null) break; - } - return null; - } - - /** - * before �Ŏw�肵���g���[�X�|�C���g�ȑO�̓���Ăяo���ؓ��̑S���s�����t�����ɒT������(�������Avisitor �� true ��Ԃ��܂�) - * @param visitor �r�W�^�[ - * @param before �T���̊J�n�_(�T���ΏۃX���b�h���w�肵�Ă���) - * @return true -- �T���𒆒f����, false -- �Ō�܂ŒT������ - */ - public boolean traverseStatementsInCallTreeBackward(IStatementVisitor visitor, TracePoint before) { - for (;;) { - if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, before)) return true; - while (!before.stepBackOver()) { - if (!before.isValid()) break; - if (visitor.postVisitStatement(before.getStatement())) return true; - } - if (!before.isValid()) break; - } - return false; - } - - /** - * before�ȑO�̌Ăяo���؂��Ăяo���悩��̕��A�������ɍs����Ƃ���܂ŋt�����ɒT������ - * - * @param visitor ���s���̃r�W�^�[ - * @param before �T���J�n���s���_ - * @return true -- �T���𒆒f����, false -- ���A�����Ȃ����肱��ȏ�i�߂Ȃ� - */ - private boolean traverseStatamentsInCallTreeBackwardNoReturn(IStatementVisitor visitor, TracePoint before) { - for (;;) { - Statement statement = before.getStatement(); - if (statement instanceof MethodInvocation) { - // ���\�b�h�Ăяo�����̏ꍇ�́A�Ăяo���̑O��� preVisit �� postVisit ��ʁX�Ɏ��s���� - if (visitor.preVisitStatement(statement)) return true; - before.stepBackNoReturn(); - if (!before.isValid()) { - // �Ăяo����̃��\�b�h�Ŏ��s�����L�^����Ă��Ȃ��ꍇ - before.stepBackOver(); - if (visitor.postVisitStatement(statement)) return true; - if (before.isMethodEntry()) return false; - before.stepBackOver(); - } - } else { - if (visitor.preVisitStatement(statement)) return true; - if (visitor.postVisitStatement(statement)) return true; - if (before.isMethodEntry()) return false; - before.stepBackNoReturn(); - } - } - } - - /** - * before �Ŏw�肵���g���[�X�|�C���g�ȑO�̓���X���b�h���̑S���\�b�h���s���Ăяo���؂̒��ŋt�����ɒT������(�������Avisitor �� true ��Ԃ��܂�) - * @param visitor �r�W�^�[ - * @param before �T���̊J�n�_(�T���ΏۃX���b�h���w�肵�Ă���) - * @return true -- �T���𒆒f����, false -- �Ō�܂ŒT������ - */ - public boolean traverseMethodExecutionsInCallTreeBackward(IMethodExecutionVisitor visitor, TracePoint before) { - ArrayList prevMethodExecutions = before.getPreviouslyCalledMethods(); - for (int i = prevMethodExecutions.size() - 1; i >= 0; i--) { - MethodExecution child = prevMethodExecutions.get(i); - if (child.traverseMethodExecutionsBackward(visitor)) return true; - } - MethodExecution methodExecution = before.getMethodExecution(); - if (visitor.postVisitMethodExecution(methodExecution, null)) return true; - TracePoint caller = methodExecution.getCallerTracePoint(); - if (caller != null) { - if (traverseMethodExecutionsInCallTreeBackward(visitor, caller)) return true; - } - return false; - } - - public static String getDeclaringType(String methodSignature, boolean isConstructor) { - if (methodSignature == null) return null; - if (isConstructor) { - String[] fragments = methodSignature.split("\\("); - return fragments[0].substring(fragments[0].lastIndexOf(' ') + 1); - } - String[] fragments = methodSignature.split("\\("); - return fragments[0].substring(fragments[0].lastIndexOf(' ') + 1, fragments[0].lastIndexOf('.')); - } - - public static String getMethodName(String methodSignature) { - String[] fragments = methodSignature.split("\\("); - String[] fragments2 = fragments[0].split("\\."); - return fragments2[fragments2.length - 1]; - } - - public static String getReturnType(String methodSignature) { - String[] fragments = methodSignature.split(" "); - for (int i = 0; i < fragments.length; i++) { - if (!fragments[i].equals("public") && !fragments[i].equals("private") && !fragments[i].equals("protected") - && !fragments[i].equals("abstract") && !fragments[i].equals("final") && !fragments[i].equals("static") - && !fragments[i].equals("synchronized") && !fragments[i].equals("native")) { - return fragments[i]; - } - } - return ""; - } - - public static boolean isNull(String objectId) { - return objectId.equals("0"); - } - - public static String getNull() { - return "0"; - } - - public static boolean isPrimitive(String typeName) { - if (typeName.equals("int") - || typeName.equals("boolean") - || typeName.equals("long") - || typeName.equals("double") - || typeName.equals("float") - || typeName.equals("char") - || typeName.equals("byte") - || typeName.equals("java.lang.Integer") - || typeName.equals("java.lang.Boolean") - || typeName.equals("java.lang.Long") - || typeName.equals("java.lang.Double") - || typeName.equals("java.lang.Float") - || typeName.equals("java.lang.Character") - || typeName.equals("java.lang.Byte")) return true; - return false; - } -} +package org.ntlab.trace; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Stack; + +public class Trace { + protected static final boolean EAGER_DETECTION_OF_ARRAY_SET = false; // �z��v�f�ւ̑���̌��o�𑽂����ς��邩?(�������ς����False Positive�ɂȂ�”\��������) + protected static Trace theTrace = null; + protected HashMap threads = new HashMap(); + + protected Trace() { + } + + /** + * �w�肵��PlainText�̃g���[�X�t�@�C������ǂ��� Trace �I�u�W�F�N�g�𐶐����� + * @param file �g���[�X�t�@�C�� + */ + public Trace(BufferedReader file) { + try { + read(file); + file.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * �w�肵��PlainText�̃g���[�X�t�@�C������ǂ��� Trace �I�u�W�F�N�g�𐶐����� + * @param traceFile �g���[�X�t�@�C���̃p�X + */ + public Trace(String traceFile) { + BufferedReader file; + try { + file = new BufferedReader(new FileReader(traceFile)); + read(file); + file.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void read(BufferedReader file) throws IOException { + // �g���[�X�t�@�C���ǂݍ��� + String line, prevLine = null; + String signature; + String callerSideSignature; + String threadNo = null; + String[] methodData; + String[] argData; + String[] returnData; + String[] accessData; + String[] updateData; + String thisObjectId; + String thisClassName; + boolean isConstractor = false; + boolean isCollectionType = false; + boolean isStatic = false; + long timeStamp = 0L; + ThreadInstance thread = null; + HashMap> stacks = new HashMap>(); + while ((line = file.readLine()) != null) { + // �g���[�X�t�@�C���̉�� + if (line.startsWith("Method")) { + // ���\�b�h�Ăяo���i�R���X�g���N�^�Ăяo�����܂ށj + methodData = line.split(":"); + int n = methodData[0].indexOf(','); + signature = methodData[0].substring(n + 1); + threadNo = methodData[methodData.length - 1].split(" ")[1]; + thisObjectId = methodData[1]; + thisClassName = methodData[0].substring(0, n).split(" ")[1]; + isConstractor = false; + isStatic = false; + if (signature.contains("static ")) { + isStatic = true; + } + callerSideSignature = signature; + timeStamp = Long.parseLong(methodData[methodData.length - 2]); + if (prevLine != null) { + if (prevLine.startsWith("New")) { + isConstractor = true; + } else if (prevLine.startsWith("Invoke")) { + callerSideSignature = prevLine.split(":")[1]; + } + } + thread = threads.get(threadNo); + Stack stack; + if (thread == null) { + thread = new ThreadInstance(threadNo); + threads.put(threadNo, thread); + stack = new Stack(); + stacks.put(threadNo, stack); + } else { + stack = stacks.get(threadNo); + } + stack.push(line); + thread.callMethod(signature, callerSideSignature, thisClassName, thisObjectId, isConstractor, isStatic, timeStamp); + } else if (line.startsWith("Args")) { + // ���\�b�h�Ăяo���̈��� + argData = line.split(":"); + threadNo = argData[argData.length - 1].split(" ")[1]; + thread = threads.get(threadNo); + ArrayList arguments = new ArrayList(); + for (int k = 1; k < argData.length - 2; k += 2) { + arguments.add(new ObjectReference(argData[k+1], argData[k])); + } + thread.setArgments(arguments); + } else if (line.startsWith("Return")) { + // ���\�b�h����̕��A + returnData = line.split(":"); + threadNo = returnData[returnData.length - 1].split(" ")[1]; + Stack stack = stacks.get(threadNo); + if (!stack.isEmpty()) { + String line2 = stack.peek(); + if (line2.split("\\(")[0].endsWith(line.split("\\(")[1])) { + stack.pop(); + } else { + do { + stack.pop(); + thread.terminateMethod(); + 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); + } + } else if (line.startsWith("get")) { + // �t�B�[���h�A�N�Z�X + accessData = line.split(":"); + threadNo = accessData[8].split(" ")[1]; + thread = threads.get(threadNo); + if (thread != null) thread.fieldAccess(accessData[5], accessData[6], accessData[3], accessData[4], accessData[1], accessData[2]); + } else if (line.startsWith("set")) { + // �t�B�[���h�X�V + updateData = line.split(":"); + threadNo = updateData[6].split(" ")[1]; + thread = threads.get(threadNo); + if (thread != null) thread.fieldUpdate(updateData[3], updateData[4], updateData[1], updateData[2]); + } + prevLine = line; + } + } + + /** + * �I�����C����͗p�V���O���g���̎擾 + * @return �I�����C����͗p�g���[�X + */ + public static Trace getInstance() { + if (theTrace == null) { + theTrace = new Trace(); + } + return 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���擾����(�I�����C����͗p) + * @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���擾����(�I�����C����͗p) + * @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(); + } + + /** + * �S�X���b�h���擾���� + * @return �X���b�hID����X���b�h�C���X�^���X�ւ̃}�b�v + */ + public HashMap getAllThreads() { + return threads; + } + + /** + * ���\�b�h���ɑS���\�b�h���s��S�ẴX���b�h������o�� + * @return ���\�b�h�V�O�j�`�����烁�\�b�h���s�̃��X�g�ւ�HashMap + */ + public HashMap> getAllMethodExecutions() { + Iterator threadsIterator = threads.keySet().iterator(); + final HashMap> results = new HashMap<>(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + String signature = methodExecution.getSignature(); + ArrayList executions = results.get(signature); + if (executions == null) { + executions = new ArrayList<>(); + results.put(signature, executions); + } + executions.add(methodExecution); + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }); + } + return results; + } + + /** + * �S���\�b�h�̃V�O�j�`�����擾���� + * @return �S���\�b�h�V�O�j�`�� + */ + public HashSet getAllMethodSignatures() { + final HashSet signatures = new HashSet(); + Iterator threadsIterator = threads.keySet().iterator(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + signatures.add(methodExecution.getSignature()); + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }); + } + return signatures; + } + + /** + * ���\�b�h���� methodSignature�@�ɑO����v���郁�\�b�h���s��S�ẴX���b�h������o�� + * @param methodSignature ���������� + * @return ��v�����S���\�b�h���s + */ + public ArrayList getMethodExecutions(final String methodSignature) { + Iterator threadsIterator = threads.keySet().iterator(); + final ArrayList results = new ArrayList(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + if (methodExecution.getSignature().startsWith(methodSignature)) { + results.add(methodExecution); + } + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }); + } + return results; + } + + /** + * methodSignature �ɑO����v���郁�\�b�h�������ƒ��\�b�h�̍Ō�̎��s + * @param methodSignature ���\�b�h��(�O����v�Ō�������) + * @return �Y������Ō�̃��\�b�h���s + */ + public MethodExecution getLastMethodExecution(final String methodSignature) { + return traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { return false; } + @Override + public boolean postVisitThread(ThreadInstance thread) { return false; } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { return false; } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + if (methodExecution.getSignature().startsWith(methodSignature)) return true; + return false; + } + }); + } + + /** + * methodSignature �ɑO����v���郁�\�b�h�������ƒ��\�b�h�� before �ȑO�̍Ō�̎��s + * @param methodSignature ���\�b�h��(�O����v�Ō�������) + * @param before�@�T���J�n�g���[�X�|�C���g(������ȑO��T��) + * @return�@�Y������Ō�̃��\�b�h���s + */ + public MethodExecution getLastMethodExecution(final String methodSignature, TracePoint before) { + return traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { return false; } + @Override + public boolean postVisitThread(ThreadInstance thread) { return false; } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { return false; } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + if (methodExecution.getSignature().startsWith(methodSignature)) return true; + return false; + } + }, before); + } + + /** + * �}�[�N���Ŏ��s���J�n���ꂽ�S���\�b�h�̃V�O�j�`�����擾���� + * @param markStart �}�[�N�̊J�n���� + * @param markEnd �}�[�N�̏I������ + * @return �Y�����郁�\�b�h�V�O�j�`�� + */ + public HashSet getMarkedMethodSignatures(final long markStart, final long markEnd) { + final HashSet signatures = new HashSet(); + Iterator threadsIterator = threads.keySet().iterator(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.traverseMarkedMethodExecutions(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + signatures.add(methodExecution.getSignature()); + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }, markStart, markEnd); + } + return signatures; + } + + /** + * �}�[�N���Ŏ��s���J�n���ꂽ�S���\�b�h���s�����\�b�h���Ɏ擾���� + * @param markStart �}�[�N�̊J�n���� + * @param markEnd �}�[�N�̏I������ + * @return ���\�b�h�V�O�j�`������Y�����郁�\�b�h���s�̃��X�g�ւ�HashMap + */ + public HashMap> getMarkedMethodExecutions(final long markStart, final long markEnd) { + final HashMap>allExecutions = new HashMap<>(); + Iterator threadsIterator = threads.keySet().iterator(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.traverseMarkedMethodExecutions(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + ArrayList executions = allExecutions.get(methodExecution.getSignature()); + if (executions == null) { + executions = new ArrayList<>(); + allExecutions.put(methodExecution.getSignature(), executions); + } + executions.add(methodExecution); + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }, markStart, markEnd); + } + return allExecutions; + } + + /** + * �}�[�N�O�Ŏ��s���J�n���ꂽ�S���\�b�h�̃V�O�j�`�����擾���� + * @param markStart �}�[�N�̊J�n���� + * @param markEnd �}�[�N�̏I������ + * @return �Y�����郁�\�b�h�V�O�j�`�� + */ + public HashSet getUnmarkedMethodSignatures(long markStart, long markEnd) { + HashSet signatures = new HashSet(); + Iterator threadsIterator = threads.keySet().iterator(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.getUnmarkedMethodSignatures(signatures, markStart, markEnd); + } + return signatures; + } + + /** + * �}�[�N�O�Ŏ��s���J�n���ꂽ�S���\�b�h���s���擾���� + * @param markStart �}�[�N�̊J�n���� + * @param markEnd �}�[�N�̏I������ + * @return ���\�b�h�V�O�j�`������Y�����郁�\�b�h���s�̃��X�g�ւ�HashMap + */ + public HashMap> getUnmarkedMethodExecutions(long markStart, long markEnd) { + HashMap> executions = new HashMap<>(); + Iterator threadsIterator = threads.keySet().iterator(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.getUnmarkedMethodExecutions(executions, markStart, markEnd); + } + return executions; + } + + + protected TracePoint getLastMethodEntryInThread(ArrayList rootExecutions) { + MethodExecution lastExecution = rootExecutions.remove(rootExecutions.size() - 1); + return getLastMethodEntryInThread(rootExecutions, lastExecution.getExitOutPoint()); + } + + protected TracePoint getLastMethodEntryInThread(ArrayList rootExecutions, TracePoint start) { + return getLastMethodEntryInThread(rootExecutions, start, -1L); + } + + /** + * + * @param rootExecutions + * @param start + * @param before + * @return + */ + protected TracePoint getLastMethodEntryInThread(ArrayList rootExecutions, TracePoint start, final long before) { + final TracePoint cp[] = new TracePoint[1]; + cp[0] = start; + for (;;) { + if (!cp[0].isStepBackOut() && traverseMethodExecutionsInCallTreeBackward ( + new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { return false; } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { return false; } + @Override + public boolean postVisitThread(ThreadInstance thread) { return false; } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + if (methodExecution.getEntryTime() < before || before == -1L) { + cp[0] = methodExecution.getEntryPoint(); + return true; + } + return false; + } + }, cp[0])) { + return cp[0]; + } + if (rootExecutions.size() == 0) break; + MethodExecution lastExecution = rootExecutions.remove(rootExecutions.size() - 1); + cp[0] = lastExecution.getExitOutPoint(); + } + return null; + } + + public boolean getLastStatementInThread(String threadId, final TracePoint[] start, final IStatementVisitor visitor) { + return getLastStatementInThread((ArrayList) threads.get(threadId).getRoot().clone(), start, start[0].getStatement().getTimeStamp(), visitor); + } + + protected boolean getLastStatementInThread(ArrayList rootExecutions, final TracePoint[] start, final long before, final IStatementVisitor visitor) { + final boolean[] bArrived = new boolean[] { + false + }; + for (;;) { + if (start[0].isValid() && traverseStatementsInCallTreeBackward( + new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { + if (statement instanceof MethodInvocation) { + MethodExecution methodExecution = ((MethodInvocation) statement).getCalledMethodExecution(); + if ((!methodExecution.isTerminated() && methodExecution.getExitTime() < before) || before == -1L) { + if (visitor.preVisitStatement(statement)) return true; + bArrived[0] = true; + return true; + } + } else { + if (statement.getTimeStamp() < before || before == -1L) { + if (visitor.preVisitStatement(statement)) return true; + bArrived[0] = true; + return true; + } + } + return visitor.preVisitStatement(statement); + } + @Override + public boolean postVisitStatement(Statement statement) { + return visitor.postVisitStatement(statement); + } + }, start[0])) { + return !bArrived[0]; + } + if (rootExecutions.size() == 0) break; + MethodExecution lastExecution = rootExecutions.remove(rootExecutions.size() - 1); + start[0] = lastExecution.getExitPoint(); + } + 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) { + if (before != null) before = before.duplicate(); + before = traverseStatementsInTraceBackward( + new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { + if (statement instanceof MethodInvocation) { + MethodInvocation mi = (MethodInvocation)statement; + if (mi.getCalledMethodExecution().isConstructor() + && mi.getCalledMethodExecution().getReturnValue().equals(newObjectId)) { + return true; + } + } + return false; + } + @Override + public boolean postVisitStatement(Statement statement) { return false; } + }, before); + if (before != null) { + return before; + } + return null; + } + + public TracePoint getFieldUpdateTracePoint(final Reference ref, TracePoint before) { + if (before != null) before = before.duplicate(); + final String srcType = ref.getSrcClassName(); + final String dstType = ref.getDstClassName(); + final String srcObjId = ref.getSrcObjectId(); + final String dstObjId = ref.getDstObjectId(); + + before = traverseStatementsInTraceBackward(new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { + if (statement instanceof FieldUpdate) { + FieldUpdate fu = (FieldUpdate)statement; + if (fu.getContainerObjId().equals(srcObjId) + && fu.getValueObjId().equals(dstObjId)) { + // �I�u�W�F�N�gID���݂��Ɉ�v�����ꍇ + return true; + } else if ((srcObjId == null || isNull(srcObjId)) && fu.getContainerClassName().equals(srcType)) { + if ((dstObjId == null || isNull(dstObjId)) && fu.getValueClassName().equals(dstType)) { + // ref �ɃI�u�W�F�N�gID���w�肵�Ă��Ȃ������ꍇ + ref.setSrcObjectId(fu.getContainerObjId()); + ref.setDstObjectId(fu.getValueObjId()); + return true; + } else if (fu.getValueObjId().equals(dstObjId)) { + // �N���X�ϐ��ւ̑���̏ꍇ + ref.setSrcObjectId(srcObjId); + ref.setDstClassName(dstType); + return true; + } + } + } + return false; + } + @Override + public boolean postVisitStatement(Statement statement) { return false; } + }, before); + if (before != null) { + return before; + } + return null; + } + + public TracePoint getCollectionAddTracePoint(final Reference ref, TracePoint before) { + final TracePoint[] result = new TracePoint[1]; + if (traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + String srcType = ref.getSrcClassName(); + String dstType = ref.getDstClassName(); + String srcObjId = ref.getSrcObjectId(); + String dstObjId = ref.getDstObjectId(); + if (methodExecution.isCollectionType() && isCollectionAdd(methodExecution.getSignature())) { + if (dstObjId != null && methodExecution.getThisObjId().equals(srcObjId)) { + ArrayList args = methodExecution.getArguments(); + for (int i = 0; i < args.size(); i++) { + ObjectReference arg = args.get(i); + if (arg.getId().equals(dstObjId)) { + ref.setSrcClassName(methodExecution.getThisClassName()); + ref.setDstClassName(arg.getActualType()); + result[0] = methodExecution.getCallerTracePoint(); + return true; + } + } + } else if (dstObjId == null && methodExecution.getThisClassName().equals(srcType)) { + ArrayList args = methodExecution.getArguments(); + for (int i = 0; i < args.size(); i++) { + ObjectReference arg = args.get(i); + if (arg.getActualType().equals(dstType)) { + ref.setSrcObjectId(methodExecution.getThisObjId()); + ref.setDstObjectId(arg.getId()); + result[0] = methodExecution.getCallerTracePoint(); + return true; + } + } + } + } + return false; + } + }, before) != null) { + return result[0]; + } + return null; + } + + public TracePoint getArraySetTracePoint(final Reference ref, TracePoint before) { + final TracePoint start = (before == null) ? null : before.duplicate(); + before = traverseStatementsInTraceBackward(new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { + if (statement instanceof FieldAccess) { + if (isArraySet(ref, start)) { + return true; + } + } + return false; + } + @Override + public boolean postVisitStatement(Statement statement) { return false; } + }, start); + if (before != null) { + return before; + } + return null; + } + + private boolean isCollectionAdd(String methodSignature) { + return (methodSignature.contains("add(") || methodSignature.contains("set(") || methodSignature.contains("put(") || methodSignature.contains("push(") || methodSignature.contains("addElement(")); + } + + private boolean isArraySet(Reference ref, TracePoint fieldAccessPoint) { + FieldAccess fieldAccess = (FieldAccess)fieldAccessPoint.getStatement(); + String srcObjId = ref.getSrcObjectId(); + String dstObjId = ref.getDstObjectId(); + if (fieldAccess.getValueClassName().startsWith("[L") + && fieldAccess.getValueObjId().equals(srcObjId)) { + // srcId �͔z�� + // ���\�b�h���s�J�n���� fieldAccessPoint �܂ł̊Ԃ̃��\�b�h���s���� dstId ���o��������? + TracePoint p = fieldAccessPoint.duplicate(); + while (p.stepBackOver()) { + Statement statement = p.getStatement(); + if (statement instanceof MethodInvocation) { + MethodExecution calledMethod = ((MethodInvocation)statement).getCalledMethodExecution(); + if (calledMethod.getReturnValue().getId().equals(dstObjId)) { + // dstId �͖߂�l�Ƃ��ďo�� + ref.setSrcClassName(fieldAccess.getValueClassName()); + ref.setDstClassName(calledMethod.getReturnValue().getActualType()); + return true; + } else if (dstObjId == null || isNull(dstObjId) && calledMethod.getReturnValue().getActualType().equals(ref.getDstClassName())) { + // dstClassName �͖߂�l�̌^�Ƃ��ďo�� + ref.setSrcObjectId(fieldAccess.getValueObjId()); + ref.setDstObjectId(calledMethod.getReturnValue().getId()); + return true; + } + } + if (EAGER_DETECTION_OF_ARRAY_SET) { + if (statement instanceof FieldAccess) { + if (((FieldAccess)statement).getContainerObjId().equals(dstObjId)) { + // dstId �̓t�B�[���h�ɏo�� + ref.setSrcClassName(fieldAccess.getValueClassName()); + ref.setDstClassName(((FieldAccess)statement).getContainerClassName()); + return true; + } else if (dstObjId == null || isNull(dstObjId) && ((FieldAccess)statement).getContainerClassName().equals(ref.getDstClassName())) { + // dstClassName �̓t�B�[���h�̌^�Ƃ��ďo�� + ref.setSrcObjectId(fieldAccess.getValueObjId()); + ref.setDstObjectId(((FieldAccess)statement).getContainerObjId()); + return true; + } + } + } + } + ArrayList args = fieldAccessPoint.getMethodExecution().getArguments(); + int argindex = args.indexOf(new ObjectReference(dstObjId)); + if (argindex != -1) { + // dstId �͈����ɏo�� + ref.setSrcClassName(fieldAccess.getValueClassName()); + ref.setDstClassName(args.get(argindex).getActualType()); + return true; + } else if (dstObjId == null || isNull(dstObjId)) { + for (int j = 0; j < args.size(); j++) { + if (args.get(j).getActualType().equals(ref.getDstClassName())) { + // dstClassName �͈����̌^�ɏo�� + ref.setSrcObjectId(fieldAccess.getValueObjId()); + ref.setDstObjectId(args.get(j).getId()); + return true; + } + } + } + } + return false; + } + + /** + * �g���[�X���̑S���\�b�h���s�̊J�n�n�_���t�����ɒT������ + * @param visitor ���\�b�h���s�̃r�W�^�[(postVisitMethodExecution()�����ĂѕԂ��Ȃ��̂Œ���) + * @return ���f�������\�b�h���s + */ + public MethodExecution traverseMethodEntriesInTraceBackward(IMethodExecutionVisitor 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 rootExecutions = (ArrayList)thread.getRoot().clone(); + threadRoots.put(threadId, rootExecutions); + TracePoint threadLastTp = getLastMethodEntryInThread(rootExecutions); + threadLastPoints.put(threadId, threadLastTp); + if (threadLastTp != null) { + long threadLastTime = threadLastTp.getMethodExecution().getEntryTime(); + if (traceLastTime < threadLastTime) { + traceLastTime2 = traceLastTime; + traceLastThread2 = traceLastThread; + traceLastTime = threadLastTime; + traceLastThread = threadId; + } + } + } + return traverseMethodEntriesInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); + } + + /** + * �w�肵�����s���_�ȑO�Ɏ��s���J�n���ꂽ���\�b�h���s�̊J�n���_���t�����ɒT������ + * @param visitor ���\�b�h���s�̃r�W�^�[(postVisitMethodExecution()�����ĂѕԂ��Ȃ��̂Œ���) + * @param before �T���J�n���_ + * @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()); + ArrayList rootExecutions = (ArrayList)thread.getRoot().clone(); + for (int n = rootExecutions.size() - 1; n >= 0; n--) { + MethodExecution root = rootExecutions.get(n); + if (root.getEntryTime() > before.getMethodExecution().getEntryTime()) { + rootExecutions.remove(n); + } else { + break; + } + } + if (rootExecutions.size() > 0) { + rootExecutions.remove(rootExecutions.size() - 1); + } + before = getLastMethodEntryInThread(rootExecutions, before); + for (String threadId: threads.keySet()) { + ThreadInstance t = threads.get(threadId); + if (t == thread) { + threadRoots.put(threadId, rootExecutions); + traceLastThread = threadId; + threadLastPoints.put(threadId, before); + } else { + ArrayList rootExes = (ArrayList)t.getRoot().clone(); + threadRoots.put(threadId, rootExes); + MethodExecution threadLastExecution = rootExes.remove(rootExes.size() - 1); + TracePoint threadBeforeTp = getLastMethodEntryInThread(rootExes, threadLastExecution.getExitOutPoint(), before.getMethodExecution().getEntryTime()); + threadLastPoints.put(threadId, threadBeforeTp); + if (threadBeforeTp != null) { + long threadLastTime = threadBeforeTp.getMethodExecution().getEntryTime(); + if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; + } + } + } + } + return traverseMethodEntriesInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); + } + + private MethodExecution traverseMethodEntriesInTraceBackwardSub( + final IMethodExecutionVisitor visitor, + HashMap> threadRoots, HashMap threadLastPoints, + String traceLastThread, String traceLastThread2, long traceLastTime2) { + // �S�X���b�h�̓������Ƃ�Ȃ���t�����Ƀ��\�b�h���s��T������ + for (;;) { + // �T���Ώۂ̃X���b�h���̋t�����T�� + TracePoint threadLastTp = threadLastPoints.get(traceLastThread); + MethodExecution threadLastExecution = threadLastTp.getMethodExecution(); + do { + threadLastTp.stepBackOver(); + // ���̃X���b�h�̎��̃��\�b�h���s�J�n���_�܂ŒT������ + threadLastTp = getLastMethodEntryInThread(threadRoots.get(traceLastThread), threadLastTp); + if (threadLastTp == null) break; + if (visitor.postVisitMethodExecution(threadLastExecution, threadLastExecution.getChildren())) { + // �Y�����郁�\�b�h���s�����‚��� + return threadLastExecution; + } + threadLastExecution = threadLastTp.getMethodExecution(); + } while (threadLastExecution.getEntryTime() > traceLastTime2); + threadLastPoints.put(traceLastThread, threadLastTp); + traceLastThread = traceLastThread2; + // ���̎��ɒT�����ׂ��X���b�h(���T���̗̈悪��ԍŌ�܂Ŏc���Ă���X���b�h)�����肷�� + traceLastTime2 = 0; + traceLastThread2 = null; + boolean continueTraverse = false; + for (String threadId: threadLastPoints.keySet()) { + if (!threadId.equals(traceLastThread)) { + TracePoint lastTp = threadLastPoints.get(threadId); + if (lastTp != null) { + continueTraverse = true; + long threadLastTime = lastTp.getMethodExecution().getEntryTime(); + if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; + } + } + } + } + if (!continueTraverse && threadLastPoints.get(traceLastThread) == null) break; + } + return null; + } + + /** + * �Ăяo�����̎����� markStart ���� markEnd �̊Ԃɂ���S�X���b�h���̑S���\�b�h���s��T������ + * @param visitor�@�r�W�^�[ + * @param markStart �J�n���� + * @param markEnd �I������ + */ + public void traverseMarkedMethodExecutions(IMethodExecutionVisitor visitor, long markStart, long markEnd) { + for (String threadId: threads.keySet()) { + ThreadInstance thread = threads.get(threadId); + thread.traverseMarkedMethodExecutions(visitor, markStart, markEnd); + } + } + + /** + * �g���[�X���̑S�X���b�h�𓯊������Ȃ炪�S���s�����������ɒT������ + * + * @param visitor ���s���̃r�W�^�[ + * @return ���f�����g���[�X�|�C���g + */ + public TracePoint traverseStatementsInTrace(IStatementVisitor visitor) { + HashMap> threadRoots = new HashMap>(); + HashMap threadCurPoints = new HashMap(); + // �e�X���b�h�ɂ����Ĉ�ԍŏ��ɊJ�n�������\�b�h���s��T�� + long traceCurTime = -1; + String traceCurThread = null; + long traceCurTime2 = -1; + String traceCurThread2 = null; + for (String threadId: threads.keySet()) { + ThreadInstance thread = threads.get(threadId); + ArrayList roots = (ArrayList)thread.getRoot().clone(); + threadRoots.put(threadId, roots); + TracePoint threadCurTp; + do { + MethodExecution threadCurExecution = roots.remove(0); + threadCurTp = threadCurExecution.getEntryPoint(); + } while (!threadCurTp.isValid() && roots.size() > 0); + if (threadCurTp.isValid()) { + threadCurPoints.put(threadId, threadCurTp); + long methodEntry = threadCurTp.getMethodExecution().getEntryTime(); + if (traceCurTime == -1 || traceCurTime > methodEntry) { + traceCurTime2 = traceCurTime; + traceCurThread2 = traceCurThread; + traceCurTime = methodEntry; + traceCurThread = threadId; + } else if (traceCurTime2 == -1 || traceCurTime2 > methodEntry) { + traceCurTime2 = methodEntry; + traceCurThread2 = threadId; + } + } else { + threadCurPoints.put(threadId, null); + } + } + return traverseStatementsInTraceSub(visitor, threadRoots, threadCurPoints, traceCurThread, traceCurThread2, traceCurTime2); + } + + private TracePoint traverseStatementsInTraceSub(IStatementVisitor visitor, + HashMap> threadRoots, + HashMap threadCurPoints, + String curThreadId, String nextThreadId, long nextThreadTime) { + // �S�X���b�h�̓������Ƃ�Ȃ��珇�����Ɏ��s����T������ + for (;;) { + // �T���Ώۂ̃X���b�h���̏������T�� + TracePoint curTp = threadCurPoints.get(curThreadId); + 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; + } + curTp.stepNoReturn(); // ���A�����ɌĂяo���؂�����Ă��� + if (!curTp.isValid()) { + // ���A���Ȃ��Ƃ���ȏ�T���ł��Ȃ� + 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; + } else { + // �Ăяo���؂̊J�n���_�܂ŒT�����I�����ꍇ + ArrayList roots = threadRoots.get(curThreadId); + while (!curTp.isValid() && roots.size() > 0) { + // ���̌Ăяo���؂�����΂�����ŏ�����T�� + MethodExecution firstExecution = roots.remove(0); + curTp = firstExecution.getEntryPoint(); + } + if (curTp.isValid()) { + // ���̌Ăяo���؂�����΂�����ŏ�����T�� + threadCurPoints.put(curThreadId, curTp); + } else { + // ���̃X���b�h�̒T�������ׂďI�������ꍇ + threadCurPoints.put(curThreadId, null); + curTp = null; + } + break; + } + } + } + } + curThreadId = nextThreadId; + if (curThreadId == null) break; + // ���̎��ɒT�����ׂ��X���b�h(���T���̗̈悪��ԍŏ��Ɏn�܂�X���b�h)�����肷�� + nextThreadTime = -1; + nextThreadId = null; + boolean continueTraverse = false; + for (String threadId: threadCurPoints.keySet()) { + if (!threadId.equals(curThreadId)) { + TracePoint threadTp = threadCurPoints.get(threadId); + if (threadTp != null) { + continueTraverse = true; + long threadTime = threadTp.getStatement().getTimeStamp(); + if (threadTime > 0 && (nextThreadTime == -1 || nextThreadTime > threadTime)) { + nextThreadTime = threadTime; + nextThreadId = threadId; + } + } + } + } + if (!continueTraverse && threadCurPoints.get(curThreadId) == null) break; + } + return null; + } + + /** + * �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 root = (ArrayList)thread.getRoot().clone(); + threadRoots.put(threadId, root); + TracePoint threadLastTp; + do { + MethodExecution threadLastExecution = root.remove(root.size() - 1); + threadLastTp = threadLastExecution.getExitPoint(); + } while (!threadLastTp.isValid() && root.size() > 0); + if (threadLastTp.isValid()) { + threadLastPoints.put(threadId, threadLastTp); + if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, threadLastTp)) return threadLastTp; + long methodEntry = threadLastTp.getMethodExecution().getEntryTime(); + if (traceLastTime < methodEntry) { + traceLastTime2 = traceLastTime; + traceLastThread2 = traceLastThread; + traceLastTime = methodEntry; + traceLastThread = threadId; + } else if (traceLastTime2 < methodEntry) { + traceLastTime2 = methodEntry; + traceLastThread2 = threadId; + } + } else { + threadLastPoints.put(threadId, null); + } + } + return traverseStatementsInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); + } + + /** + * + * @param visitor + * @param before + * @return + */ + public TracePoint traverseStatementsInTraceBackward(IStatementVisitor visitor, TracePoint before) { + if (before == null) { + return traverseStatementsInTraceBackward(visitor); + } + if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, before)) return before; + 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.getMethodExecution().getEntryTime()) { + rootExecutions.remove(n); + } else { + break; + } + } + if (rootExecutions.size() > 0) { + rootExecutions.remove(rootExecutions.size() - 1); + } + } else { + MethodExecution threadLastExecution = rootExecutions.remove(rootExecutions.size() - 1); + TracePoint threadBeforeTp = getLastMethodEntryInThread(rootExecutions, threadLastExecution.getExitOutPoint(), before.getMethodExecution().getEntryTime()); + threadLastPoints.put(threadId, threadBeforeTp); + if (threadBeforeTp != null) { + long threadLastTime = threadBeforeTp.getMethodExecution().getEntryTime(); + if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; + } + } + } + } + return traverseStatementsInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); + } + + private TracePoint traverseStatementsInTraceBackwardSub(IStatementVisitor visitor, + HashMap> threadRoots, + HashMap threadLastPoints, + String traceLastThread, String traceLastThread2, long traceLastTime2) { + // �S�X���b�h�̓������Ƃ�Ȃ���t�����Ɏ��s����T������ + for (;;) { + // �T���Ώۂ̃X���b�h���̋t�����T�� + TracePoint lastTp = threadLastPoints.get(traceLastThread); + do { + if (lastTp.stepBackOver()) { + // ���̃X���b�h�̎��̃��\�b�h���s�J�n���_�܂ŒT������ + if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, lastTp)) return lastTp; + } else { + // �Ăяo�����ɖ߂����ꍇ + if (lastTp.isValid()) { + if (visitor.postVisitStatement(lastTp.getStatement())) return lastTp; + } else { + // �Ăяo���؂̊J�n���_�܂ŒT�����I�����ꍇ + ArrayList root = threadRoots.get(traceLastThread); + while (!lastTp.isValid() && root.size() > 0) { + // ���̌Ăяo���؂�����΂�����Ōォ��T�� + MethodExecution lastExecution = root.remove(root.size() - 1); + lastTp = lastExecution.getExitPoint(); + } + if (lastTp.isValid()) { + // ���̌Ăяo���؂�����΂�����Ōォ��T�� + threadLastPoints.put(traceLastThread, lastTp); + if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, lastTp)) return lastTp; + } else { + // ���̃X���b�h�̒T�������ׂďI�������ꍇ + threadLastPoints.put(traceLastThread, null); + break; + } + } + } + } while (lastTp.getMethodExecution().getEntryTime() >= traceLastTime2); + traceLastThread = traceLastThread2; + // ���̎��ɒT�����ׂ��X���b�h(���T���̗̈悪��ԍŌ�܂Ŏc���Ă���X���b�h)�����肷�� + traceLastTime2 = 0; + traceLastThread2 = null; + boolean continueTraverse = false; + for (String threadId: threadLastPoints.keySet()) { + if (!threadId.equals(traceLastThread)) { + TracePoint threadLastTp = threadLastPoints.get(threadId); + if (threadLastTp != null) { + continueTraverse = true; + long threadLastTime = threadLastTp.getMethodExecution().getEntryTime(); + if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; + } + } + } + } + if (!continueTraverse && threadLastPoints.get(traceLastThread) == null) break; + } + return null; + } + + /** + * before �Ŏw�肵���g���[�X�|�C���g�ȑO�̓���Ăяo���ؓ��̑S���s�����t�����ɒT������(�������Avisitor �� true ��Ԃ��܂�) + * @param visitor �r�W�^�[ + * @param before �T���̊J�n�_(�T���ΏۃX���b�h���w�肵�Ă���) + * @return true -- �T���𒆒f����, false -- �Ō�܂ŒT������ + */ + public boolean traverseStatementsInCallTreeBackward(IStatementVisitor visitor, TracePoint before) { + for (;;) { + if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, before)) return true; + while (!before.stepBackOver()) { + if (!before.isValid()) break; + if (visitor.postVisitStatement(before.getStatement())) return true; + } + if (!before.isValid()) break; + } + return false; + } + + /** + * before�ȑO�̌Ăяo���؂��Ăяo���悩��̕��A�������ɍs����Ƃ���܂ŋt�����ɒT������ + * + * @param visitor ���s���̃r�W�^�[ + * @param before �T���J�n���s���_ + * @return true -- �T���𒆒f����, false -- ���A�����Ȃ����肱��ȏ�i�߂Ȃ� + */ + private boolean traverseStatamentsInCallTreeBackwardNoReturn(IStatementVisitor visitor, TracePoint before) { + for (;;) { + Statement statement = before.getStatement(); + if (statement instanceof MethodInvocation) { + // ���\�b�h�Ăяo�����̏ꍇ�́A�Ăяo���̑O��� preVisit �� postVisit ��ʁX�Ɏ��s���� + if (visitor.preVisitStatement(statement)) return true; + before.stepBackNoReturn(); + if (!before.isValid()) { + // �Ăяo����̃��\�b�h�Ŏ��s�����L�^����Ă��Ȃ��ꍇ + before.stepBackOver(); + if (visitor.postVisitStatement(statement)) return true; + if (before.isMethodEntry()) return false; + before.stepBackOver(); + } + } else { + if (visitor.preVisitStatement(statement)) return true; + if (visitor.postVisitStatement(statement)) return true; + if (before.isMethodEntry()) return false; + before.stepBackNoReturn(); + } + } + } + + /** + * before �Ŏw�肵���g���[�X�|�C���g�ȑO�̓���X���b�h���̑S���\�b�h���s���Ăяo���؂̒��ŋt�����ɒT������(�������Avisitor �� true ��Ԃ��܂�) + * @param visitor �r�W�^�[ + * @param before �T���̊J�n�_(�T���ΏۃX���b�h���w�肵�Ă���) + * @return true -- �T���𒆒f����, false -- �Ō�܂ŒT������ + */ + public boolean traverseMethodExecutionsInCallTreeBackward(IMethodExecutionVisitor visitor, TracePoint before) { + ArrayList prevMethodExecutions = before.getPreviouslyCalledMethods(); + for (int i = prevMethodExecutions.size() - 1; i >= 0; i--) { + MethodExecution child = prevMethodExecutions.get(i); + if (child.traverseMethodExecutionsBackward(visitor)) return true; + } + MethodExecution methodExecution = before.getMethodExecution(); + if (visitor.postVisitMethodExecution(methodExecution, null)) return true; + TracePoint caller = methodExecution.getCallerTracePoint(); + if (caller != null) { + if (traverseMethodExecutionsInCallTreeBackward(visitor, caller)) return true; + } + return false; + } + + public static String getDeclaringType(String methodSignature, boolean isConstructor) { + if (methodSignature == null) return null; + if (isConstructor) { + String[] fragments = methodSignature.split("\\("); + return fragments[0].substring(fragments[0].lastIndexOf(' ') + 1); + } + String[] fragments = methodSignature.split("\\("); + return fragments[0].substring(fragments[0].lastIndexOf(' ') + 1, fragments[0].lastIndexOf('.')); + } + + public static String getMethodName(String methodSignature) { + String[] fragments = methodSignature.split("\\("); + String[] fragments2 = fragments[0].split("\\."); + return fragments2[fragments2.length - 1]; + } + + public static String getReturnType(String methodSignature) { + String[] fragments = methodSignature.split(" "); + for (int i = 0; i < fragments.length; i++) { + if (!fragments[i].equals("public") && !fragments[i].equals("private") && !fragments[i].equals("protected") + && !fragments[i].equals("abstract") && !fragments[i].equals("final") && !fragments[i].equals("static") + && !fragments[i].equals("synchronized") && !fragments[i].equals("native")) { + return fragments[i]; + } + } + return ""; + } + + public static boolean isNull(String objectId) { + return objectId.equals("0"); + } + + public static String getNull() { + return "0"; + } + + public static boolean isPrimitive(String typeName) { + if (typeName.equals("int") + || typeName.equals("boolean") + || typeName.equals("long") + || typeName.equals("double") + || typeName.equals("float") + || typeName.equals("char") + || typeName.equals("byte") + || typeName.equals("java.lang.Integer") + || typeName.equals("java.lang.Boolean") + || typeName.equals("java.lang.Long") + || typeName.equals("java.lang.Double") + || typeName.equals("java.lang.Float") + || typeName.equals("java.lang.Character") + || typeName.equals("java.lang.Byte")) return true; + return false; + } +} diff --git a/src/org/ntlab/trace/TraceJSON.java b/src/org/ntlab/trace/TraceJSON.java index 973290a..7ef09a5 100644 --- a/src/org/ntlab/trace/TraceJSON.java +++ b/src/org/ntlab/trace/TraceJSON.java @@ -217,6 +217,8 @@ || 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; } @@ -703,6 +705,9 @@ traceLastThread2 = traceLastThread; traceLastTime = threadLastTime; traceLastThread = threadId; + } else if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; } } else { threadLastPoints.put(threadId, null); @@ -835,6 +840,9 @@ traceLastThread2 = traceLastThread; traceLastTime = threadLastTime; traceLastThread = threadId; + } else if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; } } } else { diff --git a/src/org/ntlab/trace/TracePoint.java b/src/org/ntlab/trace/TracePoint.java index 75b6f06..0b90e02 100644 --- a/src/org/ntlab/trace/TracePoint.java +++ b/src/org/ntlab/trace/TracePoint.java @@ -159,6 +159,15 @@ 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; @@ -172,4 +181,12 @@ 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/traces/ArgoUMLBenchmarkWithMoreStandardClasses.trace b/traces/ArgoUMLBenchmarkWithMoreStandardClasses.trace index 989a070..e7fe043 100644 --- a/traces/ArgoUMLBenchmarkWithMoreStandardClasses.trace +++ b/traces/ArgoUMLBenchmarkWithMoreStandardClasses.trace Binary files differ diff --git a/traces/jEditBenchmarkWithMoreStandardClasses.trace b/traces/jEditBenchmarkWithMoreStandardClasses.trace index c45dc64..6f8285c 100644 --- a/traces/jEditBenchmarkWithMoreStandardClasses.trace +++ b/traces/jEditBenchmarkWithMoreStandardClasses.trace Binary files differ diff --git a/traces/jHotDrawBenchmarkWithMoreStandardClasses.trace b/traces/jHotDrawBenchmarkWithMoreStandardClasses.trace index 517c6c2..97ee36b 100644 --- a/traces/jHotDrawBenchmarkWithMoreStandardClasses.trace +++ b/traces/jHotDrawBenchmarkWithMoreStandardClasses.trace Binary files differ diff --git a/traces/pre_Exp1.txt b/traces/pre_Exp1.txt new file mode 100644 index 0000000..ae4b8d4 --- /dev/null +++ b/traces/pre_Exp1.txt @@ -0,0 +1,54 @@ +{"type":"classDef","name":"Main","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp1/bin/Main.class","loaderPath":"/"}, +{"type":"methodEntry","signature":"public static void Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":118352462}],"threadId":1,"time":189620045371400}, +{"type":"blockEntry","methodSignature":"Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":3,"time":189620045410000}, +{"type":"methodCall","callerSideSignature":"A()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"A","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp1/bin/A.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public A()","class":"A","args":[],"threadId":1,"time":189620047294000}, +{"type":"methodCall","callerSideSignature":"B()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"B","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp1/bin/B.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public B()","class":"B","args":[],"threadId":1,"time":189620049394000}, +{"type":"methodCall","callerSideSignature":"C()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"C","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp1/bin/C.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public C()","class":"C","args":[],"threadId":1,"time":189620050239200}, +{"type":"constructorExit","shortSignature":"C()","returnValue":{"class":"C","id":1550089733},"threadId":1,"time":189620050287500}, +{"type":"fieldSet","fieldName":"B.c","container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":2,"time":189620050340800}, +{"type":"constructorExit","shortSignature":"B()","returnValue":{"class":"B","id":865113938},"threadId":1,"time":189620050355900}, +{"type":"fieldSet","fieldName":"A.b","container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":2,"time":189620050394900}, +{"type":"methodCall","callerSideSignature":"D()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"D","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp1/bin/D.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public D()","class":"D","args":[],"threadId":1,"time":189620051559200}, +{"type":"methodCall","callerSideSignature":"E()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"E","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp1/bin/E.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public E()","class":"E","args":[],"threadId":1,"time":189620053171200}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"---","id":0},"threadId":1,"lineNum":2,"time":189620053238100}, +{"type":"constructorExit","shortSignature":"E()","returnValue":{"class":"E","id":1028566121},"threadId":1,"time":189620053263200}, +{"type":"fieldSet","fieldName":"D.e","container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":2,"time":189620054266600}, +{"type":"constructorExit","shortSignature":"D()","returnValue":{"class":"D","id":1118140819},"threadId":1,"time":189620054295500}, +{"type":"fieldSet","fieldName":"A.d","container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":3,"time":189620054571400}, +{"type":"constructorExit","shortSignature":"A()","returnValue":{"class":"A","id":1442407170},"threadId":1,"time":189620054598500}, +{"type":"methodCall","callerSideSignature":"A.m()","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"void A.m()","receiver":{"class":"A","id":1442407170},"args":[],"threadId":1,"time":189620054640100}, +{"type":"blockEntry","methodSignature":"A.m()","blockId":0,"incomings":0,"threadId":1,"lineNum":5,"time":189620054655000}, +{"type":"fieldGet","fieldName":"A.d","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":5,"time":189620054673800}, +{"type":"methodCall","callerSideSignature":"D.passA(A)","threadId":1,"lineNum":5}, +{"type":"methodEntry","signature":"void D.passA(A)","receiver":{"class":"D","id":1118140819},"args":[{"class":"A","id":1442407170}],"threadId":1,"time":189620054708300}, +{"type":"blockEntry","methodSignature":"D.passA(A)","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189620054719000}, +{"type":"fieldGet","fieldName":"D.e","this":{"class":"D","id":1118140819},"container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":4,"time":189620054736400}, +{"type":"methodCall","callerSideSignature":"E.passA(A)","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"void E.passA(A)","receiver":{"class":"E","id":1028566121},"args":[{"class":"A","id":1442407170}],"threadId":1,"time":189620054765900}, +{"type":"blockEntry","methodSignature":"E.passA(A)","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189620054775400}, +{"type":"methodCall","callerSideSignature":"A.getB()","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"B A.getB()","receiver":{"class":"A","id":1442407170},"args":[],"threadId":1,"time":189620054802000}, +{"type":"blockEntry","methodSignature":"A.getB()","blockId":0,"incomings":0,"threadId":1,"lineNum":8,"time":189620054811200}, +{"type":"fieldGet","fieldName":"A.b","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":8,"time":189620054832400}, +{"type":"methodExit","shortSignature":"A.getB()","receiver":{"class":"A","id":1442407170},"returnValue":{"class":"B","id":865113938},"threadId":1,"time":189620054847200}, +{"type":"methodCall","callerSideSignature":"B.getC()","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"C B.getC()","receiver":{"class":"B","id":865113938},"args":[],"threadId":1,"time":189620054873400}, +{"type":"blockEntry","methodSignature":"B.getC()","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189620054882500}, +{"type":"fieldGet","fieldName":"B.c","this":{"class":"B","id":865113938},"container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":4,"time":189620054898600}, +{"type":"methodExit","shortSignature":"B.getC()","receiver":{"class":"B","id":865113938},"returnValue":{"class":"C","id":1550089733},"threadId":1,"time":189620054915400}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":4,"time":189620054930000}, +{"type":"methodExit","shortSignature":"E.passA(A)","receiver":{"class":"E","id":1028566121},"returnValue":{"class":"void","id":0},"threadId":1,"time":189620054945000}, +{"type":"methodExit","shortSignature":"D.passA(A)","receiver":{"class":"D","id":1118140819},"returnValue":{"class":"void","id":0},"threadId":1,"time":189620054961900}, +{"type":"methodExit","shortSignature":"A.m()","receiver":{"class":"A","id":1442407170},"returnValue":{"class":"void","id":0},"threadId":1,"time":189620054974600}, +{"type":"methodExit","shortSignature":"Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":189620054989000}, diff --git a/traces/pre_Exp2.txt b/traces/pre_Exp2.txt new file mode 100644 index 0000000..8714459 --- /dev/null +++ b/traces/pre_Exp2.txt @@ -0,0 +1,50 @@ +{"type":"classDef","name":"Main","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp2/bin/Main.class","loaderPath":"/"}, +{"type":"methodEntry","signature":"public static void Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":118352462}],"threadId":1,"time":189694992236600}, +{"type":"blockEntry","methodSignature":"Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":3,"time":189694992280600}, +{"type":"methodCall","callerSideSignature":"A()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"A","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp2/bin/A.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public A()","class":"A","args":[],"threadId":1,"time":189694993670900}, +{"type":"methodCall","callerSideSignature":"B()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"B","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp2/bin/B.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public B()","class":"B","args":[],"threadId":1,"time":189694995135400}, +{"type":"methodCall","callerSideSignature":"C()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"C","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp2/bin/C.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public C()","class":"C","args":[],"threadId":1,"time":189694995959200}, +{"type":"constructorExit","shortSignature":"C()","returnValue":{"class":"C","id":1550089733},"threadId":1,"time":189694996013700}, +{"type":"fieldSet","fieldName":"B.c","container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":2,"time":189694996072700}, +{"type":"constructorExit","shortSignature":"B()","returnValue":{"class":"B","id":865113938},"threadId":1,"time":189694996096200}, +{"type":"fieldSet","fieldName":"A.b","container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":2,"time":189694996141600}, +{"type":"methodCall","callerSideSignature":"D()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"D","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp2/bin/D.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public D()","class":"D","args":[],"threadId":1,"time":189694997282500}, +{"type":"methodCall","callerSideSignature":"E()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"E","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp2/bin/E.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public E()","class":"E","args":[],"threadId":1,"time":189694998513400}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"---","id":0},"threadId":1,"lineNum":2,"time":189694998581500}, +{"type":"constructorExit","shortSignature":"E()","returnValue":{"class":"E","id":1028566121},"threadId":1,"time":189694998604400}, +{"type":"fieldSet","fieldName":"D.e","container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":2,"time":189694998666200}, +{"type":"constructorExit","shortSignature":"D()","returnValue":{"class":"D","id":1118140819},"threadId":1,"time":189694998696500}, +{"type":"fieldSet","fieldName":"A.d","container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":3,"time":189694998753000}, +{"type":"constructorExit","shortSignature":"A()","returnValue":{"class":"A","id":1442407170},"threadId":1,"time":189694998770400}, +{"type":"methodCall","callerSideSignature":"A.m()","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"void A.m()","receiver":{"class":"A","id":1442407170},"args":[],"threadId":1,"time":189694998805100}, +{"type":"blockEntry","methodSignature":"A.m()","blockId":0,"incomings":0,"threadId":1,"lineNum":5,"time":189694998824100}, +{"type":"fieldGet","fieldName":"A.d","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":5,"time":189694998848400}, +{"type":"fieldGet","fieldName":"A.b","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":5,"time":189694998870400}, +{"type":"methodCall","callerSideSignature":"D.passB(B)","threadId":1,"lineNum":5}, +{"type":"methodEntry","signature":"void D.passB(B)","receiver":{"class":"D","id":1118140819},"args":[{"class":"B","id":865113938}],"threadId":1,"time":189694998908100}, +{"type":"blockEntry","methodSignature":"D.passB(B)","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189694998919500}, +{"type":"fieldGet","fieldName":"D.e","this":{"class":"D","id":1118140819},"container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":4,"time":189694998945900}, +{"type":"methodCall","callerSideSignature":"B.getC()","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"C B.getC()","receiver":{"class":"B","id":865113938},"args":[],"threadId":1,"time":189694998990000}, +{"type":"blockEntry","methodSignature":"B.getC()","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189694999001600}, +{"type":"fieldGet","fieldName":"B.c","this":{"class":"B","id":865113938},"container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":4,"time":189694999030300}, +{"type":"methodExit","shortSignature":"B.getC()","receiver":{"class":"B","id":865113938},"returnValue":{"class":"C","id":1550089733},"threadId":1,"time":189694999047700}, +{"type":"methodCall","callerSideSignature":"E.setC(C)","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"void E.setC(C)","receiver":{"class":"E","id":1028566121},"args":[{"class":"C","id":1550089733}],"threadId":1,"time":189694999083100}, +{"type":"blockEntry","methodSignature":"E.setC(C)","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189694999093900}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":4,"time":189694999107800}, +{"type":"methodExit","shortSignature":"E.setC(C)","receiver":{"class":"E","id":1028566121},"returnValue":{"class":"void","id":0},"threadId":1,"time":189694999128500}, +{"type":"methodExit","shortSignature":"D.passB(B)","receiver":{"class":"D","id":1118140819},"returnValue":{"class":"void","id":0},"threadId":1,"time":189694999146000}, +{"type":"methodExit","shortSignature":"A.m()","receiver":{"class":"A","id":1442407170},"returnValue":{"class":"void","id":0},"threadId":1,"time":189694999167300}, +{"type":"methodExit","shortSignature":"Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":189694999182700}, diff --git a/traces/pre_Exp3.txt b/traces/pre_Exp3.txt new file mode 100644 index 0000000..bed0645 --- /dev/null +++ b/traces/pre_Exp3.txt @@ -0,0 +1,63 @@ +{"type":"classDef","name":"Main","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp3/bin/Main.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"static Main.()","class":"Main","args":[],"threadId":1,"time":189735062981900}, +{"type":"constructorExit","shortSignature":"Main.()","returnValue":{"class":"void","id":0},"threadId":1,"time":189735083665400}, +{"type":"methodEntry","signature":"public static void Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":118352462}],"threadId":1,"time":189735083861000}, +{"type":"methodCall","callerSideSignature":"A()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"A","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp3/bin/A.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"static A.()","class":"A","args":[],"threadId":1,"time":189735114328000}, +{"type":"constructorExit","shortSignature":"A.()","returnValue":{"class":"void","id":0},"threadId":1,"time":189735114353200}, +{"type":"constructorEntry","signature":"public A()","class":"A","args":[],"threadId":1,"time":189735114364000}, +{"type":"methodCall","callerSideSignature":"B()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"B","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp3/bin/B.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"static B.()","class":"B","args":[],"threadId":1,"time":189735115290200}, +{"type":"constructorExit","shortSignature":"B.()","returnValue":{"class":"void","id":0},"threadId":1,"time":189735115313100}, +{"type":"constructorEntry","signature":"public B()","class":"B","args":[],"threadId":1,"time":189735115326100}, +{"type":"methodCall","callerSideSignature":"C()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"C","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp3/bin/C.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"static C.()","class":"C","args":[],"threadId":1,"time":189735116072700}, +{"type":"constructorExit","shortSignature":"C.()","returnValue":{"class":"void","id":0},"threadId":1,"time":189735116101300}, +{"type":"constructorEntry","signature":"public C()","class":"C","args":[],"threadId":1,"time":189735116112400}, +{"type":"constructorExit","shortSignature":"C()","returnValue":{"class":"C","id":1550089733},"threadId":1,"time":189735116247600}, +{"type":"fieldSet","fieldName":"B.c","container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":2,"time":189735116280300}, +{"type":"constructorExit","shortSignature":"B()","returnValue":{"class":"B","id":865113938},"threadId":1,"time":189735116469300}, +{"type":"fieldSet","fieldName":"A.b","container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":2,"time":189735116510000}, +{"type":"methodCall","callerSideSignature":"D()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"D","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp3/bin/D.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"static D.()","class":"D","args":[],"threadId":1,"time":189735117552400}, +{"type":"constructorExit","shortSignature":"D.()","returnValue":{"class":"void","id":0},"threadId":1,"time":189735117575000}, +{"type":"constructorEntry","signature":"public D()","class":"D","args":[],"threadId":1,"time":189735117588100}, +{"type":"methodCall","callerSideSignature":"E()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"E","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp3/bin/E.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"static E.()","class":"E","args":[],"threadId":1,"time":189735118603200}, +{"type":"constructorExit","shortSignature":"E.()","returnValue":{"class":"void","id":0},"threadId":1,"time":189735118642200}, +{"type":"constructorEntry","signature":"public E()","class":"E","args":[],"threadId":1,"time":189735118661300}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"---","id":0},"threadId":1,"lineNum":2,"time":189735118769300}, +{"type":"constructorExit","shortSignature":"E()","returnValue":{"class":"E","id":1028566121},"threadId":1,"time":189735118863200}, +{"type":"fieldSet","fieldName":"D.e","container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":2,"time":189735118907700}, +{"type":"constructorExit","shortSignature":"D()","returnValue":{"class":"D","id":1118140819},"threadId":1,"time":189735118961100}, +{"type":"fieldSet","fieldName":"A.d","container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":3,"time":189735118979000}, +{"type":"constructorExit","shortSignature":"A()","returnValue":{"class":"A","id":1442407170},"threadId":1,"time":189735119037000}, +{"type":"methodCall","callerSideSignature":"A.m()","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"void A.m()","receiver":{"class":"A","id":1442407170},"args":[],"threadId":1,"time":189735119076100}, +{"type":"fieldGet","fieldName":"A.d","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":5,"time":189735119170300}, +{"type":"fieldGet","fieldName":"A.b","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":5,"time":189735119475100}, +{"type":"methodCall","callerSideSignature":"D.passB(B)","threadId":1,"lineNum":5}, +{"type":"methodEntry","signature":"void D.passB(B)","receiver":{"class":"D","id":1118140819},"args":[{"class":"B","id":865113938}],"threadId":1,"time":189735119523900}, +{"type":"methodCall","callerSideSignature":"B.getC()","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"C B.getC()","receiver":{"class":"B","id":865113938},"args":[],"threadId":1,"time":189735125606200}, +{"type":"fieldGet","fieldName":"B.c","this":{"class":"B","id":865113938},"container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":4,"time":189735125650200}, +{"type":"methodExit","shortSignature":"B.getC()","receiver":{"class":"B","id":865113938},"returnValue":{"class":"C","id":1550089733},"threadId":1,"time":189735125708400}, +{"type":"methodCall","callerSideSignature":"C.passD(D)","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"void C.passD(D)","receiver":{"class":"C","id":1550089733},"args":[{"class":"D","id":1118140819}],"threadId":1,"time":189735125742600}, +{"type":"methodCall","callerSideSignature":"D.getE()","threadId":1,"lineNum":3}, +{"type":"methodEntry","signature":"E D.getE()","receiver":{"class":"D","id":1118140819},"args":[],"threadId":1,"time":189735125807000}, +{"type":"fieldGet","fieldName":"D.e","this":{"class":"D","id":1118140819},"container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":7,"time":189735125847000}, +{"type":"methodExit","shortSignature":"D.getE()","receiver":{"class":"D","id":1118140819},"returnValue":{"class":"E","id":1028566121},"threadId":1,"time":189735125900500}, +{"type":"methodCall","callerSideSignature":"E.setC(C)","threadId":1,"lineNum":3}, +{"type":"methodEntry","signature":"void E.setC(C)","receiver":{"class":"E","id":1028566121},"args":[{"class":"C","id":1550089733}],"threadId":1,"time":189735125929800}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":4,"time":189735125980700}, +{"type":"methodExit","shortSignature":"E.setC(C)","receiver":{"class":"E","id":1028566121},"returnValue":{"class":"void","id":0},"threadId":1,"time":189735126042500}, +{"type":"methodExit","shortSignature":"C.passD(D)","receiver":{"class":"C","id":1550089733},"returnValue":{"class":"void","id":0},"threadId":1,"time":189735126092200}, +{"type":"methodExit","shortSignature":"D.passB(B)","receiver":{"class":"D","id":1118140819},"returnValue":{"class":"void","id":0},"threadId":1,"time":189735126127000}, +{"type":"methodExit","shortSignature":"A.m()","receiver":{"class":"A","id":1442407170},"returnValue":{"class":"void","id":0},"threadId":1,"time":189735126177300}, +{"type":"methodExit","shortSignature":"Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":189735126242900}, diff --git a/traces/pre_Exp4.txt b/traces/pre_Exp4.txt new file mode 100644 index 0000000..246b776 --- /dev/null +++ b/traces/pre_Exp4.txt @@ -0,0 +1,50 @@ +{"type":"classDef","name":"Main","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp4/bin/Main.class","loaderPath":"/"}, +{"type":"methodEntry","signature":"public static void Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":118352462}],"threadId":1,"time":189767951131800}, +{"type":"blockEntry","methodSignature":"Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":3,"time":189767951158500}, +{"type":"methodCall","callerSideSignature":"A()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"A","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp4/bin/A.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public A()","class":"A","args":[],"threadId":1,"time":189767952335300}, +{"type":"methodCall","callerSideSignature":"B()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"B","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp4/bin/B.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public B()","class":"B","args":[],"threadId":1,"time":189767953475400}, +{"type":"methodCall","callerSideSignature":"C()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"C","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp4/bin/C.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public C()","class":"C","args":[],"threadId":1,"time":189767954169300}, +{"type":"constructorExit","shortSignature":"C()","returnValue":{"class":"C","id":1550089733},"threadId":1,"time":189767954204100}, +{"type":"fieldSet","fieldName":"B.c","container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":2,"time":189767954239000}, +{"type":"constructorExit","shortSignature":"B()","returnValue":{"class":"B","id":865113938},"threadId":1,"time":189767954248800}, +{"type":"fieldSet","fieldName":"A.b","container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":2,"time":189767954272900}, +{"type":"methodCall","callerSideSignature":"D()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"D","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp4/bin/D.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public D()","class":"D","args":[],"threadId":1,"time":189767955075700}, +{"type":"methodCall","callerSideSignature":"E()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"E","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp4/bin/E.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public E()","class":"E","args":[],"threadId":1,"time":189767955942600}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"---","id":0},"threadId":1,"lineNum":2,"time":189767955986000}, +{"type":"constructorExit","shortSignature":"E()","returnValue":{"class":"E","id":1028566121},"threadId":1,"time":189767955996200}, +{"type":"fieldSet","fieldName":"D.e","container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":2,"time":189767956038400}, +{"type":"constructorExit","shortSignature":"D()","returnValue":{"class":"D","id":1118140819},"threadId":1,"time":189767956068300}, +{"type":"fieldSet","fieldName":"A.d","container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":3,"time":189767956127300}, +{"type":"constructorExit","shortSignature":"A()","returnValue":{"class":"A","id":1442407170},"threadId":1,"time":189767956160500}, +{"type":"methodCall","callerSideSignature":"A.m()","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"void A.m()","receiver":{"class":"A","id":1442407170},"args":[],"threadId":1,"time":189767956194300}, +{"type":"blockEntry","methodSignature":"A.m()","blockId":0,"incomings":0,"threadId":1,"lineNum":5,"time":189767956212300}, +{"type":"fieldGet","fieldName":"A.d","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":5,"time":189767956227700}, +{"type":"methodCall","callerSideSignature":"D.getE()","threadId":1,"lineNum":5}, +{"type":"methodEntry","signature":"E D.getE()","receiver":{"class":"D","id":1118140819},"args":[],"threadId":1,"time":189767956244400}, +{"type":"blockEntry","methodSignature":"D.getE()","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189767956254100}, +{"type":"fieldGet","fieldName":"D.e","this":{"class":"D","id":1118140819},"container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":4,"time":189767956267000}, +{"type":"methodExit","shortSignature":"D.getE()","receiver":{"class":"D","id":1118140819},"returnValue":{"class":"E","id":1028566121},"threadId":1,"time":189767956277600}, +{"type":"fieldGet","fieldName":"A.b","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":5,"time":189767956291500}, +{"type":"methodCall","callerSideSignature":"B.getC()","threadId":1,"lineNum":5}, +{"type":"methodEntry","signature":"C B.getC()","receiver":{"class":"B","id":865113938},"args":[],"threadId":1,"time":189767956311900}, +{"type":"blockEntry","methodSignature":"B.getC()","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189767956321000}, +{"type":"fieldGet","fieldName":"B.c","this":{"class":"B","id":865113938},"container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":4,"time":189767956342700}, +{"type":"methodExit","shortSignature":"B.getC()","receiver":{"class":"B","id":865113938},"returnValue":{"class":"C","id":1550089733},"threadId":1,"time":189767956354400}, +{"type":"methodCall","callerSideSignature":"E.setC(C)","threadId":1,"lineNum":5}, +{"type":"methodEntry","signature":"void E.setC(C)","receiver":{"class":"E","id":1028566121},"args":[{"class":"C","id":1550089733}],"threadId":1,"time":189767956428100}, +{"type":"blockEntry","methodSignature":"E.setC(C)","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189767956451700}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":4,"time":189767956472600}, +{"type":"methodExit","shortSignature":"E.setC(C)","receiver":{"class":"E","id":1028566121},"returnValue":{"class":"void","id":0},"threadId":1,"time":189767956484400}, +{"type":"methodExit","shortSignature":"A.m()","receiver":{"class":"A","id":1442407170},"returnValue":{"class":"void","id":0},"threadId":1,"time":189767956497800}, +{"type":"methodExit","shortSignature":"Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":189767956508100}, diff --git a/traces/pre_Exp5.txt b/traces/pre_Exp5.txt new file mode 100644 index 0000000..0d666e0 --- /dev/null +++ b/traces/pre_Exp5.txt @@ -0,0 +1,58 @@ +{"type":"classDef","name":"Main","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp5/bin/Main.class","loaderPath":"/"}, +{"type":"methodEntry","signature":"public static void Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":118352462}],"threadId":1,"time":189800651375600}, +{"type":"blockEntry","methodSignature":"Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":3,"time":189800651403100}, +{"type":"methodCall","callerSideSignature":"A()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"A","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp5/bin/A.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public A()","class":"A","args":[],"threadId":1,"time":189800653189600}, +{"type":"methodCall","callerSideSignature":"B()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"B","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp5/bin/B.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public B()","class":"B","args":[],"threadId":1,"time":189800654886300}, +{"type":"methodCall","callerSideSignature":"C()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"C","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp5/bin/C.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public C()","class":"C","args":[],"threadId":1,"time":189800656051200}, +{"type":"constructorExit","shortSignature":"C()","returnValue":{"class":"C","id":1550089733},"threadId":1,"time":189800656141300}, +{"type":"fieldSet","fieldName":"B.c","container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":2,"time":189800656197300}, +{"type":"constructorExit","shortSignature":"B()","returnValue":{"class":"B","id":865113938},"threadId":1,"time":189800656214100}, +{"type":"fieldSet","fieldName":"A.b","container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":2,"time":189800656260000}, +{"type":"methodCall","callerSideSignature":"D()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"D","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp5/bin/D.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public D()","class":"D","args":[],"threadId":1,"time":189800657478200}, +{"type":"methodCall","callerSideSignature":"E()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"E","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp5/bin/E.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public E()","class":"E","args":[],"threadId":1,"time":189800658522100}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"---","id":0},"threadId":1,"lineNum":2,"time":189800658568700}, +{"type":"constructorExit","shortSignature":"E()","returnValue":{"class":"E","id":1028566121},"threadId":1,"time":189800658579100}, +{"type":"fieldSet","fieldName":"D.e","container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":2,"time":189800658622100}, +{"type":"constructorExit","shortSignature":"D()","returnValue":{"class":"D","id":1118140819},"threadId":1,"time":189800658658000}, +{"type":"fieldSet","fieldName":"A.d","container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":3,"time":189800658697200}, +{"type":"constructorExit","shortSignature":"A()","returnValue":{"class":"A","id":1442407170},"threadId":1,"time":189800658711500}, +{"type":"methodCall","callerSideSignature":"A.m()","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"void A.m()","receiver":{"class":"A","id":1442407170},"args":[],"threadId":1,"time":189800658766900}, +{"type":"blockEntry","methodSignature":"A.m()","blockId":0,"incomings":0,"threadId":1,"lineNum":5,"time":189800658785200}, +{"type":"fieldGet","fieldName":"A.b","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":5,"time":189800658813000}, +{"type":"methodCall","callerSideSignature":"B.setA(A)","threadId":1,"lineNum":5}, +{"type":"methodEntry","signature":"void B.setA(A)","receiver":{"class":"B","id":865113938},"args":[{"class":"A","id":1442407170}],"threadId":1,"time":189800658846000}, +{"type":"blockEntry","methodSignature":"B.setA(A)","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189800658859800}, +{"type":"fieldGet","fieldName":"B.c","this":{"class":"B","id":865113938},"container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":4,"time":189800658879800}, +{"type":"methodCall","callerSideSignature":"C.setA(A)","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"void C.setA(A)","receiver":{"class":"C","id":1550089733},"args":[{"class":"A","id":1442407170}],"threadId":1,"time":189800658931800}, +{"type":"blockEntry","methodSignature":"C.setA(A)","blockId":0,"incomings":0,"threadId":1,"lineNum":3,"time":189800658945200}, +{"type":"methodCall","callerSideSignature":"A.getD()","threadId":1,"lineNum":3}, +{"type":"methodEntry","signature":"D A.getD()","receiver":{"class":"A","id":1442407170},"args":[],"threadId":1,"time":189800658971000}, +{"type":"blockEntry","methodSignature":"A.getD()","blockId":0,"incomings":0,"threadId":1,"lineNum":8,"time":189800658984700}, +{"type":"fieldGet","fieldName":"A.d","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":8,"time":189800659003800}, +{"type":"methodExit","shortSignature":"A.getD()","receiver":{"class":"A","id":1442407170},"returnValue":{"class":"D","id":1118140819},"threadId":1,"time":189800659022800}, +{"type":"methodCall","callerSideSignature":"D.setC(C)","threadId":1,"lineNum":3}, +{"type":"methodEntry","signature":"void D.setC(C)","receiver":{"class":"D","id":1118140819},"args":[{"class":"C","id":1550089733}],"threadId":1,"time":189800659057300}, +{"type":"blockEntry","methodSignature":"D.setC(C)","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189800659068300}, +{"type":"fieldGet","fieldName":"D.e","this":{"class":"D","id":1118140819},"container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":4,"time":189800659091300}, +{"type":"methodCall","callerSideSignature":"E.setC(C)","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"void E.setC(C)","receiver":{"class":"E","id":1028566121},"args":[{"class":"C","id":1550089733}],"threadId":1,"time":189800659122900}, +{"type":"blockEntry","methodSignature":"E.setC(C)","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189800659137100}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":4,"time":189800659150600}, +{"type":"methodExit","shortSignature":"E.setC(C)","receiver":{"class":"E","id":1028566121},"returnValue":{"class":"void","id":0},"threadId":1,"time":189800659166500}, +{"type":"methodExit","shortSignature":"D.setC(C)","receiver":{"class":"D","id":1118140819},"returnValue":{"class":"void","id":0},"threadId":1,"time":189800659184200}, +{"type":"methodExit","shortSignature":"C.setA(A)","receiver":{"class":"C","id":1550089733},"returnValue":{"class":"void","id":0},"threadId":1,"time":189800659198800}, +{"type":"methodExit","shortSignature":"B.setA(A)","receiver":{"class":"B","id":865113938},"returnValue":{"class":"void","id":0},"threadId":1,"time":189800659216600}, +{"type":"methodExit","shortSignature":"A.m()","receiver":{"class":"A","id":1442407170},"returnValue":{"class":"void","id":0},"threadId":1,"time":189800659230900}, +{"type":"methodExit","shortSignature":"Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":189800659242200}, diff --git a/traces/pre_Exp6.txt b/traces/pre_Exp6.txt new file mode 100644 index 0000000..5b7fde4 --- /dev/null +++ b/traces/pre_Exp6.txt @@ -0,0 +1,54 @@ +{"type":"classDef","name":"Main","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp6/bin/Main.class","loaderPath":"/"}, +{"type":"methodEntry","signature":"public static void Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":118352462}],"threadId":1,"time":189828604826900}, +{"type":"blockEntry","methodSignature":"Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":3,"time":189828604869800}, +{"type":"methodCall","callerSideSignature":"A()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"A","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp6/bin/A.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public A()","class":"A","args":[],"threadId":1,"time":189828606381300}, +{"type":"methodCall","callerSideSignature":"B()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"B","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp6/bin/B.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public B()","class":"B","args":[],"threadId":1,"time":189828608077800}, +{"type":"methodCall","callerSideSignature":"C()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"C","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp6/bin/C.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public C()","class":"C","args":[],"threadId":1,"time":189828609356200}, +{"type":"constructorExit","shortSignature":"C()","returnValue":{"class":"C","id":1550089733},"threadId":1,"time":189828609410200}, +{"type":"fieldSet","fieldName":"B.c","container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":2,"time":189828609457500}, +{"type":"constructorExit","shortSignature":"B()","returnValue":{"class":"B","id":865113938},"threadId":1,"time":189828609470900}, +{"type":"fieldSet","fieldName":"A.b","container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":2,"time":189828609509700}, +{"type":"methodCall","callerSideSignature":"D()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"D","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp6/bin/D.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public D()","class":"D","args":[],"threadId":1,"time":189828610765200}, +{"type":"methodCall","callerSideSignature":"E()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"E","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp6/bin/E.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public E()","class":"E","args":[],"threadId":1,"time":189828612102400}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"---","id":0},"threadId":1,"lineNum":2,"time":189828612193500}, +{"type":"constructorExit","shortSignature":"E()","returnValue":{"class":"E","id":1028566121},"threadId":1,"time":189828612231600}, +{"type":"fieldSet","fieldName":"D.e","container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":2,"time":189828612308300}, +{"type":"constructorExit","shortSignature":"D()","returnValue":{"class":"D","id":1118140819},"threadId":1,"time":189828612625500}, +{"type":"fieldSet","fieldName":"A.d","container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":3,"time":189828612764600}, +{"type":"constructorExit","shortSignature":"A()","returnValue":{"class":"A","id":1442407170},"threadId":1,"time":189828612786300}, +{"type":"methodCall","callerSideSignature":"A.m()","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"void A.m()","receiver":{"class":"A","id":1442407170},"args":[],"threadId":1,"time":189828612837000}, +{"type":"blockEntry","methodSignature":"A.m()","blockId":0,"incomings":0,"threadId":1,"lineNum":5,"time":189828612854900}, +{"type":"fieldGet","fieldName":"A.b","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":5,"time":189828612876800}, +{"type":"fieldGet","fieldName":"A.d","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":5,"time":189828612899600}, +{"type":"methodCall","callerSideSignature":"B.passD(D)","threadId":1,"lineNum":5}, +{"type":"methodEntry","signature":"void B.passD(D)","receiver":{"class":"B","id":865113938},"args":[{"class":"D","id":1118140819}],"threadId":1,"time":189828612933200}, +{"type":"blockEntry","methodSignature":"B.passD(D)","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189828612947300}, +{"type":"fieldGet","fieldName":"B.c","this":{"class":"B","id":865113938},"container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":4,"time":189828612967100}, +{"type":"methodCall","callerSideSignature":"D.getE()","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"E D.getE()","receiver":{"class":"D","id":1118140819},"args":[],"threadId":1,"time":189828612995900}, +{"type":"blockEntry","methodSignature":"D.getE()","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189828613009400}, +{"type":"fieldGet","fieldName":"D.e","this":{"class":"D","id":1118140819},"container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":4,"time":189828613028900}, +{"type":"methodExit","shortSignature":"D.getE()","receiver":{"class":"D","id":1118140819},"returnValue":{"class":"E","id":1028566121},"threadId":1,"time":189828613048600}, +{"type":"methodCall","callerSideSignature":"C.passE(E)","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"void C.passE(E)","receiver":{"class":"C","id":1550089733},"args":[{"class":"E","id":1028566121}],"threadId":1,"time":189828613078600}, +{"type":"blockEntry","methodSignature":"C.passE(E)","blockId":0,"incomings":0,"threadId":1,"lineNum":3,"time":189828613093300}, +{"type":"methodCall","callerSideSignature":"E.setC(C)","threadId":1,"lineNum":3}, +{"type":"methodEntry","signature":"void E.setC(C)","receiver":{"class":"E","id":1028566121},"args":[{"class":"C","id":1550089733}],"threadId":1,"time":189828613120800}, +{"type":"blockEntry","methodSignature":"E.setC(C)","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189828613130000}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":4,"time":189828613147200}, +{"type":"methodExit","shortSignature":"E.setC(C)","receiver":{"class":"E","id":1028566121},"returnValue":{"class":"void","id":0},"threadId":1,"time":189828613166000}, +{"type":"methodExit","shortSignature":"C.passE(E)","receiver":{"class":"C","id":1550089733},"returnValue":{"class":"void","id":0},"threadId":1,"time":189828613184100}, +{"type":"methodExit","shortSignature":"B.passD(D)","receiver":{"class":"B","id":865113938},"returnValue":{"class":"void","id":0},"threadId":1,"time":189828613202200}, +{"type":"methodExit","shortSignature":"A.m()","receiver":{"class":"A","id":1442407170},"returnValue":{"class":"void","id":0},"threadId":1,"time":189828613241000}, +{"type":"methodExit","shortSignature":"Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":189828613269200}, diff --git a/traces/pre_Exp7.txt b/traces/pre_Exp7.txt new file mode 100644 index 0000000..9948c84 --- /dev/null +++ b/traces/pre_Exp7.txt @@ -0,0 +1,50 @@ +{"type":"classDef","name":"Main","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp7/bin/Main.class","loaderPath":"/"}, +{"type":"methodEntry","signature":"public static void Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":118352462}],"threadId":1,"time":189858565361200}, +{"type":"blockEntry","methodSignature":"Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":3,"time":189858565568400}, +{"type":"methodCall","callerSideSignature":"A()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"A","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp7/bin/A.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public A()","class":"A","args":[],"threadId":1,"time":189858567477500}, +{"type":"methodCall","callerSideSignature":"B()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"B","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp7/bin/B.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public B()","class":"B","args":[],"threadId":1,"time":189858569339600}, +{"type":"methodCall","callerSideSignature":"C()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"C","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp7/bin/C.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public C()","class":"C","args":[],"threadId":1,"time":189858571014700}, +{"type":"constructorExit","shortSignature":"C()","returnValue":{"class":"C","id":1550089733},"threadId":1,"time":189858571076800}, +{"type":"fieldSet","fieldName":"B.c","container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":2,"time":189858571125500}, +{"type":"constructorExit","shortSignature":"B()","returnValue":{"class":"B","id":865113938},"threadId":1,"time":189858571136200}, +{"type":"fieldSet","fieldName":"A.b","container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":2,"time":189858571160800}, +{"type":"methodCall","callerSideSignature":"D()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"D","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp7/bin/D.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public D()","class":"D","args":[],"threadId":1,"time":189858572102800}, +{"type":"methodCall","callerSideSignature":"E()","threadId":1,"lineNum":2}, +{"type":"classDef","name":"E","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/Exp7/bin/E.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public E()","class":"E","args":[],"threadId":1,"time":189858572985700}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"---","id":0},"threadId":1,"lineNum":2,"time":189858573026600}, +{"type":"constructorExit","shortSignature":"E()","returnValue":{"class":"E","id":1028566121},"threadId":1,"time":189858573040900}, +{"type":"fieldSet","fieldName":"D.e","container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":2,"time":189858573076000}, +{"type":"constructorExit","shortSignature":"D()","returnValue":{"class":"D","id":1118140819},"threadId":1,"time":189858573084400}, +{"type":"fieldSet","fieldName":"A.d","container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":3,"time":189858573128600}, +{"type":"constructorExit","shortSignature":"A()","returnValue":{"class":"A","id":1442407170},"threadId":1,"time":189858573143200}, +{"type":"methodCall","callerSideSignature":"A.m()","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"void A.m()","receiver":{"class":"A","id":1442407170},"args":[],"threadId":1,"time":189858573166200}, +{"type":"blockEntry","methodSignature":"A.m()","blockId":0,"incomings":0,"threadId":1,"lineNum":5,"time":189858573178300}, +{"type":"fieldGet","fieldName":"A.d","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":5,"time":189858573192700}, +{"type":"fieldGet","fieldName":"A.b","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":5,"time":189858573206000}, +{"type":"methodCall","callerSideSignature":"B.getC()","threadId":1,"lineNum":5}, +{"type":"methodEntry","signature":"C B.getC()","receiver":{"class":"B","id":865113938},"args":[],"threadId":1,"time":189858573225100}, +{"type":"blockEntry","methodSignature":"B.getC()","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189858573231600}, +{"type":"fieldGet","fieldName":"B.c","this":{"class":"B","id":865113938},"container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":4,"time":189858573244600}, +{"type":"methodExit","shortSignature":"B.getC()","receiver":{"class":"B","id":865113938},"returnValue":{"class":"C","id":1550089733},"threadId":1,"time":189858573257300}, +{"type":"methodCall","callerSideSignature":"D.passC(C)","threadId":1,"lineNum":5}, +{"type":"methodEntry","signature":"void D.passC(C)","receiver":{"class":"D","id":1118140819},"args":[{"class":"C","id":1550089733}],"threadId":1,"time":189858573277700}, +{"type":"blockEntry","methodSignature":"D.passC(C)","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189858573284300}, +{"type":"fieldGet","fieldName":"D.e","this":{"class":"D","id":1118140819},"container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":4,"time":189858573296200}, +{"type":"methodCall","callerSideSignature":"E.setC(C)","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"void E.setC(C)","receiver":{"class":"E","id":1028566121},"args":[{"class":"C","id":1550089733}],"threadId":1,"time":189858573316000}, +{"type":"blockEntry","methodSignature":"E.setC(C)","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":189858573322200}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":4,"time":189858573333800}, +{"type":"methodExit","shortSignature":"E.setC(C)","receiver":{"class":"E","id":1028566121},"returnValue":{"class":"void","id":0},"threadId":1,"time":189858573344200}, +{"type":"methodExit","shortSignature":"D.passC(C)","receiver":{"class":"D","id":1118140819},"returnValue":{"class":"void","id":0},"threadId":1,"time":189858573353300}, +{"type":"methodExit","shortSignature":"A.m()","receiver":{"class":"A","id":1442407170},"returnValue":{"class":"void","id":0},"threadId":1,"time":189858573384200}, +{"type":"methodExit","shortSignature":"Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":189858573425700},