diff --git a/JavassistTest/.classpath b/JavassistTest/.classpath
new file mode 100644
index 0000000..5923d21
--- /dev/null
+++ b/JavassistTest/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/JavassistTest/.project b/JavassistTest/.project
new file mode 100644
index 0000000..be295c6
--- /dev/null
+++ b/JavassistTest/.project
@@ -0,0 +1,17 @@
+
+
+ JavassistTest
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/JavassistTest/bin/.gitignore b/JavassistTest/bin/.gitignore
new file mode 100644
index 0000000..bf8bba0
--- /dev/null
+++ b/JavassistTest/bin/.gitignore
@@ -0,0 +1,3 @@
+/instrumenter/
+/sample/
+/tracer/
diff --git a/JavassistTest/sample/F.class b/JavassistTest/sample/F.class
new file mode 100644
index 0000000..eabeb80
--- /dev/null
+++ b/JavassistTest/sample/F.class
Binary files differ
diff --git a/JavassistTest/src/instrumenter/Instrumenter.java b/JavassistTest/src/instrumenter/Instrumenter.java
new file mode 100644
index 0000000..ec6015b
--- /dev/null
+++ b/JavassistTest/src/instrumenter/Instrumenter.java
@@ -0,0 +1,67 @@
+package instrumenter;
+
+import java.io.IOException;
+
+import javassist.CannotCompileException;
+import javassist.ClassPool;
+import javassist.CodeConverter;
+import javassist.CtClass;
+import javassist.CtMethod;
+import javassist.NotFoundException;
+import javassist.bytecode.BadBytecode;
+import javassist.bytecode.analysis.ControlFlow;
+import javassist.bytecode.analysis.ControlFlow.Block;
+import javassist.expr.ExprEditor;
+import javassist.expr.MethodCall;
+
+public class Instrumenter {
+
+ public static void main(String[] args) {
+ ClassPool cp = ClassPool.getDefault();
+ CtClass cc;
+ try {
+ cc = cp.get("sample.F");
+ CtMethod m = cc.getDeclaredMethod("getC");
+ ControlFlow cf = new ControlFlow(m);
+ Block[] blocks = cf.basicBlocks();
+ int block0 = m.getMethodInfo().getLineNumber(blocks[0].position());
+ int block1 = m.getMethodInfo().getLineNumber(blocks[1].position());
+ int block2 = m.getMethodInfo().getLineNumber(blocks[2].position());
+ int block3 = m.getMethodInfo().getLineNumber(blocks[3].position());
+ int block4 = m.getMethodInfo().getLineNumber(blocks[4].position());
+ m.insertAt(block0, "System.out.println(\"block0:\" + " + block0 + ");");
+ m.insertAt(block1, "System.out.println(\"block1:\" + " + block1 + ");");
+ m.insertAt(block2, "System.out.println(\"block2:\" + " + block2 + ");");
+ m.insertAt(block3, "System.out.println(\"block3:\" + " + block3 + ");");
+ m.insertAt(block4, "System.out.println(\"block4:\" + " + block4 + ");");
+
+
+// int block0 = m.getMethodInfo().getLineNumber(blocks[0].position());
+// m.insertAt(block0, "System.out.println(\"block0\");");
+// m = cc.getDeclaredMethod("getC");
+// cf = new ControlFlow(m);
+// blocks = cf.basicBlocks();
+// int block1 = m.getMethodInfo().getLineNumber(blocks[1].position());
+// m.insertAt(block1, "System.out.println(\"block1\");");
+// m = cc.getDeclaredMethod("getC");
+// cf = new ControlFlow(m);
+// blocks = cf.basicBlocks();
+// int block2 = m.getMethodInfo().getLineNumber(blocks[2].position());
+// m.insertAt(block2, "System.out.println(\"block2\");");
+
+// m.instrument(new ExprEditor() {
+// public void edit(MethodCall m) throws CannotCompileException {
+// if (m.getClassName().equals("Hello")
+// && m.getMethodName().equals("say"))
+// m.replace("$0.hi();");
+// }
+// });
+ cc.writeFile("bin");
+ } catch (NotFoundException | BadBytecode | CannotCompileException | IOException e) {
+ e.printStackTrace();
+// } catch (CannotCompileException | IOException e) {
+// e.printStackTrace();
+ }
+ }
+
+}
diff --git a/JavassistTest/src/sample/A2.java b/JavassistTest/src/sample/A2.java
new file mode 100644
index 0000000..d05a07d
--- /dev/null
+++ b/JavassistTest/src/sample/A2.java
@@ -0,0 +1,10 @@
+package sample;
+
+public class A2 {
+ F f = new F();
+ D d = new D();
+
+ public void m() {
+ d.passB(f, 10);
+ }
+}
diff --git a/JavassistTest/src/sample/B.java b/JavassistTest/src/sample/B.java
new file mode 100644
index 0000000..3c33693
--- /dev/null
+++ b/JavassistTest/src/sample/B.java
@@ -0,0 +1,9 @@
+package sample;
+
+public class B {
+ C c = new C();
+
+ public C getC() {
+ return c;
+ }
+}
diff --git a/JavassistTest/src/sample/C.java b/JavassistTest/src/sample/C.java
new file mode 100644
index 0000000..731faaf
--- /dev/null
+++ b/JavassistTest/src/sample/C.java
@@ -0,0 +1,5 @@
+package sample;
+
+public class C {
+
+}
diff --git a/JavassistTest/src/sample/D.java b/JavassistTest/src/sample/D.java
new file mode 100644
index 0000000..fe4e592
--- /dev/null
+++ b/JavassistTest/src/sample/D.java
@@ -0,0 +1,10 @@
+package sample;
+
+public class D {
+ E e = new E();
+ B b = new B();
+ public void passB(B b, int i) {
+ C c = b.getC();
+ e.setC(c);
+ }
+}
diff --git a/JavassistTest/src/sample/E.java b/JavassistTest/src/sample/E.java
new file mode 100644
index 0000000..1d110ed
--- /dev/null
+++ b/JavassistTest/src/sample/E.java
@@ -0,0 +1,15 @@
+package sample;
+
+public class E {
+ C c = new C();
+ C c2 = new C();
+
+
+ public void setC(C c) {
+ System.out.println("this.c = "+this.c.toString() +"/ Argu c = "+ c.toString());
+ System.out.println("this.c = "+this.c.hashCode() +"/ Argu c = "+ c.hashCode());
+ this.c = c;
+
+ }
+
+}
diff --git a/JavassistTest/src/sample/F.java b/JavassistTest/src/sample/F.java
new file mode 100644
index 0000000..2d04086
--- /dev/null
+++ b/JavassistTest/src/sample/F.java
@@ -0,0 +1,14 @@
+package sample;
+
+public class F extends B {
+ C c = null;
+
+ public C getC() {
+ if (c == null) {
+ for (int n = 0; n < 3; n++) {
+ c = super.getC();
+ }
+ }
+ return c;
+ }
+}
diff --git a/JavassistTest/src/sample/Main.java b/JavassistTest/src/sample/Main.java
new file mode 100644
index 0000000..13862ea
--- /dev/null
+++ b/JavassistTest/src/sample/Main.java
@@ -0,0 +1,16 @@
+package sample;
+
+public class Main {
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ // TODO Auto-generated method stub
+ A2 a = new A2();
+ A2 b = new A2();
+ a.m();
+ b.m();
+ }
+
+}
diff --git a/JavassistTest/src/tracer/MyPrintStream.java b/JavassistTest/src/tracer/MyPrintStream.java
new file mode 100644
index 0000000..c703ffb
--- /dev/null
+++ b/JavassistTest/src/tracer/MyPrintStream.java
@@ -0,0 +1,92 @@
+package tracer;
+
+import java.util.ArrayList;
+
+public class MyPrintStream extends Thread {
+ private static MyPrintStream theInstance;
+ private static ArrayList output;
+ private static String s;
+// private static boolean bFlushed = false;
+// private static int count = 0;
+
+ private static MyPrintStream getInstance() {
+ if (theInstance == null) {
+ theInstance = new MyPrintStream();
+ output = new ArrayList();
+ Runtime.getRuntime().addShutdownHook(theInstance); // �V���b�g�_�E���p
+// theInstance.start();
+ }
+ return theInstance;
+ }
+
+ public static void print(int n) {
+ getInstance()._print(n);
+ }
+
+ public static void print(String s) {
+ getInstance()._print(s);
+ }
+
+ public static void println() {
+ getInstance()._println();
+ }
+
+ public static void println(String s) {
+ getInstance()._println(s);
+ }
+
+ public void run() {
+// if (count == 0) {
+// // �ʏ�̃g���[�X�o��
+// count++;
+// String s;
+// Runtime.getRuntime().addShutdownHook(new MyPrintStream()); // �V���b�g�_�E���p�ɂ����ЂƂC���X�^���X���쐬����
+// while(!bFlushed) {
+// try {
+// Thread.sleep(10);
+// if (output.size() > 0) {
+// synchronized (output) {
+// s = output.remove(0);
+// }
+// System.out.println(s);
+// }
+// } catch (InterruptedException e) {
+// e.printStackTrace();
+// }
+// }
+// } else {
+ // �V���b�g�_�E�����Ƀo�b�t�@�Ɏc�����g���[�X���o�͂���
+// bFlushed = true;
+ for (int n = 0; n < output.size(); n++) {
+ System.out.println(output.get(n));
+ }
+// }
+ }
+
+ private void _print(int n) {
+ if (s == null) s = new String();
+ s += n;
+ }
+
+ private void _print(String s1) {
+ if (s == null) s = new String();
+ s += s1;
+ }
+
+ private void _println() {
+ if (s == null) s = new String();
+ synchronized (output) {
+ output.add(s);
+ }
+ s = new String();
+ }
+
+ private void _println(String s1) {
+ if (s == null) s = new String();
+ s += s1;
+ synchronized (output) {
+ output.add(s);
+ }
+ s = new String();
+ }
+}
diff --git a/JavassistTest/src/tracer/Tracer.java b/JavassistTest/src/tracer/Tracer.java
new file mode 100644
index 0000000..dc4b908
--- /dev/null
+++ b/JavassistTest/src/tracer/Tracer.java
@@ -0,0 +1,194 @@
+package tracer;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.Enumeration;
+
+import javassist.CannotCompileException;
+import javassist.ClassPool;
+import javassist.CodeConverter;
+import javassist.CodeConverter.ArrayAccessReplacementMethodNames;
+import javassist.CtClass;
+import javassist.CtField;
+import javassist.CtMethod;
+import javassist.Modifier;
+import javassist.NotFoundException;
+import javassist.bytecode.BadBytecode;
+import javassist.bytecode.analysis.ControlFlow;
+import javassist.bytecode.analysis.ControlFlow.Block;
+import javassist.expr.ExprEditor;
+import javassist.expr.FieldAccess;
+import javassist.expr.MethodCall;
+
+public class Tracer {
+
+ public static void main(String[] args) {
+ String packageName = "sample"; // �w�肵���p�b�P�[�W�����̑S�N���X�ɃC���X�g�D�������e�[�V�������s��
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ URL resource = loader.getResource(packageName);
+ File dir;
+ try {
+ dir = new File( URLDecoder.decode(resource.getPath(), "UTF-8"));
+ for (String file : dir.list()) {
+ if (file.endsWith(".class")) {
+ String className = packageName + "." + file.replace(".class", "");
+ classInstrumentation(className);
+ }
+ }
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * �w�肵���N���X�ɃC���X�g�D�������e�[�V�������s���i���j
+ * @param className �N���X��
+ */
+ private static void classInstrumentation(String className) {
+ ClassPool cp = ClassPool.getDefault();
+ CtClass cc;
+ try {
+ cc = cp.get(className);
+ for (CtMethod m : cc.getDeclaredMethods()) {
+ ControlFlow cf = new ControlFlow(m);
+ String declaredClassName = cc.getName();
+ String longName = m.getLongName();
+ String methodSignature = m.getSignature();
+ if ((m.getModifiers() & Modifier.STATIC) == 0) {
+ CtClass parameterClasses[] = m.getParameterTypes();
+ String parameters = "\",{\"";
+ String delimiter = " + ";
+ int p = 1;
+ for (CtClass c: parameterClasses) {
+ if (!c.isPrimitive()) {
+ parameters += delimiter + "System.identityHashCode($" + p + ")";
+ delimiter = " + \",\" + ";
+ }
+ p++;
+ }
+ // System.out.println("System.out.println(\"Method " + declaredClassName + "," + longName + ":\" + System.identityHashCode(this) + " + parameters + " + \"}:ThreadNo \" + Thread.currentThread().getId());");
+ m.insertBefore("System.out.println(\"Method " + declaredClassName + "," + longName + ":\" + System.identityHashCode(this) + " + parameters + " + \"}:ThreadNo \" + Thread.currentThread().getId());");
+ m.instrument(new ExprEditor() {
+ public void edit(FieldAccess f) throws CannotCompileException {
+ if (f.isReader()) {
+ f.replace("{$_ = $proceed(); System.out.println(\"FieldGet \" + System.identityHashCode($0) + \",\" + System.identityHashCode($_));}");
+ } else {
+ f.replace("$proceed($$); System.out.println(\"FieldSet \" + System.identityHashCode($0) + \",\" + System.identityHashCode($1));");
+ }
+ }
+ });
+ m.insertAfter("System.out.println(\"Return:\" + System.identityHashCode($_));");
+ // CodeConverter conv = new CodeConverter();
+ // conv.replaceArrayAccess(cc, new ArrayAccessReplacementMethodNames() {
+ // @Override
+ // public String shortWrite() {
+ // return null;
+ // }
+ // @Override
+ // public String shortRead() {
+ // return null;
+ // }
+ // @Override
+ // public String objectWrite() {
+ // return null;
+ // }
+ // @Override
+ // public String objectRead() {
+ // return null;
+ // }
+ // @Override
+ // public String longWrite() {
+ // return null;
+ // }
+ // @Override
+ // public String longRead() {
+ // return null;
+ // }
+ // @Override
+ // public String intWrite() {
+ // return null;
+ // }
+ // @Override
+ // public String intRead() {
+ // return null;
+ // }
+ // @Override
+ // public String floatWrite() {
+ // return null;
+ // }
+ // @Override
+ // public String floatRead() {
+ // return null;
+ // }
+ // @Override
+ // public String doubleWrite() {
+ // return null;
+ // }
+ // @Override
+ // public String doubleRead() {
+ // return null;
+ // }
+ // @Override
+ // public String charWrite() {
+ // return null;
+ // }
+ // @Override
+ // public String charRead() {
+ // return null;
+ // }
+ // @Override
+ // public String byteOrBooleanWrite() {
+ // return null;
+ // }
+ // @Override
+ // public String byteOrBooleanRead() {
+ // return null;
+ // }
+ // });
+ }
+ Block[] blocks = cf.basicBlocks();
+ int block0 = m.getMethodInfo().getLineNumber(blocks[0].position());
+ // int block1 = m.getMethodInfo().getLineNumber(blocks[1].position());
+ // int block2 = m.getMethodInfo().getLineNumber(blocks[2].position());
+ // int block3 = m.getMethodInfo().getLineNumber(blocks[3].position());
+ // int block4 = m.getMethodInfo().getLineNumber(blocks[4].position());
+ m.insertAt(block0, "System.out.println(\"block0:\" + " + block0 + ");");
+ // m.insertAt(block1, "System.out.println(\"block1:\" + " + block1 + ");");
+ // m.insertAt(block2, "System.out.println(\"block2:\" + " + block2 + ");");
+ // m.insertAt(block3, "System.out.println(\"block3:\" + " + block3 + ");");
+ // m.insertAt(block4, "System.out.println(\"block4:\" + " + block4 + ");");
+
+
+ // int block0 = m.getMethodInfo().getLineNumber(blocks[0].position());
+ // m.insertAt(block0, "System.out.println(\"block0\");");
+ // m = cc.getDeclaredMethod("getC");
+ // cf = new ControlFlow(m);
+ // blocks = cf.basicBlocks();
+ // int block1 = m.getMethodInfo().getLineNumber(blocks[1].position());
+ // m.insertAt(block1, "System.out.println(\"block1\");");
+ // m = cc.getDeclaredMethod("getC");
+ // cf = new ControlFlow(m);
+ // blocks = cf.basicBlocks();
+ // int block2 = m.getMethodInfo().getLineNumber(blocks[2].position());
+ // m.insertAt(block2, "System.out.println(\"block2\");");
+
+ // m.instrument(new ExprEditor() {
+ // public void edit(MethodCall m) throws CannotCompileException {
+ // if (m.getClassName().equals("Hello")
+ // && m.getMethodName().equals("say"))
+ // m.replace("$0.hi();");
+ // }
+ // });
+ }
+ cc.writeFile("bin");
+ } catch (NotFoundException | BadBytecode | CannotCompileException | IOException e) {
+ e.printStackTrace();
+// } catch (CannotCompileException | IOException e) {
+// e.printStackTrace();
+ }
+ }
+
+}