Skip to content

Commit 0205389

Browse files
committed
Change output to group by jar
1 parent e9df11e commit 0205389

File tree

2 files changed

+43
-59
lines changed

2 files changed

+43
-59
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/AnalyzeMethodsRequiringMetadataUsageFeature.java

+42-58
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
import java.nio.file.Path;
4242
import java.util.ArrayList;
4343
import java.util.Collections;
44-
import java.util.Comparator;
44+
import java.util.HashMap;
4545
import java.util.HashSet;
4646
import java.util.Objects;
4747
import java.util.Set;
@@ -60,71 +60,54 @@ public final class AnalyzeMethodsRequiringMetadataUsageFeature implements Intern
6060
public static final String METHODTYPE_RESOURCE = "resource";
6161
public static final String METHODTYPE_SERIALIZATION = "serialization";
6262
public static final String METHODTYPE_PROXY = "proxy";
63-
private final Map<String, List<String>> reflectiveCalls;
64-
private final Map<String, List<String>> resourceCalls;
65-
private final Map<String, List<String>> serializationCalls;
66-
private final Map<String, List<String>> proxyCalls;
6763
private final Set<String> jarPaths;
64+
private final Map<String, Map<String, Map<String, List<String>>>> callsByJar;
6865
private final Set<FoldEntry> foldEntries = ConcurrentHashMap.newKeySet();
6966

7067
public AnalyzeMethodsRequiringMetadataUsageFeature() {
71-
this.reflectiveCalls = new TreeMap<>();
72-
this.resourceCalls = new TreeMap<>();
73-
this.serializationCalls = new TreeMap<>();
74-
this.proxyCalls = new TreeMap<>();
68+
this.callsByJar = new ConcurrentHashMap<>();
7569
this.jarPaths = Collections.unmodifiableSet(new HashSet<>(AnalyzeMethodsRequiringMetadataUsageFeature.Options.TrackMethodsRequiringMetadata.getValue().values()));
7670
}
7771

7872
public static AnalyzeMethodsRequiringMetadataUsageFeature instance() {
7973
return ImageSingletons.lookup(AnalyzeMethodsRequiringMetadataUsageFeature.class);
8074
}
8175

