8204110: serviceability/sa/ClhsdbSymbol.java and ClhsdbInspect.java failed when running in CDS mode
Summary: ClhsdbSymbol - added printing of symbols from shared table. ClhsdbInspect - find type via FileMapInfo if guessTypeForAddress returns null and sharing is enabled.
Reviewed-by: jgeorge, sspitsyn, iklam
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java Fri Jun 08 10:09:40 2018 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java Fri Jun 08 11:04:58 2018 -0700
@@ -49,6 +49,7 @@
import sun.jvm.hotspot.debugger.Address;
import sun.jvm.hotspot.debugger.OopHandle;
import sun.jvm.hotspot.classfile.ClassLoaderDataGraph;
+import sun.jvm.hotspot.memory.FileMapInfo;
import sun.jvm.hotspot.memory.SymbolTable;
import sun.jvm.hotspot.memory.SystemDictionary;
import sun.jvm.hotspot.memory.Universe;
@@ -89,6 +90,7 @@
import sun.jvm.hotspot.ui.tree.SimpleTreeNode;
import sun.jvm.hotspot.utilities.AddressOps;
import sun.jvm.hotspot.utilities.Assert;
+import sun.jvm.hotspot.utilities.CompactHashTable;
import sun.jvm.hotspot.utilities.HeapProgressThunk;
import sun.jvm.hotspot.utilities.LivenessPathElement;
import sun.jvm.hotspot.utilities.MethodArray;
@@ -637,12 +639,22 @@
},
new Command("symboldump", "symboldump", false) {
public void doit(Tokens t) {
- SymbolTable.getTheTable().symbolsDo(new SymbolTable.SymbolVisitor() {
+ SymbolTable theTable = SymbolTable.getTheTable();
+ theTable.symbolsDo(new SymbolTable.SymbolVisitor() {
public void visit(Symbol sym) {
sym.printValueOn(out);
out.println();
}
});
+ CompactHashTable sharedTable = theTable.getSharedTable();
+ if (sharedTable != null) {
+ sharedTable.symbolsDo(new CompactHashTable.SymbolVisitor() {
+ public void visit(Symbol sym) {
+ sym.printValueOn(out);
+ out.println();
+ }
+ });
+ }
}
},
new Command("flags", "flags [ flag | -nd ]", false) {
@@ -1048,6 +1060,15 @@
}
if (node == null) {
Type type = VM.getVM().getTypeDataBase().guessTypeForAddress(a);
+ if (type == null && VM.getVM().isSharingEnabled()) {
+ // Check if the value falls in the _md_region
+ Address loc1 = a.getAddressAt(0);
+ FileMapInfo cdsFileMapInfo = VM.getVM().getFileMapInfo();
+ if (cdsFileMapInfo.inCopiedVtableSpace(loc1)) {
+ type = cdsFileMapInfo.getTypeForVptrAddress(loc1);
+ }
+
+ }
if (type != null) {
out.println("Type is " + type.getName() + " (size of " + type.getSize() + ")");
node = new CTypeTreeNodeAdapter(a, type, null);
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/SymbolTable.java Fri Jun 08 10:09:40 2018 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/SymbolTable.java Fri Jun 08 11:04:58 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, 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
@@ -65,6 +65,10 @@
return table;
}
+ public CompactHashTable getSharedTable() {
+ return sharedTable;
+ }
+
public static long getSeed() {
return (long) seedField.getValue();
}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java Fri Jun 08 10:09:40 2018 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java Fri Jun 08 11:04:58 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, 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
@@ -119,4 +119,39 @@
}
return null;
}
+
+ public interface SymbolVisitor {
+ public void visit(Symbol sym);
+ }
+
+ public void symbolsDo(SymbolVisitor visitor) {
+ long symOffset;
+ Symbol sym;
+ Address baseAddress = baseAddressField.getValue(addr);
+ Address bucket = bucketsField.getValue(addr);
+ for (long index = 0; index < bucketCount(); index++) {
+ int bucketInfo = (int)bucket.getCIntegerAt(index * uintSize, uintSize, true);
+ int bucketOffset = bucketOffset(bucketInfo);
+ int nextBucketInfo = (int)bucket.getCIntegerAt((index+1) * uintSize, uintSize, true);
+ int nextBucketOffset = bucketOffset(nextBucketInfo);
+
+ Address entry = entriesField.getValue(addr).addOffsetTo(bucketOffset * uintSize);
+
+ if (isValueOnlyBucket(bucketInfo)) {
+ symOffset = entry.getCIntegerAt(0, uintSize, true);
+ sym = Symbol.create(baseAddress.addOffsetTo(symOffset));
+ visitor.visit(sym);
+ } else {
+ Address entryMax = entriesField.getValue(addr).addOffsetTo(nextBucketOffset * uintSize);
+ while (entry.lessThan(entryMax)) {
+ symOffset = entry.getCIntegerAt(uintSize, uintSize, true);
+ Address symAddr = baseAddress.addOffsetTo(symOffset);
+ sym = Symbol.create(symAddr);
+ visitor.visit(sym);
+ entry = entry.addOffsetTo(2 * uintSize);
+ }
+ }
+ }
+ }
}
+