300 lines · 9.6 KB · Java
RawDownload
/* * 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;    }}