diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/trace/Alias.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/trace/Alias.java new file mode 100644 index 0000000..4ffeaff --- /dev/null +++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/trace/Alias.java @@ -0,0 +1,173 @@ +package org.ntlab.traceCollector.tracer.trace; + +import java.util.ArrayList; + +/** + * �I�u�W�F�N�g�̎Q�Ə��(�G�C���A�X)��\���N���X + * @author Isitani + * + */ +public class Alias { + private String objectId; + private TracePoint occurrencePoint; // ���Y�I�u�W�F�N�g�̎Q�Ƃ��s���Ă�����s�ӏ��ɑΉ�����TracePoint + /** + * ���Y�I�u�W�F�N�g�̎Q�Ƃ�TracePoint�ɂ����Ăǂ��Ɍ���Ă��邩��\��
+ * 0 �t�B�[���h�A�N�Z�X���̃R���e�i �������� ���\�b�h�Ăяo�����̃��V�[�o
+ * 1, 2, 3 �c�c n �t�B�[���h�A�N�Z�X���̃t�B�[���h(1) �������� ���\�b�h�Ăяo������n�Ԗڂ̎����� (1���珇�Ԃ�)
+ * -1 ���\�b�h�Ăяo�����̖߂�l
+ *
+ * ��1: d = a.m(b, c);
+ *
+ * ��1�̎��s���ɂ�����, a�̓��\�b�h�Ăяo���̃��V�[�o�Ȃ̂�0, b�̓��\�b�h�Ăяo����1�Ԗڂ̎������Ȃ̂�1,
+ * c�̓��\�b�h�Ăяo����2�Ԗڂ̎������Ȃ̂�2, a.m(b, c)�̖߂�l��-1 �ƂȂ�.
+ *
+ * ��2: d = a.f;
+ * ��2�̎��s���ɂ�����, a�̓t�B�[���h�̃R���e�i�Ȃ̂�0, b�̓t�B�[���h�Ȃ̂�1 �ƂȂ�. + * + */ + private int occurrenceExp; + public static final int OCCURRENCE_EXP_CONTAINER = 0; + public static final int OCCURRENCE_EXP_RECEIVER = 0; + public static final int OCCURRENCE_EXP_FIELD = 1; + public static final int OCCURRENCE_EXP_ARRAY = 1; + public static final int OCCURRENCE_EXP_FIRST_ARG = 1; + public static final int OCCURRENCE_EXP_RETURN = -1; + + + public Alias(String objectId, TracePoint occurrencePoint, int occurrenceExp) { + this.objectId = objectId; + this.occurrencePoint = occurrencePoint; + this.occurrenceExp = occurrenceExp; + } + + public String getObjectId() { + return objectId; + } + + public TracePoint getOccurrencePoint() { + return occurrencePoint; + } + + public int getOccurrenceExp() { + return occurrenceExp; + } + + public MethodExecution getMethodExecution() { + return occurrencePoint.getMethodExecution(); + } + + public String getMethodSignature() { + return occurrencePoint.getMethodExecution().getCallerSideSignature(); + } + + public int getLineNo() { + Statement statement = occurrencePoint.getStatement(); + return statement.getLineNo(); + } + + public String getStatementType() { + Statement statement = occurrencePoint.getStatement(); + String statementType = ""; + if (statement instanceof FieldAccess) { + FieldAccess fa = (FieldAccess)statement; + statementType = "FieldAccess"; + } else if (statement instanceof FieldUpdate) { + FieldUpdate fu = (FieldUpdate)statement; + statementType = "FieldUpdate"; + } else if (statement instanceof ArrayAccess) { + ArrayAccess aa = (ArrayAccess)statement; + statementType = "ArrayAccess"; + } else if (statement instanceof ArrayUpdate) { + ArrayUpdate au = (ArrayUpdate)statement; + statementType = "ArrayUpdate"; + } else if (statement instanceof ArrayCreate) { + ArrayCreate ac = (ArrayCreate)statement; + statementType = "ArrayCreate"; + } else if (statement instanceof MethodInvocation) { + MethodExecution me = ((MethodInvocation)statement).getCalledMethodExecution(); + statementType = "MethodInvocation"; + } + return statementType; + } + + public String getStatementSignature() { + Statement statement = occurrencePoint.getStatement(); + String statementSignature = ""; + if (statement instanceof FieldAccess) { + FieldAccess fa = (FieldAccess)statement; + statementSignature = fa.getFieldName(); + } else if (statement instanceof FieldUpdate) { + FieldUpdate fu = (FieldUpdate)statement; + statementSignature = fu.getFieldName(); + } else if (statement instanceof ArrayAccess) { + ArrayAccess aa = (ArrayAccess)statement; + statementSignature = aa.getArrayClassName() + "[" + aa.getIndex() + "]"; + } else if (statement instanceof ArrayUpdate) { + ArrayUpdate au = (ArrayUpdate)statement; + statementSignature = au.getArrayClassName() + "[" + au.getIndex() + "]"; + } else if (statement instanceof ArrayCreate) { + ArrayCreate ac = (ArrayCreate)statement; + statementSignature = ac.getArrayClassName(); + } else if (statement instanceof MethodInvocation) { + MethodExecution me = ((MethodInvocation)statement).getCalledMethodExecution(); + statementSignature = me.getCallerSideSignature(); + } + return statementSignature; + } + + public String getClassName() { + Statement statement = occurrencePoint.getStatement(); + String className = ""; + if (statement instanceof FieldAccess) { + if (occurrenceExp == OCCURRENCE_EXP_CONTAINER) { + className = ((FieldAccess) statement).getContainerClassName(); + } else if (occurrenceExp == OCCURRENCE_EXP_FIELD) { + className = ((FieldAccess) statement).getValueClassName(); + } + } else if (statement instanceof FieldUpdate) { + if (occurrenceExp == OCCURRENCE_EXP_CONTAINER) { + className = ((FieldUpdate) statement).getContainerClassName(); + } else if (occurrenceExp == OCCURRENCE_EXP_FIELD) { + className = ((FieldUpdate) statement).getValueClassName(); + } + } else if (statement instanceof ArrayAccess) { + className = ((ArrayAccess) statement).getValueClassName(); + } else if (statement instanceof ArrayUpdate) { + className = ((ArrayUpdate) statement).getValueClassName(); + } else if (statement instanceof ArrayCreate) { + className = ((ArrayCreate) statement).getArrayClassName(); + } else if (statement instanceof MethodInvocation) { + MethodExecution me = ((MethodInvocation)statement).getCalledMethodExecution(); + if (occurrenceExp == OCCURRENCE_EXP_RETURN) { + className = me.getReturnValue().getActualType(); + } else if (occurrenceExp == OCCURRENCE_EXP_RECEIVER) { + className = me.getThisClassName(); + } else { + int index = occurrenceExp - OCCURRENCE_EXP_FIRST_ARG; + ArrayList args = me.getArguments(); + if (index >= 0 && index < args.size()) { + className = me.getArguments().get(index).getActualType(); + } + } + } + return className; + } + + @Override + public String toString() { + Statement statement = occurrencePoint.getStatement(); + String className = getClassName(); + String methodSignature = getMethodSignature(); + String statementType = getStatementType(); + String statementSigunarure = getStatementSignature(); + String indent = " "; + StringBuilder str = new StringBuilder(); + str.append("objId: " + objectId + " (class = " + className + ")" + "\n"); + str.append("tp: " + occurrencePoint + "\n"); + str.append(indent + "signature: " + methodSignature + "\n"); + str.append(indent + "lineNo: " + statement.getLineNo() + "\n"); + str.append(indent + "statementType: " + statementType + " -> " + statementSigunarure + "\n"); + str.append("occurrenceExp: " + occurrenceExp + "\n"); + return str.toString(); + } +} diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/trace/MethodExecution.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/trace/MethodExecution.java index c16140c..3eabbf5 100644 --- a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/trace/MethodExecution.java +++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/trace/MethodExecution.java @@ -268,13 +268,21 @@ * @return �����œn���ꂽmethodExecution���Ăяo�������Ƃ��L�^���Ă��郁�\�b�h�Ăяo�� */ public MethodInvocation getMethodInvocation(MethodExecution child) { - for (Statement statement : statements) { - if (statement instanceof MethodInvocation) { - MethodExecution calledMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution(); - if (calledMethodExecution.equals(child)) { - return (MethodInvocation)statement; - } - } + int callerStatementExecution = child.getCallerStatementExecution(); + if (callerStatementExecution != -1) { + return (MethodInvocation)statements.get(callerStatementExecution); + } + return null; + } + + /** + * order���w�肵�đΉ�����TracePoint��Ԃ� + * @param order TracePoint��order + * @return + */ + public TracePoint getTracePoint(int order) { + if (order < this.getStatements().size()) { + return new TracePoint(this, order); } return null; } diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/trace/TraceJSON.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/trace/TraceJSON.java index a8231c8..7a5037c 100644 --- a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/trace/TraceJSON.java +++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/trace/TraceJSON.java @@ -7,12 +7,16 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Stack; import org.ntlab.traceCollector.tracer.OnlineTraceOutput; +//import com.sun.jdi.ObjectReference; +//import com.sun.jdi.Value; + public class TraceJSON extends Trace { // private static TraceJSON theTrace = null; private HashMap classes = new HashMap<>(); @@ -844,7 +848,7 @@ if (getInstance().thread != null) getInstance().thread.blockEnter(Integer.parseInt(blockId), Integer.parseInt(incomings), Integer.parseInt(lineNum), timeStamp); } - public static ThreadInstance getThreadInstanceForDebuggingControl(String threadId) { + public static ThreadInstance getThreadInstance(String threadId) { return getInstance().threads.get(threadId); } @@ -875,18 +879,30 @@ * @param thread * @return */ - public static FieldUpdate getRecentlyFieldUpdateForDebuggingControl(String containerObjId, String fieldName, Thread thread) { + public static FieldUpdate getRecentlyFieldUpdate(String containerObjId, String fieldName, Thread thread) { TracePoint before = getCurrentTracePoint(thread); if (!before.isValid()) { before.stepBackOver(); + if (!before.isValid()) { + return null; // �t�����T���ł���ȏ�H��Ȃ������ꍇ(root���\�b�h���s��1�s�ڂȂ�)�@���ꂪ�Ȃ��Ǝ��s����TimeoutException�ŗ����� + } } - TracePoint tp = getFieldUpdateTracePointForDebuggingControl(containerObjId, fieldName, before); + TracePoint tp = getFieldUpdateTracePoint(containerObjId, fieldName, before); if (tp != null && tp.getStatement() instanceof FieldUpdate) { return (FieldUpdate)tp.getStatement(); } return null; } + private static TracePoint getRecentlyFieldUpdate(TracePoint tp) { + Statement statement = tp.getStatement(); + if (statement instanceof FieldAccess) { + FieldAccess fa = (FieldAccess)statement; + return getFieldUpdateTracePoint(fa.getContainerObjId(), fa.getFieldName(), tp); + } + return null; + } + /** * �����Ŏw�肵���R���e�i�̎��“���̃t�B�[���h���Ō�ɍX�V���ꂽstatement���t�����ɒT�����āA
* ���‚�����statement�ɑΉ�����TracePoint��Ԃ� @@ -895,7 +911,7 @@ * @param before * @return */ - public static TracePoint getFieldUpdateTracePointForDebuggingControl(final String containerObjId, final String fieldName, TracePoint before) { + public static TracePoint getFieldUpdateTracePoint(final String containerObjId, final String fieldName, TracePoint before) { before = before.duplicate(); before = getInstance().traverseStatementsInTraceBackward(new IStatementVisitor() { @Override @@ -926,18 +942,30 @@ * @param thread * @return */ - public static ArrayUpdate getRecentlyArrayUpdateForDebuggingControl(String arrayObjId, int index, Thread thread) { + public static ArrayUpdate getRecentlyArrayUpdate(String arrayObjId, int index, Thread thread) { TracePoint before = getCurrentTracePoint(thread); if (!before.isValid()) { before.stepBackOver(); + if (!before.isValid()) { + return null; // �t�����T���ł���ȏ�H��Ȃ������ꍇ(root���\�b�h���s��1�s�ڂȂ�)�@���ꂪ�Ȃ��Ǝ��s����TimeoutException�ŗ����� + } } - TracePoint tp = getArrayUpdateTracePointForDebuggingControl(arrayObjId, index, before); + TracePoint tp = getArrayUpdateTracePoint(arrayObjId, index, before); if (tp != null && tp.getStatement() instanceof ArrayUpdate) { return (ArrayUpdate)tp.getStatement(); } return null; } - + + private static TracePoint getRecentlyArrayUpdate(TracePoint tp) { + Statement statement = tp.getStatement(); + if (statement instanceof ArrayAccess) { + ArrayAccess aa = (ArrayAccess)statement; + return getArrayUpdateTracePoint(aa.getArrayObjectId(), aa.getIndex(), tp); + } + return null; + } + /** * �����Ŏw�肵���z��ŁA���Žw�肵���C���f�b�N�X���Ō�ɍX�V���ꂽstatement���t�����ɒT�����āA
* ���‚�����statement�ɑΉ�����TracePoint��Ԃ� @@ -946,7 +974,7 @@ * @param before * @return */ - public static TracePoint getArrayUpdateTracePointForDebuggingControl(final String arrayObjId, final int index, TracePoint before) { + public static TracePoint getArrayUpdateTracePoint(final String arrayObjId, final int index, TracePoint before) { before = before.duplicate(); before = getInstance().traverseStatementsInTraceBackward(new IStatementVisitor() { @Override @@ -969,4 +997,135 @@ } return null; } + + public static ArrayList findAllStartAlias(MethodExecution me) { + ArrayList startAliasList = new ArrayList<>(); + List statements = me.getStatements(); + for (int i = 0; i < statements.size(); i++) { + TracePoint tp = me.getTracePoint(i); + Statement statement = statements.get(i); + if (statement instanceof FieldAccess) { + FieldAccess fa = (FieldAccess)statement; + startAliasList.add(new Alias(fa.getContainerObjId(), tp, Alias.OCCURRENCE_EXP_CONTAINER)); + startAliasList.add(new Alias(fa.getValueObjId(), tp, Alias.OCCURRENCE_EXP_FIELD)); + } else if (statement instanceof FieldUpdate) { + FieldUpdate fu = (FieldUpdate)statement; + startAliasList.add(new Alias(fu.getContainerObjId(), tp, Alias.OCCURRENCE_EXP_CONTAINER)); + startAliasList.add(new Alias(fu.getValueObjId(), tp, Alias.OCCURRENCE_EXP_FIELD)); + } else if (statement instanceof ArrayAccess) { + String valueObjId = ((ArrayAccess)statement).getValueObjectId(); + startAliasList.add(new Alias(valueObjId, tp, Alias.OCCURRENCE_EXP_ARRAY)); + } else if (statement instanceof ArrayUpdate) { + String valueObjId = ((ArrayUpdate)statement).getValueObjectId(); + startAliasList.add(new Alias(valueObjId, tp, Alias.OCCURRENCE_EXP_ARRAY)); + } else if (statement instanceof ArrayCreate) { + String valueObjId = ((ArrayAccess)statement).getValueObjectId(); + startAliasList.add(new Alias(valueObjId, tp, Alias.OCCURRENCE_EXP_RETURN)); + } else if (statement instanceof MethodInvocation) { + MethodExecution calledMe = ((MethodInvocation)statement).getCalledMethodExecution(); + startAliasList.add(new Alias(calledMe.getThisObjId(), tp, Alias.OCCURRENCE_EXP_RECEIVER)); + List args = calledMe.getArguments(); + for (int j = 0; j < args.size(); j++) { + startAliasList.add(new Alias(args.get(j).getId(), tp, (j + Alias.OCCURRENCE_EXP_FIRST_ARG))); + } + startAliasList.add(new Alias(calledMe.getReturnValue().getId(), tp, Alias.OCCURRENCE_EXP_RETURN)); + } + } + return startAliasList; + } + + public static Alias getAlias(String objectId, TracePoint occurrencePoint, int occurrenceExp) { + return new Alias(objectId, occurrencePoint, occurrenceExp); + } + + public static ArrayList> getObjectFlow(Alias startAlias) { + ArrayList> aliasLists = new ArrayList<>(); + ArrayList aliasList = new ArrayList<>(); + aliasLists.add(aliasList); +// aliasList.add(alias); + String objId = startAlias.getObjectId(); + TracePoint tp = startAlias.getOccurrencePoint().duplicate(); + ArrayList> resultLists = getObjectFlow(aliasLists, objId, tp, 0); + for (int i = 0; i < resultLists.size(); i++) { + ArrayList resultList = resultLists.get(i); + System.out.println("---------------------------------------------------------"); // �m�F�p + for (Alias alias : resultList) System.out.println(alias); // �m�F�p +// int lastAliasOccurrenceEXP = resultList.get(resultList.size() - 1).getOccurrenceExp(); +// if (lastAliasOccurrenceEXP != Alias.OCCURRENCE_EXP_RETURN) { +// resultLists.remove(resultList); // �����̃G�C���A�X���z�񐶐���R���X�g���N�^�Ăяo���ł͂Ȃ����X�g���폜���� +// } + } + return resultLists; + } + + private static ArrayList> getObjectFlow(ArrayList> aliasLists, + String objId, TracePoint tp, int side) { + ArrayList aliasList = aliasLists.get(aliasLists.size() - 1); // ����getObjectFlow���\�b�h���s���Ō��‚������G�C���A�X�����Ă������X�g + do { + Statement statement = tp.getStatement(); + if (statement instanceof FieldAccess) { + // �t�B�[���h�Q�Ƃ̏ꍇ + FieldAccess fa = (FieldAccess)statement; + if (fa.getValueObjId().equals(objId)) { + // ���Y�n�_�ł̃G�C���A�X�����X�g�ɒlj��������, �t�B�[���h�ŏI�X�V�ɔ�ԃp�^�[���Ƃ��̂܂ܑk��p�^�[���Ƃŕ��� + aliasList.add(new Alias(objId, tp.duplicate(), Alias.OCCURRENCE_EXP_FIELD)); + aliasList = new ArrayList<>(aliasList); // ���X�g���̂��f�B�[�v�R�s�[���Ă���(�t�B�[���h�ŏI�X�V�ɔ�ԍċA�����I�����, ���̂܂ܑk��p�^�[���ŗp����) + TracePoint fieldUpdateTp = getRecentlyFieldUpdate(tp); + aliasLists = getObjectFlow(aliasLists, objId, fieldUpdateTp, 0); + aliasLists.add(aliasList); // �ċA�����ɓ���O�Ƀf�B�[�v�R�s�[���Ă������X�g���Ō���ɒlj� (�ȍ~�̑k��ɂ���Č��‚����G�C���A�X�͂��̃��X�g�ɓ������) + } + } else if (statement instanceof ArrayAccess) { + // �z��v�f�Q�Ƃ̏ꍇ + ArrayAccess aa = (ArrayAccess)statement; + if (aa.getValueObjectId().equals(objId)) { + aliasList.add(new Alias(objId, tp.duplicate(), Alias.OCCURRENCE_EXP_ARRAY)); + aliasList = new ArrayList<>(aliasList); + TracePoint arrayUpdateTp = getRecentlyArrayUpdate(tp); + aliasLists = getObjectFlow(aliasLists, objId, arrayUpdateTp, 0); + aliasLists.add(aliasList); + } + } else if (statement instanceof ArrayCreate) { + // �z�񐶐��̏ꍇ + ArrayCreate ac = (ArrayCreate)statement; + if (ac.getArrayObjectId().equals(objId)) { + aliasList.add(new Alias(objId, tp.duplicate(), Alias.OCCURRENCE_EXP_RETURN)); // �z�񐶐��� new �^��[] �̖߂�l + return aliasLists; // �z�񐶐��ӏ��̓G�C���A�X�̋N���Ȃ̂ł���ȑO�ɂ͂����Ȃ��͂� + } + } else if (statement instanceof MethodInvocation) { + // ���\�b�h�Ăяo���̏ꍇ + MethodExecution calledMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution(); + ObjectReference returnValue = calledMethodExecution.getReturnValue(); + if (returnValue.getId().equals(objId)) { + // �߂�l�ɃG�C���A�X�̃I�u�W�F�N�gID����v�����ꍇ + aliasList.add(new Alias(objId, tp.duplicate(), Alias.OCCURRENCE_EXP_RETURN)); + if (calledMethodExecution.isConstructor()) { + System.out.println("return (Constructor)"); + return aliasLists; // �R���X�g���N�^�Ăяo���ӏ��̓G�C���A�X�̋N���Ȃ̂ł���ȑO�ɂ͂����Ȃ��͂� + } + TracePoint exitTp = calledMethodExecution.getExitPoint(); // �Ăяo�����\�b�h���s�̍ŏI�X�e�[�g�����g���w��tp���擾 + aliasLists = getObjectFlow(aliasLists, objId, exitTp, side + 1); // �Ăяo����̃��\�b�h���s�ɐ��� + aliasList = aliasLists.get(aliasLists.size() - 1); + } + } + } while (tp.stepBackOver()); // �Ăяo�����ɖ߂邩����ȏ�H��Ȃ��Ȃ�܂Ń��[�v + if (!tp.isValid()) { + return aliasLists; // ����ȏチ�\�b�h���s��k��Ȃ��ꍇ(main���\�b�h�̂���ɑO�Ȃ�)�͂��̎��_�ŏI�� + } + // --- ���̎��_�� tracePoint�� �Ăяo�������w���Ă��� (���O�܂ők���Ă������\�b�h���s�ɂ‚��Ẵ��\�b�h�Ăяo�����w���Ă���) --- + MethodExecution calledMethodExecution = ((MethodInvocation)tp.getStatement()).getCalledMethodExecution(); + ArrayList args = calledMethodExecution.getArguments(); + for (int i = 0; i < args.size(); i++) { + if (args.get(i).getId().equals(objId)) { + // ���\�b�h�Ăяo���̎������ɃG�C���A�X�̃I�u�W�F�N�gID����v�����ꍇ + aliasList.add(new Alias(objId, tp.duplicate(), (i + Alias.OCCURRENCE_EXP_FIRST_ARG))); + if (side == 0) { + // �T���J�n���\�b�h���s�܂��̓t�B�[���h��z��v�f�̍ŏI�X�V�T���Ŕ�񂾐�̃��\�b�h���s����, �X�^�b�N�g���[�X�ł��ǂ��S���\�b�h���s�̏ꍇ + TracePoint previousTp = tp.duplicate(); + previousTp.stepBackOver(); + aliasLists = getObjectFlow(aliasLists, objId, previousTp, 0); // �Ăяo�����̃��\�b�h���s�ɖ߂� + } + } + } + return aliasLists; + } }