annotate agent/src/share/classes/sun/jvm/hotspot/jdi/SAJDIClassLoader.java @ 152:c70a245cad3a

6670684: 4/5 SA command universe did not print out CMS space information Summary: Forward port of Yumin's fix for 6670684 from HSX-11; Yumin verified the port was correct. Reviewed-by: dcubed
author dcubed
date Fri, 09 May 2008 08:55:13 -0700
parents a61af66fc99e
children d1605aabd0a1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2 * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 package sun.jvm.hotspot.jdi;
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 import java.io.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
28 import java.net.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
29
a61af66fc99e Initial load
duke
parents:
diff changeset
30 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
31 * This class loader is used for two different reasons:
a61af66fc99e Initial load
duke
parents:
diff changeset
32 *
a61af66fc99e Initial load
duke
parents:
diff changeset
33 * 1) To support multiple simultaneous debuggees.
a61af66fc99e Initial load
duke
parents:
diff changeset
34 *
a61af66fc99e Initial load
duke
parents:
diff changeset
35 * SA's architecture does not allow us to use multiple simultaneous
a61af66fc99e Initial load
duke
parents:
diff changeset
36 * debuggees. This is because of lots of static fields caching
a61af66fc99e Initial load
duke
parents:
diff changeset
37 * vmStruct fields and singleton assumption in classes such as
a61af66fc99e Initial load
duke
parents:
diff changeset
38 * 'sun.jvm.hotspot.runtime.VM'. Hence, we use instances of this
a61af66fc99e Initial load
duke
parents:
diff changeset
39 * class loader to create a separate namespace for each debuggee VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
40 *
a61af66fc99e Initial load
duke
parents:
diff changeset
41 * 2) To support cross VM version debugging.
a61af66fc99e Initial load
duke
parents:
diff changeset
42 *
a61af66fc99e Initial load
duke
parents:
diff changeset
43 * SA has very close dependency on VM data structures. Due to this, a
a61af66fc99e Initial load
duke
parents:
diff changeset
44 * version of SA can only support debuggees running a same dot-dot release and
a61af66fc99e Initial load
duke
parents:
diff changeset
45 * update releases only. For eg. this version of SA supports only 1.4.2 and
a61af66fc99e Initial load
duke
parents:
diff changeset
46 * 1.4.2_xx releases only. But, users may want to debug debuggees running
a61af66fc99e Initial load
duke
parents:
diff changeset
47 * a different version of VM. To support this, we use an instance of this
a61af66fc99e Initial load
duke
parents:
diff changeset
48 * class loader to load classes from corresponding sa-jdi.jar.
a61af66fc99e Initial load
duke
parents:
diff changeset
49 *
a61af66fc99e Initial load
duke
parents:
diff changeset
50 * Note that JDI classes would still be loaded from the debugger's tools.jar
a61af66fc99e Initial load
duke
parents:
diff changeset
51 * and not from debuggee's tools.jar. This means that if JDI interface evolved
a61af66fc99e Initial load
duke
parents:
diff changeset
52 * b/w debuggee and debugger VM versions, user may still get problems. This is
a61af66fc99e Initial load
duke
parents:
diff changeset
53 * the case when debugger runs on 1.5.0 and debuggee runs on 1.4.2. Because JDI
a61af66fc99e Initial load
duke
parents:
diff changeset
54 * evolved b/w these versions (generics, enum, varargs etc.), 1.4.2 sa-jdi.jar
a61af66fc99e Initial load
duke
parents:
diff changeset
55 * won't implement 1.5.0 JDI properly and user would get verifier errors. This
a61af66fc99e Initial load
duke
parents:
diff changeset
56 * class loader solution is suited for different dot-dot release where JDI will
a61af66fc99e Initial load
duke
parents:
diff changeset
57 * not evolve but VM data structures might change and SA implementation might
a61af66fc99e Initial load
duke
parents:
diff changeset
58 * have to change. For example, a debuggee running 1.5.1 VM can be debugged
a61af66fc99e Initial load
duke
parents:
diff changeset
59 * with debugger running on 1.5.0 VM. Here, JDI is same but VM data structures
a61af66fc99e Initial load
duke
parents:
diff changeset
60 * could still change.
a61af66fc99e Initial load
duke
parents:
diff changeset
61 */
a61af66fc99e Initial load
duke
parents:
diff changeset
62
a61af66fc99e Initial load
duke
parents:
diff changeset
63 class SAJDIClassLoader extends URLClassLoader {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 private static final boolean DEBUG;
a61af66fc99e Initial load
duke
parents:
diff changeset
65 static {
a61af66fc99e Initial load
duke
parents:
diff changeset
66 DEBUG = System.getProperty("sun.jvm.hotspot.jdi.SAJDIClassLoader.DEBUG") != null;
a61af66fc99e Initial load
duke
parents:
diff changeset
67 }
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 private ClassLoader parent;
a61af66fc99e Initial load
duke
parents:
diff changeset
70 private boolean classPathSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72 SAJDIClassLoader(ClassLoader parent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
73 super(new URL[0], parent);
a61af66fc99e Initial load
duke
parents:
diff changeset
74 this.parent = parent;
a61af66fc99e Initial load
duke
parents:
diff changeset
75 }
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 SAJDIClassLoader(ClassLoader parent, String classPath) {
a61af66fc99e Initial load
duke
parents:
diff changeset
78 this(parent);
a61af66fc99e Initial load
duke
parents:
diff changeset
79 this.classPathSet = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
80 try {
152
c70a245cad3a 6670684: 4/5 SA command universe did not print out CMS space information
dcubed
parents: 0
diff changeset
81 addURL(new File(classPath).toURI().toURL());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
82 } catch(MalformedURLException mue) {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 throw new RuntimeException(mue);
a61af66fc99e Initial load
duke
parents:
diff changeset
84 }
a61af66fc99e Initial load
duke
parents:
diff changeset
85 }
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 public synchronized Class loadClass(String name)
a61af66fc99e Initial load
duke
parents:
diff changeset
88 throws ClassNotFoundException {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // First, check if the class has already been loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
90 Class c = findLoadedClass(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
91 if (c == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
92 /* If we are loading any class in 'sun.jvm.hotspot.' or any of the
a61af66fc99e Initial load
duke
parents:
diff changeset
93 * sub-packages (except for 'debugger' sub-pkg. please refer below),
a61af66fc99e Initial load
duke
parents:
diff changeset
94 * we load it by 'this' loader. Or else, we forward the request to
a61af66fc99e Initial load
duke
parents:
diff changeset
95 * 'parent' loader, system loader etc. (rest of the code follows
a61af66fc99e Initial load
duke
parents:
diff changeset
96 * the patten in java.lang.ClassLoader.loadClass).
a61af66fc99e Initial load
duke
parents:
diff changeset
97 *
a61af66fc99e Initial load
duke
parents:
diff changeset
98 * 'sun.jvm.hotspot.debugger.' and sub-package classes are
a61af66fc99e Initial load
duke
parents:
diff changeset
99 * also loaded by parent loader. This is done for two reasons:
a61af66fc99e Initial load
duke
parents:
diff changeset
100 *
a61af66fc99e Initial load
duke
parents:
diff changeset
101 * 1. to avoid code bloat by too many classes.
a61af66fc99e Initial load
duke
parents:
diff changeset
102 * 2. to avoid loading same native library multiple times
a61af66fc99e Initial load
duke
parents:
diff changeset
103 * from multiple class loaders (which results in getting a
a61af66fc99e Initial load
duke
parents:
diff changeset
104 * UnsatisifiedLinkageError from System.loadLibrary).
a61af66fc99e Initial load
duke
parents:
diff changeset
105 */
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 if (name.startsWith("sun.jvm.hotspot.") &&
a61af66fc99e Initial load
duke
parents:
diff changeset
108 !name.startsWith("sun.jvm.hotspot.debugger.")) {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 return findClass(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
111 if (parent != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 c = parent.loadClass(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
113 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
114 c = findSystemClass(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
117 return c;
a61af66fc99e Initial load
duke
parents:
diff changeset
118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
119
a61af66fc99e Initial load
duke
parents:
diff changeset
120 protected Class findClass(String name) throws ClassNotFoundException {
a61af66fc99e Initial load
duke
parents:
diff changeset
121 if (DEBUG) {
a61af66fc99e Initial load
duke
parents:
diff changeset
122 System.out.println("SA/JDI loader: about to load " + name);
a61af66fc99e Initial load
duke
parents:
diff changeset
123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
124 if (classPathSet) {
a61af66fc99e Initial load
duke
parents:
diff changeset
125 return super.findClass(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
126 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
127 byte[] b = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
128 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
129 InputStream in = getResourceAsStream(name.replace('.', '/') + ".class");
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // Read until end of stream is reached
a61af66fc99e Initial load
duke
parents:
diff changeset
131 b = new byte[1024];
a61af66fc99e Initial load
duke
parents:
diff changeset
132 int total = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
133 int len = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
134 while ((len = in.read(b, total, b.length - total)) != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
135 total += len;
a61af66fc99e Initial load
duke
parents:
diff changeset
136 if (total >= b.length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
137 byte[] tmp = new byte[total * 2];
a61af66fc99e Initial load
duke
parents:
diff changeset
138 System.arraycopy(b, 0, tmp, 0, total);
a61af66fc99e Initial load
duke
parents:
diff changeset
139 b = tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // Trim array to correct size, if necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
143 if (total != b.length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 byte[] tmp = new byte[total];
a61af66fc99e Initial load
duke
parents:
diff changeset
145 System.arraycopy(b, 0, tmp, 0, total);
a61af66fc99e Initial load
duke
parents:
diff changeset
146 b = tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
148 } catch (Exception exp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
149 throw (ClassNotFoundException) new ClassNotFoundException().initCause(exp);
a61af66fc99e Initial load
duke
parents:
diff changeset
150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
151 return defineClass(name, b, 0, b.length);
a61af66fc99e Initial load
duke
parents:
diff changeset
152 }
a61af66fc99e Initial load
duke
parents:
diff changeset
153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
154 }