History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/tools/hat/internal/model/JavaClass.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/tools/hat/internal/model/JavaClass.java+503−0
@@ -0,0 +1,503 @@
1/*
2 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26
27/*
28 * The Original Code is HAT. The Initial Developer of the
29 * Original Code is Bill Foote, with contributions from others
30 * at JavaSoft/Sun.
31 */
32
33package com.sun.tools.hat.internal.model;
34
35import java.util.Vector;
36import java.util.Enumeration;
37import com.sun.tools.hat.internal.util.CompositeEnumeration;
38import com.sun.tools.hat.internal.parser.ReadBuffer;
39
40/**
41 *
42 * @author Bill Foote
43 */
44
45
46public class JavaClass extends JavaHeapObject {
47 // my id
48 private long id;
49 // my name
50 private String name;
51
52 // These are JavaObjectRef before resolve
53 private JavaThing superclass;
54 private JavaThing loader;
55 private JavaThing signers;
56 private JavaThing protectionDomain;
57
58 // non-static fields
59 private JavaField[] fields;
60 // static fields
61 private JavaStatic[] statics;
62
63 private static final JavaClass[] EMPTY_CLASS_ARRAY = new JavaClass[0];
64 // my subclasses
65 private JavaClass[] subclasses = EMPTY_CLASS_ARRAY;
66
67 // my instances
68 private Vector<JavaHeapObject> instances = new Vector<JavaHeapObject>();
69
70 // Who I belong to. Set on resolve.
71 private Snapshot mySnapshot;
72
73 // Size of an instance, including VM overhead
74 private int instanceSize;
75 // Total number of fields including inherited ones
76 private int totalNumFields;
77
78
79 public JavaClass(long id, String name, long superclassId, long loaderId,
80 long signersId, long protDomainId,
81 JavaField[] fields, JavaStatic[] statics,
82 int instanceSize) {
83 this.id = id;
84 this.name = name;
85 this.superclass = new JavaObjectRef(superclassId);
86 this.loader = new JavaObjectRef(loaderId);
87 this.signers = new JavaObjectRef(signersId);
88 this.protectionDomain = new JavaObjectRef(protDomainId);
89 this.fields = fields;
90 this.statics = statics;
91 this.instanceSize = instanceSize;
92 }
93
94 public JavaClass(String name, long superclassId, long loaderId,
95 long signersId, long protDomainId,
96 JavaField[] fields, JavaStatic[] statics,
97 int instanceSize) {
98 this(-1L, name, superclassId, loaderId, signersId,
99 protDomainId, fields, statics, instanceSize);
100 }
101
102 public final JavaClass getClazz() {
103 return mySnapshot.getJavaLangClass();
104 }
105
106 public final int getIdentifierSize() {
107 return mySnapshot.getIdentifierSize();
108 }
109
110 public final int getMinimumObjectSize() {
111 return mySnapshot.getMinimumObjectSize();
112 }
113
114 public void resolve(Snapshot snapshot) {
115 if (mySnapshot != null) {
116 return;
117 }
118 mySnapshot = snapshot;
119 resolveSuperclass(snapshot);
120 if (superclass != null) {
121 ((JavaClass) superclass).addSubclass(this);
122 }
123
124 loader = loader.dereference(snapshot, null);
125 signers = signers.dereference(snapshot, null);
126 protectionDomain = protectionDomain.dereference(snapshot, null);
127
128 for (int i = 0; i < statics.length; i++) {
129 statics[i].resolve(this, snapshot);
130 }
131 snapshot.getJavaLangClass().addInstance(this);
132 super.resolve(snapshot);
133 return;
134 }
135
136 /**
137 * Resolve our superclass. This might be called well before
138 * all instances are available (like when reading deferred
139 * instances in a 1.2 dump file :-) Calling this is sufficient
140 * to be able to explore this class' fields.
141 */
142 public void resolveSuperclass(Snapshot snapshot) {
143 if (superclass == null) {
144 // We must be java.lang.Object, so we have no superclass.
145 } else {
146 totalNumFields = fields.length;
147 superclass = superclass.dereference(snapshot, null);
148 if (superclass == snapshot.getNullThing()) {
149 superclass = null;
150 } else {
151 try {
152 JavaClass sc = (JavaClass) superclass;
153 sc.resolveSuperclass(snapshot);
154 totalNumFields += sc.totalNumFields;
155 } catch (ClassCastException ex) {
156 System.out.println("Warning! Superclass of " + name + " is " + superclass);
157 superclass = null;
158 }
159 }
160 }
161 }
162
163 public boolean isString() {
164 return mySnapshot.getJavaLangString() == this;
165 }
166
167 public boolean isClassLoader() {
168 return mySnapshot.getJavaLangClassLoader().isAssignableFrom(this);
169 }
170
171 /**
172 * Get a numbered field from this class
173 */
174 public JavaField getField(int i) {
175 if (i < 0 || i >= fields.length) {
176 throw new Error("No field " + i + " for " + name);
177 }
178 return fields[i];
179 }
180
181 /**
182 * Get the total number of fields that are part of an instance of
183 * this class. That is, include superclasses.
184 */
185 public int getNumFieldsForInstance() {
186 return totalNumFields;
187 }
188
189 /**
190 * Get a numbered field from all the fields that are part of instance
191 * of this class. That is, include superclasses.
192 */
193 public JavaField getFieldForInstance(int i) {
194 if (superclass != null) {
195 JavaClass sc = (JavaClass) superclass;
196 if (i < sc.totalNumFields) {
197 return sc.getFieldForInstance(i);
198 }
199 i -= sc.totalNumFields;
200 }
201 return getField(i);
202 }
203
204 /**
205 * Get the class responsible for field i, where i is a field number that
206 * could be passed into getFieldForInstance.
207 *
208 * @see JavaClass.getFieldForInstance()
209 */
210 public JavaClass getClassForField(int i) {
211 if (superclass != null) {
212 JavaClass sc = (JavaClass) superclass;
213 if (i < sc.totalNumFields) {
214 return sc.getClassForField(i);
215 }
216 }
217 return this;
218 }
219
220 public long getId() {
221 return id;
222 }
223
224 public String getName() {
225 return name;
226 }
227
228 public boolean isArray() {
229 return name.indexOf('[') != -1;
230 }
231
232 public Enumeration getInstances(boolean includeSubclasses) {
233 if (includeSubclasses) {
234 Enumeration res = instances.elements();
235 for (int i = 0; i < subclasses.length; i++) {
236 res = new CompositeEnumeration(res,
237 subclasses[i].getInstances(true));
238 }
239 return res;
240 } else {
241 return instances.elements();
242 }
243 }
244
245 /**
246 * @return a count of the instances of this class
247 */
248 public int getInstancesCount(boolean includeSubclasses) {
249 int result = instances.size();
250 if (includeSubclasses) {
251 for (int i = 0; i < subclasses.length; i++) {
252 result += subclasses[i].getInstancesCount(includeSubclasses);
253 }
254 }
255 return result;
256 }
257
258 public JavaClass[] getSubclasses() {
259 return subclasses;
260 }
261
262 /**
263 * This can only safely be called after resolve()
264 */
265 public JavaClass getSuperclass() {
266 return (JavaClass) superclass;
267 }
268
269 /**
270 * This can only safely be called after resolve()
271 */
272 public JavaThing getLoader() {
273 return loader;
274 }
275
276 /**
277 * This can only safely be called after resolve()
278 */
279 public boolean isBootstrap() {
280 return loader == mySnapshot.getNullThing();
281 }
282
283 /**
284 * This can only safely be called after resolve()
285 */
286 public JavaThing getSigners() {
287 return signers;
288 }
289
290 /**
291 * This can only safely be called after resolve()
292 */
293 public JavaThing getProtectionDomain() {
294 return protectionDomain;
295 }
296
297 public JavaField[] getFields() {
298 return fields;
299 }
300
301 /**
302 * Includes superclass fields
303 */
304 public JavaField[] getFieldsForInstance() {
305 Vector<JavaField> v = new Vector<JavaField>();
306 addFields(v);
307 JavaField[] result = new JavaField[v.size()];
308 for (int i = 0; i < v.size(); i++) {
309 result[i] = v.elementAt(i);
310 }
311 return result;
312 }
313
314
315 public JavaStatic[] getStatics() {
316 return statics;
317 }
318
319 // returns value of static field of given name
320 public JavaThing getStaticField(String name) {
321 for (int i = 0; i < statics.length; i++) {
322 JavaStatic s = statics[i];
323 if (s.getField().getName().equals(name)) {
324 return s.getValue();
325 }
326 }
327 return null;
328 }
329
330 public String toString() {
331 return "class " + name;
332 }
333
334 public int compareTo(JavaThing other) {
335 if (other instanceof JavaClass) {
336 return name.compareTo(((JavaClass) other).name);
337 }
338 return super.compareTo(other);
339 }
340
341
342 /**
343 * @return true iff a variable of type this is assignable from an instance
344 * of other
345 */
346 public boolean isAssignableFrom(JavaClass other) {
347 if (this == other) {
348 return true;
349 } else if (other == null) {
350 return false;
351 } else {
352 return isAssignableFrom((JavaClass) other.superclass);
353 // Trivial tail recursion: I have faith in javac.
354 }
355 }
356
357 /**
358 * Describe the reference that this thing has to target. This will only
359 * be called if target is in the array returned by getChildrenForRootset.
360 */
361 public String describeReferenceTo(JavaThing target, Snapshot ss) {
362 for (int i = 0; i < statics.length; i++) {
363 JavaField f = statics[i].getField();
364 if (f.hasId()) {
365 JavaThing other = statics[i].getValue();
366 if (other == target) {
367 return "static field " + f.getName();
368 }
369 }
370 }
371 return super.describeReferenceTo(target, ss);
372 }
373
374 /**
375 * @return the size of an instance of this class. Gives 0 for an array
376 * type.
377 */
378 public int getInstanceSize() {
379 return instanceSize + mySnapshot.getMinimumObjectSize();
380 }
381
382
383 /**
384 * @return The size of all instances of this class. Correctly handles
385 * arrays.
386 */
387 public long getTotalInstanceSize() {
388 int count = instances.size();
389 if (count == 0 || !isArray()) {
390 return count * instanceSize;
391 }
392
393 // array class and non-zero count, we have to
394 // get the size of each instance and sum it
395 long result = 0;
396 for (int i = 0; i < count; i++) {
397 JavaThing t = (JavaThing) instances.elementAt(i);
398 result += t.getSize();
399 }
400 return result;
401 }
402
403 /**
404 * @return the size of this object
405 */
406 public int getSize() {
407 JavaClass cl = mySnapshot.getJavaLangClass();
408 if (cl == null) {
409 return 0;
410 } else {
411 return cl.getInstanceSize();
412 }
413 }
414
415 public void visitReferencedObjects(JavaHeapObjectVisitor v) {
416 super.visitReferencedObjects(v);
417 JavaHeapObject sc = getSuperclass();
418 if (sc != null) v.visit(getSuperclass());
419
420 JavaThing other;
421 other = getLoader();
422 if (other instanceof JavaHeapObject) {
423 v.visit((JavaHeapObject)other);
424 }
425 other = getSigners();
426 if (other instanceof JavaHeapObject) {
427 v.visit((JavaHeapObject)other);
428 }
429 other = getProtectionDomain();
430 if (other instanceof JavaHeapObject) {
431 v.visit((JavaHeapObject)other);
432 }
433
434 for (int i = 0; i < statics.length; i++) {
435 JavaField f = statics[i].getField();
436 if (!v.exclude(this, f) && f.hasId()) {
437 other = statics[i].getValue();
438 if (other instanceof JavaHeapObject) {
439 v.visit((JavaHeapObject) other);
440 }
441 }
442 }
443 }
444
445 // package-privates below this point
446 final ReadBuffer getReadBuffer() {
447 return mySnapshot.getReadBuffer();
448 }
449
450 final void setNew(JavaHeapObject obj, boolean flag) {
451 mySnapshot.setNew(obj, flag);
452 }
453
454 final boolean isNew(JavaHeapObject obj) {
455 return mySnapshot.isNew(obj);
456 }
457
458 final StackTrace getSiteTrace(JavaHeapObject obj) {
459 return mySnapshot.getSiteTrace(obj);
460 }
461
462 final void addReferenceFromRoot(Root root, JavaHeapObject obj) {
463 mySnapshot.addReferenceFromRoot(root, obj);
464 }
465
466 final Root getRoot(JavaHeapObject obj) {
467 return mySnapshot.getRoot(obj);
468 }
469
470 final Snapshot getSnapshot() {
471 return mySnapshot;
472 }
473
474 void addInstance(JavaHeapObject inst) {
475 instances.addElement(inst);
476 }
477
478 // Internals only below this point
479 private void addFields(Vector<JavaField> v) {
480 if (superclass != null) {
481 ((JavaClass) superclass).addFields(v);
482 }
483 for (int i = 0; i < fields.length; i++) {
484 v.addElement(fields[i]);
485 }
486 }
487
488 private void addSubclassInstances(Vector<JavaHeapObject> v) {
489 for (int i = 0; i < subclasses.length; i++) {
490 subclasses[i].addSubclassInstances(v);
491 }
492 for (int i = 0; i < instances.size(); i++) {
493 v.addElement(instances.elementAt(i));
494 }
495 }
496
497 private void addSubclass(JavaClass sub) {
498 JavaClass newValue[] = new JavaClass[subclasses.length + 1];
499 System.arraycopy(subclasses, 0, newValue, 0, subclasses.length);
500 newValue[subclasses.length] = sub;
501 subclasses = newValue;
502 }
503}