blob: d663dea6fecf480c3bc973ddc603670b52ab42b6 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003-2004 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.management.counter.perf;
27
28import sun.management.counter.*;
29import java.nio.*;
30import java.io.UnsupportedEncodingException;
31
32class PerfDataEntry {
33 private class EntryFieldOffset {
34 private final static int SIZEOF_BYTE = 1;
35 private final static int SIZEOF_INT = 4;
36 private final static int SIZEOF_LONG = 8;
37
38 private final static int ENTRY_LENGTH_SIZE = SIZEOF_INT;
39 private final static int NAME_OFFSET_SIZE = SIZEOF_INT;
40 private final static int VECTOR_LENGTH_SIZE = SIZEOF_INT;
41 private final static int DATA_TYPE_SIZE = SIZEOF_BYTE;
42 private final static int FLAGS_SIZE = SIZEOF_BYTE;
43 private final static int DATA_UNIT_SIZE = SIZEOF_BYTE;
44 private final static int DATA_VAR_SIZE = SIZEOF_BYTE;
45 private final static int DATA_OFFSET_SIZE = SIZEOF_INT;
46
47 final static int ENTRY_LENGTH = 0;
48 final static int NAME_OFFSET = ENTRY_LENGTH + ENTRY_LENGTH_SIZE;
49 final static int VECTOR_LENGTH = NAME_OFFSET + NAME_OFFSET_SIZE;;
50 final static int DATA_TYPE = VECTOR_LENGTH + VECTOR_LENGTH_SIZE;
51 final static int FLAGS = DATA_TYPE + DATA_TYPE_SIZE;
52 final static int DATA_UNIT = FLAGS + FLAGS_SIZE;
53 final static int DATA_VAR = DATA_UNIT + DATA_UNIT_SIZE;
54 final static int DATA_OFFSET = DATA_VAR + DATA_VAR_SIZE;
55 }
56
57 private String name;
58 private int entryStart;
59 private int entryLength;
60 private int vectorLength;
61 private PerfDataType dataType;
62 private int flags;
63 private Units unit;
64 private Variability variability;
65 private int dataOffset;
66 private int dataSize;
67 private ByteBuffer data;
68
69 PerfDataEntry(ByteBuffer b) {
70 entryStart = b.position();
71 entryLength = b.getInt();
72
73 // check for valid entry length
74 if (entryLength <= 0 || entryLength > b.limit()) {
75 throw new InstrumentationException("Invalid entry length: " +
76 " entryLength = " + entryLength);
77 }
78 // check if last entry occurs before the eof.
79 if ((entryStart + entryLength) > b.limit()) {
80 throw new InstrumentationException("Entry extends beyond end of buffer: " +
81 " entryStart = " + entryStart +
82 " entryLength = " + entryLength +
83 " buffer limit = " + b.limit());
84 }
85
86 b.position(entryStart + EntryFieldOffset.NAME_OFFSET);
87 int nameOffset = b.getInt();
88
89 if ((entryStart + nameOffset) > b.limit()) {
90 throw new InstrumentationException("Invalid name offset: " +
91 " entryStart = " + entryStart +
92 " nameOffset = " + nameOffset +
93 " buffer limit = " + b.limit());
94 }
95
96
97 b.position(entryStart + EntryFieldOffset.VECTOR_LENGTH);
98 vectorLength = b.getInt();
99
100 b.position(entryStart + EntryFieldOffset.DATA_TYPE);
101 dataType = PerfDataType.toPerfDataType(b.get());
102
103 b.position(entryStart + EntryFieldOffset.FLAGS);
104 flags = b.get();
105
106 b.position(entryStart + EntryFieldOffset.DATA_UNIT);
107 unit = Units.toUnits(b.get());
108
109 b.position(entryStart + EntryFieldOffset.DATA_VAR);
110 variability = Variability.toVariability(b.get());
111
112 b.position(entryStart + EntryFieldOffset.DATA_OFFSET);
113 dataOffset = b.getInt();
114
115 // read in the perfData item name, casting bytes to chars. skip the
116 // null terminator
117 b.position(entryStart + nameOffset);
118 // calculate the length of the name
119 int nameLength = 0;
120 byte c;
121 for (; (c = b.get()) != (byte)0; nameLength++);
122
123 byte[] symbolBytes = new byte[nameLength];
124 b.position(entryStart + nameOffset);
125 for (int i = 0; i < nameLength; i++) {
126 symbolBytes[i] = b.get();
127 }
128
129 // convert name into a String
130 try {
131 name = new String(symbolBytes, "UTF-8");
132 }
133 catch (UnsupportedEncodingException e) {
134 // should not reach here
135 // "UTF-8" is always a known encoding
136 throw new InternalError(e.getMessage());
137 }
138
139 if (variability == Variability.INVALID) {
140 throw new InstrumentationException("Invalid variability attribute:" +
141 " name = " + name);
142 }
143 if (unit == Units.INVALID) {
144 throw new InstrumentationException("Invalid units attribute: " +
145 " name = " + name);
146 }
147
148 if (vectorLength > 0) {
149 dataSize = vectorLength * dataType.size();
150 } else {
151 dataSize = dataType.size();
152 }
153
154 // check if data beyond the eof.
155 if ((entryStart + dataOffset + dataSize) > b.limit()) {
156 throw new InstrumentationException("Data extends beyond end of buffer: " +
157 " entryStart = " + entryStart +
158 " dataOffset = " + dataOffset+
159 " dataSize = " + dataSize +
160 " buffer limit = " + b.limit());
161 }
162 // Construct a ByteBuffer for the data
163 b.position(entryStart + dataOffset);
164 data = b.slice();
165 data.order(b.order());
166 data.limit(dataSize);
167 }
168
169
170 public int size() {
171 return entryLength;
172 }
173
174 public String name() {
175 return name;
176 }
177
178 public PerfDataType type() {
179 return dataType;
180 }
181
182 public Units units() {
183 return unit;
184 }
185
186 public int flags() {
187 return flags;
188 }
189
190 /**
191 * Returns the number of elements in the data.
192 */
193 public int vectorLength() {
194 return vectorLength;
195 }
196
197 public Variability variability() {
198 return variability;
199 }
200
201 public ByteBuffer byteData() {
202 data.position(0);
203 assert data.remaining() == vectorLength();
204 return data.duplicate();
205 }
206
207 public LongBuffer longData() {
208 LongBuffer lb = data.asLongBuffer();
209 return lb;
210 }
211}