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, HotSpotProxified { 32 33 // private static final DebugMetric metricInsufficentSpace = 34 // Debug.metric("InsufficientSpaceForProfilingData"); 35 36 private final HotSpotMethodData methodData; 37 private final HotSpotResolvedJavaMethod method; 38 39 private boolean isMature; 40 private int position; 41 private int hintPosition; 42 private int hintBCI; 43 private HotSpotMethodDataAccessor dataAccessor; 44 45 private boolean includeNormal; 46 private boolean includeOSR; 47 48 public HotSpotProfilingInfo(HotSpotMethodData methodData, HotSpotResolvedJavaMethod method, boolean includeNormal, boolean includeOSR) { 49 this.methodData = methodData; 50 this.method = method; 51 this.includeNormal = includeNormal; 52 this.includeOSR = includeOSR; 53 this.isMature = methodData.isProfileMature(); 54 hintPosition = 0; 55 hintBCI = -1; 56 } 57 58 @Override 59 public int getCodeSize() { 60 return method.getCodeSize(); 61 } 62 63 @Override 64 public JavaTypeProfile getTypeProfile(int bci) { 65 if (!isMature) { 66 return null; 67 } 68 findBCI(bci, false); 69 return dataAccessor.getTypeProfile(methodData, position); 70 } 71 72 @Override 73 public JavaMethodProfile getMethodProfile(int bci) { 74 if (!isMature) { 75 return null; 76 } 77 findBCI(bci, false); 78 return dataAccessor.getMethodProfile(methodData, position); 79 } 80 81 @Override 82 public double getBranchTakenProbability(int bci) { 83 if (!isMature) { 84 return -1; 85 } 86 findBCI(bci, false); 87 return dataAccessor.getBranchTakenProbability(methodData, position); 88 } 89 90 @Override 91 public double[] getSwitchProbabilities(int bci) { 92 if (!isMature) { 93 return null; 94 } 95 findBCI(bci, false); 96 return dataAccessor.getSwitchProbabilities(methodData, position); 97 } 98 99 @Override 100 public TriState getExceptionSeen(int bci) { 101 findBCI(bci, true); 102 return dataAccessor.getExceptionSeen(methodData, position); 103 } 104 105 @Override 106 public TriState getNullSeen(int bci) { 107 findBCI(bci, false); 108 return dataAccessor.getNullSeen(methodData, position); 109 } 110 111 @Override 112 public int getExecutionCount(int bci) { 113 if (!isMature) { 114 return -1; 115 } 116 findBCI(bci, false); 117 return dataAccessor.getExecutionCount(methodData, position); 118 } 119 120 @Override 121 public int getDeoptimizationCount(DeoptimizationReason reason) { 122 int count = 0; 123 if (includeNormal) { 124 count += methodData.getDeoptimizationCount(reason); 125 } 126 if (includeOSR) { 127 count += methodData.getOSRDeoptimizationCount(reason); 128 } 129 return count; 130 } 131 132 private void findBCI(int targetBCI, boolean searchExtraData) { 133 assert targetBCI >= 0 : "invalid BCI"; 134 135 if (methodData.hasNormalData()) { 136 int currentPosition = targetBCI < hintBCI ? 0 : hintPosition; 137 HotSpotMethodDataAccessor currentAccessor; 138 while ((currentAccessor = methodData.getNormalData(currentPosition)) != null) { 139 int currentBCI = currentAccessor.getBCI(methodData, currentPosition); 140 if (currentBCI == targetBCI) { 141 normalDataFound(currentAccessor, currentPosition, currentBCI); 142 return; 143 } else if (currentBCI > targetBCI) { 144 break; 145 } 146 currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition); 147 } 148 } 149 150 boolean exceptionPossiblyNotRecorded = false; 151 if (searchExtraData && methodData.hasExtraData()) { 152 int currentPosition = methodData.getExtraDataBeginOffset(); 153 HotSpotMethodDataAccessor currentAccessor; 154 while ((currentAccessor = methodData.getExtraData(currentPosition)) != null) { 155 int currentBCI = currentAccessor.getBCI(methodData, currentPosition); 156 if (currentBCI == targetBCI) { 157 extraDataFound(currentAccessor, currentPosition); 158 return; 159 } 160 currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition); 161 } 162 163 if (!methodData.isWithin(currentPosition)) { 164 exceptionPossiblyNotRecorded = true; 165 // metricInsufficentSpace.increment(); 166 } 167 } 168 169 noDataFound(exceptionPossiblyNotRecorded); 170 } 171 172 private void normalDataFound(HotSpotMethodDataAccessor data, int pos, int bci) { 173 setCurrentData(data, pos); 174 this.hintPosition = position; 175 this.hintBCI = bci; 176 } 177 178 private void extraDataFound(HotSpotMethodDataAccessor data, int pos) { 179 setCurrentData(data, pos); 180 } 181 182 private void noDataFound(boolean exceptionPossiblyNotRecorded) { 183 HotSpotMethodDataAccessor accessor = HotSpotMethodData.getNoDataAccessor(exceptionPossiblyNotRecorded); 184 setCurrentData(accessor, -1); 185 } 186 187 private void setCurrentData(HotSpotMethodDataAccessor dataAccessor, int position) { 188 this.dataAccessor = dataAccessor; 189 this.position = position; 190 } 191 192 @Override 193 public boolean isMature() { 194 return isMature; 195 } 196 197 public void ignoreMature() { 198 isMature = true; 199 } 200 201 @Override 202 public String toString() { 203 return "HotSpotProfilingInfo<" + this.toString(null, "; ") + ">"; 204 } 205 206 @Override 207 public void setMature() { 208 isMature = true; 209 } 210 211 /** 212 * {@code MethodData::_jvmci_ir_size} (currently) supports at most one JVMCI compiler IR type 213 * which will be determined by the first JVMCI compiler that calls 214 * {@link #setCompilerIRSize(Class, int)}. 215 */ 216 private static volatile Class<?> supportedCompilerIRType; 217 218 @Override 219 public boolean setCompilerIRSize(Class<?> irType, int size) { 220 if (supportedCompilerIRType == null) { 221 synchronized (HotSpotProfilingInfo.class) { 222 if (supportedCompilerIRType == null) { 223 supportedCompilerIRType = irType; 224 } 225 } 226 } 227 if (supportedCompilerIRType != irType) { 228 return false; 229 } 230 methodData.setCompiledIRSize(size); 231 return true; 232 } 233 234 @Override 235 public int getCompilerIRSize(Class<?> irType) { 236 if (irType == supportedCompilerIRType) { 237 return methodData.getCompiledIRSize(); 238 } 239 return -1; 240 } 241 }