Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@
import com.oracle.svm.configure.config.ConfigurationSet;
import com.oracle.svm.configure.config.conditional.ConditionalConfigurationPredicate;
import com.oracle.svm.configure.filters.ComplexFilter;
import com.oracle.svm.configure.filters.ConfigurationFilter;
import com.oracle.svm.configure.filters.FilterConfigurationParser;
import com.oracle.svm.configure.filters.HierarchyFilterNode;
import com.oracle.svm.configure.trace.AccessAdvisor;
Expand Down Expand Up @@ -137,6 +136,7 @@ protected JNIHandleSet constructJavaHandles(JNIEnvironment env) {
protected int onLoadCallback(JNIJavaVM vm, JvmtiEnv jvmti, JvmtiEventCallbacks callbacks, String options) {
String traceOutputFile = null;
String configOutputDir = null;
String ignoredEntriesFile = null;
ConfigurationFileCollection mergeConfigs = new ConfigurationFileCollection();
ConfigurationFileCollection omittedConfigs = new ConfigurationFileCollection();
boolean builtinCallerFilter = true;
Expand Down Expand Up @@ -170,6 +170,13 @@ protected int onLoadCallback(JNIJavaVM vm, JvmtiEnv jvmti, JvmtiEventCallbacks c
if (token.startsWith("config-merge-dir=")) {
mergeConfigs.addDirectory(Paths.get(configOutputDir));
}
} else if (token.startsWith("experimental-ignored-entries-output=")) {
if (ignoredEntriesFile != null) {
return usage("cannot specify ignored-entries-output= more than once.");
}
warn("Ignored entries logging (enabled by the \"experimental-ignored-entries-output\" argument) is " +
"experimental and will be removed in the future. Do not rely on this feature.");
ignoredEntriesFile = getTokenValue(token);
} else if (token.startsWith("config-to-omit=")) {
String omittedConfigDir = getTokenValue(token);
omittedConfigDir = transformPath(omittedConfigDir);
Expand Down Expand Up @@ -308,7 +315,7 @@ protected int onLoadCallback(JNIJavaVM vm, JvmtiEnv jvmti, JvmtiEventCallbacks c
if (experimentalOmitClasspathConfig) {
ignoreConfigFromClasspath(jvmti, omittedConfigs);
}
AccessAdvisor advisor = createAccessAdvisor(builtinHeuristicFilter, callerFilter, accessFilter);
AccessAdvisor advisor = new AccessAdvisor(builtinHeuristicFilter, callerFilter, accessFilter, ignoredEntriesFile);
TraceProcessor processor = new TraceProcessor(advisor);
ConfigurationSet omittedConfiguration = new ConfigurationSet();
Predicate<String> shouldExcludeClassesWithHash = null;
Expand Down Expand Up @@ -452,18 +459,6 @@ private static boolean checkJVMVersion(JvmtiEnv jvmti) {
return true;
}

private static AccessAdvisor createAccessAdvisor(boolean builtinHeuristicFilter, ConfigurationFilter callerFilter, ConfigurationFilter accessFilter) {
AccessAdvisor advisor = new AccessAdvisor();
advisor.setHeuristicsEnabled(builtinHeuristicFilter);
if (callerFilter != null) {
advisor.setCallerFilterTree(callerFilter);
}
if (accessFilter != null) {
advisor.setAccessFilterTree(accessFilter);
}
return advisor;
}

private static int parseIntegerOrNegative(String number) {
try {
return Integer.parseInt(number);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,101 +24,27 @@
*/
package com.oracle.svm.agent.tracing;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;

import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.MapCursor;

import com.oracle.svm.agent.tracing.core.Tracer;
import com.oracle.svm.agent.tracing.core.TracingResultWriter;
import com.oracle.svm.core.util.VMError;

import jdk.graal.compiler.util.json.JsonWriter;
import com.oracle.svm.configure.trace.JsonFileWriter;

public class TraceFileWriter extends Tracer implements TracingResultWriter {
private final Object lock = new Object();
private final BufferedWriter writer;
private boolean open = true;
private int written = 0;
private final JsonFileWriter jsonFileWriter;

@SuppressWarnings("this-escape")
public TraceFileWriter(Path path) throws IOException {
writer = Files.newBufferedWriter(path);
JsonWriter json = new JsonWriter(writer);
json.append('[').newline();
jsonFileWriter = new JsonFileWriter(path);
traceInitialization();
json.flush(); // avoid close() on underlying stream
}

@Override
protected void traceEntry(EconomicMap<String, Object> entry) {
try {
StringWriter str = new StringWriter();
try (JsonWriter json = new JsonWriter(str)) {
json.append('{');
boolean first = true;
MapCursor<String, Object> cursor = entry.getEntries();
while (cursor.advance()) {
if (!first) {
json.append(", ");
}
json.quote(cursor.getKey()).append(':');
if (cursor.getValue() instanceof Object[]) {
printArray(json, (Object[]) cursor.getValue());
} else {
printValue(json, cursor.getValue());
}
first = false;
}
json.append('}');
}
traceEntry(str.toString());
} catch (IOException e) {
throw VMError.shouldNotReachHere(e);
}
}

private static void printArray(JsonWriter json, Object[] array) throws IOException {
json.append('[');
for (int i = 0; i < array.length; i++) {
if (i > 0) {
json.append(',');
}
Object obj = array[i];
if (obj instanceof Object[]) {
printArray(json, (Object[]) obj);
} else {
printValue(json, array[i]);
}
}
json.append(']');
}

private static void printValue(JsonWriter json, Object value) throws IOException {
Object s = null;
if (value instanceof byte[]) {
s = Base64.getEncoder().encodeToString((byte[]) value);
} else if (value != null) {
s = value;
}
json.printValue(s);
}

private void traceEntry(String s) throws IOException {
synchronized (lock) {
if (open) { // late events on exit
if (written > 0) {
writer.write(",\n");
}
writer.write(s);
written++;
}
}
jsonFileWriter.printObject(entry);
}

@Override
Expand All @@ -133,13 +59,6 @@ public boolean supportsPeriodicTraceWriting() {

@Override
public void close() {
synchronized (lock) {
try {
writer.write("\n]\n");
writer.close();
} catch (IOException ignored) {
}
open = false;
}
jsonFileWriter.close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -282,15 +282,7 @@ protected static void generate(Iterator<String> argumentsIterator, boolean accep
}

if (!traceInputs.isEmpty()) {
AccessAdvisor advisor = new AccessAdvisor();
advisor.setHeuristicsEnabled(builtinHeuristicFilter);
if (callersFilter != null) {
advisor.setCallerFilterTree(callersFilter);
}
if (accessFilter != null) {
advisor.setAccessFilterTree(accessFilter);
}

AccessAdvisor advisor = new AccessAdvisor(builtinHeuristicFilter, callersFilter, accessFilter, null);
TraceProcessor processor = new TraceProcessor(advisor);
for (URI uri : traceInputs) {
try (Reader reader = Files.newBufferedReader(Paths.get(uri))) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public abstract class AbstractProcessor {
AbstractProcessor() {
}

abstract void processEntry(EconomicMap<String, ?> entry, ConfigurationSet configurationSet);
abstract void processEntry(EconomicMap<String, Object> entry, ConfigurationSet configurationSet);

void setInLivePhase(@SuppressWarnings("unused") boolean live) {
}
Expand All @@ -59,4 +59,17 @@ static byte[] asBinary(Object obj) {
}
return Base64.getDecoder().decode((String) obj);
}

/**
* Returns a fresh copy of the trace entry with an additional key-value pair identifying it.
* Useful when logging entries to the access advisor.
*/
protected EconomicMap<String, Object> copyWithUniqueEntry(EconomicMap<String, Object> entry, String key, Object value) {
if (entry.containsKey(key)) {
throw new AssertionError(String.format("Tried to set unique identifier %s but field already exists: %s%n", key, entry));
}
EconomicMap<String, Object> result = EconomicMap.create(entry);
result.put(key, value);
return result;
}
}
Loading