ex11: done through CSV
This commit is contained in:
parent
7969cef8aa
commit
aa826bf10f
4 changed files with 65 additions and 26 deletions
1
DiSLProject2022/.gitignore
vendored
1
DiSLProject2022/.gitignore
vendored
|
@ -2,4 +2,5 @@ bin-profiler
|
||||||
build/profiler.jar
|
build/profiler.jar
|
||||||
*.iml
|
*.iml
|
||||||
.idea/
|
.idea/
|
||||||
|
*.csv
|
||||||
|
|
||||||
|
|
|
@ -2,25 +2,7 @@ package ex11;
|
||||||
|
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public record CallInfo(int instruction, long index, String caller, String callee, String callTarget) {
|
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() {
|
public String invokeType() {
|
||||||
return switch (instruction) {
|
return switch (instruction) {
|
||||||
case Opcodes.INVOKEDYNAMIC -> "dynamic";
|
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);
|
default -> throw new IllegalStateException("Not an INVOKE* bytecode instruction: " + instruction);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return String.format(FORMAT, caller, index, invokeType(), callee, callTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
48
DiSLProject2022/src-profiler/ex11/CallInfoCSVWriter.java
Normal file
48
DiSLProject2022/src-profiler/ex11/CallInfoCSVWriter.java
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +1,32 @@
|
||||||
package ex11;
|
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.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public final class Profiler {
|
public final class Profiler {
|
||||||
private static final Map<CallInfo, long[]> count = new HashMap<>();
|
private static final Map<CallInfo, long[]> count = new HashMap<>();
|
||||||
|
|
||||||
|
private static final Path outFile = Path.of("ex11.csv");
|
||||||
|
|
||||||
private static boolean stop = false;
|
private static boolean stop = false;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||||
stop = true;
|
stop = true;
|
||||||
|
try (final OutputStream path = Files.newOutputStream(outFile, StandardOpenOption.WRITE)) {
|
||||||
|
final CallInfoCSVWriter w = new CallInfoCSVWriter(path);
|
||||||
for (final var entry : count.entrySet()) {
|
for (final var entry : count.entrySet()) {
|
||||||
System.out.println(entry.getKey().toString() + "\n#invokes " + entry.getValue()[0] + "\n");
|
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);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue