Mercurial > hg > truffle
changeset 6170:d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
Summary: Bug fix of 7126277 changed hashing algorithm and also changed key as final field, this led SA unable to set correct value for key. Solution by reading key/value and insert them into the new table.
Reviewed-by: dholmes, mikael
Contributed-by: yumin.qi@oracle.com
author | minqi |
---|---|
date | Fri, 22 Jun 2012 15:39:16 -0700 |
parents | cfa2c82f4c04 |
children | 588f559105c1 246d977b51f2 |
files | agent/src/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java |
diffstat | 1 files changed, 118 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java Fri Jun 22 15:35:30 2012 -0700 +++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java Fri Jun 22 15:39:16 2012 -0700 @@ -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 @@ 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 @@ } 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<size; i++) { + Oop entry = kvs.getObjAt(i); + if (entry != null && entry.isInstance()) { + setHashtableEntry(table, entry); + } + } + return table; + } + public Object readInstance(Instance oop) throws ClassNotFoundException { Object result = getFromObjTable(oop); if (result == null) { @@ -134,11 +232,21 @@ // Handle java.lang.String instances differently. As part of JSR-133, fields of immutable // classes have been made final. The algorithm below will not be able to read Strings from // debuggee (can't use reflection to set final fields). But, need to read Strings is very - // important. FIXME: need a framework to handle many other special cases. + // important. + // Same for Hashtable, key and hash are final, could not be set in the algorithm too. + // FIXME: need a framework to handle many other special cases. if (kls.getName().equals(javaLangString())) { return OopUtilities.stringOopToString(oop); } + if (kls.getName().equals(javaUtilHashtable())) { + return getHashtable(oop, false); + } + + if (kls.getName().equals(javaUtilProperties())) { + return getHashtable(oop, true); + } + Class clz = readClass(kls); try { result = clz.newInstance(); @@ -164,8 +272,8 @@ break; } catch (Exception exp) { if (DEBUG) { - System.err.println("Can't create object using " + c); - exp.printStackTrace(); + debugPrintln("Can't create object using " + c); + debugPrintStackTrace(exp); } } } @@ -329,8 +437,8 @@ arrayObj[ifd.getIndex()] = readObject(field.getValue(getObj())); } catch (Exception e) { if (DEBUG) { - System.err.println("Array element set failed for " + ifd); - e.printStackTrace(); + debugPrintln("Array element set failed for " + ifd); + debugPrintStackTrace(e); } } } @@ -348,8 +456,8 @@ private void printFieldSetError(java.lang.reflect.Field f, Exception ex) { if (DEBUG) { - if (f != null) System.err.println("Field set failed for " + f); - ex.printStackTrace(); + if (f != null) debugPrintln("Field set failed for " + f); + debugPrintStackTrace(ex); } } @@ -601,7 +709,7 @@ return Class.forName(className, true, cl); } catch (Exception e) { if (DEBUG) { - System.err.println("Can't load class " + className); + debugPrintln("Can't load class " + className); } throw new RuntimeException(e); }