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+
33+package com.sun.tools.hat.internal.model;
34+
35+import com.sun.tools.hat.internal.parser.ReadBuffer;
36+import 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+ */
43+public 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+}