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 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
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
187 Object value = null;
188 Oop next = null;
189 try {
190 key = readObject(keyField.getValue(oop));
191 value = readObject(valueField.getValue(oop));
192 next = (Oop)nextField.getValue(oop);
193 // For Properties, should use setProperty(k, v). Since it only runs in SA
194 // using put(k, v) should be OK.
195 p.put(key, value);
196 if (next != null) {
197 setHashtableEntry(p, next);
198 }
199 } catch (ClassNotFoundException ce) {
200 if( DEBUG) {
201 debugPrintln("Class not found " + ce);
202 debugPrintStackTrace(ce);
203 }
204 }
205 }
206
207 protected Object getHashtable(Instance oop, boolean isProperties) {
208 InstanceKlass k = (InstanceKlass)oop.getKlass();
209 OopField tableField = (OopField)k.findField("table", "[Ljava/util/Hashtable$Entry;");
210 if (tableField == null) {
211 debugPrintln("Could not find field of [Ljava/util/Hashtable$Entry;");
212 return null;
213 }
214 java.util.Hashtable table = (isProperties) ? new java.util.Properties()
215 : new java.util.Hashtable();
216 ObjArray kvs = (ObjArray)tableField.getValue(oop);
217 long size = kvs.getLength();
218 debugPrintln("Hashtable$Entry Size = " + size);
219 for (long i=0; i<size; i++) {
220 Oop entry = kvs.getObjAt(i);
221 if (entry != null && entry.isInstance()) {
222 setHashtableEntry(table, entry);
223 }
224 }
225 return table;
226 }
227
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
235 // important.
236 // Same for Hashtable, key and hash are final, could not be set in the algorithm too.
237 // FIXME: need a framework to handle many other special cases.
238 if (kls.getName().equals(javaLangString())) {
239 return OopUtilities.stringOopToString(oop);
240 }
241
242 if (kls.getName().equals(javaUtilHashtable())) {
243 return getHashtable(oop, false);
244 }
245
246 if (kls.getName().equals(javaUtilProperties())) {
247 return getHashtable(oop, true);
248 }
249
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 }
|
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 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 package sun.jvm.hotspot.utilities;
26
27 import java.lang.reflect.Modifier;
28 import java.util.*;
29 import java.util.stream.*;
30 import sun.jvm.hotspot.debugger.*;
31 import sun.jvm.hotspot.oops.*;
32 import sun.jvm.hotspot.runtime.*;
33 import sun.jvm.hotspot.utilities.*;
34
35 /**
36 * ObjectReader can "deserialize" objects from debuggee.
37 *
38 * Class Loading:
39 *
40 * ObjectReader loads classes using the given class loader. If no
41 * class loader is supplied, it uses a ProcImageClassLoader, which
42 * loads classes from debuggee core or process.
43
44 * Object creation:
45 *
46 * This class uses no-arg constructor to construct objects. But if
47 * there is no no-arg constructor in a given class, then it tries to
48 * use other constructors with 'default' values - null for object
49 * types, 0, 0.0, false etc. for primitives. If this process fails to
188 Object value = null;
189 Oop next = null;
190 try {
191 key = readObject(keyField.getValue(oop));
192 value = readObject(valueField.getValue(oop));
193 next = (Oop)nextField.getValue(oop);
194 // For Properties, should use setProperty(k, v). Since it only runs in SA
195 // using put(k, v) should be OK.
196 p.put(key, value);
197 if (next != null) {
198 setHashtableEntry(p, next);
199 }
200 } catch (ClassNotFoundException ce) {
201 if( DEBUG) {
202 debugPrintln("Class not found " + ce);
203 debugPrintStackTrace(ce);
204 }
205 }
206 }
207
208 private void setPropertiesEntry(java.util.Properties p, Oop oop) {
209 InstanceKlass ik = (InstanceKlass)oop.getKlass();
210 OopField keyField = (OopField)ik.findField("key", "Ljava/lang/Object;");
211 OopField valueField = (OopField)ik.findField("val", "Ljava/lang/Object;");
212
213 try {
214 p.setProperty((String)readObject(keyField.getValue(oop)),
215 (String)readObject(valueField.getValue(oop)));
216 } catch (ClassNotFoundException ce) {
217 if (DEBUG) {
218 debugPrintStackTrace(ce);
219 }
220 }
221 }
222
223 protected Object getHashtable(Instance oop) {
224 InstanceKlass k = (InstanceKlass)oop.getKlass();
225 OopField tableField = (OopField)k.findField("table", "[Ljava/util/Hashtable$Entry;");
226 if (tableField == null) {
227 debugPrintln("Could not find field of [Ljava/util/Hashtable$Entry;");
228 return null;
229 }
230 java.util.Hashtable table = new java.util.Hashtable();
231 ObjArray kvs = (ObjArray)tableField.getValue(oop);
232 long size = kvs.getLength();
233 debugPrintln("Hashtable$Entry Size = " + size);
234 for (long i=0; i<size; i++) {
235 Oop entry = kvs.getObjAt(i);
236 if (entry != null && entry.isInstance()) {
237 setHashtableEntry(table, entry);
238 }
239 }
240 return table;
241 }
242
243 private Properties getProperties(Instance oop) {
244 InstanceKlass k = (InstanceKlass)oop.getKlass();
245 OopField mapField = (OopField)k.findField("map", "Ljava/util/concurrent/ConcurrentHashMap;");
246 if (mapField == null) {
247 debugPrintln("Could not find field of Ljava/util/concurrent/ConcurrentHashMap");
248 return null;
249 }
250
251 Instance mapObj = (Instance)mapField.getValue(oop);
252 if (mapObj == null) {
253 debugPrintln("Could not get map field from java.util.Properties");
254 return null;
255 }
256
257 InstanceKlass mk = (InstanceKlass)mapObj.getKlass();
258 OopField tableField = (OopField)mk.findField("table", "[Ljava/util/concurrent/ConcurrentHashMap$Node;");
259 if (tableField == null) {
260 debugPrintln("Could not find field of [Ljava/util/concurrent/ConcurrentHashMap$Node");
261 return null;
262 }
263
264 java.util.Properties props = new java.util.Properties();
265 ObjArray kvs = (ObjArray)tableField.getValue(mapObj);
266 long size = kvs.getLength();
267 debugPrintln("ConcurrentHashMap$Node Size = " + size);
268 LongStream.range(0, size)
269 .mapToObj(kvs::getObjAt)
270 .filter(o -> o != null)
271 .forEach(o -> setPropertiesEntry(props, o));
272
273 return props;
274 }
275
276 public Object readInstance(Instance oop) throws ClassNotFoundException {
277 Object result = getFromObjTable(oop);
278 if (result == null) {
279 InstanceKlass kls = (InstanceKlass) oop.getKlass();
280 // Handle java.lang.String instances differently. As part of JSR-133, fields of immutable
281 // classes have been made final. The algorithm below will not be able to read Strings from
282 // debuggee (can't use reflection to set final fields). But, need to read Strings is very
283 // important.
284 // Same for Hashtable, key and hash are final, could not be set in the algorithm too.
285 // FIXME: need a framework to handle many other special cases.
286 if (kls.getName().equals(javaLangString())) {
287 return OopUtilities.stringOopToString(oop);
288 }
289
290 if (kls.getName().equals(javaUtilHashtable())) {
291 return getHashtable(oop);
292 }
293
294 if (kls.getName().equals(javaUtilProperties())) {
295 return getProperties(oop);
296 }
297
298 Class clz = readClass(kls);
299 try {
300 result = clz.newInstance();
301 } catch (Exception ex) {
302 // no-arg constructor failed to create object. Let us try
303 // to call constructors one-by-one with default arguments
304 // (null for objects, 0/0.0 etc. for primitives) till we
305 // succeed or fail on all constructors.
306
307 java.lang.reflect.Constructor[] ctrs = clz.getDeclaredConstructors();
308 for (int n = 0; n < ctrs.length; n++) {
309 java.lang.reflect.Constructor c = ctrs[n];
310 Class[] paramTypes = c.getParameterTypes();
311 Object[] params = new Object[paramTypes.length];
312 for (int i = 0; i < params.length; i++) {
313 if (paramTypes[i].isPrimitive()) {
314 params[i] = getDefaultPrimitiveValue(paramTypes[i]);
315 }
|