/* * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */package sun.jvmstat.perfdata.monitor;import sun.jvmstat.monitor.*;import java.nio.ByteOrder;import java.nio.ByteBuffer;import java.nio.IntBuffer;/** * Abstraction representing the HotSpot PerfData instrumentation buffer * header. This class represents only the fixed portion of the header. * Version specific classes represent the portion of the header that * may change from release to release. * <p> * The PerfDataBufferProlog class supports parsing of the following * C structure: * <pre> * typedef struct { * jint magic; // magic number - 0xcafec0c0 * jbyte byte_order; // byte order of the buffer * jbyte major_version; // major and minor version numbers * jbyte minor_version; * jbyte reserved_byte1; // reserved - see concrete implementations for * // possible definition. * ... // remainder is handled by the subclasses. * } PerfDataPrologue * </pre> * * @author Brian Doherty * @since 1.5 */public abstract class AbstractPerfDataBufferPrologue { protected ByteBuffer byteBuffer; /* * the following constants must match the field offsets and sizes * in the PerfDataPrologue structure in perfMemory.hpp */ final static int PERFDATA_PROLOG_OFFSET=0; final static int PERFDATA_PROLOG_MAGIC_OFFSET=0; final static int PERFDATA_PROLOG_BYTEORDER_OFFSET=4; final static int PERFDATA_PROLOG_BYTEORDER_SIZE=1; // sizeof(byte) final static int PERFDATA_PROLOG_MAJOR_OFFSET=5; final static int PERFDATA_PROLOG_MAJOR_SIZE=1; // sizeof(byte) final static int PERFDATA_PROLOG_MINOR_OFFSET=6; final static int PERFDATA_PROLOG_MINOR_SIZE=1; // sizeof(byte) final static int PERFDATA_PROLOG_RESERVEDB1_OFFSET=7; final static int PERFDATA_PROLOG_RESERVEDB1_SIZE=1; // sizeof(byte) final static int PERFDATA_PROLOG_SIZE=8; // sizeof(struct PerfDataProlog) // these constants should match their #define counterparts in perfMemory.hpp final static byte PERFDATA_BIG_ENDIAN=0; final static byte PERFDATA_LITTLE_ENDIAN=1; final static int PERFDATA_MAGIC = 0xcafec0c0; // names for counters that expose the prolog fields public final static String PERFDATA_MAJOR_NAME = "sun.perfdata.majorVersion"; public final static String PERFDATA_MINOR_NAME = "sun.perfdata.minorVersion"; /** * Construct a PerfDataBufferPrologue instance. * * @param byteBuffer buffer containing the instrumentation data */ public AbstractPerfDataBufferPrologue(ByteBuffer byteBuffer) throws MonitorException { this.byteBuffer = byteBuffer.duplicate(); // the magic number is always stored in big-endian format if (getMagic() != PERFDATA_MAGIC) { throw new MonitorVersionException( "Bad Magic: " + Integer.toHexString(getMagic())); } // set the byte order this.byteBuffer.order(getByteOrder()); } /** * Get the magic number. * * @return int - the magic number */ public int getMagic() { // the magic number is always stored in big-endian format ByteOrder order = byteBuffer.order(); byteBuffer.order(ByteOrder.BIG_ENDIAN); // get the magic number byteBuffer.position(PERFDATA_PROLOG_MAGIC_OFFSET); int magic = byteBuffer.getInt(); // restore the byte order byteBuffer.order(order); return magic; } /** * Get the byte order. * * @return int - the byte order of the instrumentation buffer */ public ByteOrder getByteOrder() { // byte order field is byte order independent byteBuffer.position(PERFDATA_PROLOG_BYTEORDER_OFFSET); byte byte_order = byteBuffer.get(); if (byte_order == PERFDATA_BIG_ENDIAN) { return ByteOrder.BIG_ENDIAN; } else { return ByteOrder.LITTLE_ENDIAN; } } /** * Get the major version. * * @return int - the major version */ public int getMajorVersion() { // major version field is byte order independent byteBuffer.position(PERFDATA_PROLOG_MAJOR_OFFSET); return (int)byteBuffer.get(); } /** * Get the minor version. * * @return int - the minor version */ public int getMinorVersion() { // minor version field is byte order independent byteBuffer.position(PERFDATA_PROLOG_MINOR_OFFSET); return (int)byteBuffer.get(); } /** * Get the accessible flag. If supported, it indicates that the shared * memory region is sufficiently initialized for client acccess. * * @return boolean - the initialized status * @see #supportsAccessible() */ public abstract boolean isAccessible(); /** * Test if the accessible flag is supported by this version of * the PerfDataBufferPrologue. Although not an abstract method, this * method should be overridden by version specific subclasses. * * @return boolean - the initialized flag support status. * @see #isAccessible() */ public abstract boolean supportsAccessible(); /** * Get the size of the header portion of the instrumentation buffer. * * @return int - the size of the header */ public int getSize() { return PERFDATA_PROLOG_SIZE; // sizeof(struct PerfDataProlog) } /** * Return an IntBuffer that accesses the major version number. * This is used to create a Monitor object for this value. * * @return IntBuffer - a ByteBuffer that accesses the major version number * in the instrumentation buffer header. */ public IntBuffer majorVersionBuffer() { int[] holder = new int[1]; holder[0] = getMajorVersion(); IntBuffer ib = IntBuffer.wrap(holder); ib.limit(1); return ib; } /** * Return an IntBuffer that accesses the minor version number. * This is used to create a Monitor object for this value. * * @return IntBuffer - a ByteBuffer that accesses the minor version number * in the instrumentation buffer header. */ public IntBuffer minorVersionBuffer() { int[] holder = new int[1]; holder[0] = getMinorVersion(); IntBuffer ib = IntBuffer.wrap(holder); ib.limit(1); return ib; } /** * Get the magic number from the given byteBuffer. * * @return int - the magic number */ public static int getMagic(ByteBuffer bb) { // save buffer state int position = bb.position(); ByteOrder order = bb.order(); // the magic number is always stored in big-endian format bb.order(ByteOrder.BIG_ENDIAN); bb.position(PERFDATA_PROLOG_MAGIC_OFFSET); int magic = bb.getInt(); // restore buffer state. bb.order(order); bb.position(position); return magic; } /** * Get the major version number from the given ByteBuffer. * * @return int - the major version */ public static int getMajorVersion(ByteBuffer bb) { // save buffer state int position = bb.position(); bb.position(PERFDATA_PROLOG_MAJOR_OFFSET); int major = (int) bb.get(); // restore buffer state. bb.position(position); return major; } /** * Get the minor version number from the given ByteBuffer. * * @return int - the minor version */ public static int getMinorVersion(ByteBuffer bb) { // save buffer state int position = bb.position(); bb.position(PERFDATA_PROLOG_MINOR_OFFSET); int minor = (int)bb.get(); // restore buffer state. bb.position(position); return minor; } /** * Get the byte order for the given ByteBuffer. * * @return int - the byte order of the instrumentation buffer */ public static ByteOrder getByteOrder(ByteBuffer bb) { // save buffer state int position = bb.position(); bb.position(PERFDATA_PROLOG_BYTEORDER_OFFSET); ByteOrder order = (bb.get() == PERFDATA_BIG_ENDIAN) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; // restore buffer state. bb.position(position); return order; }}
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.jvmstat.perfdata.monitor;
import sun.jvmstat.monitor.*;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
/**
* Abstraction representing the HotSpot PerfData instrumentation buffer
* header. This class represents only the fixed portion of the header.
* Version specific classes represent the portion of the header that
* may change from release to release.
* <p>
* The PerfDataBufferProlog class supports parsing of the following
* C structure:
* <pre>
* typedef struct {
* jint magic; // magic number - 0xcafec0c0
* jbyte byte_order; // byte order of the buffer
* jbyte major_version; // major and minor version numbers
* jbyte minor_version;
* jbyte reserved_byte1; // reserved - see concrete implementations for
* // possible definition.
* ... // remainder is handled by the subclasses.
* } PerfDataPrologue
* </pre>
*
* @author Brian Doherty
* @since 1.5
*/
public abstract class AbstractPerfDataBufferPrologue {
protected ByteBuffer byteBuffer;
/*
* the following constants must match the field offsets and sizes
* in the PerfDataPrologue structure in perfMemory.hpp
*/
final static int PERFDATA_PROLOG_OFFSET=0;
final static int PERFDATA_PROLOG_MAGIC_OFFSET=0;
final static int PERFDATA_PROLOG_BYTEORDER_OFFSET=4;
final static int PERFDATA_PROLOG_BYTEORDER_SIZE=1; // sizeof(byte)
final static int PERFDATA_PROLOG_MAJOR_OFFSET=5;
final static int PERFDATA_PROLOG_MAJOR_SIZE=1; // sizeof(byte)
final static int PERFDATA_PROLOG_MINOR_OFFSET=6;
final static int PERFDATA_PROLOG_MINOR_SIZE=1; // sizeof(byte)
final static int PERFDATA_PROLOG_RESERVEDB1_OFFSET=7;
final static int PERFDATA_PROLOG_RESERVEDB1_SIZE=1; // sizeof(byte)
final static int PERFDATA_PROLOG_SIZE=8; // sizeof(struct PerfDataProlog)
// these constants should match their #define counterparts in perfMemory.hpp
final static byte PERFDATA_BIG_ENDIAN=0;
final static byte PERFDATA_LITTLE_ENDIAN=1;
final static int PERFDATA_MAGIC = 0xcafec0c0;
// names for counters that expose the prolog fields
public final static String PERFDATA_MAJOR_NAME =
"sun.perfdata.majorVersion";
public final static String PERFDATA_MINOR_NAME =
"sun.perfdata.minorVersion";
/**
* Construct a PerfDataBufferPrologue instance.
*
* @param byteBuffer buffer containing the instrumentation data
*/
public AbstractPerfDataBufferPrologue(ByteBuffer byteBuffer)
throws MonitorException {
this.byteBuffer = byteBuffer.duplicate();
// the magic number is always stored in big-endian format
if (getMagic() != PERFDATA_MAGIC) {
throw new MonitorVersionException(
"Bad Magic: " + Integer.toHexString(getMagic()));
}
// set the byte order
this.byteBuffer.order(getByteOrder());
}
/**
* Get the magic number.
*
* @return int - the magic number
*/
public int getMagic() {
// the magic number is always stored in big-endian format
ByteOrder order = byteBuffer.order();
byteBuffer.order(ByteOrder.BIG_ENDIAN);
// get the magic number
byteBuffer.position(PERFDATA_PROLOG_MAGIC_OFFSET);
int magic = byteBuffer.getInt();
// restore the byte order
byteBuffer.order(order);
return magic;
}
/**
* Get the byte order.
*
* @return int - the byte order of the instrumentation buffer
*/
public ByteOrder getByteOrder() {
// byte order field is byte order independent
byteBuffer.position(PERFDATA_PROLOG_BYTEORDER_OFFSET);
byte byte_order = byteBuffer.get();
if (byte_order == PERFDATA_BIG_ENDIAN) {
return ByteOrder.BIG_ENDIAN;
} else {
return ByteOrder.LITTLE_ENDIAN;
}
}
/**
* Get the major version.
*
* @return int - the major version
*/
public int getMajorVersion() {
// major version field is byte order independent
byteBuffer.position(PERFDATA_PROLOG_MAJOR_OFFSET);
return (int)byteBuffer.get();
}
/**
* Get the minor version.
*
* @return int - the minor version
*/
public int getMinorVersion() {
// minor version field is byte order independent
byteBuffer.position(PERFDATA_PROLOG_MINOR_OFFSET);
return (int)byteBuffer.get();
}
/**
* Get the accessible flag. If supported, it indicates that the shared
* memory region is sufficiently initialized for client acccess.
*
* @return boolean - the initialized status
* @see #supportsAccessible()
*/
public abstract boolean isAccessible();
/**
* Test if the accessible flag is supported by this version of
* the PerfDataBufferPrologue. Although not an abstract method, this
* method should be overridden by version specific subclasses.
*
* @return boolean - the initialized flag support status.
* @see #isAccessible()
*/
public abstract boolean supportsAccessible();
/**
* Get the size of the header portion of the instrumentation buffer.
*
* @return int - the size of the header
*/
public int getSize() {
return PERFDATA_PROLOG_SIZE; // sizeof(struct PerfDataProlog)
}
/**
* Return an IntBuffer that accesses the major version number.
* This is used to create a Monitor object for this value.
*
* @return IntBuffer - a ByteBuffer that accesses the major version number
* in the instrumentation buffer header.
*/
public IntBuffer majorVersionBuffer() {
int[] holder = new int[1];
holder[0] = getMajorVersion();
IntBuffer ib = IntBuffer.wrap(holder);
ib.limit(1);
return ib;
}
/**
* Return an IntBuffer that accesses the minor version number.
* This is used to create a Monitor object for this value.
*
* @return IntBuffer - a ByteBuffer that accesses the minor version number
* in the instrumentation buffer header.
*/
public IntBuffer minorVersionBuffer() {
int[] holder = new int[1];
holder[0] = getMinorVersion();
IntBuffer ib = IntBuffer.wrap(holder);
ib.limit(1);
return ib;
}
/**
* Get the magic number from the given byteBuffer.
*
* @return int - the magic number
*/
public static int getMagic(ByteBuffer bb) {
// save buffer state
int position = bb.position();
ByteOrder order = bb.order();
// the magic number is always stored in big-endian format
bb.order(ByteOrder.BIG_ENDIAN);
bb.position(PERFDATA_PROLOG_MAGIC_OFFSET);
int magic = bb.getInt();
// restore buffer state.
bb.order(order);
bb.position(position);
return magic;
}
/**
* Get the major version number from the given ByteBuffer.
*
* @return int - the major version
*/
public static int getMajorVersion(ByteBuffer bb) {
// save buffer state
int position = bb.position();
bb.position(PERFDATA_PROLOG_MAJOR_OFFSET);
int major = (int) bb.get();
// restore buffer state.
bb.position(position);
return major;
}
/**
* Get the minor version number from the given ByteBuffer.
*
* @return int - the minor version
*/
public static int getMinorVersion(ByteBuffer bb) {
// save buffer state
int position = bb.position();
bb.position(PERFDATA_PROLOG_MINOR_OFFSET);
int minor = (int)bb.get();
// restore buffer state.
bb.position(position);
return minor;
}
/**
* Get the byte order for the given ByteBuffer.
*
* @return int - the byte order of the instrumentation buffer
*/
public static ByteOrder getByteOrder(ByteBuffer bb) {
// save buffer state
int position = bb.position();
bb.position(PERFDATA_PROLOG_BYTEORDER_OFFSET);
ByteOrder order = (bb.get() == PERFDATA_BIG_ENDIAN)
? ByteOrder.BIG_ENDIAN
: ByteOrder.LITTLE_ENDIAN;
// restore buffer state.
bb.position(position);
return order;
}
}