Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1370,6 +1370,11 @@ public Boolean getValue(OptionValues values) {
@Option(help = "Create a heap dump and exit.")//
public static final RuntimeOptionKey<Boolean> DumpHeapAndExit = new RuntimeOptionKey<>(false, Immutable);

@Option(help = "Name of a csv file into which image heap metadata should be dumped. " +
"This csv file will be located in the same directory as the image. " +
"If this option is an empty string, the metadata will not be dumped.") //
public static final HostedOptionKey<String> ImageHeapMetadataDumpFileName = new HostedOptionKey<>("");

@Option(help = "Print some VM information and exit.")//
public static final RuntimeOptionKey<Boolean> PrintVMInfoAndExit = new RuntimeOptionKey<>(false, Immutable);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ public void build(String imageName, DebugContext debug) {
// We print the heap statistics after the heap was successfully written because this
// could modify objects that will be part of the image heap.
printHeapStatistics(heap.getLayouter().getPartitions());
heap.dumpMetadata();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,13 @@

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

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Modifier;
import java.nio.file.Path;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Collection;
Expand All @@ -41,6 +46,7 @@
import java.util.Set;
import java.util.function.Predicate;

import com.oracle.svm.core.option.HostedOptionValues;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.c.function.RelocatedPointer;
import org.graalvm.word.UnsignedWord;
Expand Down Expand Up @@ -792,6 +798,35 @@ public ObjectInfo addLateToImageHeap(Object object, Object reason) {
return addToImageHeap(object, (HostedClass) type, getSize(object, type), System.identityHashCode(object), reason);
}

/**
* Dumps metadata for every object in the image heap.
*/
public void dumpMetadata() {
String metadataFileName = SubstrateOptions.ImageHeapMetadataDumpFileName.getValue();
if (metadataFileName == null || metadataFileName.isEmpty()) {
// Do not dump metadata if the file name isn't set
return;
}

Path metadataFilePath = SubstrateOptions.getImagePath(HostedOptionValues.singleton()).resolve(metadataFileName);
File metadataFile = metadataFilePath.toFile();
String metadataDir = metadataFile.getParent();
if (!new File(metadataDir).exists()) {
throw VMError.shouldNotReachHere("Image heap metadata directory does not exist: " + metadataDir);
}

try (FileWriter metadataOut = new FileWriter(metadataFile);
BufferedWriter metadataBw = new BufferedWriter(metadataOut)) {
metadataBw.write("class-name,partition,offset-in-heap,size\n");
for (ObjectInfo info : getObjects()) {
String csvLine = info.getClazz().getName() + "," + info.getPartition().getName() + "," + info.getOffset() + "," + info.getSize() + System.lineSeparator();
metadataBw.write(csvLine);
}
} catch (IOException ex) {
throw new RuntimeException("Failed to dump image heap metadata to " + metadataFile, ex);
}
}

private long getSize(Object object, HostedType type) {
if (type.isInstanceClass()) {
HostedInstanceClass clazz = (HostedInstanceClass) type;
Expand Down
Loading