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

Unified · Split

java/pkg/com/sun/tools/hat/internal/model/JavaValueArray.java+433−0
@@ -0,0 +1,433 @@
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 com.sun.tools.hat.internal.parser.ReadBuffer;
36import java.io.IOException;
37
38/**
39 * An array of values, that is, an array of ints, boolean, floats or the like.
40 *
41 * @author Bill Foote
42 */
43public class JavaValueArray extends JavaLazyReadObject
44 /*imports*/ implements ArrayTypeCodes {
45
46 private static String arrayTypeName(byte sig) {
47 switch (sig) {
48 case 'B':
49 return "byte[]";
50 case 'Z':
51 return "boolean[]";
52 case 'C':
53 return "char[]";
54 case 'S':
55 return "short[]";
56 case 'I':
57 return "int[]";
58 case 'F':
59 return "float[]";
60 case 'J':
61 return "long[]";
62 case 'D':
63 return "double[]";
64 default:
65 throw new RuntimeException("invalid array element sig: " + sig);
66 }
67 }
68
69 private static int elementSize(byte type) {
70 switch (type) {
71 case T_BYTE:
72 case T_BOOLEAN:
73 return 1;
74 case T_CHAR:
75 case T_SHORT:
76 return 2;
77 case T_INT:
78 case T_FLOAT:
79 return 4;
80 case T_LONG:
81 case T_DOUBLE:
82 return 8;
83 default:
84 throw new RuntimeException("invalid array element type: " + type);
85 }
86 }
87
88 /*
89 * Java primitive array record (HPROF_GC_PRIM_ARRAY_DUMP) looks
90 * as below:
91 *
92 * object ID
93 * stack trace serial number (int)
94 * length of the instance data (int)
95 * element type (byte)
96 * array data
97 */
98 protected final int readValueLength() throws IOException {
99 JavaClass cl = getClazz();
100 ReadBuffer buf = cl.getReadBuffer();
101 int idSize = cl.getIdentifierSize();
102 long offset = getOffset() + idSize + 4;
103 // length of the array
104 int len = buf.getInt(offset);
105 // typecode of array element type
106 byte type = buf.getByte(offset + 4);
107 return len * elementSize(type);
108 }
109
110 protected final byte[] readValue() throws IOException {
111 JavaClass cl = getClazz();
112 ReadBuffer buf = cl.getReadBuffer();
113 int idSize = cl.getIdentifierSize();
114 long offset = getOffset() + idSize + 4;
115 // length of the array
116 int length = buf.getInt(offset);
117 // typecode of array element type
118 byte type = buf.getByte(offset + 4);
119 if (length == 0) {
120 return Snapshot.EMPTY_BYTE_ARRAY;
121 } else {
122 length *= elementSize(type);
123 byte[] res = new byte[length];
124 buf.get(offset + 5, res);
125 return res;
126 }
127 }
128
129 // JavaClass set only after resolve.
130 private JavaClass clazz;
131
132 // This field contains elementSignature byte and
133 // divider to be used to calculate length. Note that
134 // length of content byte[] is not same as array length.
135 // Actual array length is (byte[].length / divider)
136 private int data;
137
138 // First 8 bits of data is used for element signature
139 private static final int SIGNATURE_MASK = 0x0FF;
140
141 // Next 8 bits of data is used for length divider
142 private static final int LENGTH_DIVIDER_MASK = 0x0FF00;
143
144 // Number of bits to shift to get length divider
145 private static final int LENGTH_DIVIDER_SHIFT = 8;
146
147 public JavaValueArray(byte elementSignature, long offset) {
148 super(offset);
149 this.data = (elementSignature & SIGNATURE_MASK);
150 }
151
152 public JavaClass getClazz() {
153 return clazz;
154 }
155
156 public void visitReferencedObjects(JavaHeapObjectVisitor v) {
157 super.visitReferencedObjects(v);
158 }
159
160 public void resolve(Snapshot snapshot) {
161 if (clazz instanceof JavaClass) {
162 return;
163 }
164 byte elementSig = getElementType();
165 clazz = snapshot.findClass(arrayTypeName(elementSig));
166 if (clazz == null) {
167 clazz = snapshot.getArrayClass("" + ((char) elementSig));
168 }
169 getClazz().addInstance(this);
170 super.resolve(snapshot);
171 }
172
173 public int getLength() {
174 int divider = (data & LENGTH_DIVIDER_MASK) >>> LENGTH_DIVIDER_SHIFT;
175 if (divider == 0) {
176 byte elementSignature = getElementType();
177 switch (elementSignature) {
178 case 'B':
179 case 'Z':
180 divider = 1;
181 break;
182 case 'C':
183 case 'S':
184 divider = 2;
185 break;
186 case 'I':
187 case 'F':
188 divider = 4;
189 break;
190 case 'J':
191 case 'D':
192 divider = 8;
193 break;
194 default:
195 throw new RuntimeException("unknown primitive type: " +
196 elementSignature);
197 }
198 data |= (divider << LENGTH_DIVIDER_SHIFT);
199 }
200 return (getValueLength() / divider);
201 }
202
203 public Object getElements() {
204 final int len = getLength();
205 final byte et = getElementType();
206 byte[] data = getValue();
207 int index = 0;
208 switch (et) {
209 case 'Z': {
210 boolean[] res = new boolean[len];
211 for (int i = 0; i < len; i++) {
212 res[i] = booleanAt(index, data);
213 index++;
214 }
215 return res;
216 }
217 case 'B': {
218 byte[] res = new byte[len];
219 for (int i = 0; i < len; i++) {
220 res[i] = byteAt(index, data);
221 index++;
222 }
223 return res;
224 }
225 case 'C': {
226 char[] res = new char[len];
227 for (int i = 0; i < len; i++) {
228 res[i] = charAt(index, data);
229 index += 2;
230 }
231 return res;
232 }
233 case 'S': {
234 short[] res = new short[len];
235 for (int i = 0; i < len; i++) {
236 res[i] = shortAt(index, data);
237 index += 2;
238 }
239 return res;
240 }
241 case 'I': {
242 int[] res = new int[len];
243 for (int i = 0; i < len; i++) {
244 res[i] = intAt(index, data);
245 index += 4;
246 }
247 return res;
248 }
249 case 'J': {
250 long[] res = new long[len];
251 for (int i = 0; i < len; i++) {
252 res[i] = longAt(index, data);
253 index += 8;
254 }
255 return res;
256 }
257 case 'F': {
258 float[] res = new float[len];
259 for (int i = 0; i < len; i++) {
260 res[i] = floatAt(index, data);
261 index += 4;
262 }
263 return res;
264 }
265 case 'D': {
266 double[] res = new double[len];
267 for (int i = 0; i < len; i++) {
268 res[i] = doubleAt(index, data);
269 index += 8;
270 }
271 return res;
272 }
273 default: {
274 throw new RuntimeException("unknown primitive type?");
275 }
276 }
277 }
278
279 public byte getElementType() {
280 return (byte) (data & SIGNATURE_MASK);
281 }
282
283 private void checkIndex(int index) {
284 if (index < 0 || index >= getLength()) {
285 throw new ArrayIndexOutOfBoundsException(index);
286 }
287 }
288
289 private void requireType(char type) {
290 if (getElementType() != type) {
291 throw new RuntimeException("not of type : " + type);
292 }
293 }
294
295 public boolean getBooleanAt(int index) {
296 checkIndex(index);
297 requireType('Z');
298 return booleanAt(index, getValue());
299 }
300
301 public byte getByteAt(int index) {
302 checkIndex(index);
303 requireType('B');
304 return byteAt(index, getValue());
305 }
306
307 public char getCharAt(int index) {
308 checkIndex(index);
309 requireType('C');
310 return charAt(index << 1, getValue());
311 }
312
313 public short getShortAt(int index) {
314 checkIndex(index);
315 requireType('S');
316 return shortAt(index << 1, getValue());
317 }
318
319 public int getIntAt(int index) {
320 checkIndex(index);
321 requireType('I');
322 return intAt(index << 2, getValue());
323 }
324
325 public long getLongAt(int index) {
326 checkIndex(index);
327 requireType('J');
328 return longAt(index << 3, getValue());
329 }
330
331 public float getFloatAt(int index) {
332 checkIndex(index);
333 requireType('F');
334 return floatAt(index << 2, getValue());
335 }
336
337 public double getDoubleAt(int index) {
338 checkIndex(index);
339 requireType('D');
340 return doubleAt(index << 3, getValue());
341 }
342
343 public String valueString() {
344 return valueString(true);
345 }
346
347 public String valueString(boolean bigLimit) {
348 // Char arrays deserve special treatment
349 StringBuffer result;
350 byte[] value = getValue();
351 int max = value.length;
352 byte elementSignature = getElementType();
353 if (elementSignature == 'C') {
354 result = new StringBuffer();
355 for (int i = 0; i < value.length; ) {
356 char val = charAt(i, value);
357 result.append(val);
358 i += 2;
359 }
360 } else {
361 int limit = 8;
362 if (bigLimit) {
363 limit = 1000;
364 }
365 result = new StringBuffer("{");
366 int num = 0;
367 for (int i = 0; i < value.length; ) {
368 if (num > 0) {
369 result.append(", ");
370 }
371 if (num >= limit) {
372 result.append("... ");
373 break;
374 }
375 num++;
376 switch (elementSignature) {
377 case 'Z': {
378 boolean val = booleanAt(i, value);
379 if (val) {
380 result.append("true");
381 } else {
382 result.append("false");
383 }
384 i++;
385 break;
386 }
387 case 'B': {
388 int val = 0xFF & byteAt(i, value);
389 result.append("0x" + Integer.toString(val, 16));
390 i++;
391 break;
392 }
393 case 'S': {
394 short val = shortAt(i, value);
395 i += 2;
396 result.append("" + val);
397 break;
398 }
399 case 'I': {
400 int val = intAt(i, value);
401 i += 4;
402 result.append("" + val);
403 break;
404 }
405 case 'J': { // long
406 long val = longAt(i, value);
407 result.append("" + val);
408 i += 8;
409 break;
410 }
411 case 'F': {
412 float val = floatAt(i, value);
413 result.append("" + val);
414 i += 4;
415 break;
416 }
417 case 'D': { // double
418 double val = doubleAt(i, value);
419 result.append("" + val);
420 i += 8;
421 break;
422 }
423 default: {
424 throw new RuntimeException("unknown primitive type?");
425 }
426 }
427 }
428 result.append("}");
429 }
430 return result.toString();
431 }
432
433}