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