1 /* 2 * Copyright (c) 2004, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.jvmstat.perfdata.monitor.v2_0; 27 28 import sun.jvmstat.monitor.*; 29 import sun.jvmstat.perfdata.monitor.*; 30 import java.nio.*; 31 32 /** 33 * Class representing the 2.0 version of the HotSpot PerfData instrumentation 34 * buffer header. 35 * <p> 36 * The PerfDataBufferPrologue class supports parsing of the version 37 * specific portions of the PerfDataPrologue C structure: 38 * <pre> 39 * typedef struct { 40 * ... // handled by superclass 41 * jint used; // number of PerfData memory bytes used 42 * jint overflow; // number of bytes of overflow 43 * jlong mod_time_stamp; // time stamp of the last structural modification 44 * jint entry_offset; // offset of the first PerfDataEntry 45 * jint num_entries; // number of allocated PerfData entries 46 * } PerfDataPrologue 47 * </pre> 48 * 49 * @author Brian Doherty 50 * @since 1.5 51 */ 52 public class PerfDataBufferPrologue extends AbstractPerfDataBufferPrologue { 53 54 private final static int SUPPORTED_MAJOR_VERSION = 2; 55 private final static int SUPPORTED_MINOR_VERSION = 0; 56 57 /* 58 * the following constants must match the field offsets and sizes 59 * in the PerfDataPrologue structure in perfMemory.hpp. offsets are 60 * relative to the start of the PerfDataPrologue structure. 61 * 62 * note that PERFDATA_PROLOG_ACCESSIBLE_OFFSET redefines 63 * PERFDATA_PROLOG_RESERVEDB1_OFFSET from AbstractPerfDataBufferPrologue. 64 */ 65 final static int PERFDATA_PROLOG_ACCESSIBLE_OFFSET=7; 66 final static int PERFDATA_PROLOG_ACCESSIBLE_SIZE=1; // sizeof(byte) 67 final static int PERFDATA_PROLOG_USED_OFFSET=8; 68 final static int PERFDATA_PROLOG_USED_SIZE=4; // sizeof(int) 69 final static int PERFDATA_PROLOG_OVERFLOW_OFFSET=12; 70 final static int PERFDATA_PROLOG_OVERFLOW_SIZE=4; // sizeof(int) 71 final static int PERFDATA_PROLOG_MODTIMESTAMP_OFFSET=16; 72 final static int PERFDATA_PROLOG_MODTIMESTAMP_SIZE=8; // sizeof(long) 73 final static int PERFDATA_PROLOG_ENTRYOFFSET_OFFSET=24; 74 final static int PERFDATA_PROLOG_ENTRYOFFSET_SIZE=4; // sizeof(int) 75 final static int PERFDATA_PROLOG_NUMENTRIES_OFFSET=28; 76 final static int PERFDATA_PROLOG_NUMENTRIES_SIZE=4; // sizeof(int) 77 78 final static int PERFDATA_PROLOG_SIZE=32; // sizeof(struct PerfDataProlog) 79 80 // names for counters that expose prologue fields 81 final static String PERFDATA_BUFFER_SIZE_NAME = "sun.perfdata.size"; 82 final static String PERFDATA_BUFFER_USED_NAME = "sun.perfdata.used"; 83 final static String PERFDATA_OVERFLOW_NAME = "sun.perfdata.overflow"; 84 final static String PERFDATA_MODTIMESTAMP_NAME = "sun.perfdata.timestamp"; 85 final static String PERFDATA_NUMENTRIES_NAME = "sun.perfdata.entries"; 86 87 /** 88 * Create an instance of PerfDataBufferPrologue from the given 89 * ByteBuffer object. 90 * 91 * @param byteBuffer the buffer containing the binary header data 92 */ PerfDataBufferPrologue(ByteBuffer byteBuffer)93 public PerfDataBufferPrologue(ByteBuffer byteBuffer) 94 throws MonitorException { 95 super(byteBuffer); 96 assert ((getMajorVersion() == 2) && (getMinorVersion() == 0)); 97 } 98 99 /** 100 * {@inheritDoc} 101 */ supportsAccessible()102 public boolean supportsAccessible() { 103 return true; 104 } 105 106 /** 107 * {@inheritDoc} 108 */ isAccessible()109 public boolean isAccessible() { 110 assert supportsAccessible(); 111 byteBuffer.position(PERFDATA_PROLOG_ACCESSIBLE_OFFSET); 112 byte value = byteBuffer.get(); 113 return value != 0; 114 } 115 116 /** 117 * Get the utilization of the instrumentation memory buffer. 118 * 119 * @return int - the utilization of the buffer 120 */ getUsed()121 public int getUsed() { 122 byteBuffer.position(PERFDATA_PROLOG_USED_OFFSET); 123 return byteBuffer.getInt(); 124 } 125 126 /** 127 * Get the size of the instrumentation memory buffer. 128 * 129 * @return int - the size of the buffer 130 */ getBufferSize()131 public int getBufferSize() { 132 return byteBuffer.capacity(); 133 } 134 135 /** 136 * Get the buffer overflow amount. This value is non-zero if the 137 * HotSpot JVM has overflowed the instrumentation memory buffer. 138 * The target JVM can be restarted with -XX:PerfDataMemSize=X to 139 * create a larger memory buffer. 140 * 141 * @return int - the size of the buffer 142 */ getOverflow()143 public int getOverflow() { 144 byteBuffer.position(PERFDATA_PROLOG_OVERFLOW_OFFSET); 145 return byteBuffer.getInt(); 146 } 147 148 /** 149 * Get the time of last modification for the instrumentation 150 * memory buffer. This method returns the time, as ticks since the 151 * start of the target JVM, of the last structural modification to 152 * the instrumentation buffer. Structural modifications correspond to 153 * the addition or deletion of instrumentation objects. Updates to 154 * counter values are not structural modifications. 155 */ getModificationTimeStamp()156 public long getModificationTimeStamp() { 157 byteBuffer.position(PERFDATA_PROLOG_MODTIMESTAMP_OFFSET); 158 return byteBuffer.getLong(); 159 } 160 161 /** 162 * Get the offset of the first PerfDataEntry. 163 */ getEntryOffset()164 public int getEntryOffset() { 165 byteBuffer.position(PERFDATA_PROLOG_ENTRYOFFSET_OFFSET); 166 return byteBuffer.getInt(); 167 } 168 169 /** 170 * Get the offset of the first PerfDataEntry. 171 */ getNumEntries()172 public int getNumEntries() { 173 byteBuffer.position(PERFDATA_PROLOG_NUMENTRIES_OFFSET); 174 return byteBuffer.getInt(); 175 } 176 177 /** 178 * {@inheritDoc} 179 */ getSize()180 public int getSize() { 181 return PERFDATA_PROLOG_SIZE; // sizeof(struct PerfDataProlog) 182 } 183 184 /** 185 * Return an IntBuffer that accesses the used value. This is used 186 * to create a Monitor object for this value. 187 * 188 * @return IntBuffer - a ByteBuffer that accesses the used value 189 * in the instrumentation buffer header. 190 * @see #getUsed() 191 */ usedBuffer()192 IntBuffer usedBuffer() { 193 byteBuffer.position(PERFDATA_PROLOG_USED_OFFSET); 194 IntBuffer ib = byteBuffer.asIntBuffer(); 195 ib.limit(1); 196 return ib; 197 } 198 199 /** 200 * Return an IntBuffer that accesses the size value. This is used 201 * to create a Monitor object for this value. 202 * 203 * @return IntBuffer - a ByteBuffer that accesses the size value 204 * in the instrumentation buffer header. 205 * @see #getBufferSize() 206 */ sizeBuffer()207 IntBuffer sizeBuffer() { 208 IntBuffer ib = IntBuffer.allocate(1); 209 ib.put(byteBuffer.capacity()); 210 return ib; 211 } 212 213 /** 214 * Return an IntBuffer that accesses the overflow value. This is used 215 * to create a Monitor object for this value. 216 * 217 * @return IntBuffer - a ByteBuffer that accesses the overflow value 218 * in the instrumentation buffer header. 219 * @see #getOverflow() 220 */ overflowBuffer()221 IntBuffer overflowBuffer() { 222 byteBuffer.position(PERFDATA_PROLOG_OVERFLOW_OFFSET); 223 IntBuffer ib = byteBuffer.asIntBuffer(); 224 ib.limit(1); 225 return ib; 226 } 227 228 /** 229 * Return a LongBuffer that accesses the modification timestamp value. 230 * This is used to create a Monitor object for this value. 231 * 232 * @return LongBuffer - a ByteBuffer that accesses the modification time 233 * stamp value in the instrumentation buffer header. 234 * @see #getModificationTimeStamp() 235 */ modificationTimeStampBuffer()236 LongBuffer modificationTimeStampBuffer() { 237 byteBuffer.position(PERFDATA_PROLOG_MODTIMESTAMP_OFFSET); 238 LongBuffer lb = byteBuffer.asLongBuffer(); 239 lb.limit(1); 240 return lb; 241 } 242 243 /** 244 * Return an IntBuffer that accesses the number of entries value. 245 * This is used to create a Monitor object for this value. 246 * 247 * @return LongBuffer - a ByteBuffer that accesses the num_entries 248 * value in the instrumentation buffer header. 249 * @see #getNumEntries() 250 */ numEntriesBuffer()251 IntBuffer numEntriesBuffer() { 252 byteBuffer.position(PERFDATA_PROLOG_NUMENTRIES_OFFSET); 253 IntBuffer ib = byteBuffer.asIntBuffer(); 254 ib.limit(1); 255 return ib; 256 } 257 } 258