Skip to content
Browse files

Support JSON formatting

  • Loading branch information...
1 parent 5eaef5c commit fcd6fc3be2098c012540254843ecf3130d188323 @Dinduks committed Jun 13, 2013
View
15 src/main/scala/com/Main.scala
@@ -12,7 +12,7 @@ import org.objectweb.asm.{ClassReader, ClassWriter}
object Main {
def main (args: Array[String]) {
- if (2 == args.size) {
+ if (2 <= args.size) {
if (args(0) == "printinvi") {
try {
val path = Paths.get(args(1))
@@ -29,11 +29,12 @@ object Main {
} else if (args(0) == "patch") {
val sourcePath: Path = Paths.get(System.getProperty("user.dir")).resolve(args(1))
val sourceFile: File = new java.io.File(sourcePath.toString)
+ val jsonify = args.size == 3 && args(2) == "--json"
if (FileFilterUtils.suffixFileFilter("class").accept(sourceFile)) {
- patchAClass(sourcePath)
+ patchAClass(sourcePath, jsonify)
} else if (FileFilterUtils.suffixFileFilter("jar").accept(sourceFile)) {
- patchAJar(sourcePath)
+ patchAJar(sourcePath, jsonify)
} else {
println("The specified file is neither a JAR nor a class")
}
@@ -65,14 +66,14 @@ object Main {
}
}
- def patchAClass(sourcePath: Path) = {
+ def patchAClass(sourcePath: Path, jsonify: Boolean) = {
val targetPath: Path = sourcePath.getParent.resolve("indy").resolve(sourcePath.getFileName)
try { Files.createDirectory(targetPath.getParent) } catch { case _: Throwable => () }
try {
val is = Files.newInputStream(sourcePath, StandardOpenOption.READ)
- val cw: ClassWriter = Transformer.invokeVirtualToInvokeDynamic(new ClassReader(is))
+ val cw: ClassWriter = Transformer.invokeVirtualToInvokeDynamic(new ClassReader(is), jsonify)
val bytes: Array[Byte] = cw.toByteArray
Files.write(targetPath, bytes)
@@ -84,7 +85,7 @@ object Main {
}
}
- def patchAJar(sourcePath: Path) = {
+ def patchAJar(sourcePath: Path, jsonify: Boolean) = {
try {
val jarFiles: Seq[String] = JarUtil.getFiles(sourcePath)
val extractionDir: Path = Paths.get("%s%smireille-test-%s".format(System.getProperty("java.io.tmpdir"),
@@ -103,7 +104,7 @@ object Main {
} else {
val is = Files.newInputStream(extractionDir.resolve(jarFile), StandardOpenOption.READ)
val classReader: ClassReader = new ClassReader(is)
- val cw: ClassWriter = Transformer.invokeVirtualToInvokeDynamic(classReader)
+ val cw: ClassWriter = Transformer.invokeVirtualToInvokeDynamic(classReader, jsonify)
val bytes: Array[Byte] = cw.toByteArray
Files.createDirectories(targetPath.resolve(jarFile).getParent)
View
4 src/main/scala/com/dindane/mireille/Transformer.scala
@@ -10,9 +10,9 @@ import visitors.InvokeDynamicTransformerVisitor
*/
object Transformer {
- def invokeVirtualToInvokeDynamic(classReader: ClassReader): ClassWriter = {
+ def invokeVirtualToInvokeDynamic(classReader: ClassReader, jsonify: Boolean): ClassWriter = {
val classWriter = new ClassWriter(0)
- val classVisitor = new InvokeDynamicTransformerVisitor(classReader.getClassName, classWriter)
+ val classVisitor = new InvokeDynamicTransformerVisitor(classReader.getClassName, classWriter, jsonify)
classReader.accept(classVisitor, 0)
CheckClassAdapter.verify(new ClassReader(classWriter.toByteArray), false, new PrintWriter(System.err))
View
10 src/main/scala/com/dindane/mireille/runtime/CallSiteInformation.java
@@ -38,11 +38,11 @@ public String jsonify() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("{");
- stringBuilder.append(String.format("\"object\" :%s,", obj));
- stringBuilder.append(String.format("\"methodName\" :%s,", methodName));
- stringBuilder.append(String.format("\"fileName\" :%s,", fileName));
- stringBuilder.append(String.format("\"lineNumber\" :%d,", lineNumber));
- stringBuilder.append(String.format("\"description\" :%s", description));
+ stringBuilder.append(String.format("\"object\": \"%s\",", obj));
+ stringBuilder.append(String.format("\"methodName\": \"%s\",", methodName));
+ stringBuilder.append(String.format("\"fileName\": \"%s\",", fileName));
+ stringBuilder.append(String.format("\"lineNumber\": %d,", lineNumber));
+ stringBuilder.append(String.format("\"description\": \"%s\"", description));
stringBuilder.append("}");
return stringBuilder.toString();
View
3 src/main/scala/com/dindane/mireille/runtime/CallSiteInformationMap.java
@@ -11,9 +11,10 @@ public String jsonify() {
for (String key : keySet()) {
for (CallSiteInformation csi : get(key)) {
stringBuilder.append(csi.jsonify());
+ stringBuilder.append(", ");
}
- stringBuilder.append(", ");
}
+ if (stringBuilder.length() > 1) stringBuilder.setLength(stringBuilder.length() - 2);
stringBuilder.append("]");
return stringBuilder.toString();
View
8 src/main/scala/com/dindane/mireille/runtime/RT.java
@@ -7,12 +7,14 @@
public class RT {
public MethodHandle FALLBACK;
- private HashMap<String, ArrayList<CallSiteInformation>> callsInfo = new CallSiteInformationMap();
+ private CallSiteInformationMap callsInfo = new CallSiteInformationMap();
private static RT instance;
+ private static boolean jsonify;
private PrintStream originalOutput = System.out;
- public static void init() {
+ public static void init(boolean jsonify_) {
+ jsonify = jsonify_;
instance = getInstance();
}
@@ -24,7 +26,7 @@ public static RT getInstance() {
private RT() {
System.setOut(new PrintStream(new NullOutputStream()));
- Runtime.getRuntime().addShutdownHook(new ShutDownHook(callsInfo, originalOutput));
+ Runtime.getRuntime().addShutdownHook(new ShutDownHook(callsInfo, originalOutput, jsonify));
}
public static CallSite bootstrap(MethodHandles.Lookup lookUp, String methodName, MethodType methodType,
View
16 src/main/scala/com/dindane/mireille/runtime/ShutDownHook.java
@@ -2,18 +2,19 @@
import java.io.PrintStream;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.Map;
public class ShutDownHook extends Thread {
- private HashMap<String, ArrayList<CallSiteInformation>> callsInfo;
- private HashMap<String, ArrayList<CallSiteInformation>> nonOptimCallsInfo = new HashMap<>();
+ private Boolean jsonify;
+ private CallSiteInformationMap callsInfo;
+ private CallSiteInformationMap nonOptimCallsInfo = new CallSiteInformationMap();
private PrintStream originalOutput;
- public ShutDownHook(HashMap<String, ArrayList<CallSiteInformation>> callsInfo, PrintStream originalOutput) {
+ public ShutDownHook(CallSiteInformationMap callsInfo, PrintStream originalOutput, boolean jsonify) {
super();
this.callsInfo = callsInfo;
this.originalOutput = originalOutput;
+ this.jsonify = jsonify;
}
@Override
@@ -22,20 +23,21 @@ public void run() {
int totalMethodCalls = 0;
- System.out.println("Non-optimized method calls:");
- System.out.println("===========================");
for (Map.Entry<String, ArrayList<CallSiteInformation>> info : callsInfo.entrySet()) {
totalMethodCalls += info.getValue().size();
if (info.getValue().size() > 2) nonOptimCallsInfo.put(info.getKey(), info.getValue());
}
- printRawSummary(totalMethodCalls);
+ if (jsonify) System.out.println(nonOptimCallsInfo.jsonify());
+ else printRawSummary(totalMethodCalls);
}
private void printRawSummary(int totalMethodCalls) {
int nonOptimCounter = 0;
String stringBuffer;
+ System.out.println("Summary");
+ System.out.println("=======");
for (Map.Entry<String, ArrayList<CallSiteInformation>> info : nonOptimCallsInfo.entrySet()) {
System.out.println();
for (CallSiteInformation callInfo : info.getValue()) {
View
16 src/main/scala/com/dindane/mireille/visitors/InvokeDynamicTransformerVisitor.scala
@@ -4,7 +4,7 @@ import java.lang.invoke.{CallSite, MethodType}
import java.lang.invoke.MethodHandles.Lookup
import org.objectweb.asm._
-class InvokeDynamicTransformerVisitor(className: String, classVisitor: ClassVisitor)
+class InvokeDynamicTransformerVisitor(className: String, classVisitor: ClassVisitor, jsonify: Boolean)
extends ClassVisitor(Opcodes.ASM4, classVisitor) {
private var fileName: Option[String] = None
@@ -18,17 +18,23 @@ class InvokeDynamicTransformerVisitor(className: String, classVisitor: ClassVisi
override def visitMethod(access: Int, name: String, desc: String, signature: String, exceptions: Array[String]) = {
val methodVisitor = classVisitor.visitMethod(access, name, desc, signature, exceptions)
- new InvokeDynamicTransformerAdapter(methodVisitor, fileName)
+ new InvokeDynamicTransformerAdapter(methodVisitor, fileName, jsonify, name)
}
-
}
-class InvokeDynamicTransformerAdapter(methodVisitor: MethodVisitor, fileName: Option[String])
+class InvokeDynamicTransformerAdapter(methodVisitor: MethodVisitor,
+ fileName: Option[String],
+ jsonify: Boolean,
+ methodName: String)
extends MethodVisitor(Opcodes.ASM4, methodVisitor) {
private var lineNumber: Option[Int] = None
override def visitCode() {
- super.visitMethodInsn(Opcodes.INVOKESTATIC, "main/scala/com/dindane/mireille/runtime/RT", "init", "()V")
+ // TODO: The INVOKESTATIC call isn't made if realized from inside the constructor
+ //if (methodName == "<init>") {
+ super.visitInsn(if (jsonify == true) Opcodes.ICONST_1 else Opcodes.ICONST_0);
+ super.visitMethodInsn(Opcodes.INVOKESTATIC, "main/scala/com/dindane/mireille/runtime/RT", "init", "(Z)V")
+ //}
}
override def visitLineNumber(line: Int, startLabel: Label) {

0 comments on commit fcd6fc3

Please sign in to comment.
Something went wrong with that request. Please try again.