Skip to content

Commit 1234f03

Browse files
committed
[GR-61524] Log configuration entries filtered by the NI agent.
PullRequest: graal/19922
2 parents b3d5a24 + 1ec7fd3 commit 1234f03

File tree

11 files changed

+311
-208
lines changed

11 files changed

+311
-208
lines changed

substratevm/src/com.oracle.svm.agent/src/com/oracle/svm/agent/NativeImageAgent.java

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@
7474
import com.oracle.svm.configure.config.ConfigurationSet;
7575
import com.oracle.svm.configure.config.conditional.ConditionalConfigurationPredicate;
7676
import com.oracle.svm.configure.filters.ComplexFilter;
77-
import com.oracle.svm.configure.filters.ConfigurationFilter;
7877
import com.oracle.svm.configure.filters.FilterConfigurationParser;
7978
import com.oracle.svm.configure.filters.HierarchyFilterNode;
8079
import com.oracle.svm.configure.trace.AccessAdvisor;
@@ -137,6 +136,7 @@ protected JNIHandleSet constructJavaHandles(JNIEnvironment env) {
137136
protected int onLoadCallback(JNIJavaVM vm, JvmtiEnv jvmti, JvmtiEventCallbacks callbacks, String options) {
138137
String traceOutputFile = null;
139138
String configOutputDir = null;
139+
String ignoredEntriesFile = null;
140140
ConfigurationFileCollection mergeConfigs = new ConfigurationFileCollection();
141141
ConfigurationFileCollection omittedConfigs = new ConfigurationFileCollection();
142142
boolean builtinCallerFilter = true;
@@ -170,6 +170,13 @@ protected int onLoadCallback(JNIJavaVM vm, JvmtiEnv jvmti, JvmtiEventCallbacks c
170170
if (token.startsWith("config-merge-dir=")) {
171171
mergeConfigs.addDirectory(Paths.get(configOutputDir));
172172
}
173+
} else if (token.startsWith("experimental-ignored-entries-output=")) {
174+
if (ignoredEntriesFile != null) {
175+
return usage("cannot specify ignored-entries-output= more than once.");
176+
}
177+
warn("Ignored entries logging (enabled by the \"experimental-ignored-entries-output\" argument) is " +
178+
"experimental and will be removed in the future. Do not rely on this feature.");
179+
ignoredEntriesFile = getTokenValue(token);
173180
} else if (token.startsWith("config-to-omit=")) {
174181
String omittedConfigDir = getTokenValue(token);
175182
omittedConfigDir = transformPath(omittedConfigDir);
@@ -308,7 +315,7 @@ protected int onLoadCallback(JNIJavaVM vm, JvmtiEnv jvmti, JvmtiEventCallbacks c
308315
if (experimentalOmitClasspathConfig) {
309316
ignoreConfigFromClasspath(jvmti, omittedConfigs);
310317
}
311-
AccessAdvisor advisor = createAccessAdvisor(builtinHeuristicFilter, callerFilter, accessFilter);
318+
AccessAdvisor advisor = new AccessAdvisor(builtinHeuristicFilter, callerFilter, accessFilter, ignoredEntriesFile);
312319
TraceProcessor processor = new TraceProcessor(advisor);
313320
ConfigurationSet omittedConfiguration = new ConfigurationSet();
314321
Predicate<String> shouldExcludeClassesWithHash = null;
@@ -452,18 +459,6 @@ private static boolean checkJVMVersion(JvmtiEnv jvmti) {
452459
return true;
453460
}
454461

455-
private static AccessAdvisor createAccessAdvisor(boolean builtinHeuristicFilter, ConfigurationFilter callerFilter, ConfigurationFilter accessFilter) {
456-
AccessAdvisor advisor = new AccessAdvisor();
457-
advisor.setHeuristicsEnabled(builtinHeuristicFilter);
458-
if (callerFilter != null) {
459-
advisor.setCallerFilterTree(callerFilter);
460-
}
461-
if (accessFilter != null) {
462-
advisor.setAccessFilterTree(accessFilter);
463-
}
464-
return advisor;
465-
}
466-
467462
private static int parseIntegerOrNegative(String number) {
468463
try {
469464
return Integer.parseInt(number);

substratevm/src/com.oracle.svm.agent/src/com/oracle/svm/agent/tracing/TraceFileWriter.java

Lines changed: 5 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -24,101 +24,27 @@
2424
*/
2525
package com.oracle.svm.agent.tracing;
2626

27-
import java.io.BufferedWriter;
2827
import java.io.IOException;
29-
import java.io.StringWriter;
30-
import java.nio.file.Files;
3128
import java.nio.file.Path;
32-
import java.util.Base64;
3329

3430
import org.graalvm.collections.EconomicMap;
35-
import org.graalvm.collections.MapCursor;
3631

3732
import com.oracle.svm.agent.tracing.core.Tracer;
3833
import com.oracle.svm.agent.tracing.core.TracingResultWriter;
39-
import com.oracle.svm.core.util.VMError;
40-
41-
import jdk.graal.compiler.util.json.JsonWriter;
34+
import com.oracle.svm.configure.trace.JsonFileWriter;
4235

4336
public class TraceFileWriter extends Tracer implements TracingResultWriter {
44-
private final Object lock = new Object();
45-
private final BufferedWriter writer;
46-
private boolean open = true;
47-
private int written = 0;
37+
private final JsonFileWriter jsonFileWriter;
4838

4939
@SuppressWarnings("this-escape")
5040
public TraceFileWriter(Path path) throws IOException {
51-
writer = Files.newBufferedWriter(path);
52-
JsonWriter json = new JsonWriter(writer);
53-
json.append('[').newline();
41+
jsonFileWriter = new JsonFileWriter(path);
5442
traceInitialization();
55-
json.flush(); // avoid close() on underlying stream
5643
}
5744

5845
@Override
5946
protected void traceEntry(EconomicMap<String, Object> entry) {
60-
try {
61-
StringWriter str = new StringWriter();
62-
try (JsonWriter json = new JsonWriter(str)) {
63-
json.append('{');
64-
boolean first = true;
65-
MapCursor<String, Object> cursor = entry.getEntries();
66-
while (cursor.advance()) {
67-
if (!first) {
68-
json.append(", ");
69-
}
70-
json.quote(cursor.getKey()).append(':');
71-
if (cursor.getValue() instanceof Object[]) {
72-
printArray(json, (Object[]) cursor.getValue());
73-
} else {
74-
printValue(json, cursor.getValue());
75-
}
76-
first = false;
77-
}
78-
json.append('}');
79-
}
80-
traceEntry(str.toString());
81-
} catch (IOException e) {
82-
throw VMError.shouldNotReachHere(e);
83-
}
84-
}
85-
86-
private static void printArray(JsonWriter json, Object[] array) throws IOException {
87-
json.append('[');
88-
for (int i = 0; i < array.length; i++) {
89-
if (i > 0) {
90-
json.append(',');
91-
}
92-
Object obj = array[i];
93-
if (obj instanceof Object[]) {
94-
printArray(json, (Object[]) obj);
95-
} else {
96-
printValue(json, array[i]);
97-
}
98-
}
99-
json.append(']');
100-
}
101-
102-
private static void printValue(JsonWriter json, Object value) throws IOException {
103-
Object s = null;
104-
if (value instanceof byte[]) {
105-
s = Base64.getEncoder().encodeToString((byte[]) value);
106-
} else if (value != null) {
107-
s = value;
108-
}
109-
json.printValue(s);
110-
}
111-
112-
private void traceEntry(String s) throws IOException {
113-
synchronized (lock) {
114-
if (open) { // late events on exit
115-
if (written > 0) {
116-
writer.write(",\n");
117-
}
118-
writer.write(s);
119-
written++;
120-
}
121-
}
47+
jsonFileWriter.printObject(entry);
12248
}
12349

12450
@Override
@@ -133,13 +59,6 @@ public boolean supportsPeriodicTraceWriting() {
13359

13460
@Override
13561
public void close() {
136-
synchronized (lock) {
137-
try {
138-
writer.write("\n]\n");
139-
writer.close();
140-
} catch (IOException ignored) {
141-
}
142-
open = false;
143-
}
62+
jsonFileWriter.close();
14463
}
14564
}

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/command/ConfigurationGenerateCommand.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -282,15 +282,7 @@ protected static void generate(Iterator<String> argumentsIterator, boolean accep
282282
}
283283

284284
if (!traceInputs.isEmpty()) {
285-
AccessAdvisor advisor = new AccessAdvisor();
286-
advisor.setHeuristicsEnabled(builtinHeuristicFilter);
287-
if (callersFilter != null) {
288-
advisor.setCallerFilterTree(callersFilter);
289-
}
290-
if (accessFilter != null) {
291-
advisor.setAccessFilterTree(accessFilter);
292-
}
293-
285+
AccessAdvisor advisor = new AccessAdvisor(builtinHeuristicFilter, callersFilter, accessFilter, null);
294286
TraceProcessor processor = new TraceProcessor(advisor);
295287
for (URI uri : traceInputs) {
296288
try (Reader reader = Files.newBufferedReader(Paths.get(uri))) {

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/AbstractProcessor.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public abstract class AbstractProcessor {
3636
AbstractProcessor() {
3737
}
3838

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

4141
void setInLivePhase(@SuppressWarnings("unused") boolean live) {
4242
}
@@ -59,4 +59,17 @@ static byte[] asBinary(Object obj) {
5959
}
6060
return Base64.getDecoder().decode((String) obj);
6161
}
62+
63+
/**
64+
* Returns a fresh copy of the trace entry with an additional key-value pair identifying it.
65+
* Useful when logging entries to the access advisor.
66+
*/
67+
protected EconomicMap<String, Object> copyWithUniqueEntry(EconomicMap<String, Object> entry, String key, Object value) {
68+
if (entry.containsKey(key)) {
69+
throw new AssertionError(String.format("Tried to set unique identifier %s but field already exists: %s%n", key, entry));
70+
}
71+
EconomicMap<String, Object> result = EconomicMap.create(entry);
72+
result.put(key, value);
73+
return result;
74+
}
6275
}

0 commit comments

Comments
 (0)