--- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java 2018-06-07 09:25:51.933395732 -0700 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java 2018-06-07 09:25:51.609365166 -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); --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/SymbolTable.java 2018-06-07 09:25:52.708468844 -0700 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/SymbolTable.java 2018-06-07 09:25:52.380437901 -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(); } --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java 2018-06-07 09:25:53.451538938 -0700 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java 2018-06-07 09:25:53.142509787 -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); + } + } + } + } } +