diff --git a/agent/src/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java b/agent/src/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java index 55cb299562107531bbe1639b57bed94d6a6c66f6..1f17a7fdb63d2901d20e8760d236a0d7cf6e4550 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java +++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012, 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 @@ -85,6 +85,21 @@ public class ObjectReader { this(new ProcImageClassLoader()); } + static void debugPrintln(String msg) { + if (DEBUG) { + System.err.println("DEBUG>" + msg); + } + } + + static void debugPrintStackTrace(Exception exp) { + if (DEBUG) { + StackTraceElement[] els = exp.getStackTrace(); + for (int i = 0; i < els.length; i++) { + System.err.println("DEBUG>" + els[i].toString()); + } + } + } + public Object readObject(Oop oop) throws ClassNotFoundException { if (oop instanceof Instance) { return readInstance((Instance) oop); @@ -120,13 +135,96 @@ public class ObjectReader { } protected Symbol javaLangString; + protected Symbol javaUtilHashtableEntry; + protected Symbol javaUtilHashtable; + protected Symbol javaUtilProperties; + + protected Symbol getVMSymbol(String name) { + return VM.getVM().getSymbolTable().probe(name); + } + protected Symbol javaLangString() { if (javaLangString == null) { - javaLangString = VM.getVM().getSymbolTable().probe("java/lang/String"); + javaLangString = getVMSymbol("java/lang/String"); } return javaLangString; } + protected Symbol javaUtilHashtableEntry() { + if (javaUtilHashtableEntry == null) { + javaUtilHashtableEntry = getVMSymbol("java/util/Hashtable$Entry"); + } + return javaUtilHashtableEntry; + } + + protected Symbol javaUtilHashtable() { + if (javaUtilHashtable == null) { + javaUtilHashtable = getVMSymbol("java/util/Hashtable"); + } + return javaUtilHashtable; + } + + protected Symbol javaUtilProperties() { + if (javaUtilProperties == null) { + javaUtilProperties = getVMSymbol("java/util/Properties"); + } + return javaUtilProperties; + } + + private void setHashtableEntry(java.util.Hashtable p, Oop oop) { + InstanceKlass ik = (InstanceKlass)oop.getKlass(); + OopField keyField = (OopField)ik.findField("key", "Ljava/lang/Object;"); + OopField valueField = (OopField)ik.findField("value", "Ljava/lang/Object;"); + OopField nextField = (OopField)ik.findField("next", "Ljava/util/Hashtable$Entry;"); + if (DEBUG) { + if (Assert.ASSERTS_ENABLED) { + Assert.that(ik.getName().equals(javaUtilHashtableEntry()), "Not a Hashtable$Entry?"); + Assert.that(keyField != null && valueField != null && nextField != null, "Invalid fields!"); + } + } + + Object key = null; + Object value = null; + Oop next = null; + try { + key = readObject(keyField.getValue(oop)); + value = readObject(valueField.getValue(oop)); + next = (Oop)nextField.getValue(oop); + // For Properties, should use setProperty(k, v). Since it only runs in SA + // using put(k, v) should be OK. + p.put(key, value); + if (next != null) { + setHashtableEntry(p, next); + } + } catch (ClassNotFoundException ce) { + if( DEBUG) { + debugPrintln("Class not found " + ce); + debugPrintStackTrace(ce); + } + } + } + + protected Object getHashtable(Instance oop, boolean isProperties) { + InstanceKlass k = (InstanceKlass)oop.getKlass(); + OopField tableField = (OopField)k.findField("table", "[Ljava/util/Hashtable$Entry;"); + if (tableField == null) { + debugPrintln("Could not find field of [Ljava/util/Hashtable$Entry;"); + return null; + } + java.util.Hashtable table = (isProperties) ? new java.util.Properties() + : new java.util.Hashtable(); + ObjArray kvs = (ObjArray)tableField.getValue(oop); + long size = kvs.getLength(); + debugPrintln("Hashtable$Entry Size = " + size); + for (long i=0; i