Mercurial > hg > graal-jvmci-8
annotate agent/src/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java @ 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 | c18cbe5936b8 |
children | da91efe96a93 |
rev | line source |
---|---|
0 | 1 /* |
6170
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
2 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 package sun.jvm.hotspot.utilities; | |
26 | |
27 import java.lang.reflect.Modifier; | |
28 import java.util.*; | |
29 import sun.jvm.hotspot.debugger.*; | |
30 import sun.jvm.hotspot.oops.*; | |
31 import sun.jvm.hotspot.runtime.*; | |
32 import sun.jvm.hotspot.utilities.*; | |
33 | |
34 /** | |
35 * ObjectReader can "deserialize" objects from debuggee. | |
36 * | |
37 * Class Loading: | |
38 * | |
39 * ObjectReader loads classes using the given class loader. If no | |
40 * class loader is supplied, it uses a ProcImageClassLoader, which | |
41 * loads classes from debuggee core or process. | |
42 | |
43 * Object creation: | |
44 * | |
45 * This class uses no-arg constructor to construct objects. But if | |
46 * there is no no-arg constructor in a given class, then it tries to | |
47 * use other constructors with 'default' values - null for object | |
48 * types, 0, 0.0, false etc. for primitives. If this process fails to | |
49 * construct an instance (because of null checking by constructor or 0 | |
50 * being invalid for an int arg etc.), then null is returned. While | |
51 * constructing complete object graph 'null' is inserted silently on | |
52 * failure and the deserialization continues to construct best-effort | |
53 * object graph. | |
54 * | |
55 * Debug messages: | |
56 * | |
57 * The flag sun.jvm.hotspot.utilities.ObjectReader.DEBUG may be set to | |
58 * non-null to get debug error messages and stack traces. | |
59 * | |
60 * JDK version: | |
61 * | |
62 * JDK classes are loaded by bootstrap class loader and not by the | |
63 * supplied class loader or ProcImageClassLoader. This may create | |
64 * problems if a JDK class evolves. i.e., if SA runs a JDK version | |
65 * different from that of the debuggee, there is a possibility of | |
66 * schema change. It is recommended that the matching JDK version be | |
67 * used to run SA for proper object deserialization. | |
68 * | |
69 */ | |
70 | |
71 public class ObjectReader { | |
72 | |
73 private static final boolean DEBUG; | |
74 static { | |
75 DEBUG = System.getProperty("sun.jvm.hotspot.utilities.ObjectReader.DEBUG") != null; | |
76 } | |
77 | |
78 public ObjectReader(ClassLoader cl) { | |
79 this.cl = cl; | |
80 this.oopToObjMap = new HashMap(); | |
81 this.fieldMap = new HashMap(); | |
82 } | |
83 | |
84 public ObjectReader() { | |
85 this(new ProcImageClassLoader()); | |
86 } | |
87 | |
6170
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
88 static void debugPrintln(String msg) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
89 if (DEBUG) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
90 System.err.println("DEBUG>" + msg); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
91 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
92 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
93 |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
94 static void debugPrintStackTrace(Exception exp) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
95 if (DEBUG) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
96 StackTraceElement[] els = exp.getStackTrace(); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
97 for (int i = 0; i < els.length; i++) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
98 System.err.println("DEBUG>" + els[i].toString()); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
99 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
100 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
101 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
102 |
0 | 103 public Object readObject(Oop oop) throws ClassNotFoundException { |
104 if (oop instanceof Instance) { | |
105 return readInstance((Instance) oop); | |
106 } else if (oop instanceof TypeArray){ | |
107 return readPrimitiveArray((TypeArray)oop); | |
108 } else if (oop instanceof ObjArray){ | |
109 return readObjectArray((ObjArray)oop); | |
110 } else { | |
111 return null; | |
112 } | |
113 } | |
114 | |
115 protected final Object getDefaultPrimitiveValue(Class clz) { | |
116 if (clz == Boolean.TYPE) { | |
117 return Boolean.FALSE; | |
118 } else if (clz == Character.TYPE) { | |
119 return new Character(' '); | |
120 } else if (clz == Byte.TYPE) { | |
121 return new Byte((byte) 0); | |
122 } else if (clz == Short.TYPE) { | |
123 return new Short((short) 0); | |
124 } else if (clz == Integer.TYPE) { | |
125 return new Integer(0); | |
126 } else if (clz == Long.TYPE) { | |
127 return new Long(0L); | |
128 } else if (clz == Float.TYPE) { | |
129 return new Float(0.0f); | |
130 } else if (clz == Double.TYPE) { | |
131 return new Double(0.0); | |
132 } else { | |
133 throw new RuntimeException("should not reach here!"); | |
134 } | |
135 } | |
136 | |
137 protected Symbol javaLangString; | |
6170
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
138 protected Symbol javaUtilHashtableEntry; |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
139 protected Symbol javaUtilHashtable; |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
140 protected Symbol javaUtilProperties; |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
141 |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
142 protected Symbol getVMSymbol(String name) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
143 return VM.getVM().getSymbolTable().probe(name); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
144 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
145 |
0 | 146 protected Symbol javaLangString() { |
147 if (javaLangString == null) { | |
6170
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
148 javaLangString = getVMSymbol("java/lang/String"); |
0 | 149 } |
150 return javaLangString; | |
151 } | |
152 | |
6170
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
153 protected Symbol javaUtilHashtableEntry() { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
154 if (javaUtilHashtableEntry == null) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
155 javaUtilHashtableEntry = getVMSymbol("java/util/Hashtable$Entry"); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
156 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
157 return javaUtilHashtableEntry; |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
158 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
159 |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
160 protected Symbol javaUtilHashtable() { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
161 if (javaUtilHashtable == null) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
162 javaUtilHashtable = getVMSymbol("java/util/Hashtable"); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
163 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
164 return javaUtilHashtable; |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
165 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
166 |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
167 protected Symbol javaUtilProperties() { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
168 if (javaUtilProperties == null) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
169 javaUtilProperties = getVMSymbol("java/util/Properties"); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
170 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
171 return javaUtilProperties; |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
172 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
173 |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
174 private void setHashtableEntry(java.util.Hashtable p, Oop oop) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
175 InstanceKlass ik = (InstanceKlass)oop.getKlass(); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
176 OopField keyField = (OopField)ik.findField("key", "Ljava/lang/Object;"); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
177 OopField valueField = (OopField)ik.findField("value", "Ljava/lang/Object;"); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
178 OopField nextField = (OopField)ik.findField("next", "Ljava/util/Hashtable$Entry;"); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
179 if (DEBUG) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
180 if (Assert.ASSERTS_ENABLED) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
181 Assert.that(ik.getName().equals(javaUtilHashtableEntry()), "Not a Hashtable$Entry?"); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
182 Assert.that(keyField != null && valueField != null && nextField != null, "Invalid fields!"); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
183 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
184 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
185 |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
186 Object key = null; |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
187 Object value = null; |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
188 Oop next = null; |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
189 try { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
190 key = readObject(keyField.getValue(oop)); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
191 value = readObject(valueField.getValue(oop)); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
192 next = (Oop)nextField.getValue(oop); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
193 // For Properties, should use setProperty(k, v). Since it only runs in SA |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
194 // using put(k, v) should be OK. |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
195 p.put(key, value); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
196 if (next != null) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
197 setHashtableEntry(p, next); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
198 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
199 } catch (ClassNotFoundException ce) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
200 if( DEBUG) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
201 debugPrintln("Class not found " + ce); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
202 debugPrintStackTrace(ce); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
203 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
204 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
205 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
206 |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
207 protected Object getHashtable(Instance oop, boolean isProperties) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
208 InstanceKlass k = (InstanceKlass)oop.getKlass(); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
209 OopField tableField = (OopField)k.findField("table", "[Ljava/util/Hashtable$Entry;"); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
210 if (tableField == null) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
211 debugPrintln("Could not find field of [Ljava/util/Hashtable$Entry;"); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
212 return null; |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
213 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
214 java.util.Hashtable table = (isProperties) ? new java.util.Properties() |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
215 : new java.util.Hashtable(); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
216 ObjArray kvs = (ObjArray)tableField.getValue(oop); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
217 long size = kvs.getLength(); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
218 debugPrintln("Hashtable$Entry Size = " + size); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
219 for (long i=0; i<size; i++) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
220 Oop entry = kvs.getObjAt(i); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
221 if (entry != null && entry.isInstance()) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
222 setHashtableEntry(table, entry); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
223 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
224 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
225 return table; |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
226 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
227 |
0 | 228 public Object readInstance(Instance oop) throws ClassNotFoundException { |
229 Object result = getFromObjTable(oop); | |
230 if (result == null) { | |
231 InstanceKlass kls = (InstanceKlass) oop.getKlass(); | |
232 // Handle java.lang.String instances differently. As part of JSR-133, fields of immutable | |
233 // classes have been made final. The algorithm below will not be able to read Strings from | |
234 // debuggee (can't use reflection to set final fields). But, need to read Strings is very | |
6170
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
235 // important. |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
236 // Same for Hashtable, key and hash are final, could not be set in the algorithm too. |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
237 // FIXME: need a framework to handle many other special cases. |
0 | 238 if (kls.getName().equals(javaLangString())) { |
239 return OopUtilities.stringOopToString(oop); | |
240 } | |
241 | |
6170
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
242 if (kls.getName().equals(javaUtilHashtable())) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
243 return getHashtable(oop, false); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
244 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
245 |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
246 if (kls.getName().equals(javaUtilProperties())) { |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
247 return getHashtable(oop, true); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
248 } |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
249 |
0 | 250 Class clz = readClass(kls); |
251 try { | |
252 result = clz.newInstance(); | |
253 } catch (Exception ex) { | |
254 // no-arg constructor failed to create object. Let us try | |
255 // to call constructors one-by-one with default arguments | |
256 // (null for objects, 0/0.0 etc. for primitives) till we | |
257 // succeed or fail on all constructors. | |
258 | |
259 java.lang.reflect.Constructor[] ctrs = clz.getDeclaredConstructors(); | |
260 for (int n = 0; n < ctrs.length; n++) { | |
261 java.lang.reflect.Constructor c = ctrs[n]; | |
262 Class[] paramTypes = c.getParameterTypes(); | |
263 Object[] params = new Object[paramTypes.length]; | |
264 for (int i = 0; i < params.length; i++) { | |
265 if (paramTypes[i].isPrimitive()) { | |
266 params[i] = getDefaultPrimitiveValue(paramTypes[i]); | |
267 } | |
268 } | |
269 try { | |
270 c.setAccessible(true); | |
271 result = c.newInstance(params); | |
272 break; | |
273 } catch (Exception exp) { | |
274 if (DEBUG) { | |
6170
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
275 debugPrintln("Can't create object using " + c); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
276 debugPrintStackTrace(exp); |
0 | 277 } |
278 } | |
279 } | |
280 } | |
281 | |
282 if (result != null) { | |
283 putIntoObjTable(oop, result); | |
284 oop.iterate(new FieldSetter(result), false); | |
285 } | |
286 } | |
287 return result; | |
288 } | |
289 | |
290 public Object readPrimitiveArray(final TypeArray array) { | |
291 | |
292 Object result = getFromObjTable(array); | |
293 if (result == null) { | |
294 int length = (int) array.getLength(); | |
295 TypeArrayKlass klass = (TypeArrayKlass) array.getKlass(); | |
296 int type = (int) klass.getElementType(); | |
297 switch (type) { | |
298 case TypeArrayKlass.T_BOOLEAN: { | |
299 final boolean[] arrayObj = new boolean[length]; | |
300 array.iterate(new DefaultOopVisitor() { | |
301 public void doBoolean(BooleanField field, boolean isVMField) { | |
302 IndexableFieldIdentifier ifd = (IndexableFieldIdentifier) field.getID(); | |
303 arrayObj[ifd.getIndex()] = field.getValue(array); | |
304 } | |
305 }, false); | |
306 result = arrayObj; | |
307 } | |
308 break; | |
309 | |
310 case TypeArrayKlass.T_CHAR: { | |
311 final char[] arrayObj = new char[length]; | |
312 array.iterate(new DefaultOopVisitor() { | |
313 public void doChar(CharField field, boolean isVMField) { | |
314 IndexableFieldIdentifier ifd = (IndexableFieldIdentifier) field.getID(); | |
315 arrayObj[ifd.getIndex()] = field.getValue(array); | |
316 } | |
317 }, false); | |
318 result = arrayObj; | |
319 } | |
320 break; | |
321 | |
322 case TypeArrayKlass.T_FLOAT: { | |
323 final float[] arrayObj = new float[length]; | |
324 array.iterate(new DefaultOopVisitor() { | |
325 public void doFloat(FloatField field, boolean isVMField) { | |
326 IndexableFieldIdentifier ifd = (IndexableFieldIdentifier) field.getID(); | |
327 arrayObj[ifd.getIndex()] = field.getValue(array); | |
328 } | |
329 }, false); | |
330 result = arrayObj; | |
331 } | |
332 break; | |
333 | |
334 case TypeArrayKlass.T_DOUBLE: { | |
335 final double[] arrayObj = new double[length]; | |
336 array.iterate(new DefaultOopVisitor() { | |
337 public void doDouble(DoubleField field, boolean isVMField) { | |
338 IndexableFieldIdentifier ifd = (IndexableFieldIdentifier) field.getID(); | |
339 arrayObj[ifd.getIndex()] = field.getValue(array); | |
340 } | |
341 }, false); | |
342 result = arrayObj; | |
343 } | |
344 break; | |
345 | |
346 case TypeArrayKlass.T_BYTE: { | |
347 final byte[] arrayObj = new byte[length]; | |
348 array.iterate(new DefaultOopVisitor() { | |
349 public void doByte(ByteField field, boolean isVMField) { | |
350 IndexableFieldIdentifier ifd = (IndexableFieldIdentifier) field.getID(); | |
351 arrayObj[ifd.getIndex()] = field.getValue(array); | |
352 } | |
353 }, false); | |
354 result = arrayObj; | |
355 } | |
356 break; | |
357 | |
358 case TypeArrayKlass.T_SHORT: { | |
359 final short[] arrayObj = new short[length]; | |
360 array.iterate(new DefaultOopVisitor() { | |
361 public void doShort(ShortField field, boolean isVMField) { | |
362 IndexableFieldIdentifier ifd = (IndexableFieldIdentifier) field.getID(); | |
363 arrayObj[ifd.getIndex()] = field.getValue(array); | |
364 } | |
365 }, false); | |
366 result = arrayObj; | |
367 } | |
368 break; | |
369 | |
370 case TypeArrayKlass.T_INT: { | |
371 final int[] arrayObj = new int[length]; | |
372 array.iterate(new DefaultOopVisitor() { | |
373 public void doInt(IntField field, boolean isVMField) { | |
374 IndexableFieldIdentifier ifd = (IndexableFieldIdentifier) field.getID(); | |
375 arrayObj[ifd.getIndex()] = field.getValue(array); | |
376 } | |
377 }, false); | |
378 result = arrayObj; | |
379 } | |
380 break; | |
381 | |
382 case TypeArrayKlass.T_LONG: { | |
383 final long[] arrayObj = new long[length]; | |
384 array.iterate(new DefaultOopVisitor() { | |
385 public void doLong(LongField field, boolean isVMField) { | |
386 IndexableFieldIdentifier ifd = (IndexableFieldIdentifier) field.getID(); | |
387 arrayObj[ifd.getIndex()] = field.getValue(array); | |
388 } | |
389 }, false); | |
390 result = arrayObj; | |
391 } | |
392 break; | |
393 | |
394 default: | |
395 throw new RuntimeException("should not reach here!"); | |
396 } | |
397 | |
398 putIntoObjTable(array, result); | |
399 } | |
400 return result; | |
401 } | |
402 | |
403 protected final boolean isRobust(OopHandle handle) { | |
404 return RobustOopDeterminator.oopLooksValid(handle); | |
405 } | |
406 | |
407 public Object readObjectArray(final ObjArray array) throws ClassNotFoundException { | |
408 Object result = getFromObjTable(array); | |
409 if (result == null) { | |
410 int length = (int) array.getLength(); | |
411 ObjArrayKlass klass = (ObjArrayKlass) array.getKlass(); | |
412 Klass bottomKls = klass.getBottomKlass(); | |
413 Class bottomCls = null; | |
414 final int dimension = (int) klass.getDimension(); | |
415 int[] dimArray = null; | |
416 if (bottomKls instanceof InstanceKlass) { | |
417 bottomCls = readClass((InstanceKlass) bottomKls); | |
418 dimArray = new int[dimension]; | |
419 } else { // instanceof TypeArrayKlass | |
420 TypeArrayKlass botKls = (TypeArrayKlass) bottomKls; | |
421 dimArray = new int[dimension -1]; | |
422 } | |
423 // initialize the length | |
424 dimArray[0] = length; | |
425 final Object[] arrayObj = (Object[]) java.lang.reflect.Array.newInstance(bottomCls, dimArray); | |
426 putIntoObjTable(array, arrayObj); | |
427 result = arrayObj; | |
428 array.iterate(new DefaultOopVisitor() { | |
429 public void doOop(OopField field, boolean isVMField) { | |
430 OopHandle handle = field.getValueAsOopHandle(getObj()); | |
431 if (! isRobust(handle)) { | |
432 return; | |
433 } | |
434 | |
435 IndexableFieldIdentifier ifd = (IndexableFieldIdentifier) field.getID(); | |
436 try { | |
437 arrayObj[ifd.getIndex()] = readObject(field.getValue(getObj())); | |
438 } catch (Exception e) { | |
439 if (DEBUG) { | |
6170
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
440 debugPrintln("Array element set failed for " + ifd); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
441 debugPrintStackTrace(e); |
0 | 442 } |
443 } | |
444 } | |
445 }, false); | |
446 } | |
447 return result; | |
448 } | |
449 | |
450 protected class FieldSetter extends DefaultOopVisitor { | |
451 protected Object obj; | |
452 | |
453 public FieldSetter(Object obj) { | |
454 this.obj = obj; | |
455 } | |
456 | |
457 private void printFieldSetError(java.lang.reflect.Field f, Exception ex) { | |
458 if (DEBUG) { | |
6170
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
459 if (f != null) debugPrintln("Field set failed for " + f); |
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
460 debugPrintStackTrace(ex); |
0 | 461 } |
462 } | |
463 | |
464 // Callback methods for each field type in an object | |
465 public void doOop(OopField field, boolean isVMField) { | |
466 OopHandle handle = field.getValueAsOopHandle(getObj()); | |
467 if (! isRobust(handle) ) { | |
468 return; | |
469 } | |
470 | |
471 java.lang.reflect.Field f = null; | |
472 try { | |
473 f = readField(field); | |
474 if (Modifier.isFinal(f.getModifiers())) return; | |
475 f.setAccessible(true); | |
476 f.set(obj, readObject(field.getValue(getObj()))); | |
477 } catch (Exception ex) { | |
478 printFieldSetError(f, ex); | |
479 } | |
480 } | |
481 | |
482 public void doByte(ByteField field, boolean isVMField) { | |
483 java.lang.reflect.Field f = null; | |
484 try { | |
485 f = readField(field); | |
486 if (Modifier.isFinal(f.getModifiers())) return; | |
487 f.setAccessible(true); | |
488 f.setByte(obj, field.getValue(getObj())); | |
489 } catch (Exception ex) { | |
490 printFieldSetError(f, ex); | |
491 } | |
492 } | |
493 | |
494 public void doChar(CharField field, boolean isVMField) { | |
495 java.lang.reflect.Field f = null; | |
496 try { | |
497 f = readField(field); | |
498 if (Modifier.isFinal(f.getModifiers())) return; | |
499 f.setAccessible(true); | |
500 f.setChar(obj, field.getValue(getObj())); | |
501 } catch (Exception ex) { | |
502 printFieldSetError(f, ex); | |
503 } | |
504 } | |
505 | |
506 public void doBoolean(BooleanField field, boolean isVMField) { | |
507 java.lang.reflect.Field f = null; | |
508 try { | |
509 f = readField(field); | |
510 if (Modifier.isFinal(f.getModifiers())) return; | |
511 f.setAccessible(true); | |
512 f.setBoolean(obj, field.getValue(getObj())); | |
513 } catch (Exception ex) { | |
514 printFieldSetError(f, ex); | |
515 } | |
516 } | |
517 | |
518 public void doShort(ShortField field, boolean isVMField) { | |
519 java.lang.reflect.Field f = null; | |
520 try { | |
521 f = readField(field); | |
522 if (Modifier.isFinal(f.getModifiers())) return; | |
523 f.setAccessible(true); | |
524 f.setShort(obj, field.getValue(getObj())); | |
525 } catch (Exception ex) { | |
526 printFieldSetError(f, ex); | |
527 } | |
528 } | |
529 | |
530 public void doInt(IntField field, boolean isVMField) { | |
531 java.lang.reflect.Field f = null; | |
532 try { | |
533 f = readField(field); | |
534 if (Modifier.isFinal(f.getModifiers())) return; | |
535 f.setAccessible(true); | |
536 f.setInt(obj, field.getValue(getObj())); | |
537 } catch (Exception ex) { | |
538 printFieldSetError(f, ex); | |
539 } | |
540 } | |
541 | |
542 public void doLong(LongField field, boolean isVMField) { | |
543 java.lang.reflect.Field f = null; | |
544 try { | |
545 f = readField(field); | |
546 if (Modifier.isFinal(f.getModifiers())) return; | |
547 f.setAccessible(true); | |
548 f.setLong(obj, field.getValue(getObj())); | |
549 } catch (Exception ex) { | |
550 printFieldSetError(f, ex); | |
551 } | |
552 } | |
553 | |
554 public void doFloat(FloatField field, boolean isVMField) { | |
555 java.lang.reflect.Field f = null; | |
556 try { | |
557 f = readField(field); | |
558 if (Modifier.isFinal(f.getModifiers())) return; | |
559 f.setAccessible(true); | |
560 f.setFloat(obj, field.getValue(getObj())); | |
561 } catch (Exception ex) { | |
562 printFieldSetError(f, ex); | |
563 } | |
564 } | |
565 | |
566 public void doDouble(DoubleField field, boolean isVMField) { | |
567 java.lang.reflect.Field f = null; | |
568 try { | |
569 f = readField(field); | |
570 if (Modifier.isFinal(f.getModifiers())) return; | |
571 f.setAccessible(true); | |
572 f.setDouble(obj, field.getValue(getObj())); | |
573 } catch (Exception ex) { | |
574 printFieldSetError(f, ex); | |
575 } | |
576 } | |
577 | |
578 public void doCInt(CIntField field, boolean isVMField) { | |
579 throw new RuntimeException("should not reach here!"); | |
580 } | |
581 } | |
582 | |
583 public Class readClass(InstanceKlass kls) throws ClassNotFoundException { | |
584 Class cls = (Class) getFromObjTable(kls); | |
585 if (cls == null) { | |
586 cls = Class.forName(kls.getName().asString().replace('/', '.'), true, cl); | |
587 putIntoObjTable(kls, cls); | |
588 } | |
589 return cls; | |
590 } | |
591 | |
592 public Object readMethodOrConstructor(sun.jvm.hotspot.oops.Method m) | |
593 throws NoSuchMethodException, ClassNotFoundException { | |
594 String name = m.getName().asString(); | |
595 if (name.equals("<init>")) { | |
596 return readConstructor(m); | |
597 } else { | |
598 return readMethod(m); | |
599 } | |
600 } | |
601 | |
602 public java.lang.reflect.Method readMethod(sun.jvm.hotspot.oops.Method m) | |
603 throws NoSuchMethodException, ClassNotFoundException { | |
604 java.lang.reflect.Method result = (java.lang.reflect.Method) getFromObjTable(m); | |
605 if (result == null) { | |
606 Class clz = readClass((InstanceKlass)m.getMethodHolder()); | |
607 String name = m.getName().asString(); | |
608 Class[] paramTypes = getParamTypes(m.getSignature()); | |
609 result = clz.getMethod(name, paramTypes); | |
610 putIntoObjTable(m, result); | |
611 } | |
612 return result; | |
613 } | |
614 | |
615 public java.lang.reflect.Constructor readConstructor(sun.jvm.hotspot.oops.Method m) | |
616 throws NoSuchMethodException, ClassNotFoundException { | |
617 java.lang.reflect.Constructor result = (java.lang.reflect.Constructor) getFromObjTable(m); | |
618 if (result == null) { | |
619 Class clz = readClass((InstanceKlass)m.getMethodHolder()); | |
620 String name = m.getName().asString(); | |
621 Class[] paramTypes = getParamTypes(m.getSignature()); | |
622 result = clz.getDeclaredConstructor(paramTypes); | |
623 putIntoObjTable(m, result); | |
624 } | |
625 return result; | |
626 } | |
627 | |
628 public java.lang.reflect.Field readField(sun.jvm.hotspot.oops.Field f) | |
629 throws NoSuchFieldException, ClassNotFoundException { | |
630 java.lang.reflect.Field result = (java.lang.reflect.Field) fieldMap.get(f); | |
631 if (result == null) { | |
632 FieldIdentifier fieldId = f.getID(); | |
633 Class clz = readClass((InstanceKlass) f.getFieldHolder()); | |
634 String name = fieldId.getName(); | |
635 try { | |
636 result = clz.getField(name); | |
637 } catch (NoSuchFieldException nsfe) { | |
638 result = clz.getDeclaredField(name); | |
639 } | |
640 fieldMap.put(f, result); | |
641 } | |
642 return result; | |
643 } | |
644 | |
645 protected final ClassLoader cl; | |
646 protected Map oopToObjMap; // Map<Oop, Object> | |
647 protected Map fieldMap; // Map<sun.jvm.hotspot.oops.Field, java.lang.reflect.Field> | |
648 | |
649 protected void putIntoObjTable(Oop oop, Object obj) { | |
650 oopToObjMap.put(oop, obj); | |
651 } | |
652 | |
653 protected Object getFromObjTable(Oop oop) { | |
654 return oopToObjMap.get(oop); | |
655 } | |
656 | |
657 protected class SignatureParser extends SignatureIterator { | |
658 protected Vector tmp = new Vector(); // Vector<Class> | |
659 | |
660 public SignatureParser(Symbol s) { | |
661 super(s); | |
662 } | |
663 | |
664 public void doBool () { tmp.add(Boolean.TYPE); } | |
665 public void doChar () { tmp.add(Character.TYPE); } | |
666 public void doFloat () { tmp.add(Float.TYPE); } | |
667 public void doDouble() { tmp.add(Double.TYPE); } | |
668 public void doByte () { tmp.add(Byte.TYPE); } | |
669 public void doShort () { tmp.add(Short.TYPE); } | |
670 public void doInt () { tmp.add(Integer.TYPE); } | |
671 public void doLong () { tmp.add(Long.TYPE); } | |
672 public void doVoid () { | |
673 if(isReturnType()) { | |
674 tmp.add(Void.TYPE); | |
675 } else { | |
676 throw new RuntimeException("should not reach here"); | |
677 } | |
678 } | |
679 | |
680 public void doObject(int begin, int end) { | |
681 tmp.add(getClass(begin, end)); | |
682 } | |
683 | |
684 public void doArray (int begin, int end) { | |
685 int inner = arrayInnerBegin(begin); | |
686 Class elemCls = null; | |
687 switch (_signature.getByteAt(inner)) { | |
688 case 'B': elemCls = Boolean.TYPE; break; | |
689 case 'C': elemCls = Character.TYPE; break; | |
690 case 'D': elemCls = Double.TYPE; break; | |
691 case 'F': elemCls = Float.TYPE; break; | |
692 case 'I': elemCls = Integer.TYPE; break; | |
693 case 'J': elemCls = Long.TYPE; break; | |
694 case 'S': elemCls = Short.TYPE; break; | |
695 case 'Z': elemCls = Boolean.TYPE; break; | |
696 case 'L': elemCls = getClass(inner + 1, end); break; | |
697 default: break; | |
698 } | |
699 | |
700 int dimension = inner - begin; | |
701 // create 0 x 0 ... array and get class from that | |
702 int[] dimArray = new int[dimension]; | |
703 tmp.add(java.lang.reflect.Array.newInstance(elemCls, dimArray).getClass()); | |
704 } | |
705 | |
706 protected Class getClass(int begin, int end) { | |
707 String className = getClassName(begin, end); | |
708 try { | |
709 return Class.forName(className, true, cl); | |
710 } catch (Exception e) { | |
711 if (DEBUG) { | |
6170
d8a240abb23a
7177128: SA cannot get correct system properties after 7126277
minqi
parents:
1552
diff
changeset
|
712 debugPrintln("Can't load class " + className); |
0 | 713 } |
714 throw new RuntimeException(e); | |
715 } | |
716 } | |
717 | |
718 protected String getClassName(int begin, int end) { | |
719 StringBuffer buf = new StringBuffer(); | |
720 for (int i = begin; i < end; i++) { | |
721 char c = (char) (_signature.getByteAt(i) & 0xFF); | |
722 if (c == '/') { | |
723 buf.append('.'); | |
724 } else { | |
725 buf.append(c); | |
726 } | |
727 } | |
728 return buf.toString(); | |
729 } | |
730 | |
731 protected int arrayInnerBegin(int begin) { | |
732 while (_signature.getByteAt(begin) == '[') { | |
733 ++begin; | |
734 } | |
735 return begin; | |
736 } | |
737 | |
738 public int getNumParams() { | |
739 return tmp.size(); | |
740 } | |
741 | |
742 public Enumeration getParamTypes() { | |
743 return tmp.elements(); | |
744 } | |
745 } | |
746 | |
747 protected Class[] getParamTypes(Symbol signature) { | |
748 SignatureParser sp = new SignatureParser(signature); | |
749 sp.iterateParameters(); | |
750 Class result[] = new Class[sp.getNumParams()]; | |
751 Enumeration e = sp.getParamTypes(); | |
752 int i = 0; | |
753 while (e.hasMoreElements()) { | |
754 result[i] = (Class) e.nextElement(); | |
755 i++; | |
756 } | |
757 return result; | |
758 } | |
759 } |