Mercurial > hg > truffle
annotate agent/src/share/classes/sun/jvm/hotspot/jdi/SAJDIClassLoader.java @ 2245:638119ce7cfd
7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
Reviewed-by: kvn, never
author | twisti |
---|---|
date | Tue, 01 Feb 2011 03:38:44 -0800 |
parents | c18cbe5936b8 |
children |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
196
diff
changeset
|
2 * Copyright (c) 2003, 2008, 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:
196
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
196
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:
196
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 package sun.jvm.hotspot.jdi; | |
26 | |
27 import java.io.*; | |
28 import java.net.*; | |
29 | |
30 /* | |
31 * This class loader is used for two different reasons: | |
32 * | |
33 * 1) To support multiple simultaneous debuggees. | |
34 * | |
35 * SA's architecture does not allow us to use multiple simultaneous | |
36 * debuggees. This is because of lots of static fields caching | |
37 * vmStruct fields and singleton assumption in classes such as | |
38 * 'sun.jvm.hotspot.runtime.VM'. Hence, we use instances of this | |
39 * class loader to create a separate namespace for each debuggee VM. | |
40 * | |
41 * 2) To support cross VM version debugging. | |
42 * | |
43 * SA has very close dependency on VM data structures. Due to this, a | |
44 * version of SA can only support debuggees running a same dot-dot release and | |
45 * update releases only. For eg. this version of SA supports only 1.4.2 and | |
46 * 1.4.2_xx releases only. But, users may want to debug debuggees running | |
47 * a different version of VM. To support this, we use an instance of this | |
48 * class loader to load classes from corresponding sa-jdi.jar. | |
49 * | |
50 * Note that JDI classes would still be loaded from the debugger's tools.jar | |
51 * and not from debuggee's tools.jar. This means that if JDI interface evolved | |
52 * b/w debuggee and debugger VM versions, user may still get problems. This is | |
53 * the case when debugger runs on 1.5.0 and debuggee runs on 1.4.2. Because JDI | |
54 * evolved b/w these versions (generics, enum, varargs etc.), 1.4.2 sa-jdi.jar | |
55 * won't implement 1.5.0 JDI properly and user would get verifier errors. This | |
56 * class loader solution is suited for different dot-dot release where JDI will | |
57 * not evolve but VM data structures might change and SA implementation might | |
58 * have to change. For example, a debuggee running 1.5.1 VM can be debugged | |
59 * with debugger running on 1.5.0 VM. Here, JDI is same but VM data structures | |
60 * could still change. | |
61 */ | |
62 | |
63 class SAJDIClassLoader extends URLClassLoader { | |
64 private static final boolean DEBUG; | |
65 static { | |
66 DEBUG = System.getProperty("sun.jvm.hotspot.jdi.SAJDIClassLoader.DEBUG") != null; | |
67 } | |
68 | |
69 private ClassLoader parent; | |
70 private boolean classPathSet; | |
71 | |
72 SAJDIClassLoader(ClassLoader parent) { | |
73 super(new URL[0], parent); | |
74 this.parent = parent; | |
75 } | |
76 | |
77 SAJDIClassLoader(ClassLoader parent, String classPath) { | |
78 this(parent); | |
79 this.classPathSet = true; | |
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 | 82 } catch(MalformedURLException mue) { |
83 throw new RuntimeException(mue); | |
84 } | |
85 } | |
86 | |
87 public synchronized Class loadClass(String name) | |
88 throws ClassNotFoundException { | |
89 // First, check if the class has already been loaded | |
90 Class c = findLoadedClass(name); | |
91 if (c == null) { | |
92 /* If we are loading any class in 'sun.jvm.hotspot.' or any of the | |
93 * sub-packages (except for 'debugger' sub-pkg. please refer below), | |
94 * we load it by 'this' loader. Or else, we forward the request to | |
95 * 'parent' loader, system loader etc. (rest of the code follows | |
96 * the patten in java.lang.ClassLoader.loadClass). | |
97 * | |
98 * 'sun.jvm.hotspot.debugger.' and sub-package classes are | |
99 * also loaded by parent loader. This is done for two reasons: | |
100 * | |
101 * 1. to avoid code bloat by too many classes. | |
102 * 2. to avoid loading same native library multiple times | |
103 * from multiple class loaders (which results in getting a | |
104 * UnsatisifiedLinkageError from System.loadLibrary). | |
105 */ | |
106 | |
107 if (name.startsWith("sun.jvm.hotspot.") && | |
108 !name.startsWith("sun.jvm.hotspot.debugger.")) { | |
109 return findClass(name); | |
110 } | |
111 if (parent != null) { | |
112 c = parent.loadClass(name); | |
113 } else { | |
114 c = findSystemClass(name); | |
115 } | |
116 } | |
117 return c; | |
118 } | |
119 | |
120 protected Class findClass(String name) throws ClassNotFoundException { | |
121 if (DEBUG) { | |
122 System.out.println("SA/JDI loader: about to load " + name); | |
123 } | |
124 if (classPathSet) { | |
125 return super.findClass(name); | |
126 } else { | |
127 byte[] b = null; | |
128 try { | |
129 InputStream in = getResourceAsStream(name.replace('.', '/') + ".class"); | |
130 // Read until end of stream is reached | |
131 b = new byte[1024]; | |
132 int total = 0; | |
133 int len = 0; | |
134 while ((len = in.read(b, total, b.length - total)) != -1) { | |
135 total += len; | |
136 if (total >= b.length) { | |
137 byte[] tmp = new byte[total * 2]; | |
138 System.arraycopy(b, 0, tmp, 0, total); | |
139 b = tmp; | |
140 } | |
141 } | |
142 // Trim array to correct size, if necessary | |
143 if (total != b.length) { | |
144 byte[] tmp = new byte[total]; | |
145 System.arraycopy(b, 0, tmp, 0, total); | |
146 b = tmp; | |
147 } | |
148 } catch (Exception exp) { | |
149 throw (ClassNotFoundException) new ClassNotFoundException().initCause(exp); | |
150 } | |
151 return defineClass(name, b, 0, b.length); | |
152 } | |
153 } | |
154 } |