mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-09 06:28:49 +00:00
8374577: Heap dump from core does not contain HPROF_GC_ROOT_JAVA_FRAME
Reviewed-by: cjplummer, amenkov, kevinw, aturbanov
This commit is contained in:
parent
370929f826
commit
24f67917c2
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 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
|
||||
@ -96,7 +96,7 @@ public class OopMapCacheEntry {
|
||||
|
||||
Method method() { return method; }
|
||||
int bci() { return bci; }
|
||||
int numberOfEntries() { return maskSize; }
|
||||
public int numberOfEntries() { return maskSize; }
|
||||
boolean entryAt(int offset) {
|
||||
return mask.at(offset);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 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
|
||||
@ -253,13 +253,16 @@ public class ConstantPool extends Metadata implements ClassConstants {
|
||||
return res;
|
||||
}
|
||||
|
||||
private int invokedynamicBootstrapRefIndexAt(int indyIndex) {
|
||||
return getCache().getIndyEntryAt(indyIndex).getConstantPoolIndex();
|
||||
}
|
||||
|
||||
// Translate index, which could be CPCache index or Indy index, to a constant pool index
|
||||
public int to_cp_index(int index, int code) {
|
||||
Assert.that(getCache() != null, "'index' is a rewritten index so this class must have been rewritten");
|
||||
switch(code) {
|
||||
case Bytecodes._invokedynamic:
|
||||
int poolIndex = getCache().getIndyEntryAt(index).getConstantPoolIndex();
|
||||
return invokeDynamicNameAndTypeRefIndexAt(poolIndex);
|
||||
return invokedynamicBootstrapRefIndexAt(index);
|
||||
case Bytecodes._getfield:
|
||||
case Bytecodes._getstatic:
|
||||
case Bytecodes._putfield:
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 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
|
||||
@ -37,21 +37,18 @@ public class InterpretedVFrame extends JavaVFrame {
|
||||
}
|
||||
|
||||
public StackValueCollection getLocals() {
|
||||
Method m = getMethod();
|
||||
|
||||
int length = (int) m.getMaxLocals();
|
||||
|
||||
if (m.isNative()) {
|
||||
// If the method is native, getMaxLocals is not telling the truth.
|
||||
// maxlocals then equals the size of parameters
|
||||
length = (int) m.getSizeOfParameters();
|
||||
}
|
||||
|
||||
StackValueCollection result = new StackValueCollection(length);
|
||||
|
||||
// Get oopmap describing oops and int for current bci
|
||||
OopMapCacheEntry oopMask = getMethod().getMaskFor(getBCI());
|
||||
|
||||
// If the method is native, method()->max_locals() is not telling the truth.
|
||||
// For our purposes, max locals instead equals the size of parameters.
|
||||
Method method = getMethod();
|
||||
int maxLocals = method.isNative() ? (int)method.getSizeOfParameters() : (int)method.getMaxLocals();
|
||||
|
||||
int length = maxLocals;
|
||||
|
||||
StackValueCollection result = new StackValueCollection(length);
|
||||
|
||||
// handle locals
|
||||
for(int i = 0; i < length; i++) {
|
||||
// Find stack location
|
||||
@ -74,26 +71,27 @@ public class InterpretedVFrame extends JavaVFrame {
|
||||
}
|
||||
|
||||
public StackValueCollection getExpressions() {
|
||||
int length = getFrame().getInterpreterFrameExpressionStackSize();
|
||||
|
||||
if (getMethod().isNative()) {
|
||||
// If the method is native, there is no expression stack
|
||||
length = 0;
|
||||
}
|
||||
|
||||
int nofLocals = (int) getMethod().getMaxLocals();
|
||||
StackValueCollection result = new StackValueCollection(length);
|
||||
|
||||
// Get oopmap describing oops and int for current bci
|
||||
OopMapCacheEntry oopMask = getMethod().getMaskFor(getBCI());
|
||||
|
||||
int maskLen = oopMask.numberOfEntries();
|
||||
|
||||
// If the method is native, method()->max_locals() is not telling the truth.
|
||||
// For our purposes, max locals instead equals the size of parameters.
|
||||
Method method = getMethod();
|
||||
int maxLocals = method.isNative() ? (int)method.getSizeOfParameters() : (int)method.getMaxLocals();
|
||||
|
||||
int length = maskLen - maxLocals;
|
||||
|
||||
StackValueCollection result = new StackValueCollection(length);
|
||||
|
||||
for(int i = 0; i < length; i++) {
|
||||
// Find stack location
|
||||
Address addr = addressOfExpressionStackAt(i);
|
||||
|
||||
// Depending on oop/int put it in the right package
|
||||
StackValue sv;
|
||||
if (oopMask.isOop(i + nofLocals)) {
|
||||
if (oopMask.isOop(i + maxLocals)) {
|
||||
// oop value
|
||||
sv = new StackValue(addr.getOopHandleAt(0), 0);
|
||||
} else {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2024, 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
|
||||
@ -888,6 +888,16 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
||||
out.writeInt(index);
|
||||
out.writeInt(DUMMY_STACK_TRACE_ID);
|
||||
writeLocalJNIHandles(jt, index);
|
||||
|
||||
int depth = 0;
|
||||
var jvf = jt.getLastJavaVFrameDbg();
|
||||
while (jvf != null) {
|
||||
writeStackRefs(index, depth, jvf.getLocals());
|
||||
writeStackRefs(index, depth, jvf.getExpressions());
|
||||
|
||||
depth++;
|
||||
jvf = jvf.javaSender();
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeLocalJNIHandles(JavaThread jt, int index) throws IOException {
|
||||
@ -926,6 +936,23 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeStackRefs(int threadIndex, int frameIndex, StackValueCollection values) throws IOException {
|
||||
for (int index = 0; index < values.size(); index++) {
|
||||
if (values.get(index).getType() == BasicType.getTObject()) {
|
||||
OopHandle oopHandle = values.oopHandleAt(index);
|
||||
Oop oop = objectHeap.newOop(oopHandle);
|
||||
if (oop != null) {
|
||||
int size = BYTE_SIZE + OBJ_ID_SIZE + INT_SIZE * 2;
|
||||
writeHeapRecordPrologue(size);
|
||||
out.writeByte((byte) HPROF_GC_ROOT_JAVA_FRAME);
|
||||
writeObjectID(oop);
|
||||
out.writeInt(threadIndex);
|
||||
out.writeInt(frameIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeGlobalJNIHandle(Address handleAddr) throws IOException {
|
||||
OopHandle oopHandle = handleAddr.getOopHandleAt(0);
|
||||
Oop oop = objectHeap.newOop(oopHandle);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 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
|
||||
@ -27,11 +27,14 @@ import java.util.Map;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static jdk.test.lib.Asserts.assertTrue;
|
||||
import static jdk.test.lib.Asserts.assertFalse;
|
||||
import static jdk.test.lib.Asserts.fail;
|
||||
import jdk.test.lib.hprof.HprofParser;
|
||||
import jdk.test.lib.apps.LingeredApp;
|
||||
import jdk.test.lib.hprof.model.Root;
|
||||
import jdk.test.lib.hprof.parser.HprofReader;
|
||||
import jtreg.SkippedException;
|
||||
|
||||
@ -66,9 +69,22 @@ public class ClhsdbDumpheap {
|
||||
}
|
||||
}
|
||||
|
||||
private static void verifyLocalRefs(String file) throws IOException {
|
||||
try (var snapshot = HprofReader.readFile(file, false, 0)) {
|
||||
for (var root = snapshot.getRoots(); root.hasMoreElements();) {
|
||||
if (root.nextElement().getType() == Root.JAVA_LOCAL) {
|
||||
// expected
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
fail("HPROF_GC_ROOT_JAVA_FRAME 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());
|
||||
}
|
||||
|
||||
private static class SubTest {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user