blob: 04ce79ad2e9525537e01cb6ff30698f6c0d575f4 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 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.jvmstat.perfdata.monitor;
27
28import sun.jvmstat.monitor.*;
29import java.nio.ByteOrder;
30import java.nio.ByteBuffer;
31import java.nio.IntBuffer;
32
33/**
34 * Abstraction representing the HotSpot PerfData instrumentation buffer
35 * header. This class represents only the fixed portion of the header.
36 * Version specific classes represent the portion of the header that
37 * may change from release to release.
38 * <p>
39 * The PerfDataBufferProlog class supports parsing of the following
40 * C structure:
41 * <pre>
42 * typedef struct {
43 * jint magic; // magic number - 0xcafec0c0
44 * jbyte byte_order; // byte order of the buffer
45 * jbyte major_version; // major and minor version numbers
46 * jbyte minor_version;
47 * jbyte reserved_byte1; // reserved - see concrete implementations for
48 * // possible definition.
49 * ... // remainder is handled by the subclasses.
50 * } PerfDataPrologue
51 * </pre>
52 *
53 * @author Brian Doherty
54 * @since 1.5
55 */
56public abstract class AbstractPerfDataBufferPrologue {
57
58 protected ByteBuffer byteBuffer;
59
60 /*
61 * the following constants must match the field offsets and sizes
62 * in the PerfDataPrologue structure in perfMemory.hpp
63 */
64 final static int PERFDATA_PROLOG_OFFSET=0;
65 final static int PERFDATA_PROLOG_MAGIC_OFFSET=0;
66 final static int PERFDATA_PROLOG_BYTEORDER_OFFSET=4;
67 final static int PERFDATA_PROLOG_BYTEORDER_SIZE=1; // sizeof(byte)
68 final static int PERFDATA_PROLOG_MAJOR_OFFSET=5;
69 final static int PERFDATA_PROLOG_MAJOR_SIZE=1; // sizeof(byte)
70 final static int PERFDATA_PROLOG_MINOR_OFFSET=6;
71 final static int PERFDATA_PROLOG_MINOR_SIZE=1; // sizeof(byte)
72 final static int PERFDATA_PROLOG_RESERVEDB1_OFFSET=7;
73 final static int PERFDATA_PROLOG_RESERVEDB1_SIZE=1; // sizeof(byte)
74
75 final static int PERFDATA_PROLOG_SIZE=8; // sizeof(struct PerfDataProlog)
76
77 // these constants should match their #define counterparts in perfMemory.hpp
78 final static byte PERFDATA_BIG_ENDIAN=0;
79 final static byte PERFDATA_LITTLE_ENDIAN=1;
80 final static int PERFDATA_MAGIC = 0xcafec0c0;
81
82 // names for counters that expose the prolog fields
83 public final static String PERFDATA_MAJOR_NAME =
84 "sun.perfdata.majorVersion";
85 public final static String PERFDATA_MINOR_NAME =
86 "sun.perfdata.minorVersion";
87
88 /**
89 * Construct a PerfDataBufferPrologue instance.
90 *
91 * @param byteBuffer buffer containing the instrumentation data
92 */
93 public AbstractPerfDataBufferPrologue(ByteBuffer byteBuffer)
94 throws MonitorException {
95 this.byteBuffer = byteBuffer.duplicate();
96
97 // the magic number is always stored in big-endian format
98 if (getMagic() != PERFDATA_MAGIC) {
99 throw new MonitorVersionException(
100 "Bad Magic: " + Integer.toHexString(getMagic()));
101 }
102
103 // set the byte order
104 this.byteBuffer.order(getByteOrder());
105 }
106
107 /**
108 * Get the magic number.
109 *
110 * @return int - the magic number
111 */
112 public int getMagic() {
113 // the magic number is always stored in big-endian format
114 ByteOrder order = byteBuffer.order();
115 byteBuffer.order(ByteOrder.BIG_ENDIAN);
116
117 // get the magic number
118 byteBuffer.position(PERFDATA_PROLOG_MAGIC_OFFSET);
119 int magic = byteBuffer.getInt();
120
121 // restore the byte order
122 byteBuffer.order(order);
123 return magic;
124 }
125
126 /**
127 * Get the byte order.
128 *
129 * @return int - the byte order of the instrumentation buffer
130 */
131 public ByteOrder getByteOrder() {
132 // byte order field is byte order independent
133 byteBuffer.position(PERFDATA_PROLOG_BYTEORDER_OFFSET);
134
135 byte byte_order = byteBuffer.get();
136
137 if (byte_order == PERFDATA_BIG_ENDIAN) {
138 return ByteOrder.BIG_ENDIAN;
139 } else {
140 return ByteOrder.LITTLE_ENDIAN;
141 }
142 }
143
144 /**
145 * Get the major version.
146 *
147 * @return int - the major version
148 */
149 public int getMajorVersion() {
150 // major version field is byte order independent
151 byteBuffer.position(PERFDATA_PROLOG_MAJOR_OFFSET);
152 return (int)byteBuffer.get();
153 }
154
155 /**
156 * Get the minor version.
157 *
158 * @return int - the minor version
159 */
160 public int getMinorVersion() {
161 // minor version field is byte order independent
162 byteBuffer.position(PERFDATA_PROLOG_MINOR_OFFSET);
163 return (int)byteBuffer.get();
164 }
165
166 /**
167 * Get the accessible flag. If supported, it indicates that the shared
168 * memory region is sufficiently initialized for client acccess.
169 *
170 * @return boolean - the initialized status
171 * @see #supportsAccessible()
172 */
173 public abstract boolean isAccessible();
174
175 /**
176 * Test if the accessible flag is supported by this version of
177 * the PerfDataBufferPrologue. Although not an abstract method, this
178 * method should be overridden by version specific subclasses.
179 *
180 * @return boolean - the initialized flag support status.
181 * @see #isAccessible()
182 */
183 public abstract boolean supportsAccessible();
184
185 /**
186 * Get the size of the header portion of the instrumentation buffer.
187 *
188 * @return int - the size of the header
189 */
190 public int getSize() {
191 return PERFDATA_PROLOG_SIZE; // sizeof(struct PerfDataProlog)
192 }
193
194 /**
195 * Return an IntBuffer that accesses the major version number.
196 * This is used to create a Monitor object for this value.
197 *
198 * @return IntBuffer - a ByteBuffer that accesses the major version number
199 * in the instrumentation buffer header.
200 */
201 public IntBuffer majorVersionBuffer() {
202 int[] holder = new int[1];
203 holder[0] = getMajorVersion();
204 IntBuffer ib = IntBuffer.wrap(holder);
205 ib.limit(1);
206 return ib;
207 }
208
209 /**
210 * Return an IntBuffer that accesses the minor version number.
211 * This is used to create a Monitor object for this value.
212 *
213 * @return IntBuffer - a ByteBuffer that accesses the minor version number
214 * in the instrumentation buffer header.
215 */
216 public IntBuffer minorVersionBuffer() {
217 int[] holder = new int[1];
218 holder[0] = getMinorVersion();
219 IntBuffer ib = IntBuffer.wrap(holder);
220 ib.limit(1);
221 return ib;
222 }
223
224 /**
225 * Get the magic number from the given byteBuffer.
226 *
227 * @return int - the magic number
228 */
229 public static int getMagic(ByteBuffer bb) {
230 // save buffer state
231 int position = bb.position();
232 ByteOrder order = bb.order();
233
234 // the magic number is always stored in big-endian format
235 bb.order(ByteOrder.BIG_ENDIAN);
236 bb.position(PERFDATA_PROLOG_MAGIC_OFFSET);
237 int magic = bb.getInt();
238
239 // restore buffer state.
240 bb.order(order);
241 bb.position(position);
242
243 return magic;
244 }
245
246 /**
247 * Get the major version number from the given ByteBuffer.
248 *
249 * @return int - the major version
250 */
251 public static int getMajorVersion(ByteBuffer bb) {
252 // save buffer state
253 int position = bb.position();
254
255 bb.position(PERFDATA_PROLOG_MAJOR_OFFSET);
256 int major = (int) bb.get();
257
258 // restore buffer state.
259 bb.position(position);
260
261 return major;
262 }
263
264 /**
265 * Get the minor version number from the given ByteBuffer.
266 *
267 * @return int - the minor version
268 */
269 public static int getMinorVersion(ByteBuffer bb) {
270 // save buffer state
271 int position = bb.position();
272
273 bb.position(PERFDATA_PROLOG_MINOR_OFFSET);
274 int minor = (int)bb.get();
275
276 // restore buffer state.
277 bb.position(position);
278
279 return minor;
280 }
281
282 /**
283 * Get the byte order for the given ByteBuffer.
284 *
285 * @return int - the byte order of the instrumentation buffer
286 */
287 public static ByteOrder getByteOrder(ByteBuffer bb) {
288 // save buffer state
289 int position = bb.position();
290
291 bb.position(PERFDATA_PROLOG_BYTEORDER_OFFSET);
292 ByteOrder order = (bb.get() == PERFDATA_BIG_ENDIAN)
293 ? ByteOrder.BIG_ENDIAN
294 : ByteOrder.LITTLE_ENDIAN;
295
296 // restore buffer state.
297 bb.position(position);
298 return order;
299 }
300}