1 /* 2 * Copyright (c) 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package jdk.vm.ci.hotspot; 24 25 import jdk.vm.ci.meta.DeoptimizationReason; 26 import jdk.vm.ci.meta.JavaMethodProfile; 27 import jdk.vm.ci.meta.JavaTypeProfile; 28 import jdk.vm.ci.meta.ProfilingInfo; 29 import jdk.vm.ci.meta.TriState; 30 31 public final class HotSpotProfilingInfo implements ProfilingInfo { 32 33 private final HotSpotMethodData methodData; 34 private final HotSpotResolvedJavaMethod method; 35 36 private boolean isMature; 37 private int position; 38 private int hintPosition; 39 private int hintBCI; 40 private HotSpotMethodDataAccessor dataAccessor; 41 42 private boolean includeNormal; 43 private boolean includeOSR; 44 45 public HotSpotProfilingInfo(HotSpotMethodData methodData, HotSpotResolvedJavaMethod method, boolean includeNormal, boolean includeOSR) { 46 this.methodData = methodData; 47 this.method = method; 48 this.includeNormal = includeNormal; 49 this.includeOSR = includeOSR; 50 this.isMature = methodData.isProfileMature(); 51 hintPosition = 0; 52 hintBCI = -1; 53 } 54 55 @Override 56 public int getCodeSize() { 57 return method.getCodeSize(); 58 } 59 60 public int getDecompileCount() { 61 return methodData.getDecompileCount(); 62 } 63 64 public int getOverflowRecompileCount() { 65 return methodData.getOverflowRecompileCount(); 66 } 67 68 public int getOverflowTrapCount() { 69 return methodData.getOverflowTrapCount(); 70 } 71 72 @Override 73 public JavaTypeProfile getTypeProfile(int bci) { 74 if (!isMature) { 75 return null; 76 } 77 findBCI(bci, false); 78 return dataAccessor.getTypeProfile(methodData, position); 79 } 80 81 @Override 82 public JavaMethodProfile getMethodProfile(int bci) { 83 if (!isMature) { 84 return null; 85 } 86 findBCI(bci, false); 87 return dataAccessor.getMethodProfile(methodData, position); 88 } 89 90 @Override 91 public double getBranchTakenProbability(int bci) { 92 if (!isMature) { 93 return -1; 94 } 95 findBCI(bci, false); 96 return dataAccessor.getBranchTakenProbability(methodData, position); 97 } 98 99 @Override 100 public double[] getSwitchProbabilities(int bci) { 101 if (!isMature) { 102 return null; 103 } 104 findBCI(bci, false); 105 return dataAccessor.getSwitchProbabilities(methodData, position); 106 } 107 108 @Override 109 public TriState getExceptionSeen(int bci) { 110 findBCI(bci, true); 111 return dataAccessor.getExceptionSeen(methodData, position); 112 } 113 114 @Override 115 public TriState getNullSeen(int bci) { 116 findBCI(bci, false); 117 return dataAccessor.getNullSeen(methodData, position); 118 } 119 120 @Override 121 public int getExecutionCount(int bci) { 122 if (!isMature) { 123 return -1; 124 } 125 findBCI(bci, false); 126 return dataAccessor.getExecutionCount(methodData, position); 127 } 128 129 @Override 130 public int getDeoptimizationCount(DeoptimizationReason reason) { 131 int count = 0; 132 if (includeNormal) { 133 count += methodData.getDeoptimizationCount(reason); 134 } 135 if (includeOSR) { 136 count += methodData.getOSRDeoptimizationCount(reason); 137 } 138 return count; 139 } 140 141 private void findBCI(int targetBCI, boolean searchExtraData) { 142 assert targetBCI >= 0 : "invalid BCI"; 143 144 if (methodData.hasNormalData()) { 145 int currentPosition = targetBCI < hintBCI ? 0 : hintPosition; 146 HotSpotMethodDataAccessor currentAccessor; 147 while ((currentAccessor = methodData.getNormalData(currentPosition)) != null) { 148 int currentBCI = currentAccessor.getBCI(methodData, currentPosition); 149 if (currentBCI == targetBCI) { 150 normalDataFound(currentAccessor, currentPosition, currentBCI); 151 return; 152 } else if (currentBCI > targetBCI) { 153 break; 154 } 155 currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition); 156 } 157 } 158 159 boolean exceptionPossiblyNotRecorded = false; 160 if (searchExtraData && methodData.hasExtraData()) { 161 int currentPosition = methodData.getExtraDataBeginOffset(); 162 HotSpotMethodDataAccessor currentAccessor; 163 while ((currentAccessor = methodData.getExtraData(currentPosition)) != null) { 164 int currentBCI = currentAccessor.getBCI(methodData, currentPosition); 165 if (currentBCI == targetBCI) { 166 extraDataFound(currentAccessor, currentPosition); 167 return; 168 } 169 currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition); 170 } 171 172 if (!methodData.isWithin(currentPosition)) { 173 exceptionPossiblyNotRecorded = true; 174 } 175 } 176 177 noDataFound(exceptionPossiblyNotRecorded); 178 } 179 180 private void normalDataFound(HotSpotMethodDataAccessor data, int pos, int bci) { 181 setCurrentData(data, pos); 182 this.hintPosition = position; 183 this.hintBCI = bci; 184 } 185 186 private void extraDataFound(HotSpotMethodDataAccessor data, int pos) { 187 setCurrentData(data, pos); 188 } 189 190 private void noDataFound(boolean exceptionPossiblyNotRecorded) { 191 HotSpotMethodDataAccessor accessor = HotSpotMethodData.getNoDataAccessor(exceptionPossiblyNotRecorded); 192 setCurrentData(accessor, -1); 193 } 194 195 private void setCurrentData(HotSpotMethodDataAccessor dataAccessor, int position) { 196 this.dataAccessor = dataAccessor; 197 this.position = position; 198 } 199 200 @Override 201 public boolean isMature() { 202 return isMature; 203 } 204 205 public void ignoreMature() { 206 isMature = true; 207 } 208 209 @Override 210 public String toString() { 211 return "HotSpotProfilingInfo<" + this.toString(null, "; ") + ">"; 212 } 213 214 @Override 215 public void setMature() { 216 isMature = true; 217 } 218 219 /** 220 * {@code MethodData::_jvmci_ir_size} (currently) supports at most one JVMCI compiler IR type 221 * which will be determined by the first JVMCI compiler that calls 222 * {@link #setCompilerIRSize(Class, int)}. 223 */ 224 private static volatile Class<?> supportedCompilerIRType; 225 226 @Override 227 public boolean setCompilerIRSize(Class<?> irType, int size) { 228 if (supportedCompilerIRType == null) { 229 synchronized (HotSpotProfilingInfo.class) { 230 if (supportedCompilerIRType == null) { 231 supportedCompilerIRType = irType; 232 } 233 } 234 } 235 if (supportedCompilerIRType != irType) { 236 return false; 237 } 238 methodData.setCompiledIRSize(size); 239 return true; 240 } 241 242 @Override 243 public int getCompilerIRSize(Class<?> irType) { 244 if (irType == supportedCompilerIRType) { 245 return methodData.getCompiledIRSize(); 246 } 247 return -1; 248 } 249 }