Skip to content

Commit 782d0f5

Browse files
committed
Make ProgressReporter Top 10 printing package based
1 parent 924c962 commit 782d0f5

File tree

3 files changed

+79
-67
lines changed

3 files changed

+79
-67
lines changed

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

Lines changed: 8 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -24,40 +24,22 @@
2424
*/
2525
package com.oracle.svm.hosted;
2626

27-
import java.security.CodeSource;
2827
import java.util.Collection;
29-
import java.util.Collections;
30-
import java.util.HashMap;
3128
import java.util.Map;
29+
import java.util.stream.Collectors;
3230

3331
import org.graalvm.nativeimage.ImageSingletons;
3432

3533
import com.oracle.svm.hosted.code.CompileQueue.CompileTask;
36-
import com.oracle.svm.hosted.meta.HostedMethod;
3734

3835
class CodeBreakdownProvider {
39-
private Map<String, Long> codeBreakdown;
36+
private Map<Class<?>, Long> codeBreakdown;
4037

4138
CodeBreakdownProvider(Collection<CompileTask> compilationTasks) {
42-
Map<String, Long> nameToSizeMap = new HashMap<>();
43-
for (CompileTask task : compilationTasks) {
44-
String key = null;
45-
Class<?> javaClass = task.method.getDeclaringClass().getJavaClass();
46-
Module module = javaClass.getModule();
47-
if (module.isNamed()) {
48-
key = module.getName();
49-
if ("org.graalvm.nativeimage.builder".equals(key)) {
50-
key = "svm.jar (Native Image)";
51-
}
52-
} else {
53-
key = findJARFile(javaClass);
54-
if (key == null) {
55-
key = findPackageOrClassName(task.method);
56-
}
57-
}
58-
nameToSizeMap.merge(key, (long) task.result.getTargetCodeSize(), Long::sum);
59-
}
60-
codeBreakdown = Collections.unmodifiableMap(nameToSizeMap);
39+
codeBreakdown = Map.copyOf(compilationTasks.stream().collect(
40+
Collectors.groupingBy(
41+
compileTask -> compileTask.method.getDeclaringClass().getJavaClass(),
42+
Collectors.summingLong(compileTask -> compileTask.result.getTargetCodeSize()))));
6143
}
6244

6345
/**
@@ -66,31 +48,10 @@ class CodeBreakdownProvider {
6648
*
6749
* @return the code breakdown
6850
*/
69-
public static Map<String, Long> getAndClear() {
51+
public static Map<Class<?>, Long> getAndClear() {
7052
CodeBreakdownProvider singleton = ImageSingletons.lookup(CodeBreakdownProvider.class);
71-
Map<String, Long> map = singleton.codeBreakdown;
53+
var map = singleton.codeBreakdown;
7254
singleton.codeBreakdown = null;
7355
return map;
7456
}
75-
76-
private static String findJARFile(Class<?> javaClass) {
77-
CodeSource codeSource = javaClass.getProtectionDomain().getCodeSource();
78-
if (codeSource != null && codeSource.getLocation() != null) {
79-
String path = codeSource.getLocation().getPath();
80-
if (path.endsWith(".jar")) {
81-
// Use String API to determine basename of path to handle both / and \.
82-
return path.substring(Math.max(path.lastIndexOf('/') + 1, path.lastIndexOf('\\') + 1));
83-
}
84-
}
85-
return null;
86-
}
87-
88-
private static String findPackageOrClassName(HostedMethod method) {
89-
String qualifier = method.format("%H");
90-
int lastDotIndex = qualifier.lastIndexOf('.');
91-
if (lastDotIndex > 0) {
92-
qualifier = qualifier.substring(0, lastDotIndex);
93-
}
94-
return qualifier;
95-
}
9657
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ protected void calculate(BeforeImageWriteAccessImpl access, boolean resourcesAre
147147

148148
/* Extract byte[] for Strings. */
149149
if (stringByteArrayTotalSize > 0) {
150-
addEntry(entries, byteArrayEntry, new HeapBreakdownEntry(BYTE_ARRAY_PREFIX + "java.lang.String"), stringByteArrayTotalSize, stringByteArrayTotalCount);
150+
addEntry(entries, byteArrayEntry, new HeapBreakdownEntry(BYTE_ARRAY_PREFIX + "string data"), stringByteArrayTotalSize, stringByteArrayTotalCount);
151151
}
152152
/* Extract byte[] for code info. */
153153
List<Integer> codeInfoByteArrayLengths = CodeInfoTable.getCurrentLayerImageCodeCache().getTotalByteArrayLengths();
@@ -215,7 +215,8 @@ public static class HeapBreakdownEntry {
215215
int count;
216216

217217
public HeapBreakdownEntry(HostedClass hostedClass) {
218-
this(hostedClass.toJavaName(true));
218+
this(ProgressReporter.moduleNamePrefix(hostedClass.getJavaClass().getModule()) +
219+
ProgressReporter.Utils.truncateFQN(hostedClass.toJavaName(true), 40));
219220
}
220221

221222
public HeapBreakdownEntry(String name) {

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

Lines changed: 68 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.lang.management.GarbageCollectorMXBean;
3232
import java.lang.management.ManagementFactory;
3333
import java.nio.file.Path;
34+
import java.security.CodeSource;
3435
import java.util.ArrayList;
3536
import java.util.Collection;
3637
import java.util.Comparator;
@@ -75,6 +76,7 @@
7576
import com.oracle.svm.core.VM;
7677
import com.oracle.svm.core.heap.Heap;
7778
import com.oracle.svm.core.hub.ClassForNameSupport;
79+
import com.oracle.svm.core.hub.DynamicHub;
7880
import com.oracle.svm.core.jdk.Resources;
7981
import com.oracle.svm.core.option.AccumulatingLocatableMultiOptionValue;
8082
import com.oracle.svm.core.option.HostedOptionKey;
@@ -639,13 +641,50 @@ public void ensureCreationStageEndCompleted() {
639641
}
640642
}
641643

644+
private record BreakDownClassifier(Package javaPackage, Module javaModule, String location) {
645+
static BreakDownClassifier of(Class<?> clazz) {
646+
return new BreakDownClassifier(clazz.getPackage(), clazz.getModule(), sourcePath(clazz));
647+
}
648+
649+
private static String sourcePath(Class<?> clazz) {
650+
CodeSource codeSource = clazz.getProtectionDomain().getCodeSource();
651+
if (codeSource != null && codeSource.getLocation() != null) {
652+
String path = codeSource.getLocation().getPath();
653+
// Use String API to determine basename of path to handle both / and \.
654+
return path.substring(Math.max(path.lastIndexOf('/') + 1, path.lastIndexOf('\\') + 1));
655+
}
656+
return null;
657+
}
658+
659+
@Override
660+
public String toString() {
661+
String locationSuffix = location == null ? "" : " (" + Utils.truncateName(location, 14) + ")";
662+
return moduleNamePrefix(javaModule) + Utils.truncateFQN(javaPackage.getName(), 22) + locationSuffix;
663+
}
664+
665+
}
666+
667+
static String moduleNamePrefix(Module javaModule) {
668+
if (!javaModule.isNamed()) {
669+
return "";
670+
}
671+
if (javaModule.equals(DynamicHub.class.getModule())) {
672+
return "VM ";
673+
}
674+
return Utils.truncateFQN(javaModule.getName(), 19) + "/";
675+
}
676+
642677
private void printBreakdowns() {
643678
if (!SubstrateOptions.BuildOutputBreakdowns.getValue()) {
644679
return;
645680
}
646681
l().printLineSeparator();
647-
Map<String, Long> codeBreakdown = CodeBreakdownProvider.getAndClear();
648-
Iterator<Entry<String, Long>> packagesBySize = codeBreakdown.entrySet().stream()
682+
Map<BreakDownClassifier, Long> codeBreakdown = CodeBreakdownProvider.getAndClear().entrySet().stream()
683+
.collect(Collectors.groupingBy(
684+
entry -> BreakDownClassifier.of(entry.getKey()),
685+
Collectors.summingLong(entry -> entry.getValue())));
686+
687+
Iterator<Entry<BreakDownClassifier, Long>> packagesBySize = codeBreakdown.entrySet().stream()
649688
.sorted(Entry.comparingByValue(Comparator.reverseOrder())).iterator();
650689

651690
HeapBreakdownProvider heapBreakdown = HeapBreakdownProvider.singleton();
@@ -663,10 +702,9 @@ private void printBreakdowns() {
663702
for (int i = 0; i < MAX_NUM_BREAKDOWN; i++) {
664703
String codeSizePart = "";
665704
if (packagesBySize.hasNext()) {
666-
Entry<String, Long> e = packagesBySize.next();
667-
String className = Utils.truncateClassOrPackageName(e.getKey());
668-
codeSizePart = String.format("%9s %s", ByteFormattingUtil.bytesToHuman(e.getValue()), className);
669-
printedCodeBytes += e.getValue();
705+
Entry<BreakDownClassifier, Long> entry = packagesBySize.next();
706+
codeSizePart = String.format("%9s %s", ByteFormattingUtil.bytesToHuman(entry.getValue()), entry.getKey());
707+
printedCodeBytes += entry.getValue();
670708
printedCodeItems++;
671709
}
672710

@@ -676,7 +714,7 @@ private void printBreakdowns() {
676714
String className = e.label.renderToString(linkStrategy);
677715
// Do not truncate special breakdown items, they can contain links.
678716
if (e.label instanceof HeapBreakdownProvider.SimpleHeapObjectKindName) {
679-
className = Utils.truncateClassOrPackageName(className);
717+
className = Utils.truncateFQN(className);
680718
}
681719
long byteSize = e.byteSize;
682720
heapSizePart = String.format("%9s %s", ByteFormattingUtil.bytesToHuman(byteSize), className);
@@ -920,9 +958,10 @@ private static OperatingSystemMXBean getOperatingSystemMXBean() {
920958
return (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
921959
}
922960

923-
private static final class Utils {
961+
static final class Utils {
924962
private static final double MILLIS_TO_SECONDS = 1000d;
925963
private static final double NANOS_TO_SECONDS = 1000d * 1000d * 1000d;
964+
public static final String TRUNCATION_PLACEHOLDER = "~";
926965

927966
private static double millisToSeconds(double millis) {
928967
return millis / MILLIS_TO_SECONDS;
@@ -937,39 +976,50 @@ private static String getUsedMemory() {
937976
}
938977

939978
private static String stringFilledWith(int size, String fill) {
940-
return new String(new char[size]).replace("\0", fill);
979+
return fill.repeat(size);
941980
}
942981

943982
private static double toPercentage(long part, long total) {
944983
return part / (double) total * 100;
945984
}
946985

947-
private static String truncateClassOrPackageName(String classOrPackageName) {
948-
int classNameLength = classOrPackageName.length();
949-
int maxLength = CHARACTERS_PER_LINE / 2 - 10;
986+
private static String truncateName(String name, int maxLength) {
987+
int length = name.length();
988+
if (length <= maxLength) {
989+
return name;
990+
}
991+
return TRUNCATION_PLACEHOLDER + name.substring(length - maxLength + TRUNCATION_PLACEHOLDER.length(), length);
992+
}
993+
994+
private static String truncateFQN(String fqn) {
995+
return truncateFQN(fqn, CHARACTERS_PER_LINE / 2 - 10);
996+
}
997+
998+
static String truncateFQN(String fqn, int maxLength) {
999+
int classNameLength = fqn.length();
9501000
if (classNameLength <= maxLength) {
951-
return classOrPackageName;
1001+
return fqn;
9521002
}
9531003
StringBuilder sb = new StringBuilder();
9541004
int currentDot = -1;
9551005
while (true) {
956-
int nextDot = classOrPackageName.indexOf('.', currentDot + 1);
1006+
int nextDot = fqn.indexOf('.', currentDot + 1);
9571007
if (nextDot < 0) { // Not more dots, handle the rest and return.
958-
String rest = classOrPackageName.substring(currentDot + 1);
1008+
String rest = fqn.substring(currentDot + 1);
9591009
int sbLength = sb.length();
9601010
int restLength = rest.length();
9611011
if (sbLength + restLength <= maxLength) {
9621012
sb.append(rest);
9631013
} else {
9641014
int remainingSpaceDivBy2 = (maxLength - sbLength) / 2;
965-
sb.append(rest, 0, remainingSpaceDivBy2 - 1).append("~").append(rest, restLength - remainingSpaceDivBy2, restLength);
1015+
sb.append(rest, 0, remainingSpaceDivBy2 - 1).append(TRUNCATION_PLACEHOLDER).append(rest, restLength - remainingSpaceDivBy2, restLength);
9661016
}
9671017
break;
9681018
}
969-
sb.append(classOrPackageName.charAt(currentDot + 1)).append('.');
1019+
sb.append(fqn.charAt(currentDot + 1)).append('.');
9701020
if (sb.length() + (classNameLength - nextDot) <= maxLength) {
9711021
// Rest fits maxLength, append and return.
972-
sb.append(classOrPackageName.substring(nextDot + 1));
1022+
sb.append(fqn.substring(nextDot + 1));
9731023
break;
9741024
}
9751025
currentDot = nextDot;

0 commit comments

Comments
 (0)