211 lines · 7.6 KB · Java
RawDownload
/* * Copyright (c) 2003, 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.management.counter.perf; import sun.management.counter.*;import java.nio.*;import java.io.UnsupportedEncodingException; class PerfDataEntry {    private class EntryFieldOffset {        private final static int SIZEOF_BYTE = 1;        private final static int SIZEOF_INT  = 4;        private final static int SIZEOF_LONG = 8;         private final static int ENTRY_LENGTH_SIZE    = SIZEOF_INT;        private final static int NAME_OFFSET_SIZE     = SIZEOF_INT;        private final static int VECTOR_LENGTH_SIZE   = SIZEOF_INT;        private final static int DATA_TYPE_SIZE       = SIZEOF_BYTE;        private final static int FLAGS_SIZE           = SIZEOF_BYTE;        private final static int DATA_UNIT_SIZE       = SIZEOF_BYTE;        private final static int DATA_VAR_SIZE        = SIZEOF_BYTE;        private final static int DATA_OFFSET_SIZE     = SIZEOF_INT;         final static int ENTRY_LENGTH  = 0;        final static int NAME_OFFSET   = ENTRY_LENGTH + ENTRY_LENGTH_SIZE;        final static int VECTOR_LENGTH = NAME_OFFSET + NAME_OFFSET_SIZE;;        final static int DATA_TYPE     = VECTOR_LENGTH + VECTOR_LENGTH_SIZE;        final static int FLAGS         = DATA_TYPE + DATA_TYPE_SIZE;        final static int DATA_UNIT     = FLAGS + FLAGS_SIZE;        final static int DATA_VAR      = DATA_UNIT + DATA_UNIT_SIZE;        final static int DATA_OFFSET   = DATA_VAR + DATA_VAR_SIZE;    }     private String       name;    private int          entryStart;    private int          entryLength;    private int          vectorLength;    private PerfDataType dataType;    private int          flags;    private Units        unit;    private Variability  variability;    private int          dataOffset;    private int          dataSize;    private ByteBuffer   data;     PerfDataEntry(ByteBuffer b) {        entryStart = b.position();        entryLength = b.getInt();         // check for valid entry length        if (entryLength <= 0 || entryLength > b.limit()) {            throw new InstrumentationException("Invalid entry length: " +                                               " entryLength = " + entryLength);        }        // check if last entry occurs before the eof.        if ((entryStart + entryLength) > b.limit()) {            throw new InstrumentationException("Entry extends beyond end of buffer: " +                                               " entryStart = " + entryStart +                                               " entryLength = " + entryLength +                                               " buffer limit = " + b.limit());        }         b.position(entryStart + EntryFieldOffset.NAME_OFFSET);        int nameOffset = b.getInt();         if ((entryStart + nameOffset) > b.limit()) {            throw new InstrumentationException("Invalid name offset: " +                                               " entryStart = " + entryStart +                                               " nameOffset = " + nameOffset +                                               " buffer limit = " + b.limit());        }          b.position(entryStart + EntryFieldOffset.VECTOR_LENGTH);        vectorLength = b.getInt();         b.position(entryStart + EntryFieldOffset.DATA_TYPE);        dataType = PerfDataType.toPerfDataType(b.get());         b.position(entryStart + EntryFieldOffset.FLAGS);        flags = b.get();         b.position(entryStart + EntryFieldOffset.DATA_UNIT);        unit = Units.toUnits(b.get());         b.position(entryStart + EntryFieldOffset.DATA_VAR);        variability = Variability.toVariability(b.get());         b.position(entryStart + EntryFieldOffset.DATA_OFFSET);        dataOffset = b.getInt();         // read in the perfData item name, casting bytes to chars. skip the        // null terminator        b.position(entryStart + nameOffset);        // calculate the length of the name        int nameLength = 0;        byte c;        for (; (c = b.get()) != (byte)0; nameLength++);         byte[] symbolBytes = new byte[nameLength];        b.position(entryStart + nameOffset);        for (int i = 0; i < nameLength; i++) {            symbolBytes[i] = b.get();        }         // convert name into a String        try {            name = new String(symbolBytes, "UTF-8");        }        catch (UnsupportedEncodingException e) {            // should not reach here            // "UTF-8" is always a known encoding            throw new InternalError(e.getMessage());        }         if (variability == Variability.INVALID) {            throw new InstrumentationException("Invalid variability attribute:" +                                               " name = " + name);        }        if (unit == Units.INVALID) {            throw new InstrumentationException("Invalid units attribute: " +                                               " name = " + name);        }         if (vectorLength > 0) {            dataSize = vectorLength * dataType.size();        } else {            dataSize = dataType.size();        }         // check if data beyond the eof.        if ((entryStart + dataOffset + dataSize) > b.limit()) {            throw new InstrumentationException("Data extends beyond end of buffer: " +                                               " entryStart = " + entryStart +                                               " dataOffset = " + dataOffset+                                               " dataSize = " + dataSize +                                               " buffer limit = " + b.limit());        }        // Construct a ByteBuffer for the data        b.position(entryStart + dataOffset);        data = b.slice();        data.order(b.order());        data.limit(dataSize);    }      public int size() {        return entryLength;    }     public String name() {        return name;    }     public PerfDataType type() {        return dataType;    }     public Units units() {        return unit;    }     public int flags() {        return flags;    }     /**     * Returns the number of elements in the data.     */    public int vectorLength() {        return vectorLength;    }     public Variability variability() {        return variability;    }     public ByteBuffer byteData() {        data.position(0);        assert data.remaining() == vectorLength();        return data.duplicate();    }     public LongBuffer longData() {        LongBuffer lb = data.asLongBuffer();        return lb;    }}