1 /* 2 * Copyright (c) 2003, 2012, 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.management.counter.perf; 27 28 import sun.management.counter.*; 29 import java.nio.*; 30 import java.util.*; 31 import java.util.regex.*; 32 33 public class PerfInstrumentation { 34 private ByteBuffer buffer; 35 private Prologue prologue; 36 private long lastModificationTime; 37 private long lastUsed; 38 private int nextEntry; 39 private SortedMap<String, Counter> map; 40 PerfInstrumentation(ByteBuffer b)41 public PerfInstrumentation(ByteBuffer b) { 42 prologue = new Prologue(b); 43 buffer = b; 44 buffer.order(prologue.getByteOrder()); 45 46 // Check recognized versions 47 int major = getMajorVersion(); 48 int minor = getMinorVersion(); 49 50 // Support only 2.0 version 51 if (major < 2) { 52 throw new InstrumentationException("Unsupported version: " + 53 major + "." + minor); 54 } 55 rewind(); 56 } 57 getMajorVersion()58 public int getMajorVersion() { 59 return prologue.getMajorVersion(); 60 } 61 getMinorVersion()62 public int getMinorVersion() { 63 return prologue.getMinorVersion(); 64 } 65 getModificationTimeStamp()66 public long getModificationTimeStamp() { 67 return prologue.getModificationTimeStamp(); 68 } 69 rewind()70 void rewind() { 71 // rewind to the first entry 72 buffer.rewind(); 73 buffer.position(prologue.getEntryOffset()); 74 nextEntry = buffer.position(); 75 // rebuild all the counters 76 map = new TreeMap<>(); 77 } 78 hasNext()79 boolean hasNext() { 80 return (nextEntry < prologue.getUsed()); 81 } 82 getNextCounter()83 Counter getNextCounter() { 84 if (! hasNext()) { 85 return null; 86 } 87 88 if ((nextEntry % 4) != 0) { 89 // entries are always 4 byte aligned. 90 throw new InstrumentationException( 91 "Entry index not properly aligned: " + nextEntry); 92 } 93 94 if (nextEntry < 0 || nextEntry > buffer.limit()) { 95 // defensive check to protect against a corrupted shared memory region. 96 throw new InstrumentationException( 97 "Entry index out of bounds: nextEntry = " + nextEntry + 98 ", limit = " + buffer.limit()); 99 } 100 101 buffer.position(nextEntry); 102 PerfDataEntry entry = new PerfDataEntry(buffer); 103 nextEntry = nextEntry + entry.size(); 104 105 Counter counter = null; 106 PerfDataType type = entry.type(); 107 if (type == PerfDataType.BYTE) { 108 if (entry.units() == Units.STRING && entry.vectorLength() > 0) { 109 counter = new PerfStringCounter(entry.name(), 110 entry.variability(), 111 entry.flags(), 112 entry.vectorLength(), 113 entry.byteData()); 114 } else if (entry.vectorLength() > 0) { 115 counter = new PerfByteArrayCounter(entry.name(), 116 entry.units(), 117 entry.variability(), 118 entry.flags(), 119 entry.vectorLength(), 120 entry.byteData()); 121 } else { 122 // ByteArrayCounter must have vectorLength > 0 123 assert false; 124 } 125 } 126 else if (type == PerfDataType.LONG) { 127 if (entry.vectorLength() == 0) { 128 counter = new PerfLongCounter(entry.name(), 129 entry.units(), 130 entry.variability(), 131 entry.flags(), 132 entry.longData()); 133 } else { 134 counter = new PerfLongArrayCounter(entry.name(), 135 entry.units(), 136 entry.variability(), 137 entry.flags(), 138 entry.vectorLength(), 139 entry.longData()); 140 } 141 } 142 else { 143 // FIXME: Should we throw an exception for unsupported type? 144 // Currently skip such entry 145 assert false; 146 } 147 return counter; 148 } 149 getAllCounters()150 public synchronized List<Counter> getAllCounters() { 151 while (hasNext()) { 152 Counter c = getNextCounter(); 153 if (c != null) { 154 map.put(c.getName(), c); 155 } 156 } 157 return new ArrayList<>(map.values()); 158 } 159 findByPattern(String patternString)160 public synchronized List<Counter> findByPattern(String patternString) { 161 while (hasNext()) { 162 Counter c = getNextCounter(); 163 if (c != null) { 164 map.put(c.getName(), c); 165 } 166 } 167 168 Pattern pattern = Pattern.compile(patternString); 169 Matcher matcher = pattern.matcher(""); 170 List<Counter> matches = new ArrayList<>(); 171 172 173 for (Map.Entry<String,Counter> me: map.entrySet()) { 174 String name = me.getKey(); 175 176 // apply pattern to counter name 177 matcher.reset(name); 178 179 // if the pattern matches, then add Counter to list 180 if (matcher.lookingAt()) { 181 matches.add(me.getValue()); 182 } 183 } 184 return matches; 185 } 186 } 187