8204110: serviceability/sa/ClhsdbSymbol.java and ClhsdbInspect.java failed when running in CDS mode

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
This commit is contained in:
Calvin Cheung 2018-06-08 11:04:58 -07:00
parent f56c0b79d8
commit cc4dcf32d3
3 changed files with 63 additions and 3 deletions

View File

@ -49,6 +49,7 @@ import sun.jvm.hotspot.code.NMethod;
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.OopTreeNodeAdapter;
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 @@ public class CommandProcessor {
},
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 @@ public class CommandProcessor {
}
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);

View File

@ -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 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
return table;
}
public CompactHashTable getSharedTable() {
return sharedTable;
}
public static long getSeed() {
return (long) seedField.getValue();
}

View File

@ -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 @@ public class CompactHashTable extends VMObject {
}
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);
}
}
}
}
}