82-
public void addCall(String methodType, String call, String callLocation) {
83-
switch (methodType) {
84-
case METHODTYPE_REFLECTION -> this.reflectiveCalls.computeIfAbsent(call, k -> new ArrayList<>()).add(callLocation);
85-
case METHODTYPE_RESOURCE -> this.resourceCalls.computeIfAbsent(call, k -> new ArrayList<>()).add(callLocation);
86-
case METHODTYPE_SERIALIZATION -> this.serializationCalls.computeIfAbsent(call, k -> new ArrayList<>()).add(callLocation);
87-
case METHODTYPE_PROXY -> this.proxyCalls.computeIfAbsent(call, k -> new ArrayList<>()).add(callLocation);
88-
default -> throw new IllegalArgumentException("Unknown method type: " + methodType);
89-
}
76+
public void addCall(String jarPath, String methodType, String call, String callLocation) {
77+
this.callsByJar.computeIfAbsent(jarPath, k -> new HashMap<>());
78+
this.callsByJar.get(jarPath).computeIfAbsent(methodType, k -> new TreeMap<>());
79+
this.callsByJar.get(jarPath).get(methodType).computeIfAbsent(call, k -> new ArrayList<>());
80+
this.callsByJar.get(jarPath).get(methodType).get(call).add(callLocation);
9081
}
9182

92-
public void printReport(String methodType) {
93-
Map<String, List<String>> callMap = switch (methodType) {
94-
case METHODTYPE_REFLECTION -> this.reflectiveCalls;
95-
case METHODTYPE_RESOURCE -> this.resourceCalls;
96-
case METHODTYPE_SERIALIZATION -> this.serializationCalls;
97-
case METHODTYPE_PROXY -> this.proxyCalls;
98-
default -> throw new IllegalArgumentException("Unknown method type: " + methodType);
99-
};
100-
101-
System.out.println(methodType.substring(0, 1).toUpperCase() + methodType.substring(1) + " calls detected:");
102-
for (String key : callMap.keySet()) {
103-
System.out.println(" " + key + ":");
104-
callMap.get(key).sort(Comparator.comparing(String::toString));
105-
for (String callLocation : callMap.get(key)) {
106-
System.out.println(" at " + callLocation);
83+
public void printReportForJar(String jarPath) {
84+
System.out.println("Dynamic method usage detected in " + jarPath + ":");
85+
for (String methodType : callsByJar.get(jarPath).keySet()) {
86+
System.out.println(" " + methodType.substring(0, 1).toUpperCase() + methodType.substring(1) + " calls detected:");
87+
for (String call : callsByJar.get(jarPath).get(methodType).keySet()) {
88+
System.out.println(" " + call + ":");
89+
for (String callLocation : callsByJar.get(jarPath).get(methodType).get(call)) {
90+
System.out.println(" at " + callLocation);
91+
}
10792
}
10893
}
10994
}
11095

111-
public void dumpReport(String methodType) {
112-
Map<String, List<String>> calls = switch (methodType) {
113-
case METHODTYPE_REFLECTION -> this.reflectiveCalls;
114-
case METHODTYPE_RESOURCE -> this.resourceCalls;
115-
case METHODTYPE_SERIALIZATION -> this.serializationCalls;
116-
case METHODTYPE_PROXY -> this.proxyCalls;
117-
default -> throw new IllegalArgumentException("Unknown method type: " + methodType);
118-
};
119-
String fileName = methodType + "-usage.json";
120-
96+
public void dumpReportForJar(String jarPath) {
97+
String fileName = extractLibraryName(jarPath) + "-method-calls.json";
98+
Map<String, Map<String, List<String>>> calls = callsByJar.get(jarPath);
12199
Path targetPath = NativeImageGenerator.generatedFiles(HostedOptionValues.singleton()).resolve(fileName);
122100
try (var writer = new JsonWriter(targetPath);
123101
var builder = writer.objectBuilder()) {
124-
for (Map.Entry<String, List<String>> entry : calls.entrySet()) {
125-
try (JsonBuilder.ArrayBuilder array = builder.append(entry.getKey()).array()) {
126-
for (String call : entry.getValue()) {
127-
array.append(call);
102+
for (Map.Entry<String, Map<String, List<String>>> callEntry : calls.entrySet()) {
103+
try (JsonBuilder.ObjectBuilder methodsByTypeBuilder = builder.append(callEntry.getKey()).object()) {
104+
Map<String, List<String>> nestedMap = callEntry.getValue();
105+
for (Map.Entry<String, List<String>> entry : nestedMap.entrySet()) {
106+
try (JsonBuilder.ArrayBuilder array = methodsByTypeBuilder.append(entry.getKey()).array()) {
107+
for (String call : entry.getValue()) {
108+
array.append(call);
109+
}
110+
}
128111
}
129112
}
130113
}
@@ -136,25 +119,26 @@ public void dumpReport(String methodType) {
136119
}
137120

138121
public void reportMethodUsage() {
139-
Map<String, Map<String, List<String>>> callMaps = Map.of(
140-
METHODTYPE_REFLECTION, this.reflectiveCalls,
141-
METHODTYPE_RESOURCE, this.resourceCalls,
142-
METHODTYPE_SERIALIZATION, this.serializationCalls,
143-
METHODTYPE_PROXY, this.proxyCalls);
144-
for (Map.Entry<String, Map<String, List<String>>> entry : callMaps.entrySet()) {
145-
String methodType = entry.getKey();
146-
Map<String, List<String>> calls = entry.getValue();
147-
if (!calls.isEmpty()) {
148-
printReport(methodType);
149-
dumpReport(methodType);
150-
}
122+
for (String jarPath : jarPaths) {
123+
printReportForJar(jarPath);
124+
dumpReportForJar(jarPath);
151125
}
152126
}
153127

154128
public Set<String> getJarPaths() {
155129
return jarPaths;
156130
}
157131

132+
public String extractLibraryName(String path) {
133+
String fileName = path.substring(path.lastIndexOf("/") + 1);
134+
135+
if (fileName.endsWith(".jar")) {
136+
fileName = fileName.substring(0, fileName.length() - 4);
137+
}
138+
139+
return fileName;
140+
}
141+
158142
/*
159143
* Support data structure used to keep track of calls which don't require metadata, but can't be
160144
* folded.

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/AnalyzeMethodsRequiringMetadataUsagePhase.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ protected void run(StructuredGraph graph, CoreProviders context) {
193193
int bci = nspToShow.getBCI();
194194
if (!AnalyzeMethodsRequiringMetadataUsageFeature.instance().containsFoldEntry(bci, nspToShow.getMethod())) {
195195
String callLocation = nspToShow.getMethod().asStackTraceElement(bci).toString();
196-
AnalyzeMethodsRequiringMetadataUsageFeature.instance().addCall(methodType, methodName, callLocation);
196+
AnalyzeMethodsRequiringMetadataUsageFeature.instance().addCall(jarPath, methodType, methodName, callLocation);
197197
}
198198
}
199199
}

0 commit comments

Comments
 (0)