mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-25 01:30:10 +00:00
8306591: SA and hotspot generate different hprof records for GC roots
Reviewed-by: cjplummer, dholmes
This commit is contained in:
parent
171d788bce
commit
f25d429c8d
@ -408,6 +408,8 @@
|
||||
volatile_nonstatic_field(ClassLoaderData, _klasses, Klass*) \
|
||||
nonstatic_field(ClassLoaderData, _has_class_mirror_holder, bool) \
|
||||
\
|
||||
static_field(ClassLoaderData, _the_null_class_loader_data, ClassLoaderData*) \
|
||||
\
|
||||
volatile_static_field(ClassLoaderDataGraph, _head, ClassLoaderData*) \
|
||||
\
|
||||
/**********/ \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -44,12 +44,14 @@ public class ClassLoaderData extends VMObject {
|
||||
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
|
||||
Type type = db.lookupType("ClassLoaderData");
|
||||
classLoaderFieldOffset = type.getAddressField("_class_loader").getOffset();
|
||||
theNullClassLoaderDataField = type.getAddressField("_the_null_class_loader_data");
|
||||
nextField = type.getAddressField("_next");
|
||||
klassesField = new MetadataField(type.getAddressField("_klasses"), 0);
|
||||
hasClassMirrorHolderField = new CIntField(type.getCIntegerField("_has_class_mirror_holder"), 0);
|
||||
}
|
||||
|
||||
private static long classLoaderFieldOffset;
|
||||
private static AddressField theNullClassLoaderDataField;
|
||||
private static AddressField nextField;
|
||||
private static MetadataField klassesField;
|
||||
private static CIntField hasClassMirrorHolderField;
|
||||
@ -75,6 +77,10 @@ public class ClassLoaderData extends VMObject {
|
||||
return hasClassMirrorHolderField.getValue(this) != 0;
|
||||
}
|
||||
|
||||
public static ClassLoaderData theNullClassLoaderData() {
|
||||
return instantiateWrapperFor(theNullClassLoaderDataField.getValue());
|
||||
}
|
||||
|
||||
public ClassLoaderData next() {
|
||||
return instantiateWrapperFor(nextField.getValue(getAddress()));
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -121,6 +121,9 @@ public abstract class AbstractHeapGraphWriter implements HeapGraphWriter {
|
||||
// write JNI global handles
|
||||
writeGlobalJNIHandles();
|
||||
|
||||
// write classes in null class loader data
|
||||
writeStickyClasses();
|
||||
|
||||
} catch (RuntimeException re) {
|
||||
handleRuntimeException(re);
|
||||
}
|
||||
@ -168,6 +171,9 @@ public abstract class AbstractHeapGraphWriter implements HeapGraphWriter {
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeStickyClasses() throws IOException {
|
||||
}
|
||||
|
||||
protected void writeGlobalJNIHandle(Address handleAddr) throws IOException {
|
||||
}
|
||||
|
||||
|
||||
@ -967,6 +967,22 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeStickyClasses() throws IOException {
|
||||
ClassLoaderData.theNullClassLoaderData().classesDo(k -> {
|
||||
if (k instanceof InstanceKlass) {
|
||||
try {
|
||||
int size = 1 + (int)VM.getVM().getAddressSize();
|
||||
writeHeapRecordPrologue(size);
|
||||
out.writeByte((byte)HPROF_GC_ROOT_STICKY_CLASS);
|
||||
writeClassID(k);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void writeObjectArray(ObjArray array) throws IOException {
|
||||
int headerSize = getArrayHeaderSize(true);
|
||||
final int length = calculateArrayMaxLength(array.getLength(),
|
||||
@ -1304,6 +1320,10 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
||||
writeObjectID(address);
|
||||
}
|
||||
|
||||
private void writeClassID(Klass k) throws IOException {
|
||||
writeObjectID(k.getJavaMirror());
|
||||
}
|
||||
|
||||
private void writeSymbolID(Symbol sym) throws IOException {
|
||||
assert names.contains(sym);
|
||||
long address = (sym != null) ? getAddressValue(sym.getAddress()) : getAddressValue(null);
|
||||
|
||||
@ -81,10 +81,23 @@ public class ClhsdbDumpheap {
|
||||
fail("HPROF_GC_ROOT_JAVA_FRAME not found");
|
||||
}
|
||||
|
||||
private static void verifyStickyClasses(String file) throws IOException {
|
||||
try (var snapshot = HprofReader.readFile(file, false, 0)) {
|
||||
for (var root = snapshot.getRoots(); root.hasMoreElements();) {
|
||||
if (root.nextElement().getType() == Root.SYSTEM_CLASS) {
|
||||
// expected
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
fail("HPROF_GC_ROOT_STICKY_CLASS not found");
|
||||
}
|
||||
|
||||
private static void verifyDumpFile(File dump) throws Exception {
|
||||
assertTrue(dump.exists() && dump.isFile(), "Could not create dump file " + dump.getAbsolutePath());
|
||||
printStackTraces(dump.getAbsolutePath());
|
||||
verifyLocalRefs(dump.getAbsolutePath());
|
||||
verifyStickyClasses(dump.getAbsolutePath());
|
||||
}
|
||||
|
||||
private static class SubTest {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user