feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,616 @@
/*
* Copyright (c) 2004, 2010, 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.v2_0;
import sun.jvmstat.monitor.*;
import sun.jvmstat.perfdata.monitor.*;
import java.util.*;
import java.util.regex.*;
import java.nio.*;
/**
* The concrete implementation of version 2.0 of the HotSpot PerfData
* Instrumentation buffer. This class is responsible for parsing the
* instrumentation memory and constructing the necessary objects to
* represent and access the instrumentation objects contained in the
* memory buffer.
* <p>
* The structure of the 2.0 entry is defined in struct PerfDataEnry
* as decsribed in perfMemory.hpp. This structure looks like:
* <pre>
* typedef struct {
* jint entry_length; // entry length in bytes
* jint name_offset; // offset to entry name, relative to start
* // of entry
* jint vector_length; // length of the vector. If 0, then scalar.
* jbyte data_type; // JNI field descriptor type
* jbyte flags; // miscellaneous attribute flags
* // 0x01 - supported
* jbyte data_units; // unit of measure attribute
* jbyte data_variability; // variability attribute
* jbyte data_offset; // offset to data item, relative to start
* // of entry.
* } PerfDataEntry;
* </pre>
*
* @author Brian Doherty
* @since 1.5
* @see AbstractPerfDataBuffer
*/
public class PerfDataBuffer extends PerfDataBufferImpl {
private static final boolean DEBUG = false;
private static final int syncWaitMs =
Integer.getInteger("sun.jvmstat.perdata.syncWaitMs", 5000);
private static final ArrayList EMPTY_LIST = new ArrayList(0);
/*
* These are primarily for documentary purposes and the match up
* with the PerfDataEntry structure in perfMemory.hpp. They are
* generally unused in this code, but they are kept consistent with
* the data structure just in case some unforseen need arrises.
*/
private final static int PERFDATA_ENTRYLENGTH_OFFSET=0;
private final static int PERFDATA_ENTRYLENGTH_SIZE=4; // sizeof(int)
private final static int PERFDATA_NAMEOFFSET_OFFSET=4;
private final static int PERFDATA_NAMEOFFSET_SIZE=4; // sizeof(int)
private final static int PERFDATA_VECTORLENGTH_OFFSET=8;
private final static int PERFDATA_VECTORLENGTH_SIZE=4; // sizeof(int)
private final static int PERFDATA_DATATYPE_OFFSET=12;
private final static int PERFDATA_DATATYPE_SIZE=1; // sizeof(byte)
private final static int PERFDATA_FLAGS_OFFSET=13;
private final static int PERFDATA_FLAGS_SIZE=1; // sizeof(byte)
private final static int PERFDATA_DATAUNITS_OFFSET=14;
private final static int PERFDATA_DATAUNITS_SIZE=1; // sizeof(byte)
private final static int PERFDATA_DATAVAR_OFFSET=15;
private final static int PERFDATA_DATAVAR_SIZE=1; // sizeof(byte)
private final static int PERFDATA_DATAOFFSET_OFFSET=16;
private final static int PERFDATA_DATAOFFSET_SIZE=4; // sizeof(int)
PerfDataBufferPrologue prologue;
int nextEntry;
long lastNumEntries;
IntegerMonitor overflow;
ArrayList<Monitor> insertedMonitors;
/**
* Construct a PerfDataBuffer instance.
* <p>
* This class is dynamically loaded by
* {@link AbstractPerfDataBuffer#createPerfDataBuffer}, and this
* constructor is called to instantiate the instance.
*
* @param buffer the buffer containing the instrumentation data
* @param lvmid the Local Java Virtual Machine Identifier for this
* instrumentation buffer.
*/
public PerfDataBuffer(ByteBuffer buffer, int lvmid)
throws MonitorException {
super(buffer, lvmid);
prologue = new PerfDataBufferPrologue(buffer);
this.buffer.order(prologue.getByteOrder());
}
/**
* {@inheritDoc}
*/
protected void buildMonitorMap(Map<String, Monitor> map) throws MonitorException {
assert Thread.holdsLock(this);
// start at the beginning of the buffer
buffer.rewind();
// create pseudo monitors
buildPseudoMonitors(map);
// wait for the target JVM to indicate that it's intrumentation
// buffer is safely accessible
synchWithTarget();
// parse the currently defined entries starting at the first entry.
nextEntry = prologue.getEntryOffset();
// record the number of entries before parsing the structure
int numEntries = prologue.getNumEntries();
// start parsing
Monitor monitor = getNextMonitorEntry();
while (monitor != null) {
map.put(monitor.getName(), monitor);
monitor = getNextMonitorEntry();
}
/*
* keep track of the current number of entries in the shared
* memory for new entry detection purposes. It's possible for
* the data structure to be modified while the Map is being
* built and the entry count in the header might change while
* we are parsing it. The map will contain all the counters
* found, but the number recorded in numEntries might be small
* than what than the number we actually parsed (due to asynchronous
* updates). This discrepency is handled by ignoring any re-parsed
* entries when updating the Map in getNewMonitors().
*/
lastNumEntries = numEntries;
// keep track of the monitors just added.
insertedMonitors = new ArrayList<Monitor>(map.values());
}
/**
* {@inheritDoc}
*/
protected void getNewMonitors(Map<String, Monitor> map) throws MonitorException {
assert Thread.holdsLock(this);
int numEntries = prologue.getNumEntries();
if (numEntries > lastNumEntries) {
lastNumEntries = numEntries;
Monitor monitor = getNextMonitorEntry();
while (monitor != null) {
String name = monitor.getName();
// guard against re-parsed entries
if (!map.containsKey(name)) {
map.put(name, monitor);
if (insertedMonitors != null) {
insertedMonitors.add(monitor);
}
}
monitor = getNextMonitorEntry();
}
}
}
/**
* {@inheritDoc}
*/
protected MonitorStatus getMonitorStatus(Map<String, Monitor> map) throws MonitorException {
assert Thread.holdsLock(this);
assert insertedMonitors != null;
// load any new monitors
getNewMonitors(map);
// current implementation doesn't support deletion of reuse of entries
ArrayList removed = EMPTY_LIST;
ArrayList inserted = insertedMonitors;
insertedMonitors = new ArrayList<Monitor>();
return new MonitorStatus(inserted, removed);
}
/**
* Build the pseudo monitors used to map the prolog data into counters.
*/
protected void buildPseudoMonitors(Map<String, Monitor> map) {
Monitor monitor = null;
String name = null;
IntBuffer ib = null;
name = PerfDataBufferPrologue.PERFDATA_MAJOR_NAME;
ib = prologue.majorVersionBuffer();
monitor = new PerfIntegerMonitor(name, Units.NONE,
Variability.CONSTANT, false, ib);
map.put(name, monitor);
name = PerfDataBufferPrologue.PERFDATA_MINOR_NAME;
ib = prologue.minorVersionBuffer();
monitor = new PerfIntegerMonitor(name, Units.NONE,
Variability.CONSTANT, false, ib);
map.put(name, monitor);
name = PerfDataBufferPrologue.PERFDATA_BUFFER_SIZE_NAME;
ib = prologue.sizeBuffer();
monitor = new PerfIntegerMonitor(name, Units.BYTES,
Variability.MONOTONIC, false, ib);
map.put(name, monitor);
name = PerfDataBufferPrologue.PERFDATA_BUFFER_USED_NAME;
ib = prologue.usedBuffer();
monitor = new PerfIntegerMonitor(name, Units.BYTES,
Variability.MONOTONIC, false, ib);
map.put(name, monitor);
name = PerfDataBufferPrologue.PERFDATA_OVERFLOW_NAME;
ib = prologue.overflowBuffer();
monitor = new PerfIntegerMonitor(name, Units.BYTES,
Variability.MONOTONIC, false, ib);
map.put(name, monitor);
this.overflow = (IntegerMonitor)monitor;
name = PerfDataBufferPrologue.PERFDATA_MODTIMESTAMP_NAME;
LongBuffer lb = prologue.modificationTimeStampBuffer();
monitor = new PerfLongMonitor(name, Units.TICKS,
Variability.MONOTONIC, false, lb);
map.put(name, monitor);
}
/**
* Method that waits until the target jvm indicates that
* its shared memory is safe to access.
*/
protected void synchWithTarget() throws MonitorException {
/*
* synch must happen with syncWaitMs from now. Default is 5 seconds,
* which is reasonabally generous and should provide for extreme
* situations like startup delays due to allocation of large ISM heaps.
*/
long timeLimit = System.currentTimeMillis() + syncWaitMs;
// loop waiting for the accessible indicater to be non-zero
log("synchWithTarget: " + lvmid + " ");
while (!prologue.isAccessible()) {
log(".");
// give the target jvm a chance to complete initializatoin
try { Thread.sleep(20); } catch (InterruptedException e) { }
if (System.currentTimeMillis() > timeLimit) {
logln("failed: " + lvmid);
throw new MonitorException("Could not synchronize with target");
}
}
logln("success: " + lvmid);
}
/**
* method to extract the next monitor entry from the instrumentation memory.
* assumes that nextEntry is the offset into the byte array
* at which to start the search for the next entry. method leaves
* next entry pointing to the next entry or to the end of data.
*/
protected Monitor getNextMonitorEntry() throws MonitorException {
Monitor monitor = null;
// entries are always 4 byte aligned.
if ((nextEntry % 4) != 0) {
throw new MonitorStructureException(
"Misaligned entry index: "
+ Integer.toHexString(nextEntry));
}
// protect againt a corrupted shard memory region.
if ((nextEntry < 0) || (nextEntry > buffer.limit())) {
throw new MonitorStructureException(
"Entry index out of bounds: "
+ Integer.toHexString(nextEntry)
+ ", limit = " + Integer.toHexString(buffer.limit()));
}
// check for end of the buffer
if (nextEntry == buffer.limit()) {
logln("getNextMonitorEntry():"
+ " nextEntry == buffer.limit(): returning");
return null;
}
buffer.position(nextEntry);
int entryStart = buffer.position();
int entryLength = buffer.getInt();
// check for valid entry length
if ((entryLength < 0) || (entryLength > buffer.limit())) {
throw new MonitorStructureException(
"Invalid entry length: entryLength = " + entryLength
+ " (0x" + Integer.toHexString(entryLength) + ")");
}
// check if last entry occurs before the eof.
if ((entryStart + entryLength) > buffer.limit()) {
throw new MonitorStructureException(
"Entry extends beyond end of buffer: "
+ " entryStart = 0x" + Integer.toHexString(entryStart)
+ " entryLength = 0x" + Integer.toHexString(entryLength)
+ " buffer limit = 0x" + Integer.toHexString(buffer.limit()));
}
if (entryLength == 0) {
// end of data
return null;
}
// we can safely read this entry
int nameOffset = buffer.getInt();
int vectorLength = buffer.getInt();
byte typeCodeByte = buffer.get();
byte flags = buffer.get();
byte unitsByte = buffer.get();
byte varByte = buffer.get();
int dataOffset = buffer.getInt();
dump_entry_fixed(entryStart, nameOffset, vectorLength, typeCodeByte,
flags, unitsByte, varByte, dataOffset);
// convert common attributes to their object types
Units units = Units.toUnits(unitsByte);
Variability variability = Variability.toVariability(varByte);
TypeCode typeCode = null;
boolean supported = (flags & 0x01) != 0;
try {
typeCode = TypeCode.toTypeCode(typeCodeByte);
} catch (IllegalArgumentException e) {
throw new MonitorStructureException(
"Illegal type code encountered:"
+ " entry_offset = 0x" + Integer.toHexString(nextEntry)
+ ", type_code = " + Integer.toHexString(typeCodeByte));
}
// verify that the name_offset is contained within the entry bounds
if (nameOffset > entryLength) {
throw new MonitorStructureException(
"Field extends beyond entry bounds"
+ " entry_offset = 0x" + Integer.toHexString(nextEntry)
+ ", name_offset = 0x" + Integer.toHexString(nameOffset));
}
// verify that the data_offset is contained within the entry bounds
if (dataOffset > entryLength) {
throw new MonitorStructureException(
"Field extends beyond entry bounds:"
+ " entry_offset = 0x" + Integer.toHexString(nextEntry)
+ ", data_offset = 0x" + Integer.toHexString(dataOffset));
}
// validate the variability and units fields
if (variability == Variability.INVALID) {
throw new MonitorDataException(
"Invalid variability attribute:"
+ " entry_offset = 0x" + Integer.toHexString(nextEntry)
+ ", variability = 0x" + Integer.toHexString(varByte));
}
if (units == Units.INVALID) {
throw new MonitorDataException(
"Invalid units attribute: entry_offset = 0x"
+ Integer.toHexString(nextEntry)
+ ", units = 0x" + Integer.toHexString(unitsByte));
}
// the entry looks good - parse the variable length components
/*
* The name starts at nameOffset and continues up to the first null
* byte. however, we don't know the length, but we can approximate it
* without searching for the null by using the offset for the data
* field, which follows the name field.
*/
assert (buffer.position() == (entryStart + nameOffset));
assert (dataOffset > nameOffset);
// include possible pad space
int maxNameLength = dataOffset-nameOffset;
// maxNameLength better be less than the total entry length
assert (maxNameLength < entryLength);
// collect the characters, but do not collect the null byte,
// as the String(byte[]) constructor does not ignore it!
byte[] nameBytes = new byte[maxNameLength];
int nameLength = 0;
byte b;
while (((b = buffer.get()) != 0) && (nameLength < maxNameLength)) {
nameBytes[nameLength++] = b;
}
assert (nameLength < maxNameLength);
// we should before or at the start of the data field
assert (buffer.position() <= (entryStart + dataOffset));
// convert the name bytes into a String
String name = new String(nameBytes, 0, nameLength);
/*
* compute the size of the data item - this includes pad
* characters used to align the next entry.
*/
int dataSize = entryLength - dataOffset;
// set the position to the start of the data item
buffer.position(entryStart + dataOffset);
dump_entry_variable(name, buffer, dataSize);
if (vectorLength == 0) {
// create a scalar Monitor object
if (typeCode == TypeCode.LONG) {
LongBuffer lb = buffer.asLongBuffer();
lb.limit(1); // limit buffer size to one long value.
monitor = new PerfLongMonitor(name, units, variability,
supported, lb);
} else {
/*
* unexpected type code - coding error or uncoordinated
* JVM change
*/
throw new MonitorTypeException(
"Unexpected type code encountered:"
+ " entry_offset = 0x" + Integer.toHexString(nextEntry)
+ ", name = " + name
+ ", type_code = " + typeCode
+ " (0x" + Integer.toHexString(typeCodeByte) + ")");
}
} else {
// create a vector Monitor object
if (typeCode == TypeCode.BYTE) {
if (units != Units.STRING) {
// only byte arrays of type STRING are currently supported
throw new MonitorTypeException(
"Unexpected vector type encounterd:"
+ " entry_offset = "
+ Integer.toHexString(nextEntry)
+ ", name = " + name
+ ", type_code = " + typeCode + " (0x"
+ Integer.toHexString(typeCodeByte) + ")"
+ ", units = " + units + " (0x"
+ Integer.toHexString(unitsByte) + ")");
}
ByteBuffer bb = buffer.slice();
bb.limit(vectorLength); // limit buffer length to # of chars
if (variability == Variability.CONSTANT) {
monitor = new PerfStringConstantMonitor(name, supported,
bb);
} else if (variability == Variability.VARIABLE) {
monitor = new PerfStringVariableMonitor(name, supported,
bb, vectorLength-1);
} else if (variability == Variability.MONOTONIC) {
// Monotonically increasing byte arrays are not supported
throw new MonitorDataException(
"Unexpected variability attribute:"
+ " entry_offset = 0x"
+ Integer.toHexString(nextEntry)
+ " name = " + name
+ ", variability = " + variability + " (0x"
+ Integer.toHexString(varByte) + ")");
} else {
// variability was validated above, so this unexpected
assert false;
}
} else {
// coding error or uncoordinated JVM change
throw new MonitorTypeException(
"Unexpected type code encountered:"
+ " entry_offset = 0x"
+ Integer.toHexString(nextEntry)
+ ", name = " + name
+ ", type_code = " + typeCode + " (0x"
+ Integer.toHexString(typeCodeByte) + ")");
}
}
// setup index to next entry for next iteration of the loop.
nextEntry = entryStart + entryLength;
return monitor;
}
/**
* Method to dump debugging information
*/
private void dumpAll(Map<String, Monitor> map, int lvmid) {
if (DEBUG) {
Set<String> keys = map.keySet();
System.err.println("Dump for " + lvmid);
int j = 0;
for (Iterator i = keys.iterator(); i.hasNext(); j++) {
Monitor monitor = map.get(i.next());
System.err.println(j + "\t" + monitor.getName()
+ "=" + monitor.getValue());
}
System.err.println("nextEntry = " + nextEntry);
System.err.println("Buffer info:");
System.err.println("buffer = " + buffer);
}
}
/**
* Method to dump the fixed portion of an entry.
*/
private void dump_entry_fixed(int entry_start, int nameOffset,
int vectorLength, byte typeCodeByte,
byte flags, byte unitsByte, byte varByte,
int dataOffset) {
if (DEBUG) {
System.err.println("Entry at offset: 0x"
+ Integer.toHexString(entry_start));
System.err.println("\tname_offset = 0x"
+ Integer.toHexString(nameOffset));
System.err.println("\tvector_length = 0x"
+ Integer.toHexString(vectorLength));
System.err.println("\tdata_type = 0x"
+ Integer.toHexString(typeCodeByte));
System.err.println("\tflags = 0x"
+ Integer.toHexString(flags));
System.err.println("\tdata_units = 0x"
+ Integer.toHexString(unitsByte));
System.err.println("\tdata_variability = 0x"
+ Integer.toHexString(varByte));
System.err.println("\tdata_offset = 0x"
+ Integer.toHexString(dataOffset));
}
}
private void dump_entry_variable(String name, ByteBuffer bb, int size) {
if (DEBUG) {
char[] toHex = new char[] { '0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'a', 'b',
'c', 'd', 'e', 'f' };
ByteBuffer data = bb.slice();
data.limit(size);
System.err.println("\tname = " + name);
System.err.println("\tdata = ");
int count=0;
while (data.hasRemaining()) {
byte b = data.get();
byte high = (byte)((b >> 8) & 0x0f);
byte low = (byte)(b & 0x0f);
if (count % 16 == 0) {
System.err.print("\t\t" + Integer.toHexString(count / 16)
+ ": ");
}
System.err.print(String.valueOf(toHex[high])
+ String.valueOf(toHex[low]));
count++;
if (count % 16 == 0) {
System.err.println();
} else {
System.err.print(" ");
}
}
if (count % 16 != 0) {
System.err.println();
}
}
}
private void logln(String s) {
if (DEBUG) {
System.err.println(s);
}
}
private void log(String s) {
if (DEBUG) {
System.err.print(s);
}
}
}

