30
30
import java .io .PrintWriter ;
31
31
import java .lang .management .GarbageCollectorMXBean ;
32
32
import java .lang .management .ManagementFactory ;
33
+ import java .nio .file .Files ;
33
34
import java .nio .file .Path ;
34
35
import java .security .CodeSource ;
35
36
import java .util .ArrayList ;
@@ -664,35 +665,59 @@ public String renderToString(int maxLength) {
664
665
int maxLengthPackage = maxLength - moduleNamePrefix .length () - locationSuffix .length ();
665
666
return moduleNamePrefix + Utils .truncateFQN (packageName , maxLengthPackage ) + locationSuffix ;
666
667
}
668
+
669
+ public String [] elements () {
670
+ String moduleName = javaModule .isNamed () ? javaModule .getName () : "" ;
671
+ String packageName = javaPackage == null ? "" : javaPackage .getName ();
672
+ String locationName = location == null ? "" : location ;
673
+ return new String []{mapToNativeImageRuntime (moduleName ), packageName , locationName };
674
+ }
667
675
}
668
676
669
677
static String moduleNamePrefix (Module javaModule ) {
670
- if (!javaModule .isNamed ()) {
671
- return "" ;
672
- }
673
- if (javaModule .equals (DynamicHub .class .getModule ())) {
674
- return "VM " ;
678
+ String moduleName = javaModule .isNamed () ? javaModule .getName () : "" ;
679
+ return Utils .truncateFQN (mapToNativeImageRuntime (moduleName ), 0.10 ) + "/" ;
680
+ }
681
+
682
+ private static String mapToNativeImageRuntime (String moduleName ) {
683
+ String modulePrefix = "org.graalvm.nativeimage." ;
684
+ if (moduleName .equals (modulePrefix + "builder" )) {
685
+ return modulePrefix + "runtime" ;
675
686
}
676
- return Utils . truncateFQN ( javaModule . getName (), 0.10 ) + "/" ;
687
+ return moduleName ;
677
688
}
678
689
679
690
private void printBreakdowns () {
680
- if (!SubstrateOptions .BuildOutputBreakdowns .getValue ()) {
681
- return ;
682
- }
683
- l ().printLineSeparator ();
684
691
Map <BreakDownClassifier , Long > codeBreakdown = CodeBreakdownProvider .getAndClear ().entrySet ().stream ()
685
692
.collect (Collectors .groupingBy (
686
693
entry -> BreakDownClassifier .of (entry .getKey ()),
687
694
Collectors .summingLong (entry -> entry .getValue ())));
688
695
689
- Iterator <Entry <BreakDownClassifier , Long >> packagesBySize = codeBreakdown .entrySet ().stream ()
690
- .sorted (Entry .comparingByValue (Comparator .reverseOrder ())).iterator ();
696
+ List <Entry <BreakDownClassifier , Long >> sortedBreakdownData = codeBreakdown .entrySet ().stream ()
697
+ .sorted (Entry .comparingByValue (Comparator .reverseOrder ())).toList ();
698
+
699
+ if (SubstrateOptions .BuildOutputCodeBreakdownFile .getValue ()) {
700
+ String valueSeparator = "," ;
701
+ List <String > lines = new ArrayList <>();
702
+ lines .add (String .join (valueSeparator , "Size" , "Module" , "Package" , "Location" ));
703
+ sortedBreakdownData .forEach (entry -> {
704
+ lines .add (entry .getValue () + valueSeparator + String .join (valueSeparator , entry .getKey ().elements ()));
705
+ });
706
+ Path breakdownFile = SubstrateOptions .getImagePath ().resolve (SubstrateOptions .Name .getValue () + ".code_breakdown.csv" );
707
+ BuildArtifacts .singleton ().add (BuildArtifacts .ArtifactType .BUILD_INFO , breakdownFile );
708
+ try {
709
+ Files .write (breakdownFile , lines );
710
+ } catch (IOException e ) {
711
+ throw VMError .shouldNotReachHere ("Failed generating " + breakdownFile , e );
712
+ }
713
+ }
691
714
692
- HeapBreakdownProvider heapBreakdown = HeapBreakdownProvider .singleton ();
693
- Iterator <HeapBreakdownProvider .HeapBreakdownEntry > typesBySizeInHeap = heapBreakdown .getSortedBreakdownEntries ().iterator ();
715
+ if (!SubstrateOptions .BuildOutputBreakdowns .getValue ()) {
716
+ return ;
717
+ }
694
718
695
719
final TwoColumnPrinter p = new TwoColumnPrinter ();
720
+ l ().printLineSeparator ();
696
721
p .l ().yellowBold ().a (String .format ("Top %d " , MAX_NUM_BREAKDOWN )).doclink ("origins" , "#glossary-code-area-origins" ).a (" of code area:" )
697
722
.jumpToMiddle ()
698
723
.a (String .format ("Top %d object types in image heap:" , MAX_NUM_BREAKDOWN )).reset ().flushln ();
@@ -701,6 +726,9 @@ private void printBreakdowns() {
701
726
long printedHeapBytes = 0 ;
702
727
long printedCodeItems = 0 ;
703
728
long printedHeapItems = 0 ;
729
+ Iterator <Entry <BreakDownClassifier , Long >> packagesBySize = sortedBreakdownData .iterator ();
730
+ HeapBreakdownProvider heapBreakdown = HeapBreakdownProvider .singleton ();
731
+ Iterator <HeapBreakdownProvider .HeapBreakdownEntry > typesBySizeInHeap = heapBreakdown .getSortedBreakdownEntries ().iterator ();
704
732
for (int i = 0 ; i < MAX_NUM_BREAKDOWN ; i ++) {
705
733
String codeSizePart = "" ;
706
734
/* <- 10% for module name -><- remainder for class FQN -><- 10% for location -> */
0 commit comments