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/JavaObject.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/tools/hat/internal/model/JavaObject.java+334−0
@@ -0,0 +1,334 @@
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.io.IOException;
36import com.sun.tools.hat.internal.parser.ReadBuffer;
37
38/**
39 * Represents Java instance
40 *
41 * @author Bill Foote
42 */
43public class JavaObject extends JavaLazyReadObject {
44
45 private Object clazz; // Number before resolve
46 // JavaClass after resolve
47 /**
48 * Construct a new JavaObject.
49 *
50 * @param classID id of the class object
51 * @param offset The offset of field data
52 */
53 public JavaObject(long classID, long offset) {
54 super(offset);
55 this.clazz = makeId(classID);
56 }
57
58 public void resolve(Snapshot snapshot) {
59 if (clazz instanceof JavaClass) {
60 return;
61 }
62 if (clazz instanceof Number) {
63 long classID = getIdValue((Number)clazz);
64 clazz = snapshot.findThing(classID);
65 if (! (clazz instanceof JavaClass)) {
66 warn("Class " + Long.toHexString(classID) + " not found, " +
67 "adding fake class!");
68 int length;
69 ReadBuffer buf = snapshot.getReadBuffer();
70 int idSize = snapshot.getIdentifierSize();
71 long lenOffset = getOffset() + 2*idSize + 4;
72 try {
73 length = buf.getInt(lenOffset);
74 } catch (IOException exp) {
75 throw new RuntimeException(exp);
76 }
77 clazz = snapshot.addFakeInstanceClass(classID, length);
78 }
79 } else {
80 throw new InternalError("should not reach here");
81 }
82
83 JavaClass cl = (JavaClass) clazz;
84 cl.resolve(snapshot);
85
86 // while resolving, parse fields in verbose mode.
87 // but, getFields calls parseFields in non-verbose mode
88 // to avoid printing warnings repeatedly.
89 parseFields(getValue(), true);
90
91 cl.addInstance(this);
92 super.resolve(snapshot);
93 }
94
95 /**
96 * Are we the same type as other? We are iff our clazz is the
97 * same type as other's.
98 */
99 public boolean isSameTypeAs(JavaThing other) {
100 if (!(other instanceof JavaObject)) {
101 return false;
102 }
103 JavaObject oo = (JavaObject) other;
104 return getClazz().equals(oo.getClazz());
105 }
106
107 /**
108 * Return our JavaClass object. This may only be called after resolve.
109 */
110 public JavaClass getClazz() {
111 return (JavaClass) clazz;
112 }
113
114 public JavaThing[] getFields() {
115 // pass false to verbose mode so that dereference
116 // warnings are not printed.
117 return parseFields(getValue(), false);
118 }
119
120 // returns the value of field of given name
121 public JavaThing getField(String name) {
122 JavaThing[] flds = getFields();
123 JavaField[] instFields = getClazz().getFieldsForInstance();
124 for (int i = 0; i < instFields.length; i++) {
125 if (instFields[i].getName().equals(name)) {
126 return flds[i];
127 }
128 }
129 return null;
130 }
131
132 public int compareTo(JavaThing other) {
133 if (other instanceof JavaObject) {
134 JavaObject oo = (JavaObject) other;
135 return getClazz().getName().compareTo(oo.getClazz().getName());
136 }
137 return super.compareTo(other);
138 }
139
140 public void visitReferencedObjects(JavaHeapObjectVisitor v) {
141 super.visitReferencedObjects(v);
142 JavaThing[] flds = getFields();
143 for (int i = 0; i < flds.length; i++) {
144 if (flds[i] != null) {
145 if (v.mightExclude()
146 && v.exclude(getClazz().getClassForField(i),
147 getClazz().getFieldForInstance(i)))
148 {
149 // skip it
150 } else if (flds[i] instanceof JavaHeapObject) {
151 v.visit((JavaHeapObject) flds[i]);
152 }
153 }
154 }
155 }
156
157 public boolean refersOnlyWeaklyTo(Snapshot ss, JavaThing other) {
158 if (ss.getWeakReferenceClass() != null) {
159 final int referentFieldIndex = ss.getReferentFieldIndex();
160 if (ss.getWeakReferenceClass().isAssignableFrom(getClazz())) {
161 //
162 // REMIND: This introduces a dependency on the JDK
163 // implementation that is undesirable.
164 JavaThing[] flds = getFields();
165 for (int i = 0; i < flds.length; i++) {
166 if (i != referentFieldIndex && flds[i] == other) {
167 return false;
168 }
169 }
170 return true;
171 }
172 }
173 return false;
174 }
175
176 /**
177 * Describe the reference that this thing has to target. This will only
178 * be called if target is in the array returned by getChildrenForRootset.
179 */
180 public String describeReferenceTo(JavaThing target, Snapshot ss) {
181 JavaThing[] flds = getFields();
182 for (int i = 0; i < flds.length; i++) {
183 if (flds[i] == target) {
184 JavaField f = getClazz().getFieldForInstance(i);
185 return "field " + f.getName();
186 }
187 }
188 return super.describeReferenceTo(target, ss);
189 }
190
191 public String toString() {
192 if (getClazz().isString()) {
193 JavaThing value = getField("value");
194 if (value instanceof JavaValueArray) {
195 return ((JavaValueArray)value).valueString();
196 } else {
197 return "null";
198 }
199 } else {
200 return super.toString();
201 }
202 }
203
204 // Internals only below this point
205
206 /*
207 * Java instance record (HPROF_GC_INSTANCE_DUMP) looks as below:
208 *
209 * object ID
210 * stack trace serial number (int)
211 * class ID
212 * data length (int)
213 * byte[length]
214 */
215 protected final int readValueLength() throws IOException {
216 JavaClass cl = getClazz();
217 int idSize = cl.getIdentifierSize();
218 long lengthOffset = getOffset() + 2*idSize + 4;
219 return cl.getReadBuffer().getInt(lengthOffset);
220 }
221
222 protected final byte[] readValue() throws IOException {
223 JavaClass cl = getClazz();
224 int idSize = cl.getIdentifierSize();
225 ReadBuffer buf = cl.getReadBuffer();
226 long offset = getOffset() + 2*idSize + 4;
227 int length = buf.getInt(offset);
228 if (length == 0) {
229 return Snapshot.EMPTY_BYTE_ARRAY;
230 } else {
231 byte[] res = new byte[length];
232 buf.get(offset + 4, res);
233 return res;
234 }
235 }
236
237 private JavaThing[] parseFields(byte[] data, boolean verbose) {
238 JavaClass cl = getClazz();
239 int target = cl.getNumFieldsForInstance();
240 JavaField[] fields = cl.getFields();
241 JavaThing[] fieldValues = new JavaThing[target];
242 Snapshot snapshot = cl.getSnapshot();
243 int idSize = snapshot.getIdentifierSize();
244 int fieldNo = 0;
245 // In the dump file, the fields are stored in this order:
246 // fields of most derived class (immediate class) are stored
247 // first and then the super class and so on. In this object,
248 // fields are stored in the reverse ("natural") order. i.e.,
249 // fields of most super class are stored first.
250
251 // target variable is used to compensate for the fact that
252 // the dump file starts field values from the leaf working
253 // upwards in the inheritance hierarchy, whereas JavaObject
254 // starts with the top of the inheritance hierarchy and works down.
255 target -= fields.length;
256 JavaClass currClass = cl;
257 int index = 0;
258 for (int i = 0; i < fieldValues.length; i++, fieldNo++) {
259 while (fieldNo >= fields.length) {
260 currClass = currClass.getSuperclass();
261 fields = currClass.getFields();
262 fieldNo = 0;
263 target -= fields.length;
264 }
265 JavaField f = fields[fieldNo];
266 char sig = f.getSignature().charAt(0);
267 switch (sig) {
268 case 'L':
269 case '[': {
270 long id = objectIdAt(index, data);
271 index += idSize;
272 JavaObjectRef ref = new JavaObjectRef(id);
273 fieldValues[target+fieldNo] = ref.dereference(snapshot, f, verbose);
274 break;
275 }
276 case 'Z': {
277 byte value = byteAt(index, data);
278 index++;
279 fieldValues[target+fieldNo] = new JavaBoolean(value != 0);
280 break;
281 }
282 case 'B': {
283 byte value = byteAt(index, data);
284 index++;
285 fieldValues[target+fieldNo] = new JavaByte(value);
286 break;
287 }
288 case 'S': {
289 short value = shortAt(index, data);
290 index += 2;
291 fieldValues[target+fieldNo] = new JavaShort(value);
292 break;
293 }
294 case 'C': {
295 char value = charAt(index, data);
296 index += 2;
297 fieldValues[target+fieldNo] = new JavaChar(value);
298 break;
299 }
300 case 'I': {
301 int value = intAt(index, data);
302 index += 4;
303 fieldValues[target+fieldNo] = new JavaInt(value);
304 break;
305 }
306 case 'J': {
307 long value = longAt(index, data);
308 index += 8;
309 fieldValues[target+fieldNo] = new JavaLong(value);
310 break;
311 }
312 case 'F': {
313 float value = floatAt(index, data);
314 index += 4;
315 fieldValues[target+fieldNo] = new JavaFloat(value);
316 break;
317 }
318 case 'D': {
319 double value = doubleAt(index, data);
320 index += 8;
321 fieldValues[target+fieldNo] = new JavaDouble(value);
322 break;
323 }
324 default:
325 throw new RuntimeException("invalid signature: " + sig);
326 }
327 }
328 return fieldValues;
329 }
330
331 private void warn(String msg) {
332 System.out.println("WARNING: " + msg);
333 }
334}