8205534: Remove SymbolTable dependency from serviceability agent

Reviewed-by: gziemski, poonam, jgeorge, hseigel
This commit is contained in:
Coleen Phillimore 2018-07-03 13:41:18 -04:00
parent cfd42a97cc
commit c0ebf80159
20 changed files with 121 additions and 759 deletions

View File

@ -50,7 +50,6 @@ 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;
import sun.jvm.hotspot.gc.shared.CollectedHeap;
@ -628,35 +627,6 @@ public class CommandProcessor {
}
}
},
new Command("symboltable", "symboltable name", false) {
public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
} else {
out.println(SymbolTable.getTheTable().probe(t.nextToken()));
}
}
},
new Command("symboldump", "symboldump", false) {
public void doit(Tokens t) {
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) {
public void doit(Tokens t) {
int tokens = t.countTokens();

View File

@ -92,9 +92,9 @@ public class ClassLoaderData extends VMObject {
public Klass getKlasses() { return (Klass)klassesField.getValue(this); }
/** Lookup an already loaded class. If not found null is returned. */
public Klass find(Symbol className) {
public Klass find(String className) {
for (Klass l = getKlasses(); l != null; l = l.getNextLinkKlass()) {
if (className.equals(l.getName())) {
if (l.getName().equals(className)) {
return l;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 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
@ -55,10 +55,8 @@ public class ClassLoaderDataGraph {
/** Lookup an already loaded class in any class loader. */
public Klass find(String className) {
Symbol sym = VM.getVM().getSymbolTable().probe(className);
if (sym == null) return null;
for (ClassLoaderData cld = getClassLoaderGraphHead(); cld != null; cld = cld.next()) {
Klass k = cld.find(sym);
Klass k = cld.find(className);
if (k != null) {
return k;
}

View File

@ -1,94 +0,0 @@
/*
* Copyright (c) 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.memory;
public class AltHashing {
public static long murmur3_32(long seed, byte[] data) {
long h1 = seed;
int len = data.length;
int count = len;
int offset = 0;
// body
while (count >= 4) {
long k1 = (data[offset] & 0x0FF)
| (data[offset + 1] & 0x0FF) << 8
| (data[offset + 2] & 0x0FF) << 16
| data[offset + 3] << 24;
count -= 4;
offset += 4;
k1 *= 0xcc9e2d51;
k1 = Integer.rotateLeft((int)k1, 15);
k1 *= 0x1b873593;
k1 &= 0xFFFFFFFFL;
h1 ^= k1;
h1 = Integer.rotateLeft((int)h1, 13);
h1 = h1 * 5 + 0xe6546b64;
h1 &= 0xFFFFFFFFL;
}
//tail
if (count > 0) {
long k1 = 0;
switch (count) {
case 3:
k1 ^= (data[offset + 2] & 0xff) << 16;
// fall through
case 2:
k1 ^= (data[offset + 1] & 0xff) << 8;
// fall through
case 1:
k1 ^= (data[offset] & 0xff);
// fall through
default:
k1 *= 0xcc9e2d51;
k1 = Integer.rotateLeft((int)k1, 15);
k1 *= 0x1b873593;
k1 &= 0xFFFFFFFFL;
h1 ^= k1;
h1 &= 0xFFFFFFFFL;
}
}
// finalization
h1 ^= len;
// finalization mix force all bits of a hash block to avalanche
h1 ^= h1 >> 16;
h1 *= 0x85ebca6b;
h1 &= 0xFFFFFFFFL;
h1 ^= h1 >> 13;
h1 *= 0xc2b2ae35;
h1 &= 0xFFFFFFFFL;
h1 ^= h1 >> 16;
return h1 & 0xFFFFFFFFL;
}
}

View File

@ -1,155 +0,0 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.memory;
import java.io.*;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.utilities.*;
public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
initialize(VM.getVM().getTypeDataBase());
}
});
}
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("SymbolTable");
theTableField = type.getAddressField("_the_table");
sharedTableField = type.getAddressField("_shared_table");
type = db.lookupType("RehashableSymbolHashtable");
seedField = type.getCIntegerField("_seed");
}
// Fields
private static AddressField theTableField;
private static AddressField sharedTableField;
private static CIntegerField seedField;
private CompactHashTable sharedTable;
// Accessors
public static SymbolTable getTheTable() {
Address tmp = theTableField.getValue();
SymbolTable table = (SymbolTable) VMObjectFactory.newObject(SymbolTable.class, tmp);
Address shared = sharedTableField.getStaticFieldAddress();
table.sharedTable = (CompactHashTable)VMObjectFactory.newObject(CompactHashTable.class, shared);
return table;
}
public CompactHashTable getSharedTable() {
return sharedTable;
}
public static long getSeed() {
return (long) seedField.getValue();
}
public static boolean useAlternateHashcode() {
if (getSeed() != 0) {
return true;
}
return false;
}
public SymbolTable(Address addr) {
super(addr);
}
/** Clone of VM's "temporary" probe routine, as the SA currently
does not support mutation so lookup() would have no effect
anyway. Returns null if the given string is not in the symbol
table. */
public Symbol probe(String name) {
try {
return probe(toModifiedUTF8Bytes(name));
} catch (IOException e) {
return null;
}
}
/** Clone of VM's "temporary" probe routine, as the SA currently
does not support mutation so lookup() would have no effect
anyway. Searches the regular symbol table and the shared symbol
table. Null is returned if the given name is not found in both
tables. */
public Symbol probe(byte[] name) {
long hashValue = hashSymbol(name);
// shared table does not use alternate hashing algorithm,
// it always uses the same original hash code.
Symbol s = sharedTable.probe(name, hashValue);
if (s != null) {
return s;
}
if (useAlternateHashcode()) {
hashValue = AltHashing.murmur3_32(getSeed(), name);
}
for (HashtableEntry e = (HashtableEntry) bucket(hashToIndex(hashValue)); e != null; e = (HashtableEntry) e.next()) {
if (e.hash() == hashValue) {
Symbol sym = Symbol.create(e.literalValue());
if (sym.equals(name)) {
return sym;
}
}
}
return null;
}
public interface SymbolVisitor {
public void visit(Symbol sym);
}
public void symbolsDo(SymbolVisitor visitor) {
int numBuckets = tableSize();
for (int i = 0; i < numBuckets; i++) {
for (HashtableEntry e = (HashtableEntry) bucket(i); e != null;
e = (HashtableEntry) e.next()) {
visitor.visit(Symbol.create(e.literalValue()));
}
}
}
private static byte[] toModifiedUTF8Bytes(String name) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeUTF(name);
dos.flush();
byte[] buf = baos.toByteArray();
byte[] res = new byte[buf.length - 2];
// skip the length part
System.arraycopy(buf, 2, res, 0, res.length);
return res;
}
}

View File

@ -72,27 +72,27 @@ public class ArrayKlass extends Klass {
public Klass getLowerDimension() { return (Klass) lowerDimension.getValue(this); }
// constant class names - javaLangCloneable, javaIoSerializable, javaLangObject
// Initialized lazily to avoid initialization ordering dependencies between ArrayKlass and SymbolTable
private static Symbol javaLangCloneableName;
private static Symbol javaLangObjectName;
private static Symbol javaIoSerializableName;
private static Symbol javaLangCloneableName() {
// Initialized lazily to avoid initialization ordering dependencies between ArrayKlass and String
private static String javaLangCloneableName;
private static String javaLangObjectName;
private static String javaIoSerializableName;
private static String javaLangCloneableName() {
if (javaLangCloneableName == null) {
javaLangCloneableName = VM.getVM().getSymbolTable().probe("java/lang/Cloneable");
javaLangCloneableName = "java/lang/Cloneable";
}
return javaLangCloneableName;
}
private static Symbol javaLangObjectName() {
private static String javaLangObjectName() {
if (javaLangObjectName == null) {
javaLangObjectName = VM.getVM().getSymbolTable().probe("java/lang/Object");
javaLangObjectName = "java/lang/Object";
}
return javaLangObjectName;
}
private static Symbol javaIoSerializableName() {
private static String javaIoSerializableName() {
if (javaIoSerializableName == null) {
javaIoSerializableName = VM.getVM().getSymbolTable().probe("java/io/Serializable");
javaIoSerializableName = "java/io/Serializable";
}
return javaIoSerializableName;
}

View File

@ -355,7 +355,7 @@ public class ConstantPool extends Metadata implements ClassConstants {
if (klass.isArrayKlass()) {
klass = klass.getJavaSuper();
}
return ((InstanceKlass)klass).findMethod(name, sig);
return ((InstanceKlass)klass).findMethod(name.asString(), sig.asString());
}
// returns null, if not resolved.
@ -364,7 +364,7 @@ public class ConstantPool extends Metadata implements ClassConstants {
if (klass == null) return null;
Symbol name = getNameRefAt(which);
Symbol sig = getSignatureRefAt(which);
return klass.findField(name, sig);
return klass.findField(name.asString(), sig.asString());
}
public int getNameAndTypeRefIndexAt(int index) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
@ -47,7 +47,7 @@ public class Field {
offset = holder.getFieldOffset(fieldIndex);
genericSignature = holder.getFieldGenericSignature(fieldIndex);
Symbol name = holder.getFieldName(fieldIndex);
name = holder.getFieldName(fieldIndex);
id = new NamedFieldIdentifier(name.asString());
signature = holder.getFieldSignature(fieldIndex);
@ -57,6 +57,7 @@ public class Field {
accessFlags = new AccessFlags(access);
}
private Symbol name;
private long offset;
private FieldIdentifier id;
private boolean isVMField;
@ -74,6 +75,8 @@ public class Field {
/** Returns the identifier of the field */
public FieldIdentifier getID() { return id; }
public Symbol getName() { return name; }
/** Indicates whether this is a VM field */
public boolean isVMField() { return isVMField; }

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
@ -729,12 +729,12 @@ public class InstanceKlass extends Klass {
}
/** Field access by name. */
public Field findLocalField(Symbol name, Symbol sig) {
public Field findLocalField(String name, String sig) {
int length = getJavaFieldsCount();
for (int i = 0; i < length; i++) {
Symbol f_name = getFieldName(i);
Symbol f_sig = getFieldSignature(i);
if (name.equals(f_name) && sig.equals(f_sig)) {
if (f_name.equals(name) && f_sig.equals(sig)) {
return newField(i);
}
}
@ -743,14 +743,14 @@ public class InstanceKlass extends Klass {
}
/** Find field in direct superinterfaces. */
public Field findInterfaceField(Symbol name, Symbol sig) {
public Field findInterfaceField(String name, String sig) {
KlassArray interfaces = getLocalInterfaces();
int n = interfaces.length();
for (int i = 0; i < n; i++) {
InstanceKlass intf1 = (InstanceKlass) interfaces.getAt(i);
if (Assert.ASSERTS_ENABLED) {
Assert.that(intf1.isInterface(), "just checking type");
}
}
// search for field in current interface
Field f = intf1.findLocalField(name, sig);
if (f != null) {
@ -769,7 +769,7 @@ public class InstanceKlass extends Klass {
/** Find field according to JVM spec 5.4.3.2, returns the klass in
which the field is defined. */
public Field findField(Symbol name, Symbol sig) {
public Field findField(String name, String sig) {
// search order according to newest JVM spec (5.4.3.2, p.167).
// 1) search for field in current klass
Field f = findLocalField(name, sig);
@ -787,18 +787,6 @@ public class InstanceKlass extends Klass {
return null;
}
/** Find field according to JVM spec 5.4.3.2, returns the klass in
which the field is defined (convenience routine) */
public Field findField(String name, String sig) {
SymbolTable symbols = VM.getVM().getSymbolTable();
Symbol nameSym = symbols.probe(name);
Symbol sigSym = symbols.probe(sig);
if (nameSym == null || sigSym == null) {
return null;
}
return findField(nameSym, sigSym);
}
/** Find field according to JVM spec 5.4.3.2, returns the klass in
which the field is defined (retained only for backward
compatibility with jdbx) */
@ -932,20 +920,8 @@ public class InstanceKlass extends Klass {
return "L" + super.signature() + ";";
}
/** Convenience routine taking Strings; lookup is done in
SymbolTable. */
public Method findMethod(String name, String sig) {
SymbolTable syms = VM.getVM().getSymbolTable();
Symbol nameSym = syms.probe(name);
Symbol sigSym = syms.probe(sig);
if (nameSym == null || sigSym == null) {
return null;
}
return findMethod(nameSym, sigSym);
}
/** Find method in vtable. */
public Method findMethod(Symbol name, Symbol sig) {
public Method findMethod(String name, String sig) {
return findMethod(getMethods(), name, sig);
}
@ -1055,56 +1031,16 @@ public class InstanceKlass extends Klass {
throw new RuntimeException("Illegal field type at index " + index);
}
private static Method findMethod(MethodArray methods, Symbol name, Symbol signature) {
int len = methods.length();
// methods are sorted, so do binary search
int l = 0;
int h = len - 1;
while (l <= h) {
int mid = (l + h) >> 1;
Method m = methods.at(mid);
long res = m.getName().fastCompare(name);
if (res == 0) {
// found matching name; do linear search to find matching signature
// first, quick check for common case
if (m.getSignature().equals(signature)) return m;
// search downwards through overloaded methods
int i;
for (i = mid - 1; i >= l; i--) {
Method m1 = methods.at(i);
if (!m1.getName().equals(name)) break;
if (m1.getSignature().equals(signature)) return m1;
}
// search upwards
for (i = mid + 1; i <= h; i++) {
Method m1 = methods.at(i);
if (!m1.getName().equals(name)) break;
if (m1.getSignature().equals(signature)) return m1;
}
// not found
if (Assert.ASSERTS_ENABLED) {
int index = linearSearch(methods, name, signature);
if (index != -1) {
throw new DebuggerException("binary search bug: should have found entry " + index);
}
}
return null;
} else if (res < 0) {
l = mid + 1;
} else {
h = mid - 1;
}
private static Method findMethod(MethodArray methods, String name, String signature) {
int index = linearSearch(methods, name, signature);
if (index != -1) {
return methods.at(index);
} else {
return null;
}
if (Assert.ASSERTS_ENABLED) {
int index = linearSearch(methods, name, signature);
if (index != -1) {
throw new DebuggerException("binary search bug: should have found entry " + index);
}
}
return null;
}
private static int linearSearch(MethodArray methods, Symbol name, Symbol signature) {
private static int linearSearch(MethodArray methods, String name, String signature) {
int len = (int) methods.length();
for (int index = 0; index < len; index++) {
Method m = methods.at(index);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
@ -93,18 +93,18 @@ public class Method extends Metadata {
// constant method names - <init>, <clinit>
// Initialized lazily to avoid initialization ordering dependencies between Method and SymbolTable
private static Symbol objectInitializerName;
private static Symbol classInitializerName;
private static Symbol objectInitializerName() {
// Initialized lazily to avoid initialization ordering dependencies between ArrayKlass and String
private static String objectInitializerName;
private static String classInitializerName;
private static String objectInitializerName() {
if (objectInitializerName == null) {
objectInitializerName = VM.getVM().getSymbolTable().probe("<init>");
objectInitializerName = "<init>";
}
return objectInitializerName;
}
private static Symbol classInitializerName() {
private static String classInitializerName() {
if (classInitializerName == null) {
classInitializerName = VM.getVM().getSymbolTable().probe("<clinit>");
classInitializerName = "<clinit>";
}
return classInitializerName;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
@ -106,6 +106,10 @@ public class Symbol extends VMObject {
return true;
}
public boolean equals(String string) {
return asString().equals(string);
}
public byte[] asByteArray() {
int length = (int) getLength();
byte [] result = new byte [length];

View File

@ -78,7 +78,6 @@ public class VM {
private long logAddressSize;
private Universe universe;
private ObjectHeap heap;
private SymbolTable symbols;
private SystemDictionary dict;
private ClassLoaderDataGraph cldGraph;
private Threads threads;
@ -647,13 +646,6 @@ public class VM {
return heap;
}
public SymbolTable getSymbolTable() {
if (symbols == null) {
symbols = SymbolTable.getTheTable();
}
return symbols;
}
public SystemDictionary getSystemDictionary() {
if (dict == null) {
dict = new SystemDictionary();

View File

@ -43,10 +43,9 @@ import sun.jvm.hotspot.runtime.*;
public abstract class AbstractHeapGraphWriter implements HeapGraphWriter {
// the function iterates heap and calls Oop type specific writers
protected void write() throws IOException {
SymbolTable symTbl = VM.getVM().getSymbolTable();
javaLangClass = symTbl.probe("java/lang/Class");
javaLangString = symTbl.probe("java/lang/String");
javaLangThread = symTbl.probe("java/lang/Thread");
javaLangClass = "java/lang/Class";
javaLangString = "java/lang/String";
javaLangThread = "java/lang/Thread";
ObjectHeap heap = VM.getVM().getObjectHeap();
try {
heap.iterate(new DefaultHeapVisitor() {
@ -458,7 +457,7 @@ public abstract class AbstractHeapGraphWriter implements HeapGraphWriter {
}
}
protected Symbol javaLangClass;
protected Symbol javaLangString;
protected Symbol javaLangThread;
protected String javaLangClass;
protected String javaLangString;
protected String javaLangThread;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 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
@ -309,6 +309,9 @@ import sun.jvm.hotspot.classfile.*;
public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
// Record which Symbol names have been dumped already.
private HashSet<Symbol> names;
private static final long HPROF_SEGMENTED_HEAP_DUMP_THRESHOLD = 2L * 0x40000000;
// The approximate size of a heap segment. Used to calculate when to create
@ -381,6 +384,7 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
public HeapHprofBinWriter() {
this.KlassMap = new ArrayList<Klass>();
this.names = new HashSet<Symbol>();
}
public synchronized void write(String fileName) throws IOException {
@ -391,7 +395,6 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
VM vm = VM.getVM();
dbg = vm.getDebugger();
objectHeap = vm.getObjectHeap();
symTbl = vm.getSymbolTable();
OBJ_ID_SIZE = (int) vm.getOopSize();
@ -745,6 +748,11 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
} else {
lineNumber = m.getLineNumberFromBCI(bci);
}
// First dump UTF8 if needed
writeSymbol(m.getName()); // method's name
writeSymbol(m.getSignature()); // method's signature
writeSymbol(m.getMethodHolder().getSourceFileName()); // source file name
// Then write FRAME descriptor
writeHeader(HPROF_FRAME, 4 * (int)VM.getVM().getOopSize() + 2 * (int)INT_SIZE);
writeObjectID(frameSN); // frame serial number
writeSymbolID(m.getName()); // method's name
@ -955,7 +963,7 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
out.writeShort((short) fields.size());
for (Iterator itr = fields.iterator(); itr.hasNext();) {
Field field = (Field) itr.next();
Symbol name = symTbl.probe(field.getID().getName());
Symbol name = field.getName();
writeSymbolID(name);
char typeCode = (char) field.getSignature().getByteAt(0);
int kind = signatureToHprofKind(typeCode);
@ -1049,27 +1057,44 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
out.writeInt(0);
}
private void writeClassSymbols(Klass k) throws IOException {
writeSymbol(k.getName());
if (k instanceof InstanceKlass) {
InstanceKlass ik = (InstanceKlass) k;
List declaredFields = ik.getImmediateFields();
for (Iterator itr = declaredFields.iterator(); itr.hasNext();) {
Field field = (Field) itr.next();
writeSymbol(field.getName());
}
}
}
private void writeSymbols() throws IOException {
// Write all the symbols that are used by the classes
ClassLoaderDataGraph cldGraph = VM.getVM().getClassLoaderDataGraph();
try {
symTbl.symbolsDo(new SymbolTable.SymbolVisitor() {
public void visit(Symbol sym) {
try {
writeSymbol(sym);
} catch (IOException exp) {
throw new RuntimeException(exp);
}
}
});
cldGraph.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
public void visit(Klass k) {
try {
writeClassSymbols(k);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
} catch (RuntimeException re) {
handleRuntimeException(re);
}
}
private void writeSymbol(Symbol sym) throws IOException {
byte[] buf = sym.asString().getBytes("UTF-8");
writeHeader(HPROF_UTF8, buf.length + OBJ_ID_SIZE);
writeSymbolID(sym);
out.write(buf);
// If name is already written don't write it again.
if (names.add(sym)) {
byte[] buf = sym.asString().getBytes("UTF-8");
writeHeader(HPROF_UTF8, buf.length + OBJ_ID_SIZE);
writeSymbolID(sym);
out.write(buf);
}
}
private void writeClasses() throws IOException {
@ -1118,6 +1143,7 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
}
private void writeSymbolID(Symbol sym) throws IOException {
assert names.contains(sym);
writeObjectID(getAddressValue(sym.getAddress()));
}
@ -1195,7 +1221,6 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
private FileOutputStream fos;
private Debugger dbg;
private ObjectHeap objectHeap;
private SymbolTable symTbl;
private ArrayList<Klass> KlassMap;
// oopSize of the debuggee

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 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
@ -135,39 +135,35 @@ public class ObjectReader {
}
}
protected Symbol javaLangString;
protected Symbol javaUtilHashtableEntry;
protected Symbol javaUtilHashtable;
protected Symbol javaUtilProperties;
protected String javaLangString;
protected String javaUtilHashtableEntry;
protected String javaUtilHashtable;
protected String javaUtilProperties;
protected Symbol getVMSymbol(String name) {
return VM.getVM().getSymbolTable().probe(name);
}
protected Symbol javaLangString() {
protected String javaLangString() {
if (javaLangString == null) {
javaLangString = getVMSymbol("java/lang/String");
javaLangString = "java/lang/String";
}
return javaLangString;
}
protected Symbol javaUtilHashtableEntry() {
protected String javaUtilHashtableEntry() {
if (javaUtilHashtableEntry == null) {
javaUtilHashtableEntry = getVMSymbol("java/util/Hashtable$Entry");
javaUtilHashtableEntry = "java/util/Hashtable$Entry";
}
return javaUtilHashtableEntry;
}
protected Symbol javaUtilHashtable() {
protected String javaUtilHashtable() {
if (javaUtilHashtable == null) {
javaUtilHashtable = getVMSymbol("java/util/Hashtable");
javaUtilHashtable = "java/util/Hashtable";
}
return javaUtilHashtable;
}
protected Symbol javaUtilProperties() {
protected String javaUtilProperties() {
if (javaUtilProperties == null) {
javaUtilProperties = getVMSymbol("java/util/Properties");
javaUtilProperties = "java/util/Properties";
}
return javaUtilProperties;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 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
@ -127,31 +127,27 @@ public class JSJavaFactoryImpl implements JSJavaFactory {
}
// -- Internals only below this point
private Symbol javaLangString() {
private String javaLangString() {
if (javaLangString == null) {
javaLangString = getSymbol("java/lang/String");
javaLangString = "java/lang/String";
}
return javaLangString;
}
private Symbol javaLangThread() {
private String javaLangThread() {
if (javaLangThread == null) {
javaLangThread = getSymbol("java/lang/Thread");
javaLangThread = "java/lang/Thread";
}
return javaLangThread;
}
private Symbol javaLangClass() {
private String javaLangClass() {
if (javaLangClass == null) {
javaLangClass = getSymbol("java/lang/Class");
javaLangClass = "java/lang/Class";
}
return javaLangClass;
}
private Symbol getSymbol(String str) {
return VM.getVM().getSymbolTable().probe(str);
}
private JSJavaObject newJavaInstance(Instance instance) {
// look for well-known classes
Symbol className = instance.getKlass().getName();
@ -196,7 +192,7 @@ public class JSJavaFactoryImpl implements JSJavaFactory {
// Map<Oop, SoftReference<JSJavaObject>>
private Map om = new HashMap();
private Symbol javaLangString;
private Symbol javaLangThread;
private Symbol javaLangClass;
private String javaLangString;
private String javaLangThread;
private String javaLangClass;
}

View File

@ -1,146 +0,0 @@
/*
* Copyright (c) 2016, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import sun.jvm.hotspot.memory.SymbolTable;
import sun.jvm.hotspot.oops.Symbol;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.tools.Tool;
/**
* This class is launched in a sub-process by the main test,
* SASymbolTableTest.java.
*
* It uses SA to connect to another JVM process, whose PID is specified in args[].
* The purpose of the test is to validate that we can walk the SymbolTable
* and CompactHashTable of the other process. Everything should work regardless
* of whether the other process runs in CDS mode or not.
*
* Note: CompactHashTable is used only when CDS is enabled.
*/
public class SASymbolTableTestAgent extends Tool {
public SASymbolTableTestAgent() {
super();
}
public static void main(String args[]) {
SASymbolTableTestAgent tool = new SASymbolTableTestAgent();
tool.execute(args);
}
static String[] commonNames = {
"java/lang/Object",
"java/lang/String",
"java/lang/Class",
"java/lang/Cloneable",
"java/lang/ClassLoader",
"java/io/Serializable",
"java/lang/System",
"java/lang/Throwable",
"java/lang/Error",
"java/lang/ThreadDeath",
"java/lang/Exception",
"java/lang/RuntimeException",
"java/lang/SecurityManager",
"java/security/ProtectionDomain",
"java/security/AccessControlContext",
"java/security/SecureClassLoader",
"java/lang/ClassNotFoundException",
"java/lang/NoClassDefFoundError",
"java/lang/LinkageError",
"java/lang/ClassCastException",
"java/lang/ArrayStoreException",
"java/lang/VirtualMachineError",
"java/lang/OutOfMemoryError",
"java/lang/StackOverflowError",
"java/lang/IllegalMonitorStateException",
"java/lang/ref/Reference",
"java/lang/ref/SoftReference",
"java/lang/ref/WeakReference",
"java/lang/ref/FinalReference",
"java/lang/ref/PhantomReference",
"java/lang/ref/Finalizer",
"java/lang/Thread",
"java/lang/ThreadGroup",
"java/util/Properties",
"java/lang/reflect/AccessibleObject",
"java/lang/reflect/Field",
"java/lang/reflect/Method",
"java/lang/reflect/Constructor",
"java/lang/invoke/MethodHandle",
"java/lang/invoke/MemberName",
"java/lang/invoke/MethodHandleNatives",
"java/lang/invoke/MethodType",
"java/lang/BootstrapMethodError",
"java/lang/invoke/CallSite",
"java/lang/invoke/ConstantCallSite",
"java/lang/invoke/MutableCallSite",
"java/lang/invoke/VolatileCallSite",
"java/lang/StringBuffer",
"java/lang/StringBuilder",
"java/io/ByteArrayInputStream",
"java/io/File",
"java/net/URLClassLoader",
"java/net/URL",
"java/util/jar/Manifest",
"java/security/CodeSource",
};
static String[] badNames = {
"java/lang/badbadbad",
"java/io/badbadbadbad",
"this*symbol*must*not*exist"
};
public void run() {
System.out.println("SASymbolTableTestAgent: starting");
try {
VM vm = VM.getVM();
SymbolTable table = vm.getSymbolTable();
// (a) These are names that are likely to exist in the symbol table
// of a JVM after start-up. They were taken from vmSymbols.hpp
// during the middle of JDK9 development.
//
// The purpose is not to check that each name must exist (a future
// version of JDK may not preload some of the classes).
//
// The purpose of this loops is to ensure that we check a lot of symbols,
// so we will (most likely) hit on both VALUE_ONLY_BUCKET_TYPE and normal bucket type
// in CompactHashTable.probe().
for (String n : commonNames) {
Symbol s = table.probe(n);
System.out.format("%-40s = %s\n", n, s);
}
System.out.println("======================================================================");
// (b) Also test a few strings that are known to not exist in the table. This will
// both the compact table (if it exists) and the regular table to be walked.
for (String n : badNames) {
Symbol s = table.probe(n);
System.out.format("%-40s = %s\n", n, s);
}
} catch (NullPointerException e) {
System.out.println("connected too early -- please try again");
}
}
}

View File

@ -57,7 +57,7 @@ public class ClhsdbPrintStatics {
expStrMap.put("printstatics", List.of(
"All known static fields",
"Abstract_VM_Version::_vm_major_version",
"ClassLoaderDataGraph::_head", "SymbolTable::_the_table",
"ClassLoaderDataGraph::_head",
"JNIHandles::_weak_global_handles", "PerfMemory::_top",
"ObjectSynchronizer::gBlockList",
"java_lang_Class::_oop_size_offset",

View File

@ -66,8 +66,7 @@ public class ClhsdbSource {
"Available commands:",
"attach pid | exec core",
"intConstant [ name [ value ] ]",
"type [ type [ name super isOop isInteger isUnsigned size ] ]",
"symboltable name"));
"type [ type [ name super isOop isInteger isUnsigned size ] ]"));
Map<String, List<String>> unExpStrMap = new HashMap<>();
unExpStrMap.put("source clhsdb_cmd_file", List.of(

View File

@ -1,161 +0,0 @@
/*
* Copyright (c) 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import jdk.test.lib.apps.LingeredApp;
public class LingeredAppWithAltHashing extends LingeredApp {
public static void main(String args[]) {
LingeredApp.main(args);
}
// Following strings generate the same hashcode
static final String str1 = "AaAaAaAaAaAaAa";
static final String str2 = "AaAaAaAaAaAaBB";
static final String str3 = "AaAaAaAaAaBBAa";
static final String str4 = "AaAaAaAaAaBBBB";
static final String str5 = "AaAaAaAaBBAaAa";
static final String str6 = "AaAaAaAaBBAaBB";
static final String str7 = "AaAaAaAaBBBBAa";
static final String str8 = "AaAaAaAaBBBBBB";
static final String str9 = "AaAaAaBBAaAaAa";
static final String str10 = "AaAaAaBBAaAaBB";
static final String str11 = "AaAaAaBBAaBBAa";
static final String str12 = "AaAaAaBBAaBBBB";
static final String str13 = "AaAaAaBBBBAaAa";
static final String str14 = "AaAaAaBBBBAaBB";
static final String str15 = "AaAaAaBBBBBBAa";
static final String str16 = "AaAaAaBBBBBBBB";
static final String str17 = "AaAaBBAaAaAaAa";
static final String str18 = "AaAaBBAaAaAaBB";
static final String str19 = "AaAaBBAaAaBBAa";
static final String str20 = "AaAaBBAaAaBBBB";
static final String str21 = "AaAaBBAaBBAaAa";
static final String str22 = "AaAaBBAaBBAaBB";
static final String str23 = "AaAaBBAaBBBBAa";
static final String str24 = "AaAaBBAaBBBBBB";
static final String str25 = "AaAaBBBBAaAaAa";
static final String str26 = "AaAaBBBBAaAaBB";
static final String str27 = "AaAaBBBBAaBBAa";
static final String str28 = "AaAaBBBBAaBBBB";
static final String str29 = "AaAaBBBBBBAaAa";
static final String str30 = "AaAaBBBBBBAaBB";
static final String str31 = "AaAaBBBBBBBBAa";
static final String str32 = "AaAaBBBBBBBBBB";
static final String str33 = "AaBBAaAaAaAaAa";
static final String str34 = "AaBBAaAaAaAaBB";
static final String str35 = "AaBBAaAaAaBBAa";
static final String str36 = "AaBBAaAaAaBBBB";
static final String str37 = "AaBBAaAaBBAaAa";
static final String str38 = "AaBBAaAaBBAaBB";
static final String str39 = "AaBBAaAaBBBBAa";
static final String str40 = "AaBBAaAaBBBBBB";
static final String str41 = "AaBBAaBBAaAaAa";
static final String str42 = "AaBBAaBBAaAaBB";
static final String str43 = "AaBBAaBBAaBBAa";
static final String str44 = "AaBBAaBBAaBBBB";
static final String str45 = "AaBBAaBBBBAaAa";
static final String str46 = "AaBBAaBBBBAaBB";
static final String str47 = "AaBBAaBBBBBBAa";
static final String str48 = "AaBBAaBBBBBBBB";
static final String str49 = "AaBBBBAaAaAaAa";
static final String str50 = "AaBBBBAaAaAaBB";
static final String str51 = "AaBBBBAaAaBBAa";
static final String str52 = "AaBBBBAaAaBBBB";
static final String str53 = "AaBBBBAaBBAaAa";
static final String str54 = "AaBBBBAaBBAaBB";
static final String str55 = "AaBBBBAaBBBBAa";
static final String str56 = "AaBBBBAaBBBBBB";
static final String str57 = "AaBBBBBBAaAaAa";
static final String str58 = "AaBBBBBBAaAaBB";
static final String str59 = "AaBBBBBBAaBBAa";
static final String str60 = "AaBBBBBBAaBBBB";
static final String str61 = "AaBBBBBBBBAaAa";
static final String str62 = "AaBBBBBBBBAaBB";
static final String str63 = "AaBBBBBBBBBBAa";
static final String str64 = "AaBBBBBBBBBBBB";
static final String str65 = "BBAaAaAaAaAaAa";
static final String str66 = "BBAaAaAaAaAaBB";
static final String str67 = "BBAaAaAaAaBBAa";
static final String str68 = "BBAaAaAaAaBBBB";
static final String str69 = "BBAaAaAaBBAaAa";
static final String str70 = "BBAaAaAaBBAaBB";
static final String str71 = "BBAaAaAaBBBBAa";
static final String str72 = "BBAaAaAaBBBBBB";
static final String str73 = "BBAaAaBBAaAaAa";
static final String str74 = "BBAaAaBBAaAaBB";
static final String str75 = "BBAaAaBBAaBBAa";
static final String str76 = "BBAaAaBBAaBBBB";
static final String str77 = "BBAaAaBBBBAaAa";
static final String str78 = "BBAaAaBBBBAaBB";
static final String str79 = "BBAaAaBBBBBBAa";
static final String str80 = "BBAaAaBBBBBBBB";
static final String str81 = "BBAaBBAaAaAaAa";
static final String str82 = "BBAaBBAaAaAaBB";
static final String str83 = "BBAaBBAaAaBBAa";
static final String str84 = "BBAaBBAaAaBBBB";
static final String str85 = "BBAaBBAaBBAaAa";
static final String str86 = "BBAaBBAaBBAaBB";
static final String str87 = "BBAaBBAaBBBBAa";
static final String str88 = "BBAaBBAaBBBBBB";
static final String str89 = "BBAaBBBBAaAaAa";
static final String str90 = "BBAaBBBBAaAaBB";
static final String str91 = "BBAaBBBBAaBBAa";
static final String str92 = "BBAaBBBBAaBBBB";
static final String str93 = "BBAaBBBBBBAaAa";
static final String str94 = "BBAaBBBBBBAaBB";
static final String str95 = "BBAaBBBBBBBBAa";
static final String str96 = "BBAaBBBBBBBBBB";
static final String str97 = "BBBBAaAaAaAaAa";
static final String str98 = "BBBBAaAaAaAaBB";
static final String str99 = "BBBBAaAaAaBBAa";
static final String str100 = "BBBBAaAaAaBBBB";
static final String str101 = "BBBBAaAaBBAaAa";
static final String str102 = "BBBBAaAaBBAaBB";
static final String str103 = "BBBBAaAaBBBBAa";
static final String str104 = "BBBBAaAaBBBBBB";
static final String str105 = "BBBBAaBBAaAaAa";
static final String str106 = "BBBBAaBBAaAaBB";
static final String str107 = "BBBBAaBBAaBBAa";
static final String str108 = "BBBBAaBBAaBBBB";
static final String str109 = "BBBBAaBBBBAaAa";
static final String str110 = "BBBBAaBBBBAaBB";
static final String str111 = "BBBBAaBBBBBBAa";
static final String str112 = "BBBBAaBBBBBBBB";
static final String str113 = "BBBBBBAaAaAaAa";
static final String str114 = "BBBBBBAaAaAaBB";
static final String str115 = "BBBBBBAaAaBBAa";
static final String str116 = "BBBBBBAaAaBBBB";
static final String str117 = "BBBBBBAaBBAaAa";
static final String str118 = "BBBBBBAaBBAaBB";
static final String str119 = "BBBBBBAaBBBBAa";
static final String str120 = "BBBBBBAaBBBBBB";
static final String str121 = "BBBBBBBBAaAaAa";
static final String str122 = "BBBBBBBBAaAaBB";
static final String str123 = "BBBBBBBBAaBBAa";
static final String str124 = "BBBBBBBBAaBBBB";
static final String str125 = "BBBBBBBBBBAaAa";
static final String str126 = "BBBBBBBBBBAaBB";
static final String str127 = "BBBBBBBBBBBBAa";
static final String str128 = "BBBBBBBBBBBBBB";
}