View File

@@ -0,0 +1,257 @@
/*
* 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.v2_0;
import sun.jvmstat.monitor.*;
import sun.jvmstat.perfdata.monitor.*;
import java.nio.*;
/**
* Class representing the 2.0 version of the HotSpot PerfData instrumentation
* buffer header.
* <p>
* The PerfDataBufferPrologue class supports parsing of the version
* specific portions of the PerfDataPrologue C structure:
* <pre>
* typedef struct {
* ... // handled by superclass
* jint used; // number of PerfData memory bytes used
* jint overflow; // number of bytes of overflow
* jlong mod_time_stamp; // time stamp of the last structural modification
* jint entry_offset; // offset of the first PerfDataEntry
* jint num_entries; // number of allocated PerfData entries
* } PerfDataPrologue
* </pre>
*
* @author Brian Doherty
* @since 1.5
*/
public class PerfDataBufferPrologue extends AbstractPerfDataBufferPrologue {
private final static int SUPPORTED_MAJOR_VERSION = 2;
private final static int SUPPORTED_MINOR_VERSION = 0;
/*
* the following constants must match the field offsets and sizes
* in the PerfDataPrologue structure in perfMemory.hpp. offsets are
* relative to the start of the PerfDataPrologue structure.
*
* note that PERFDATA_PROLOG_ACCESSIBLE_OFFSET redefines
* PERFDATA_PROLOG_RESERVEDB1_OFFSET from AbstractPerfDataBufferPrologue.
*/
final static int PERFDATA_PROLOG_ACCESSIBLE_OFFSET=7;
final static int PERFDATA_PROLOG_ACCESSIBLE_SIZE=1; // sizeof(byte)
final static int PERFDATA_PROLOG_USED_OFFSET=8;
final static int PERFDATA_PROLOG_USED_SIZE=4; // sizeof(int)
final static int PERFDATA_PROLOG_OVERFLOW_OFFSET=12;
final static int PERFDATA_PROLOG_OVERFLOW_SIZE=4; // sizeof(int)
final static int PERFDATA_PROLOG_MODTIMESTAMP_OFFSET=16;
final static int PERFDATA_PROLOG_MODTIMESTAMP_SIZE=8; // sizeof(long)
final static int PERFDATA_PROLOG_ENTRYOFFSET_OFFSET=24;
final static int PERFDATA_PROLOG_ENTRYOFFSET_SIZE=4; // sizeof(int)
final static int PERFDATA_PROLOG_NUMENTRIES_OFFSET=28;
final static int PERFDATA_PROLOG_NUMENTRIES_SIZE=4; // sizeof(int)
final static int PERFDATA_PROLOG_SIZE=32; // sizeof(struct PerfDataProlog)
// names for counters that expose prologue fields
final static String PERFDATA_BUFFER_SIZE_NAME = "sun.perfdata.size";
final static String PERFDATA_BUFFER_USED_NAME = "sun.perfdata.used";
final static String PERFDATA_OVERFLOW_NAME = "sun.perfdata.overflow";
final static String PERFDATA_MODTIMESTAMP_NAME = "sun.perfdata.timestamp";
final static String PERFDATA_NUMENTRIES_NAME = "sun.perfdata.entries";
/**
* Create an instance of PerfDataBufferPrologue from the given
* ByteBuffer object.
*
* @param byteBuffer the buffer containing the binary header data
*/
public PerfDataBufferPrologue(ByteBuffer byteBuffer)
throws MonitorException {
super(byteBuffer);
assert ((getMajorVersion() == 2) && (getMinorVersion() == 0));
}
/**
* {@inheritDoc}
*/
public boolean supportsAccessible() {
return true;
}
/**
* {@inheritDoc}
*/
public boolean isAccessible() {
assert supportsAccessible();
byteBuffer.position(PERFDATA_PROLOG_ACCESSIBLE_OFFSET);
byte value = byteBuffer.get();
return value != 0;
}
/**
* Get the utilization of the instrumentation memory buffer.
*
* @return int - the utilization of the buffer
*/
public int getUsed() {
byteBuffer.position(PERFDATA_PROLOG_USED_OFFSET);
return byteBuffer.getInt();
}
/**
* Get the size of the instrumentation memory buffer.
*
* @return int - the size of the buffer
*/
public int getBufferSize() {
return byteBuffer.capacity();
}
/**
* Get the buffer overflow amount. This value is non-zero if the
* HotSpot JVM has overflowed the instrumentation memory buffer.
* The target JVM can be restarted with -XX:PerfDataMemSize=X to
* create a larger memory buffer.
*
* @return int - the size of the buffer
*/
public int getOverflow() {
byteBuffer.position(PERFDATA_PROLOG_OVERFLOW_OFFSET);
return byteBuffer.getInt();
}
/**
* Get the time of last modification for the instrumentation
* memory buffer. This method returns the time, as ticks since the
* start of the target JVM, of the last structural modification to
* the instrumentation buffer. Structural modifications correspond to
* the addition or deletion of instrumentation objects. Updates to
* counter values are not structural modifications.
*/
public long getModificationTimeStamp() {
byteBuffer.position(PERFDATA_PROLOG_MODTIMESTAMP_OFFSET);
return byteBuffer.getLong();
}
/**
* Get the offset of the first PerfDataEntry.
*/
public int getEntryOffset() {
byteBuffer.position(PERFDATA_PROLOG_ENTRYOFFSET_OFFSET);
return byteBuffer.getInt();
}
/**
* Get the offset of the first PerfDataEntry.
*/
public int getNumEntries() {
byteBuffer.position(PERFDATA_PROLOG_NUMENTRIES_OFFSET);
return byteBuffer.getInt();
}
/**
* {@inheritDoc}
*/
public int getSize() {
return PERFDATA_PROLOG_SIZE; // sizeof(struct PerfDataProlog)
}
/**
* Return an IntBuffer that accesses the used value. This is used
* to create a Monitor object for this value.
*
* @return IntBuffer - a ByteBuffer that accesses the used value
* in the instrumentation buffer header.
* @see #getUsed()
*/
IntBuffer usedBuffer() {
byteBuffer.position(PERFDATA_PROLOG_USED_OFFSET);
IntBuffer ib = byteBuffer.asIntBuffer();
ib.limit(1);
return ib;
}
/**
* Return an IntBuffer that accesses the size value. This is used
* to create a Monitor object for this value.
*
* @return IntBuffer - a ByteBuffer that accesses the size value
* in the instrumentation buffer header.
* @see #getBufferSize()
*/
IntBuffer sizeBuffer() {
IntBuffer ib = IntBuffer.allocate(1);
ib.put(byteBuffer.capacity());
return ib;
}
/**
* Return an IntBuffer that accesses the overflow value. This is used
* to create a Monitor object for this value.
*
* @return IntBuffer - a ByteBuffer that accesses the overflow value
* in the instrumentation buffer header.
* @see #getOverflow()
*/
IntBuffer overflowBuffer() {
byteBuffer.position(PERFDATA_PROLOG_OVERFLOW_OFFSET);
IntBuffer ib = byteBuffer.asIntBuffer();
ib.limit(1);
return ib;
}
/**
* Return a LongBuffer that accesses the modification timestamp value.
* This is used to create a Monitor object for this value.
*
* @return LongBuffer - a ByteBuffer that accesses the modification time
* stamp value in the instrumentation buffer header.
* @see #getModificationTimeStamp()
*/
LongBuffer modificationTimeStampBuffer() {
byteBuffer.position(PERFDATA_PROLOG_MODTIMESTAMP_OFFSET);
LongBuffer lb = byteBuffer.asLongBuffer();
lb.limit(1);
return lb;
}
/**
* Return an IntBuffer that accesses the number of entries value.
* This is used to create a Monitor object for this value.
*
* @return LongBuffer - a ByteBuffer that accesses the num_entries
* value in the instrumentation buffer header.
* @see #getNumEntries()
*/
IntBuffer numEntriesBuffer() {
byteBuffer.position(PERFDATA_PROLOG_NUMENTRIES_OFFSET);
IntBuffer ib = byteBuffer.asIntBuffer();
ib.limit(1);
return ib;
}
}

