annotate agent/src/share/classes/sun/jvm/hotspot/jdi/ReferenceTypeImpl.java @ 6725:da91efe96a93

6964458: Reimplement class meta-data storage to use native memory Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author coleenp
date Sat, 01 Sep 2012 13:25:18 -0400
parents 04ade88d9712
children 29985fccf378
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
6203
04ade88d9712 6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
fparain
parents: 3908
diff changeset
2 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
0
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 *
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
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
a61af66fc99e Initial load
duke
parents:
diff changeset
29 import com.sun.jdi.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
30
3908
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
31 import sun.jvm.hotspot.memory.SystemDictionary;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
32 import sun.jvm.hotspot.oops.Instance;
a61af66fc99e Initial load
duke
parents:
diff changeset
33 import sun.jvm.hotspot.oops.InstanceKlass;
a61af66fc99e Initial load
duke
parents:
diff changeset
34 import sun.jvm.hotspot.oops.ArrayKlass;
a61af66fc99e Initial load
duke
parents:
diff changeset
35 import sun.jvm.hotspot.oops.JVMDIClassStatus;
a61af66fc99e Initial load
duke
parents:
diff changeset
36 import sun.jvm.hotspot.oops.Klass;
3908
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
37 import sun.jvm.hotspot.oops.ObjArray;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
38 import sun.jvm.hotspot.oops.Oop;
a61af66fc99e Initial load
duke
parents:
diff changeset
39 import sun.jvm.hotspot.oops.Symbol;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 import sun.jvm.hotspot.oops.DefaultHeapVisitor;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 import sun.jvm.hotspot.utilities.Assert;
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 import java.util.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
44 import java.lang.ref.SoftReference;
a61af66fc99e Initial load
duke
parents:
diff changeset
45
a61af66fc99e Initial load
duke
parents:
diff changeset
46 public abstract class ReferenceTypeImpl extends TypeImpl
a61af66fc99e Initial load
duke
parents:
diff changeset
47 implements ReferenceType {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 protected Klass saKlass; // This can be an InstanceKlass or an ArrayKlass
a61af66fc99e Initial load
duke
parents:
diff changeset
49 protected Symbol typeNameSymbol; // This is used in vm.classesByName to speedup search
a61af66fc99e Initial load
duke
parents:
diff changeset
50 private int modifiers = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
51 private String signature = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
52 private SoftReference sdeRef = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
53 private SoftReference fieldsCache;
a61af66fc99e Initial load
duke
parents:
diff changeset
54 private SoftReference allFieldsCache;
a61af66fc99e Initial load
duke
parents:
diff changeset
55 private SoftReference methodsCache;
a61af66fc99e Initial load
duke
parents:
diff changeset
56 private SoftReference allMethodsCache;
a61af66fc99e Initial load
duke
parents:
diff changeset
57 private SoftReference nestedTypesCache;
3908
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
58 private SoftReference methodInvokesCache;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
59
a61af66fc99e Initial load
duke
parents:
diff changeset
60 /* to mark when no info available */
a61af66fc99e Initial load
duke
parents:
diff changeset
61 static final SDE NO_SDE_INFO_MARK = new SDE();
a61af66fc99e Initial load
duke
parents:
diff changeset
62
a61af66fc99e Initial load
duke
parents:
diff changeset
63 protected ReferenceTypeImpl(VirtualMachine aVm, sun.jvm.hotspot.oops.Klass klass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 super(aVm);
a61af66fc99e Initial load
duke
parents:
diff changeset
65 saKlass = klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
66 typeNameSymbol = saKlass.getName();
a61af66fc99e Initial load
duke
parents:
diff changeset
67 if (Assert.ASSERTS_ENABLED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 Assert.that(typeNameSymbol != null, "null type name for a Klass");
a61af66fc99e Initial load
duke
parents:
diff changeset
69 }
a61af66fc99e Initial load
duke
parents:
diff changeset
70 }
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72 Symbol typeNameAsSymbol() {
a61af66fc99e Initial load
duke
parents:
diff changeset
73 return typeNameSymbol;
a61af66fc99e Initial load
duke
parents:
diff changeset
74 }
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76 Method getMethodMirror(sun.jvm.hotspot.oops.Method ref) {
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // SA creates new Method objects when they are referenced which means
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // that the incoming object might not be the same object as on our
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // even though it is the same method. So do an address compare by
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // calling equals rather than just reference compare.
a61af66fc99e Initial load
duke
parents:
diff changeset
81 Iterator it = methods().iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
82 while (it.hasNext()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 MethodImpl method = (MethodImpl)it.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
84 if (ref.equals(method.ref())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
85 return method;
a61af66fc99e Initial load
duke
parents:
diff changeset
86 }
a61af66fc99e Initial load
duke
parents:
diff changeset
87 }
3908
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
88 if (ref.getMethodHolder().equals(SystemDictionary.getMethodHandleKlass())) {
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
89 // invoke methods are generated as needed, so make mirrors as needed
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
90 List mis = null;
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
91 if (methodInvokesCache == null) {
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
92 mis = new ArrayList();
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
93 methodInvokesCache = new SoftReference(mis);
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
94 } else {
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
95 mis = (List)methodInvokesCache.get();
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
96 }
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
97 it = mis.iterator();
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
98 while (it.hasNext()) {
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
99 MethodImpl method = (MethodImpl)it.next();
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
100 if (ref.equals(method.ref())) {
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
101 return method;
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
102 }
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
103 }
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
104
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
105 MethodImpl method = MethodImpl.createMethodImpl(vm, this, ref);
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
106 mis.add(method);
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
107 return method;
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 2471
diff changeset
108 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
109 throw new IllegalArgumentException("Invalid method id: " + ref);
a61af66fc99e Initial load
duke
parents:
diff changeset
110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
111
a61af66fc99e Initial load
duke
parents:
diff changeset
112 public boolean equals(Object obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
113 if ((obj != null) && (obj instanceof ReferenceTypeImpl)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
114 ReferenceTypeImpl other = (ReferenceTypeImpl)obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
115 return (ref().equals(other.ref())) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
116 (vm.equals(other.virtualMachine()));
a61af66fc99e Initial load
duke
parents:
diff changeset
117 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 public int hashCode() {
a61af66fc99e Initial load
duke
parents:
diff changeset
123 return saKlass.hashCode();
a61af66fc99e Initial load
duke
parents:
diff changeset
124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
125
2471
37be97a58393 7010849: 5/5 Extraneous javac source/target options when building sa-jdi
andrew
parents: 1552
diff changeset
126 public int compareTo(ReferenceType refType) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
127 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
128 * Note that it is critical that compareTo() == 0
a61af66fc99e Initial load
duke
parents:
diff changeset
129 * implies that equals() == true. Otherwise, TreeSet
a61af66fc99e Initial load
duke
parents:
diff changeset
130 * will collapse classes.
a61af66fc99e Initial load
duke
parents:
diff changeset
131 *
a61af66fc99e Initial load
duke
parents:
diff changeset
132 * (Classes of the same name loaded by different class loaders
a61af66fc99e Initial load
duke
parents:
diff changeset
133 * or in different VMs must not return 0).
a61af66fc99e Initial load
duke
parents:
diff changeset
134 */
2471
37be97a58393 7010849: 5/5 Extraneous javac source/target options when building sa-jdi
andrew
parents: 1552
diff changeset
135 ReferenceTypeImpl other = (ReferenceTypeImpl)refType;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
136 int comp = name().compareTo(other.name());
a61af66fc99e Initial load
duke
parents:
diff changeset
137 if (comp == 0) {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6203
diff changeset
138 Klass rf1 = ref();
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6203
diff changeset
139 Klass rf2 = other.ref();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // optimize for typical case: refs equal and VMs equal
a61af66fc99e Initial load
duke
parents:
diff changeset
141 if (rf1.equals(rf2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // sequenceNumbers are always positive
a61af66fc99e Initial load
duke
parents:
diff changeset
143 comp = vm.sequenceNumber -
a61af66fc99e Initial load
duke
parents:
diff changeset
144 ((VirtualMachineImpl)(other.virtualMachine())).sequenceNumber;
a61af66fc99e Initial load
duke
parents:
diff changeset
145 } else {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6203
diff changeset
146 comp = rf1.getAddress().minus(rf2.getAddress()) < 0? -1 : 1;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
149 return comp;
a61af66fc99e Initial load
duke
parents:
diff changeset
150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
151
a61af66fc99e Initial load
duke
parents:
diff changeset
152 public String signature() {
a61af66fc99e Initial load
duke
parents:
diff changeset
153 if (signature == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
154 signature = saKlass.signature();
a61af66fc99e Initial load
duke
parents:
diff changeset
155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
156 return signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
158
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // refer to JvmtiEnv::GetClassSignature.
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // null is returned for array klasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
161 public String genericSignature() {
a61af66fc99e Initial load
duke
parents:
diff changeset
162 if (saKlass instanceof ArrayKlass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
163 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
164 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 Symbol genSig = ((InstanceKlass)saKlass).getGenericSignature();
a61af66fc99e Initial load
duke
parents:
diff changeset
166 return (genSig != null)? genSig.asString() : null;
a61af66fc99e Initial load
duke
parents:
diff changeset
167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 public ClassLoaderReference classLoader() {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 Instance xx = (Instance)(((InstanceKlass)saKlass).getClassLoader());
a61af66fc99e Initial load
duke
parents:
diff changeset
172 return (ClassLoaderReferenceImpl)vm.classLoaderMirror(xx);
a61af66fc99e Initial load
duke
parents:
diff changeset
173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175 public boolean isPublic() {
a61af66fc99e Initial load
duke
parents:
diff changeset
176 return((modifiers() & VMModifiers.PUBLIC) != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 public boolean isProtected() {
a61af66fc99e Initial load
duke
parents:
diff changeset
180 return((modifiers() & VMModifiers.PROTECTED) != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
182
a61af66fc99e Initial load
duke
parents:
diff changeset
183 public boolean isPrivate() {
a61af66fc99e Initial load
duke
parents:
diff changeset
184 return((modifiers() & VMModifiers.PRIVATE) != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
186
a61af66fc99e Initial load
duke
parents:
diff changeset
187 public boolean isPackagePrivate() {
a61af66fc99e Initial load
duke
parents:
diff changeset
188 return !isPublic() && !isPrivate() && !isProtected();
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191 public boolean isAbstract() {
a61af66fc99e Initial load
duke
parents:
diff changeset
192 return((modifiers() & VMModifiers.ABSTRACT) != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
194
a61af66fc99e Initial load
duke
parents:
diff changeset
195 public boolean isFinal() {
a61af66fc99e Initial load
duke
parents:
diff changeset
196 return((modifiers() & VMModifiers.FINAL) != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
198
a61af66fc99e Initial load
duke
parents:
diff changeset
199 public boolean isStatic() {
a61af66fc99e Initial load
duke
parents:
diff changeset
200 return((modifiers() & VMModifiers.STATIC) != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
202
a61af66fc99e Initial load
duke
parents:
diff changeset
203 public boolean isPrepared() {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 return (saKlass.getClassStatus() & JVMDIClassStatus.PREPARED) != 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
206
a61af66fc99e Initial load
duke
parents:
diff changeset
207 final void checkPrepared() throws ClassNotPreparedException {
a61af66fc99e Initial load
duke
parents:
diff changeset
208 if (! isPrepared()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
209 throw new ClassNotPreparedException();
a61af66fc99e Initial load
duke
parents:
diff changeset
210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
212
a61af66fc99e Initial load
duke
parents:
diff changeset
213 public boolean isVerified() {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 return (saKlass.getClassStatus() & JVMDIClassStatus.VERIFIED) != 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 public boolean isInitialized() {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 return (saKlass.getClassStatus() & JVMDIClassStatus.INITIALIZED) != 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221 public boolean failedToInitialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
222 return (saKlass.getClassStatus() & JVMDIClassStatus.ERROR) != 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225 private boolean isThrowableBacktraceField(sun.jvm.hotspot.oops.Field fld) {
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // refer to JvmtiEnv::GetClassFields in jvmtiEnv.cpp.
a61af66fc99e Initial load
duke
parents:
diff changeset
227 // We want to filter out java.lang.Throwable.backtrace (see 4446677).
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6203
diff changeset
228 // It contains some Method*s that aren't quite real Objects.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
229 if (fld.getFieldHolder().getName().equals(vm.javaLangThrowable()) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
230 fld.getID().getName().equals("backtrace")) {
a61af66fc99e Initial load
duke
parents:
diff changeset
231 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
232 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
233 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 public final List fields() throws ClassNotPreparedException {
a61af66fc99e Initial load
duke
parents:
diff changeset
238 List fields = (fieldsCache != null)? (List) fieldsCache.get() : null;
a61af66fc99e Initial load
duke
parents:
diff changeset
239 if (fields == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 checkPrepared();
a61af66fc99e Initial load
duke
parents:
diff changeset
241 if (saKlass instanceof ArrayKlass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
242 fields = new ArrayList(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
243 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // Get a list of the sa Field types
a61af66fc99e Initial load
duke
parents:
diff changeset
245 List saFields = ((InstanceKlass)saKlass).getImmediateFields();
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 // Create a list of our Field types
a61af66fc99e Initial load
duke
parents:
diff changeset
248 int len = saFields.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
249 fields = new ArrayList(len);
a61af66fc99e Initial load
duke
parents:
diff changeset
250 for (int ii = 0; ii < len; ii++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
251 sun.jvm.hotspot.oops.Field curField = (sun.jvm.hotspot.oops.Field)saFields.get(ii);
a61af66fc99e Initial load
duke
parents:
diff changeset
252 if (! isThrowableBacktraceField(curField)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
253 fields.add(new FieldImpl(vm, this, curField));
a61af66fc99e Initial load
duke
parents:
diff changeset
254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
257 fields = Collections.unmodifiableList(fields);
a61af66fc99e Initial load
duke
parents:
diff changeset
258 fieldsCache = new SoftReference(fields);
a61af66fc99e Initial load
duke
parents:
diff changeset
259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
260 return fields;
a61af66fc99e Initial load
duke
parents:
diff changeset
261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
262
a61af66fc99e Initial load
duke
parents:
diff changeset
263 public final List allFields() throws ClassNotPreparedException {
a61af66fc99e Initial load
duke
parents:
diff changeset
264 List allFields = (allFieldsCache != null)? (List) allFieldsCache.get() : null;
a61af66fc99e Initial load
duke
parents:
diff changeset
265 if (allFields == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
266 checkPrepared();
a61af66fc99e Initial load
duke
parents:
diff changeset
267 if (saKlass instanceof ArrayKlass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // is 'length' a field of array klasses? To maintain
a61af66fc99e Initial load
duke
parents:
diff changeset
269 // consistency with JVMDI-JDI we return 0 size.
a61af66fc99e Initial load
duke
parents:
diff changeset
270 allFields = new ArrayList(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
271 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
272 List saFields;
a61af66fc99e Initial load
duke
parents:
diff changeset
273
a61af66fc99e Initial load
duke
parents:
diff changeset
274 // Get a list of the sa Field types
a61af66fc99e Initial load
duke
parents:
diff changeset
275 saFields = ((InstanceKlass)saKlass).getAllFields();
a61af66fc99e Initial load
duke
parents:
diff changeset
276
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // Create a list of our Field types
a61af66fc99e Initial load
duke
parents:
diff changeset
278 int len = saFields.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
279 allFields = new ArrayList(len);
a61af66fc99e Initial load
duke
parents:
diff changeset
280 for (int ii = 0; ii < len; ii++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
281 sun.jvm.hotspot.oops.Field curField = (sun.jvm.hotspot.oops.Field)saFields.get(ii);
a61af66fc99e Initial load
duke
parents:
diff changeset
282 if (! isThrowableBacktraceField(curField)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
283 allFields.add(new FieldImpl(vm, vm.referenceType(curField.getFieldHolder()), curField));
a61af66fc99e Initial load
duke
parents:
diff changeset
284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
287 allFields = Collections.unmodifiableList(allFields);
a61af66fc99e Initial load
duke
parents:
diff changeset
288 allFieldsCache = new SoftReference(allFields);
a61af66fc99e Initial load
duke
parents:
diff changeset
289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
290 return allFields;
a61af66fc99e Initial load
duke
parents:
diff changeset
291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 abstract List inheritedTypes();
a61af66fc99e Initial load
duke
parents:
diff changeset
294
a61af66fc99e Initial load
duke
parents:
diff changeset
295 void addVisibleFields(List visibleList, Map visibleTable, List ambiguousNames) {
a61af66fc99e Initial load
duke
parents:
diff changeset
296 List list = visibleFields();
a61af66fc99e Initial load
duke
parents:
diff changeset
297 Iterator iter = list.iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
298 while (iter.hasNext()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
299 Field field = (Field)iter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
300 String name = field.name();
a61af66fc99e Initial load
duke
parents:
diff changeset
301 if (!ambiguousNames.contains(name)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
302 Field duplicate = (Field)visibleTable.get(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
303 if (duplicate == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
304 visibleList.add(field);
a61af66fc99e Initial load
duke
parents:
diff changeset
305 visibleTable.put(name, field);
a61af66fc99e Initial load
duke
parents:
diff changeset
306 } else if (!field.equals(duplicate)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
307 ambiguousNames.add(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 visibleTable.remove(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
309 visibleList.remove(duplicate);
a61af66fc99e Initial load
duke
parents:
diff changeset
310 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // identical field from two branches; do nothing
a61af66fc99e Initial load
duke
parents:
diff changeset
312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
316
a61af66fc99e Initial load
duke
parents:
diff changeset
317 public final List visibleFields() throws ClassNotPreparedException {
a61af66fc99e Initial load
duke
parents:
diff changeset
318 checkPrepared();
a61af66fc99e Initial load
duke
parents:
diff changeset
319 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
320 * Maintain two different collections of visible fields. The
a61af66fc99e Initial load
duke
parents:
diff changeset
321 * list maintains a reasonable order for return. The
a61af66fc99e Initial load
duke
parents:
diff changeset
322 * hash map provides an efficient way to lookup visible fields
a61af66fc99e Initial load
duke
parents:
diff changeset
323 * by name, important for finding hidden or ambiguous fields.
a61af66fc99e Initial load
duke
parents:
diff changeset
324 */
a61af66fc99e Initial load
duke
parents:
diff changeset
325 List visibleList = new ArrayList();
a61af66fc99e Initial load
duke
parents:
diff changeset
326 Map visibleTable = new HashMap();
a61af66fc99e Initial load
duke
parents:
diff changeset
327
a61af66fc99e Initial load
duke
parents:
diff changeset
328 /* Track fields removed from above collection due to ambiguity */
a61af66fc99e Initial load
duke
parents:
diff changeset
329 List ambiguousNames = new ArrayList();
a61af66fc99e Initial load
duke
parents:
diff changeset
330
a61af66fc99e Initial load
duke
parents:
diff changeset
331 /* Add inherited, visible fields */
a61af66fc99e Initial load
duke
parents:
diff changeset
332 List types = inheritedTypes();
a61af66fc99e Initial load
duke
parents:
diff changeset
333 Iterator iter = types.iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
334 while (iter.hasNext()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
335 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
336 * TO DO: Be defensive and check for cyclic interface inheritance
a61af66fc99e Initial load
duke
parents:
diff changeset
337 */
a61af66fc99e Initial load
duke
parents:
diff changeset
338 ReferenceTypeImpl type = (ReferenceTypeImpl)iter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
339 type.addVisibleFields(visibleList, visibleTable, ambiguousNames);
a61af66fc99e Initial load
duke
parents:
diff changeset
340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
341
a61af66fc99e Initial load
duke
parents:
diff changeset
342 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
343 * Insert fields from this type, removing any inherited fields they
a61af66fc99e Initial load
duke
parents:
diff changeset
344 * hide.
a61af66fc99e Initial load
duke
parents:
diff changeset
345 */
a61af66fc99e Initial load
duke
parents:
diff changeset
346 List retList = new ArrayList(fields());
a61af66fc99e Initial load
duke
parents:
diff changeset
347 iter = retList.iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
348 while (iter.hasNext()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
349 Field field = (Field)iter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
350 Field hidden = (Field)visibleTable.get(field.name());
a61af66fc99e Initial load
duke
parents:
diff changeset
351 if (hidden != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
352 visibleList.remove(hidden);
a61af66fc99e Initial load
duke
parents:
diff changeset
353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
354 }
a61af66fc99e Initial load
duke
parents:
diff changeset
355 retList.addAll(visibleList);
a61af66fc99e Initial load
duke
parents:
diff changeset
356 return retList;
a61af66fc99e Initial load
duke
parents:
diff changeset
357 }
a61af66fc99e Initial load
duke
parents:
diff changeset
358
a61af66fc99e Initial load
duke
parents:
diff changeset
359 public final Field fieldByName(String fieldName) throws ClassNotPreparedException {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 java.util.List searchList;
a61af66fc99e Initial load
duke
parents:
diff changeset
361 Field f;
a61af66fc99e Initial load
duke
parents:
diff changeset
362
a61af66fc99e Initial load
duke
parents:
diff changeset
363 // visibleFields calls checkPrepared
a61af66fc99e Initial load
duke
parents:
diff changeset
364 searchList = visibleFields();
a61af66fc99e Initial load
duke
parents:
diff changeset
365
a61af66fc99e Initial load
duke
parents:
diff changeset
366 for (int i=0; i<searchList.size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
367 f = (Field)searchList.get(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
368
a61af66fc99e Initial load
duke
parents:
diff changeset
369 if (f.name().equals(fieldName)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
370 return f;
a61af66fc99e Initial load
duke
parents:
diff changeset
371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
373 //throw new NoSuchFieldException("Field '" + fieldName + "' not found in " + name());
a61af66fc99e Initial load
duke
parents:
diff changeset
374 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
376
a61af66fc99e Initial load
duke
parents:
diff changeset
377 public final List methods() throws ClassNotPreparedException {
a61af66fc99e Initial load
duke
parents:
diff changeset
378 List methods = (methodsCache != null)? (List) methodsCache.get() : null;
a61af66fc99e Initial load
duke
parents:
diff changeset
379 if (methods == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
380 checkPrepared();
a61af66fc99e Initial load
duke
parents:
diff changeset
381 if (saKlass instanceof ArrayKlass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
382 methods = new ArrayList(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
383 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
384 List saMethods;
a61af66fc99e Initial load
duke
parents:
diff changeset
385 // Get a list of the SA Method types
a61af66fc99e Initial load
duke
parents:
diff changeset
386 saMethods = ((InstanceKlass)saKlass).getImmediateMethods();
a61af66fc99e Initial load
duke
parents:
diff changeset
387
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // Create a list of our MethodImpl types
a61af66fc99e Initial load
duke
parents:
diff changeset
389 int len = saMethods.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
390 methods = new ArrayList(len);
a61af66fc99e Initial load
duke
parents:
diff changeset
391 for (int ii = 0; ii < len; ii++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
392 methods.add(MethodImpl.createMethodImpl(vm, this, (sun.jvm.hotspot.oops.Method)saMethods.get(ii)));
a61af66fc99e Initial load
duke
parents:
diff changeset
393 }
a61af66fc99e Initial load
duke
parents:
diff changeset
394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
395 methods = Collections.unmodifiableList(methods);
a61af66fc99e Initial load
duke
parents:
diff changeset
396 methodsCache = new SoftReference(methods);
a61af66fc99e Initial load
duke
parents:
diff changeset
397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
398 return methods;
a61af66fc99e Initial load
duke
parents:
diff changeset
399 }
a61af66fc99e Initial load
duke
parents:
diff changeset
400
a61af66fc99e Initial load
duke
parents:
diff changeset
401 abstract List getAllMethods();
a61af66fc99e Initial load
duke
parents:
diff changeset
402 public final List allMethods() throws ClassNotPreparedException {
a61af66fc99e Initial load
duke
parents:
diff changeset
403 List allMethods = (allMethodsCache != null)? (List) allMethodsCache.get() : null;
a61af66fc99e Initial load
duke
parents:
diff changeset
404 if (allMethods == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
405 checkPrepared();
a61af66fc99e Initial load
duke
parents:
diff changeset
406 allMethods = Collections.unmodifiableList(getAllMethods());
a61af66fc99e Initial load
duke
parents:
diff changeset
407 allMethodsCache = new SoftReference(allMethods);
a61af66fc99e Initial load
duke
parents:
diff changeset
408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
409 return allMethods;
a61af66fc99e Initial load
duke
parents:
diff changeset
410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
411
a61af66fc99e Initial load
duke
parents:
diff changeset
412 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
413 * Utility method used by subclasses to build lists of visible
a61af66fc99e Initial load
duke
parents:
diff changeset
414 * methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
415 */
a61af66fc99e Initial load
duke
parents:
diff changeset
416 void addToMethodMap(Map methodMap, List methodList) {
a61af66fc99e Initial load
duke
parents:
diff changeset
417 Iterator iter = methodList.iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
418 while (iter.hasNext()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
419 Method method = (Method)iter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
420 methodMap.put(method.name().concat(method.signature()), method);
a61af66fc99e Initial load
duke
parents:
diff changeset
421 }
a61af66fc99e Initial load
duke
parents:
diff changeset
422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
423
a61af66fc99e Initial load
duke
parents:
diff changeset
424 abstract void addVisibleMethods(Map methodMap);
a61af66fc99e Initial load
duke
parents:
diff changeset
425 public final List visibleMethods() throws ClassNotPreparedException {
a61af66fc99e Initial load
duke
parents:
diff changeset
426 checkPrepared();
a61af66fc99e Initial load
duke
parents:
diff changeset
427 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
428 * Build a collection of all visible methods. The hash
a61af66fc99e Initial load
duke
parents:
diff changeset
429 * map allows us to do this efficiently by keying on the
a61af66fc99e Initial load
duke
parents:
diff changeset
430 * concatenation of name and signature.
a61af66fc99e Initial load
duke
parents:
diff changeset
431 */
a61af66fc99e Initial load
duke
parents:
diff changeset
432 //System.out.println("jj: RTI: Calling addVisibleMethods for:" + this);
a61af66fc99e Initial load
duke
parents:
diff changeset
433 Map map = new HashMap();
a61af66fc99e Initial load
duke
parents:
diff changeset
434 addVisibleMethods(map);
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
437 * ... but the hash map destroys order. Methods should be
a61af66fc99e Initial load
duke
parents:
diff changeset
438 * returned in a sensible order, as they are in allMethods().
a61af66fc99e Initial load
duke
parents:
diff changeset
439 * So, start over with allMethods() and use the hash map
a61af66fc99e Initial load
duke
parents:
diff changeset
440 * to filter that ordered collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
441 */
a61af66fc99e Initial load
duke
parents:
diff changeset
442 //System.out.println("jj: RTI: Calling allMethods for:" + this);
a61af66fc99e Initial load
duke
parents:
diff changeset
443
a61af66fc99e Initial load
duke
parents:
diff changeset
444 List list = new ArrayList(allMethods());
a61af66fc99e Initial load
duke
parents:
diff changeset
445 //System.out.println("jj: allMethods = " + jjstr(list));
a61af66fc99e Initial load
duke
parents:
diff changeset
446 //System.out.println("jj: map = " + map.toString());
a61af66fc99e Initial load
duke
parents:
diff changeset
447 //System.out.println("jj: map = " + jjstr(map.values()));
a61af66fc99e Initial load
duke
parents:
diff changeset
448 list.retainAll(map.values());
a61af66fc99e Initial load
duke
parents:
diff changeset
449 //System.out.println("jj: map = " + jjstr(list));
a61af66fc99e Initial load
duke
parents:
diff changeset
450 //System.exit(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
451 return list;
a61af66fc99e Initial load
duke
parents:
diff changeset
452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454 static Object prev;
a61af66fc99e Initial load
duke
parents:
diff changeset
455
a61af66fc99e Initial load
duke
parents:
diff changeset
456 static public String jjstr(Collection cc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
457 StringBuffer buf = new StringBuffer();
a61af66fc99e Initial load
duke
parents:
diff changeset
458 buf.append("[");
a61af66fc99e Initial load
duke
parents:
diff changeset
459 Iterator i = cc.iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
460 boolean hasNext = i.hasNext();
a61af66fc99e Initial load
duke
parents:
diff changeset
461 while (hasNext) {
a61af66fc99e Initial load
duke
parents:
diff changeset
462 Object o = i.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
463 if (prev == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
464 prev = o;
a61af66fc99e Initial load
duke
parents:
diff changeset
465 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
466 System.out.println("prev == curr?" + prev.equals(o));
a61af66fc99e Initial load
duke
parents:
diff changeset
467 System.out.println("prev == curr?" + (prev == o));
a61af66fc99e Initial load
duke
parents:
diff changeset
468 }
a61af66fc99e Initial load
duke
parents:
diff changeset
469 buf.append( o + "@" + o.hashCode());
a61af66fc99e Initial load
duke
parents:
diff changeset
470 //buf.append( ((Object)o).toString());
a61af66fc99e Initial load
duke
parents:
diff changeset
471 hasNext = i.hasNext();
a61af66fc99e Initial load
duke
parents:
diff changeset
472 if (hasNext)
a61af66fc99e Initial load
duke
parents:
diff changeset
473 buf.append(", ");
a61af66fc99e Initial load
duke
parents:
diff changeset
474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
475
a61af66fc99e Initial load
duke
parents:
diff changeset
476 buf.append("]");
a61af66fc99e Initial load
duke
parents:
diff changeset
477 return buf.toString();
a61af66fc99e Initial load
duke
parents:
diff changeset
478 }
a61af66fc99e Initial load
duke
parents:
diff changeset
479
a61af66fc99e Initial load
duke
parents:
diff changeset
480 public final List methodsByName(String name) throws ClassNotPreparedException {
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // visibleMethods calls checkPrepared
a61af66fc99e Initial load
duke
parents:
diff changeset
482 List methods = visibleMethods();
a61af66fc99e Initial load
duke
parents:
diff changeset
483 ArrayList retList = new ArrayList(methods.size());
a61af66fc99e Initial load
duke
parents:
diff changeset
484 Iterator iter = methods.iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
485 while (iter.hasNext()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
486 Method candidate = (Method)iter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
487 if (candidate.name().equals(name)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
488 retList.add(candidate);
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
490 }
a61af66fc99e Initial load
duke
parents:
diff changeset
491 retList.trimToSize();
a61af66fc99e Initial load
duke
parents:
diff changeset
492 return retList;
a61af66fc99e Initial load
duke
parents:
diff changeset
493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
494
a61af66fc99e Initial load
duke
parents:
diff changeset
495 public final List methodsByName(String name, String signature) throws ClassNotPreparedException {
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // visibleMethods calls checkPrepared
a61af66fc99e Initial load
duke
parents:
diff changeset
497 List methods = visibleMethods();
a61af66fc99e Initial load
duke
parents:
diff changeset
498 ArrayList retList = new ArrayList(methods.size());
a61af66fc99e Initial load
duke
parents:
diff changeset
499 Iterator iter = methods.iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
500 while (iter.hasNext()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
501 Method candidate = (Method)iter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
502 if (candidate.name().equals(name) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
503 candidate.signature().equals(signature)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
504 retList.add(candidate);
a61af66fc99e Initial load
duke
parents:
diff changeset
505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
506 }
a61af66fc99e Initial load
duke
parents:
diff changeset
507 retList.trimToSize();
a61af66fc99e Initial load
duke
parents:
diff changeset
508 return retList;
a61af66fc99e Initial load
duke
parents:
diff changeset
509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
510
a61af66fc99e Initial load
duke
parents:
diff changeset
511
a61af66fc99e Initial load
duke
parents:
diff changeset
512 List getInterfaces() {
a61af66fc99e Initial load
duke
parents:
diff changeset
513 List myInterfaces;
a61af66fc99e Initial load
duke
parents:
diff changeset
514 if (saKlass instanceof ArrayKlass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // Actually, JLS says arrays implement Cloneable and Serializable
a61af66fc99e Initial load
duke
parents:
diff changeset
516 // But, JVMDI-JDI just returns 0 interfaces for arrays. We follow
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // the same for consistency.
a61af66fc99e Initial load
duke
parents:
diff changeset
518 myInterfaces = new ArrayList(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
519 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
520 // Get a list of the sa InstanceKlass types
a61af66fc99e Initial load
duke
parents:
diff changeset
521 List saInterfaces = ((InstanceKlass)saKlass).getDirectImplementedInterfaces();
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // Create a list of our InterfaceTypes
a61af66fc99e Initial load
duke
parents:
diff changeset
524 int len = saInterfaces.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
525 myInterfaces = new ArrayList(len);
a61af66fc99e Initial load
duke
parents:
diff changeset
526 for (int ii = 0; ii < len; ii++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
527 myInterfaces.add(new InterfaceTypeImpl(vm, (InstanceKlass)saInterfaces.get(ii)));
a61af66fc99e Initial load
duke
parents:
diff changeset
528 }
a61af66fc99e Initial load
duke
parents:
diff changeset
529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
530 return myInterfaces;
a61af66fc99e Initial load
duke
parents:
diff changeset
531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
532
a61af66fc99e Initial load
duke
parents:
diff changeset
533 public final List nestedTypes() {
a61af66fc99e Initial load
duke
parents:
diff changeset
534 List nestedTypes = (nestedTypesCache != null)? (List) nestedTypesCache.get() : null;
a61af66fc99e Initial load
duke
parents:
diff changeset
535 if (nestedTypes == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
536 if (saKlass instanceof ArrayKlass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
537 nestedTypes = new ArrayList(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
538 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
539 ClassLoaderReference cl = classLoader();
a61af66fc99e Initial load
duke
parents:
diff changeset
540 List classes = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
541 if (cl != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
542 classes = cl.visibleClasses();
a61af66fc99e Initial load
duke
parents:
diff changeset
543 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
544 classes = vm.bootstrapClasses();
a61af66fc99e Initial load
duke
parents:
diff changeset
545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
546 nestedTypes = new ArrayList();
a61af66fc99e Initial load
duke
parents:
diff changeset
547 Iterator iter = classes.iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
548 while (iter.hasNext()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
549 ReferenceTypeImpl refType = (ReferenceTypeImpl)iter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
550 Symbol candidateName = refType.ref().getName();
a61af66fc99e Initial load
duke
parents:
diff changeset
551 if (((InstanceKlass)saKlass).isInnerOrLocalClassName(candidateName)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
552 nestedTypes.add(refType);
a61af66fc99e Initial load
duke
parents:
diff changeset
553 }
a61af66fc99e Initial load
duke
parents:
diff changeset
554 }
a61af66fc99e Initial load
duke
parents:
diff changeset
555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
556 nestedTypes = Collections.unmodifiableList(nestedTypes);
a61af66fc99e Initial load
duke
parents:
diff changeset
557 nestedTypesCache = new SoftReference(nestedTypes);
a61af66fc99e Initial load
duke
parents:
diff changeset
558 }
a61af66fc99e Initial load
duke
parents:
diff changeset
559 return nestedTypes;
a61af66fc99e Initial load
duke
parents:
diff changeset
560 }
a61af66fc99e Initial load
duke
parents:
diff changeset
561
a61af66fc99e Initial load
duke
parents:
diff changeset
562 public Value getValue(Field sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
563 List list = new ArrayList(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
564 list.add(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
565 Map map = getValues(list);
a61af66fc99e Initial load
duke
parents:
diff changeset
566 return(Value)map.get(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
568
a61af66fc99e Initial load
duke
parents:
diff changeset
569 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
570 * Returns a map of field values
a61af66fc99e Initial load
duke
parents:
diff changeset
571 */
a61af66fc99e Initial load
duke
parents:
diff changeset
572 public Map getValues(List theFields) {
a61af66fc99e Initial load
duke
parents:
diff changeset
573 //validateMirrors();
a61af66fc99e Initial load
duke
parents:
diff changeset
574 int size = theFields.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
575 Map map = new HashMap(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
576 for (int ii=0; ii<size; ii++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
577 FieldImpl fieldImpl = (FieldImpl)theFields.get(ii);
a61af66fc99e Initial load
duke
parents:
diff changeset
578
a61af66fc99e Initial load
duke
parents:
diff changeset
579 validateFieldAccess(fieldImpl);
a61af66fc99e Initial load
duke
parents:
diff changeset
580 // Do more validation specific to ReferenceType field getting
a61af66fc99e Initial load
duke
parents:
diff changeset
581 if (!fieldImpl.isStatic()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
582 throw new IllegalArgumentException(
a61af66fc99e Initial load
duke
parents:
diff changeset
583 "Attempt to use non-static field with ReferenceType: " +
a61af66fc99e Initial load
duke
parents:
diff changeset
584 fieldImpl.name());
a61af66fc99e Initial load
duke
parents:
diff changeset
585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
586 map.put(fieldImpl, fieldImpl.getValue());
a61af66fc99e Initial load
duke
parents:
diff changeset
587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
588 return map;
a61af66fc99e Initial load
duke
parents:
diff changeset
589 }
a61af66fc99e Initial load
duke
parents:
diff changeset
590
a61af66fc99e Initial load
duke
parents:
diff changeset
591 void validateFieldAccess(Field field) {
a61af66fc99e Initial load
duke
parents:
diff changeset
592 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
593 * Field must be in this object's class, a superclass, or
a61af66fc99e Initial load
duke
parents:
diff changeset
594 * implemented interface
a61af66fc99e Initial load
duke
parents:
diff changeset
595 */
a61af66fc99e Initial load
duke
parents:
diff changeset
596 ReferenceTypeImpl declType = (ReferenceTypeImpl)field.declaringType();
a61af66fc99e Initial load
duke
parents:
diff changeset
597 if (!declType.isAssignableFrom(this)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
598 throw new IllegalArgumentException("Invalid field");
a61af66fc99e Initial load
duke
parents:
diff changeset
599 }
a61af66fc99e Initial load
duke
parents:
diff changeset
600 }
a61af66fc99e Initial load
duke
parents:
diff changeset
601
a61af66fc99e Initial load
duke
parents:
diff changeset
602 public ClassObjectReference classObject() {
a61af66fc99e Initial load
duke
parents:
diff changeset
603 return vm.classObjectMirror(ref().getJavaMirror());
a61af66fc99e Initial load
duke
parents:
diff changeset
604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
605
a61af66fc99e Initial load
duke
parents:
diff changeset
606 SDE.Stratum stratum(String stratumID) {
a61af66fc99e Initial load
duke
parents:
diff changeset
607 SDE sde = sourceDebugExtensionInfo();
a61af66fc99e Initial load
duke
parents:
diff changeset
608 if (!sde.isValid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
609 sde = NO_SDE_INFO_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
610 }
a61af66fc99e Initial load
duke
parents:
diff changeset
611 return sde.stratum(stratumID);
a61af66fc99e Initial load
duke
parents:
diff changeset
612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
613
a61af66fc99e Initial load
duke
parents:
diff changeset
614 public String sourceName() throws AbsentInformationException {
a61af66fc99e Initial load
duke
parents:
diff changeset
615 return (String)(sourceNames(vm.getDefaultStratum()).get(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
617
a61af66fc99e Initial load
duke
parents:
diff changeset
618 public List sourceNames(String stratumID)
a61af66fc99e Initial load
duke
parents:
diff changeset
619 throws AbsentInformationException {
a61af66fc99e Initial load
duke
parents:
diff changeset
620 SDE.Stratum stratum = stratum(stratumID);
a61af66fc99e Initial load
duke
parents:
diff changeset
621 if (stratum.isJava()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
622 List result = new ArrayList(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
623 result.add(baseSourceName());
a61af66fc99e Initial load
duke
parents:
diff changeset
624 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
626 return stratum.sourceNames(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
627 }
a61af66fc99e Initial load
duke
parents:
diff changeset
628
a61af66fc99e Initial load
duke
parents:
diff changeset
629 public List sourcePaths(String stratumID)
a61af66fc99e Initial load
duke
parents:
diff changeset
630 throws AbsentInformationException {
a61af66fc99e Initial load
duke
parents:
diff changeset
631 SDE.Stratum stratum = stratum(stratumID);
a61af66fc99e Initial load
duke
parents:
diff changeset
632 if (stratum.isJava()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
633 List result = new ArrayList(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
634 result.add(baseSourceDir() + baseSourceName());
a61af66fc99e Initial load
duke
parents:
diff changeset
635 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
636 }
a61af66fc99e Initial load
duke
parents:
diff changeset
637 return stratum.sourcePaths(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
638 }
a61af66fc99e Initial load
duke
parents:
diff changeset
639
a61af66fc99e Initial load
duke
parents:
diff changeset
640 String baseSourceName() throws AbsentInformationException {
a61af66fc99e Initial load
duke
parents:
diff changeset
641 if (saKlass instanceof ArrayKlass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
642 throw new AbsentInformationException();
a61af66fc99e Initial load
duke
parents:
diff changeset
643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
644 Symbol sym = ((InstanceKlass)saKlass).getSourceFileName();
a61af66fc99e Initial load
duke
parents:
diff changeset
645 if (sym != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
646 return sym.asString();
a61af66fc99e Initial load
duke
parents:
diff changeset
647 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
648 throw new AbsentInformationException();
a61af66fc99e Initial load
duke
parents:
diff changeset
649 }
a61af66fc99e Initial load
duke
parents:
diff changeset
650 }
a61af66fc99e Initial load
duke
parents:
diff changeset
651
a61af66fc99e Initial load
duke
parents:
diff changeset
652 String baseSourcePath() throws AbsentInformationException {
a61af66fc99e Initial load
duke
parents:
diff changeset
653 return baseSourceDir() + baseSourceName();
a61af66fc99e Initial load
duke
parents:
diff changeset
654 }
a61af66fc99e Initial load
duke
parents:
diff changeset
655
a61af66fc99e Initial load
duke
parents:
diff changeset
656 String baseSourceDir() {
a61af66fc99e Initial load
duke
parents:
diff changeset
657 String typeName = name();
a61af66fc99e Initial load
duke
parents:
diff changeset
658 StringBuffer sb = new StringBuffer(typeName.length() + 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
659 int index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
660 int nextIndex;
a61af66fc99e Initial load
duke
parents:
diff changeset
661
a61af66fc99e Initial load
duke
parents:
diff changeset
662 while ((nextIndex = typeName.indexOf('.', index)) > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
663 sb.append(typeName.substring(index, nextIndex));
a61af66fc99e Initial load
duke
parents:
diff changeset
664 sb.append(java.io.File.separatorChar);
a61af66fc99e Initial load
duke
parents:
diff changeset
665 index = nextIndex + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
667 return sb.toString();
a61af66fc99e Initial load
duke
parents:
diff changeset
668 }
a61af66fc99e Initial load
duke
parents:
diff changeset
669
a61af66fc99e Initial load
duke
parents:
diff changeset
670 public String sourceDebugExtension()
a61af66fc99e Initial load
duke
parents:
diff changeset
671 throws AbsentInformationException {
a61af66fc99e Initial load
duke
parents:
diff changeset
672 if (!vm.canGetSourceDebugExtension()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
673 throw new UnsupportedOperationException();
a61af66fc99e Initial load
duke
parents:
diff changeset
674 }
a61af66fc99e Initial load
duke
parents:
diff changeset
675 SDE sde = sourceDebugExtensionInfo();
a61af66fc99e Initial load
duke
parents:
diff changeset
676 if (sde == NO_SDE_INFO_MARK) {
a61af66fc99e Initial load
duke
parents:
diff changeset
677 throw new AbsentInformationException();
a61af66fc99e Initial load
duke
parents:
diff changeset
678 }
a61af66fc99e Initial load
duke
parents:
diff changeset
679 return sde.sourceDebugExtension;
a61af66fc99e Initial load
duke
parents:
diff changeset
680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
681
a61af66fc99e Initial load
duke
parents:
diff changeset
682 private SDE sourceDebugExtensionInfo() {
a61af66fc99e Initial load
duke
parents:
diff changeset
683 if (!vm.canGetSourceDebugExtension()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
684 return NO_SDE_INFO_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
686 SDE sde = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
687 sde = (sdeRef == null) ? null : (SDE)sdeRef.get();
a61af66fc99e Initial load
duke
parents:
diff changeset
688 if (sde == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
689 String extension = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
690 if (saKlass instanceof InstanceKlass) {
6203
04ade88d9712 6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
fparain
parents: 3908
diff changeset
691 extension = ((InstanceKlass)saKlass).getSourceDebugExtension();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
692 }
a61af66fc99e Initial load
duke
parents:
diff changeset
693 if (extension == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
694 sde = NO_SDE_INFO_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
695 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
696 sde = new SDE(extension);
a61af66fc99e Initial load
duke
parents:
diff changeset
697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
698 sdeRef = new SoftReference(sde);
a61af66fc99e Initial load
duke
parents:
diff changeset
699 }
a61af66fc99e Initial load
duke
parents:
diff changeset
700 return sde;
a61af66fc99e Initial load
duke
parents:
diff changeset
701 }
a61af66fc99e Initial load
duke
parents:
diff changeset
702
a61af66fc99e Initial load
duke
parents:
diff changeset
703 public List availableStrata() {
a61af66fc99e Initial load
duke
parents:
diff changeset
704 SDE sde = sourceDebugExtensionInfo();
a61af66fc99e Initial load
duke
parents:
diff changeset
705 if (sde.isValid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
706 return sde.availableStrata();
a61af66fc99e Initial load
duke
parents:
diff changeset
707 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
708 List strata = new ArrayList();
a61af66fc99e Initial load
duke
parents:
diff changeset
709 strata.add(SDE.BASE_STRATUM_NAME);
a61af66fc99e Initial load
duke
parents:
diff changeset
710 return strata;
a61af66fc99e Initial load
duke
parents:
diff changeset
711 }
a61af66fc99e Initial load
duke
parents:
diff changeset
712 }
a61af66fc99e Initial load
duke
parents:
diff changeset
713
a61af66fc99e Initial load
duke
parents:
diff changeset
714 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
715 * Always returns non-null stratumID
a61af66fc99e Initial load
duke
parents:
diff changeset
716 */
a61af66fc99e Initial load
duke
parents:
diff changeset
717 public String defaultStratum() {
a61af66fc99e Initial load
duke
parents:
diff changeset
718 SDE sdei = sourceDebugExtensionInfo();
a61af66fc99e Initial load
duke
parents:
diff changeset
719 if (sdei.isValid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
720 return sdei.defaultStratumId;
a61af66fc99e Initial load
duke
parents:
diff changeset
721 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
722 return SDE.BASE_STRATUM_NAME;
a61af66fc99e Initial load
duke
parents:
diff changeset
723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
724 }
a61af66fc99e Initial load
duke
parents:
diff changeset
725
a61af66fc99e Initial load
duke
parents:
diff changeset
726 public final int modifiers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
727 if (modifiers == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
728 modifiers = getModifiers();
a61af66fc99e Initial load
duke
parents:
diff changeset
729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
730 return modifiers;
a61af66fc99e Initial load
duke
parents:
diff changeset
731 }
a61af66fc99e Initial load
duke
parents:
diff changeset
732
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // new method since 1.6.
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // Real body will be supplied later.
a61af66fc99e Initial load
duke
parents:
diff changeset
735 public List instances(long maxInstances) {
a61af66fc99e Initial load
duke
parents:
diff changeset
736 if (!vm.canGetInstanceInfo()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
737 throw new UnsupportedOperationException(
a61af66fc99e Initial load
duke
parents:
diff changeset
738 "target does not support getting instances");
a61af66fc99e Initial load
duke
parents:
diff changeset
739 }
a61af66fc99e Initial load
duke
parents:
diff changeset
740
a61af66fc99e Initial load
duke
parents:
diff changeset
741 if (maxInstances < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
742 throw new IllegalArgumentException("maxInstances is less than zero: "
a61af66fc99e Initial load
duke
parents:
diff changeset
743 + maxInstances);
a61af66fc99e Initial load
duke
parents:
diff changeset
744 }
a61af66fc99e Initial load
duke
parents:
diff changeset
745
a61af66fc99e Initial load
duke
parents:
diff changeset
746 final List objects = new ArrayList(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
747 if (isAbstract() || (this instanceof InterfaceType)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
748 return objects;
a61af66fc99e Initial load
duke
parents:
diff changeset
749 }
a61af66fc99e Initial load
duke
parents:
diff changeset
750
a61af66fc99e Initial load
duke
parents:
diff changeset
751 final Klass givenKls = this.ref();
a61af66fc99e Initial load
duke
parents:
diff changeset
752 final long max = maxInstances;
a61af66fc99e Initial load
duke
parents:
diff changeset
753 vm.saObjectHeap().iterate(new DefaultHeapVisitor() {
a61af66fc99e Initial load
duke
parents:
diff changeset
754 private long instCount=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
755 public boolean doObj(Oop oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
756 if (givenKls.equals(oop.getKlass())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
757 objects.add(vm.objectMirror(oop));
a61af66fc99e Initial load
duke
parents:
diff changeset
758 instCount++;
a61af66fc99e Initial load
duke
parents:
diff changeset
759 }
a61af66fc99e Initial load
duke
parents:
diff changeset
760 if (max > 0 && instCount >= max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
761 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
762 }
a61af66fc99e Initial load
duke
parents:
diff changeset
763 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
764 }
a61af66fc99e Initial load
duke
parents:
diff changeset
765 });
a61af66fc99e Initial load
duke
parents:
diff changeset
766 return objects;
a61af66fc99e Initial load
duke
parents:
diff changeset
767 }
a61af66fc99e Initial load
duke
parents:
diff changeset
768
a61af66fc99e Initial load
duke
parents:
diff changeset
769 int getModifiers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
770 return (int) saKlass.getClassModifiers();
a61af66fc99e Initial load
duke
parents:
diff changeset
771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
772
a61af66fc99e Initial load
duke
parents:
diff changeset
773 public List allLineLocations()
a61af66fc99e Initial load
duke
parents:
diff changeset
774 throws AbsentInformationException {
a61af66fc99e Initial load
duke
parents:
diff changeset
775 return allLineLocations(vm.getDefaultStratum(), null);
a61af66fc99e Initial load
duke
parents:
diff changeset
776 }
a61af66fc99e Initial load
duke
parents:
diff changeset
777
a61af66fc99e Initial load
duke
parents:
diff changeset
778 public List allLineLocations(String stratumID, String sourceName)
a61af66fc99e Initial load
duke
parents:
diff changeset
779 throws AbsentInformationException {
a61af66fc99e Initial load
duke
parents:
diff changeset
780 checkPrepared();
a61af66fc99e Initial load
duke
parents:
diff changeset
781 boolean someAbsent = false; // A method that should have info, didn't
a61af66fc99e Initial load
duke
parents:
diff changeset
782 SDE.Stratum stratum = stratum(stratumID);
a61af66fc99e Initial load
duke
parents:
diff changeset
783 List list = new ArrayList(); // location list
a61af66fc99e Initial load
duke
parents:
diff changeset
784
a61af66fc99e Initial load
duke
parents:
diff changeset
785 for (Iterator iter = methods().iterator(); iter.hasNext(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
786 MethodImpl method = (MethodImpl)iter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
787 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
788 list.addAll(
a61af66fc99e Initial load
duke
parents:
diff changeset
789 method.allLineLocations(stratum.id(), sourceName));
a61af66fc99e Initial load
duke
parents:
diff changeset
790 } catch(AbsentInformationException exc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
791 someAbsent = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
792 }
a61af66fc99e Initial load
duke
parents:
diff changeset
793 }
a61af66fc99e Initial load
duke
parents:
diff changeset
794
a61af66fc99e Initial load
duke
parents:
diff changeset
795 // If we retrieved no line info, and at least one of the methods
a61af66fc99e Initial load
duke
parents:
diff changeset
796 // should have had some (as determined by an
a61af66fc99e Initial load
duke
parents:
diff changeset
797 // AbsentInformationException being thrown) then we rethrow
a61af66fc99e Initial load
duke
parents:
diff changeset
798 // the AbsentInformationException.
a61af66fc99e Initial load
duke
parents:
diff changeset
799 if (someAbsent && list.size() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
800 throw new AbsentInformationException();
a61af66fc99e Initial load
duke
parents:
diff changeset
801 }
a61af66fc99e Initial load
duke
parents:
diff changeset
802 return list;
a61af66fc99e Initial load
duke
parents:
diff changeset
803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
804
a61af66fc99e Initial load
duke
parents:
diff changeset
805 public List locationsOfLine(int lineNumber)
a61af66fc99e Initial load
duke
parents:
diff changeset
806 throws AbsentInformationException {
a61af66fc99e Initial load
duke
parents:
diff changeset
807 return locationsOfLine(vm.getDefaultStratum(),
a61af66fc99e Initial load
duke
parents:
diff changeset
808 null,
a61af66fc99e Initial load
duke
parents:
diff changeset
809 lineNumber);
a61af66fc99e Initial load
duke
parents:
diff changeset
810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
811
a61af66fc99e Initial load
duke
parents:
diff changeset
812 public List locationsOfLine(String stratumID,
a61af66fc99e Initial load
duke
parents:
diff changeset
813 String sourceName,
a61af66fc99e Initial load
duke
parents:
diff changeset
814 int lineNumber)
a61af66fc99e Initial load
duke
parents:
diff changeset
815 throws AbsentInformationException {
a61af66fc99e Initial load
duke
parents:
diff changeset
816 checkPrepared();
a61af66fc99e Initial load
duke
parents:
diff changeset
817 // A method that should have info, didn't
a61af66fc99e Initial load
duke
parents:
diff changeset
818 boolean someAbsent = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
819 // A method that should have info, did
a61af66fc99e Initial load
duke
parents:
diff changeset
820 boolean somePresent = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
821 List methods = methods();
a61af66fc99e Initial load
duke
parents:
diff changeset
822 SDE.Stratum stratum = stratum(stratumID);
a61af66fc99e Initial load
duke
parents:
diff changeset
823
a61af66fc99e Initial load
duke
parents:
diff changeset
824 List list = new ArrayList();
a61af66fc99e Initial load
duke
parents:
diff changeset
825
a61af66fc99e Initial load
duke
parents:
diff changeset
826 Iterator iter = methods.iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
827 while(iter.hasNext()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
828 MethodImpl method = (MethodImpl)iter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
829 // eliminate native and abstract to eliminate
a61af66fc99e Initial load
duke
parents:
diff changeset
830 // false positives
a61af66fc99e Initial load
duke
parents:
diff changeset
831 if (!method.isAbstract() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
832 !method.isNative()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
833 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
834 list.addAll(
a61af66fc99e Initial load
duke
parents:
diff changeset
835 method.locationsOfLine(stratum.id(),
a61af66fc99e Initial load
duke
parents:
diff changeset
836 sourceName,
a61af66fc99e Initial load
duke
parents:
diff changeset
837 lineNumber));
a61af66fc99e Initial load
duke
parents:
diff changeset
838 somePresent = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
839 } catch(AbsentInformationException exc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
840 someAbsent = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
842 }
a61af66fc99e Initial load
duke
parents:
diff changeset
843 }
a61af66fc99e Initial load
duke
parents:
diff changeset
844 if (someAbsent && !somePresent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
845 throw new AbsentInformationException();
a61af66fc99e Initial load
duke
parents:
diff changeset
846 }
a61af66fc99e Initial load
duke
parents:
diff changeset
847 return list;
a61af66fc99e Initial load
duke
parents:
diff changeset
848 }
a61af66fc99e Initial load
duke
parents:
diff changeset
849
a61af66fc99e Initial load
duke
parents:
diff changeset
850 Klass ref() {
a61af66fc99e Initial load
duke
parents:
diff changeset
851 return saKlass;
a61af66fc99e Initial load
duke
parents:
diff changeset
852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
853
a61af66fc99e Initial load
duke
parents:
diff changeset
854
a61af66fc99e Initial load
duke
parents:
diff changeset
855 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
856 * Return true if an instance of this type
a61af66fc99e Initial load
duke
parents:
diff changeset
857 * can be assigned to a variable of the given type
a61af66fc99e Initial load
duke
parents:
diff changeset
858 */
a61af66fc99e Initial load
duke
parents:
diff changeset
859 abstract boolean isAssignableTo(ReferenceType type);
a61af66fc99e Initial load
duke
parents:
diff changeset
860
a61af66fc99e Initial load
duke
parents:
diff changeset
861 boolean isAssignableFrom(ReferenceType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
862 return ((ReferenceTypeImpl)type).isAssignableTo(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
864
a61af66fc99e Initial load
duke
parents:
diff changeset
865 boolean isAssignableFrom(ObjectReference object) {
a61af66fc99e Initial load
duke
parents:
diff changeset
866 return object == null ||
a61af66fc99e Initial load
duke
parents:
diff changeset
867 isAssignableFrom(object.referenceType());
a61af66fc99e Initial load
duke
parents:
diff changeset
868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
869
a61af66fc99e Initial load
duke
parents:
diff changeset
870 int indexOf(Method method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
871 // Make sure they're all here - the obsolete method
a61af66fc99e Initial load
duke
parents:
diff changeset
872 // won't be found and so will have index -1
a61af66fc99e Initial load
duke
parents:
diff changeset
873 return methods().indexOf(method);
a61af66fc99e Initial load
duke
parents:
diff changeset
874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
875
a61af66fc99e Initial load
duke
parents:
diff changeset
876 int indexOf(Field field) {
a61af66fc99e Initial load
duke
parents:
diff changeset
877 // Make sure they're all here
a61af66fc99e Initial load
duke
parents:
diff changeset
878 return fields().indexOf(field);
a61af66fc99e Initial load
duke
parents:
diff changeset
879 }
a61af66fc99e Initial load
duke
parents:
diff changeset
880
a61af66fc99e Initial load
duke
parents:
diff changeset
881 private static boolean isPrimitiveArray(String signature) {
a61af66fc99e Initial load
duke
parents:
diff changeset
882 int i = signature.lastIndexOf('[');
a61af66fc99e Initial load
duke
parents:
diff changeset
883 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
884 * TO DO: Centralize JNI signature knowledge.
a61af66fc99e Initial load
duke
parents:
diff changeset
885 *
a61af66fc99e Initial load
duke
parents:
diff changeset
886 * Ref:
a61af66fc99e Initial load
duke
parents:
diff changeset
887 * jdk1.4/doc/guide/jpda/jdi/com/sun/jdi/doc-files/signature.html
a61af66fc99e Initial load
duke
parents:
diff changeset
888 */
a61af66fc99e Initial load
duke
parents:
diff changeset
889 boolean isPA;
a61af66fc99e Initial load
duke
parents:
diff changeset
890 if (i < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
891 isPA = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
892 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
893 char c = signature.charAt(i + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
894 isPA = (c != 'L');
a61af66fc99e Initial load
duke
parents:
diff changeset
895 }
a61af66fc99e Initial load
duke
parents:
diff changeset
896 return isPA;
a61af66fc99e Initial load
duke
parents:
diff changeset
897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
898
a61af66fc99e Initial load
duke
parents:
diff changeset
899 Type findType(String signature) throws ClassNotLoadedException {
a61af66fc99e Initial load
duke
parents:
diff changeset
900 Type type;
a61af66fc99e Initial load
duke
parents:
diff changeset
901 if (signature.length() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
902 /* OTI FIX: Must be a primitive type or the void type */
a61af66fc99e Initial load
duke
parents:
diff changeset
903 char sig = signature.charAt(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
904 if (sig == 'V') {
a61af66fc99e Initial load
duke
parents:
diff changeset
905 type = vm.theVoidType();
a61af66fc99e Initial load
duke
parents:
diff changeset
906 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
907 type = vm.primitiveTypeMirror(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
908 }
a61af66fc99e Initial load
duke
parents:
diff changeset
909 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
910 // Must be a reference type.
a61af66fc99e Initial load
duke
parents:
diff changeset
911 ClassLoaderReferenceImpl loader =
a61af66fc99e Initial load
duke
parents:
diff changeset
912 (ClassLoaderReferenceImpl)classLoader();
a61af66fc99e Initial load
duke
parents:
diff changeset
913 if ((loader == null) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
914 (isPrimitiveArray(signature)) //Work around 4450091
a61af66fc99e Initial load
duke
parents:
diff changeset
915 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
916 // Caller wants type of boot class field
a61af66fc99e Initial load
duke
parents:
diff changeset
917 type = vm.findBootType(signature);
a61af66fc99e Initial load
duke
parents:
diff changeset
918 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
919 // Caller wants type of non-boot class field
a61af66fc99e Initial load
duke
parents:
diff changeset
920 type = loader.findType(signature);
a61af66fc99e Initial load
duke
parents:
diff changeset
921 }
a61af66fc99e Initial load
duke
parents:
diff changeset
922 }
a61af66fc99e Initial load
duke
parents:
diff changeset
923 return type;
a61af66fc99e Initial load
duke
parents:
diff changeset
924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
925
a61af66fc99e Initial load
duke
parents:
diff changeset
926 String loaderString() {
a61af66fc99e Initial load
duke
parents:
diff changeset
927 if (classLoader() != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
928 return "loaded by " + classLoader().toString();
a61af66fc99e Initial load
duke
parents:
diff changeset
929 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
930 return "loaded by bootstrap loader";
a61af66fc99e Initial load
duke
parents:
diff changeset
931 }
a61af66fc99e Initial load
duke
parents:
diff changeset
932 }
a61af66fc99e Initial load
duke
parents:
diff changeset
933
a61af66fc99e Initial load
duke
parents:
diff changeset
934 long uniqueID() {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6203
diff changeset
935 return vm.getAddressValue(ref().getJavaMirror());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
936 }
a61af66fc99e Initial load
duke
parents:
diff changeset
937
a61af66fc99e Initial load
duke
parents:
diff changeset
938 // new method since 1.6
a61af66fc99e Initial load
duke
parents:
diff changeset
939 public int majorVersion() {
a61af66fc99e Initial load
duke
parents:
diff changeset
940 if (!vm.canGetClassFileVersion()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
941 throw new UnsupportedOperationException("Cannot get class file version");
a61af66fc99e Initial load
duke
parents:
diff changeset
942 }
a61af66fc99e Initial load
duke
parents:
diff changeset
943 return (int)((InstanceKlass)saKlass).majorVersion();
a61af66fc99e Initial load
duke
parents:
diff changeset
944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
945
a61af66fc99e Initial load
duke
parents:
diff changeset
946 // new method since 1.6
a61af66fc99e Initial load
duke
parents:
diff changeset
947 public int minorVersion() {
a61af66fc99e Initial load
duke
parents:
diff changeset
948 if (!vm.canGetClassFileVersion()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
949 throw new UnsupportedOperationException("Cannot get class file version");
a61af66fc99e Initial load
duke
parents:
diff changeset
950 }
a61af66fc99e Initial load
duke
parents:
diff changeset
951 return (int)((InstanceKlass)saKlass).minorVersion();
a61af66fc99e Initial load
duke
parents:
diff changeset
952 }
a61af66fc99e Initial load
duke
parents:
diff changeset
953
a61af66fc99e Initial load
duke
parents:
diff changeset
954 // new method since 1.6
a61af66fc99e Initial load
duke
parents:
diff changeset
955 public int constantPoolCount() {
a61af66fc99e Initial load
duke
parents:
diff changeset
956 if (!vm.canGetConstantPool()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
957 throw new UnsupportedOperationException("Cannot get constant pool");
a61af66fc99e Initial load
duke
parents:
diff changeset
958 }
a61af66fc99e Initial load
duke
parents:
diff changeset
959 if (saKlass instanceof ArrayKlass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
960 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
961 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
962 return (int)((InstanceKlass)saKlass).getConstants().getLength();
a61af66fc99e Initial load
duke
parents:
diff changeset
963 }
a61af66fc99e Initial load
duke
parents:
diff changeset
964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
965
a61af66fc99e Initial load
duke
parents:
diff changeset
966 // new method since 1.6
a61af66fc99e Initial load
duke
parents:
diff changeset
967 public byte[] constantPool() {
a61af66fc99e Initial load
duke
parents:
diff changeset
968 if (!vm.canGetConstantPool()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
969 throw new UnsupportedOperationException("Cannot get constant pool");
a61af66fc99e Initial load
duke
parents:
diff changeset
970 }
a61af66fc99e Initial load
duke
parents:
diff changeset
971 if (this instanceof ArrayType || this instanceof PrimitiveType) {
a61af66fc99e Initial load
duke
parents:
diff changeset
972 byte bytes[] = new byte[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
973 return bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
974 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
975 ByteArrayOutputStream bs = new ByteArrayOutputStream();
a61af66fc99e Initial load
duke
parents:
diff changeset
976 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
977 ((InstanceKlass)saKlass).getConstants().writeBytes(bs);
a61af66fc99e Initial load
duke
parents:
diff changeset
978 } catch (IOException ex) {
a61af66fc99e Initial load
duke
parents:
diff changeset
979 ex.printStackTrace();
a61af66fc99e Initial load
duke
parents:
diff changeset
980 byte bytes[] = new byte[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
981 return bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
982 }
a61af66fc99e Initial load
duke
parents:
diff changeset
983 return bs.toByteArray();
a61af66fc99e Initial load
duke
parents:
diff changeset
984 }
a61af66fc99e Initial load
duke
parents:
diff changeset
985 }
a61af66fc99e Initial load
duke
parents:
diff changeset
986 }