ex11: done through CSV

This commit is contained in:
Claudio Maggioni 2023-01-28 17:57:59 +01:00
parent 7969cef8aa
commit aa826bf10f
4 changed files with 65 additions and 26 deletions

View file

@ -2,4 +2,5 @@ bin-profiler
build/profiler.jar
*.iml
.idea/
*.csv

View file

@ -2,25 +2,7 @@ package ex11;
import org.objectweb.asm.Opcodes;
import java.util.Objects;
public record CallInfo(int instruction, long index, String caller, String callee, String callTarget) {
private static final String FORMAT = "CallerMethodFQIN %s\nCallerBCI %d\ninvoketype %s\nCalleeMethodFQIN %s\nCallTargetFQIN %s";
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CallInfo callInfo = (CallInfo) o;
return instruction == callInfo.instruction && index == callInfo.index && caller.equals(callInfo.caller) &&
callee.equals(callInfo.callee) && callTarget.equals(callInfo.callTarget);
}
@Override
public int hashCode() {
return Objects.hash(instruction, index, caller, callee, callTarget);
}
public String invokeType() {
return switch (instruction) {
case Opcodes.INVOKEDYNAMIC -> "dynamic";
@ -31,10 +13,4 @@ public record CallInfo(int instruction, long index, String caller, String callee
default -> throw new IllegalStateException("Not an INVOKE* bytecode instruction: " + instruction);
};
}
@Override
public String toString() {
return String.format(FORMAT, caller, index, invokeType(), callee, callTarget);
}
}

View file

@ -0,0 +1,48 @@
package ex11;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class CallInfoCSVWriter {
private static final String[] headerLines = new String[]{
"CallerMethodFQIN",
"CallerBCI",
"invoketype",
"CalleeMethodFQIN",
"CallTargetFQIN",
"#invokes"
};
private final BufferedWriter outFile;
public CallInfoCSVWriter(final OutputStream outFile) throws IOException {
this.outFile = new BufferedWriter(new OutputStreamWriter(outFile));
writeLine(headerLines);
}
private static String escapeSpecialCharacters(final String data) {
final String escapedData = data.replaceAll("\\R", " ");
if (data.contains(",") || data.contains("\"") || data.contains("'")) {
return "\"%s\"".formatted(data.replace("\"", "\"\""));
} else {
return escapedData;
}
}
private void writeLine(final String... data) throws IOException {
final String line = Stream.of(data)
.map(CallInfoCSVWriter::escapeSpecialCharacters)
.collect(Collectors.joining(","));
outFile.write(line + "\n");
}
public void write(final CallInfo ci, long invokes) throws IOException {
writeLine(ci.caller(), Long.toString(ci.index()), ci.invokeType(), ci.callee(), ci.callTarget(),
Long.toString(invokes));
}
}

View file

@ -1,18 +1,32 @@
package ex11;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.HashMap;
import java.util.Map;
public final class Profiler {
private static final Map<CallInfo, long[]> count = new HashMap<>();
private static final Path outFile = Path.of("ex11.csv");
private static boolean stop = false;
static {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
stop = true;
try (final OutputStream path = Files.newOutputStream(outFile, StandardOpenOption.WRITE)) {
final CallInfoCSVWriter w = new CallInfoCSVWriter(path);
for (final var entry : count.entrySet()) {
System.out.println(entry.getKey().toString() + "\n#invokes " + entry.getValue()[0] + "\n");
w.write(entry.getKey(), entry.getValue()[0]);
}
System.out.println("Invocations have been written to: " + outFile.toAbsolutePath());
} catch (final IOException e) {
throw new RuntimeException("Writing CSV file with call info failed", e);
}
}));
}