001/* 002 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package jdk.internal.jvmci.hotspot; 024 025import jdk.internal.jvmci.meta.*; 026 027public final class HotSpotProfilingInfo implements ProfilingInfo, HotSpotProxified { 028 029 // private static final DebugMetric metricInsufficentSpace = 030 // Debug.metric("InsufficientSpaceForProfilingData"); 031 032 private final HotSpotMethodData methodData; 033 private final HotSpotResolvedJavaMethod method; 034 035 private boolean isMature; 036 private int position; 037 private int hintPosition; 038 private int hintBCI; 039 private HotSpotMethodDataAccessor dataAccessor; 040 041 private boolean includeNormal; 042 private boolean includeOSR; 043 044 public HotSpotProfilingInfo(HotSpotMethodData methodData, HotSpotResolvedJavaMethod method, boolean includeNormal, boolean includeOSR) { 045 this.methodData = methodData; 046 this.method = method; 047 this.includeNormal = includeNormal; 048 this.includeOSR = includeOSR; 049 this.isMature = methodData.isProfileMature(); 050 hintPosition = 0; 051 hintBCI = -1; 052 } 053 054 @Override 055 public int getCodeSize() { 056 return method.getCodeSize(); 057 } 058 059 @Override 060 public JavaTypeProfile getTypeProfile(int bci) { 061 if (!isMature) { 062 return null; 063 } 064 findBCI(bci, false); 065 return dataAccessor.getTypeProfile(methodData, position); 066 } 067 068 @Override 069 public JavaMethodProfile getMethodProfile(int bci) { 070 if (!isMature) { 071 return null; 072 } 073 findBCI(bci, false); 074 return dataAccessor.getMethodProfile(methodData, position); 075 } 076 077 @Override 078 public double getBranchTakenProbability(int bci) { 079 if (!isMature) { 080 return -1; 081 } 082 findBCI(bci, false); 083 return dataAccessor.getBranchTakenProbability(methodData, position); 084 } 085 086 @Override 087 public double[] getSwitchProbabilities(int bci) { 088 if (!isMature) { 089 return null; 090 } 091 findBCI(bci, false); 092 return dataAccessor.getSwitchProbabilities(methodData, position); 093 } 094 095 @Override 096 public TriState getExceptionSeen(int bci) { 097 findBCI(bci, true); 098 return dataAccessor.getExceptionSeen(methodData, position); 099 } 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}