View File

@@ -0,0 +1,110 @@
/*
* 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.v2_0;
/**
* A typesafe enumeration for describing standard Java type codes.
*
* @author Brian Doherty
* @since 1.5
*/
public class TypeCode {
private final String name;
private final char value;
public static final TypeCode BOOLEAN = new TypeCode("boolean", 'Z');
public static final TypeCode CHAR = new TypeCode("char", 'C');
public static final TypeCode FLOAT = new TypeCode("float", 'F');
public static final TypeCode DOUBLE = new TypeCode("double", 'D');
public static final TypeCode BYTE = new TypeCode("byte", 'B');
public static final TypeCode SHORT = new TypeCode("short", 'S');
public static final TypeCode INT = new TypeCode("int", 'I');
public static final TypeCode LONG = new TypeCode("long", 'J');
public static final TypeCode OBJECT = new TypeCode("object", 'L');
public static final TypeCode ARRAY = new TypeCode("array", '[');
public static final TypeCode VOID = new TypeCode("void", 'V');
private static TypeCode basicTypes[] = {
LONG, BYTE, BOOLEAN, CHAR, FLOAT, DOUBLE,
SHORT, INT, OBJECT, ARRAY, VOID
};
/**
* Convert enumeration value to a String.
*
* @return String - the string representation for the enumeration.
*/
public String toString() {
return name;
}
/**
* Convert enumeration to its character representation.
*
* @return int - the integer representation for the enumeration.
*/
public int toChar() {
return value;
}
/**
* Map a character value to its corresponding TypeCode object.
*
* @param c an character representing a Java TypeCode
* @return TypeCode - The TypeCode enumeration object for the given
* character.
* @throws IllegalArgumentException Thrown if <code>c</code> is not
* a valid Java TypeCode.
*/
public static TypeCode toTypeCode(char c) {
for (int j = 0; j < basicTypes.length; j++) {
if (basicTypes[j].value == c) {
return (basicTypes[j]);
}
}
throw new IllegalArgumentException();
}
/**
* Map a character value to its corresponding TypeCode object.
*
* @param b a byte representing a Java TypeCode. This value is
* converted into a char and used to find the corresponding
* TypeCode.
* @return TypeCode - The TypeCode enumeration object for the given byte.
* @throws IllegalArgumentException Thrown if <code>v</code> is not
* a valid Java TypeCode.
*/
public static TypeCode toTypeCode(byte b) {
return toTypeCode((char)b);
}
private TypeCode(String name, char value) {
this.name = name;
this.value = value;
}
}