Skip to content

Commit 238946b

Browse files
author
Andrija Kolic
committed
Add OutHeapMetadataPath native image build option and NativeImageHeap.dumpMetadata method.
1 parent 08e4f8d commit 238946b

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,19 @@ public Boolean getValue(OptionValues values) {
13641364
"the default file name.") //
13651365
public static final RuntimeOptionKey<String> HeapDumpPath = new RuntimeOptionKey<>("", Immutable);
13661366

1367+
@Option(help = "Path of the file in which heap metadata should be dumped. " +
1368+
"If this option is an empty string, the metadata will not be dumped.")//
1369+
public static final HostedOptionKey<String> OutHeapMetadataPath = new HostedOptionKey<>("") {
1370+
@Override
1371+
protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, String oldValue, String newValue) {
1372+
if (newValue != null && !newValue.trim().isEmpty()) {
1373+
GenerateDebugInfo.update(values, 2);
1374+
DeleteLocalSymbols.update(values, false);
1375+
PreserveFramePointer.update(values, true);
1376+
}
1377+
}
1378+
};
1379+
13671380
@Option(help = "A prefix that is used for heap dump filenames if no heap dump filename was specified explicitly.")//
13681381
public static final HostedOptionKey<String> HeapDumpDefaultFilenamePrefix = new HostedOptionKey<>("svm-heapdump-");
13691382

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImage.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,7 @@ public void build(String imageName, DebugContext debug) {
562562
// We print the heap statistics after the heap was successfully written because this
563563
// could modify objects that will be part of the image heap.
564564
printHeapStatistics(heap.getLayouter().getPartitions());
565+
heap.dumpMetadata();
565566
}
566567
}
567568

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageHeap.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626

2727
import static com.oracle.svm.core.util.VMError.shouldNotReachHereUnexpectedInput;
2828

29+
import java.io.BufferedWriter;
30+
import java.io.File;
31+
import java.io.FileWriter;
32+
import java.io.IOException;
2933
import java.lang.reflect.Array;
3034
import java.lang.reflect.Modifier;
3135
import java.util.ArrayDeque;
@@ -793,6 +797,43 @@ public ObjectInfo addLateToImageHeap(Object object, Object reason) {
793797
return addToImageHeap(object, (HostedClass) type, getSize(object, type), System.identityHashCode(object), reason);
794798
}
795799

800+
/**
801+
* Dumps metadata for every object in the heap.
802+
*/
803+
public void dumpMetadata() {
804+
final String heapMetadataPath = SubstrateOptions.OutHeapMetadataPath.getValue();
805+
if (heapMetadataPath == null || heapMetadataPath.isEmpty()) {
806+
// Do not dump metadata if the path isn't set
807+
return;
808+
}
809+
810+
final File metadataFile = new File(heapMetadataPath);
811+
final String heapMetadataDir = metadataFile.getParent();
812+
if (!new File(heapMetadataDir).exists()) {
813+
throw VMError.shouldNotReachHere("Heap metadata directory does not exist: " + heapMetadataDir);
814+
}
815+
816+
try (
817+
final FileWriter metadataOut = new FileWriter(metadataFile);
818+
final BufferedWriter metadataBw = new BufferedWriter(metadataOut)) {
819+
metadataBw.write("class-name,partition,offset-in-heap,size\n");
820+
for (final ObjectInfo info : getObjects()) {
821+
try {
822+
metadataBw.write(
823+
info.getClazz().getName() + "," +
824+
info.getPartition().getName() + "," +
825+
info.getOffset() + "," +
826+
info.getSize() + System.lineSeparator());
827+
} catch (final Throwable ex) {
828+
// do nothing
829+
// write next
830+
}
831+
}
832+
} catch (final IOException ex) {
833+
// do nothing
834+
}
835+
}
836+
796837
private long getSize(Object object, HostedType type) {
797838
if (type.isInstanceClass()) {
798839
HostedInstanceClass clazz = (HostedInstanceClass) type;

0 commit comments

Comments
 (0)