|
1 | 1 | /* |
2 | | - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | 4 | * |
5 | 5 | * This code is free software; you can redistribute it and/or modify it |
|
22 | 22 | */ |
23 | 23 | package jdk.vm.ci.hotspot; |
24 | 24 |
|
25 | | -import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; |
26 | | - |
27 | | -import jdk.vm.ci.meta.DeoptimizationReason; |
28 | | -import jdk.vm.ci.meta.JavaMethodProfile; |
29 | | -import jdk.vm.ci.meta.JavaTypeProfile; |
30 | 25 | import jdk.vm.ci.meta.ProfilingInfo; |
31 | | -import jdk.vm.ci.meta.TriState; |
32 | | - |
33 | | -final class HotSpotProfilingInfo implements ProfilingInfo { |
34 | | - |
35 | | - private final HotSpotMethodData methodData; |
36 | | - private final HotSpotResolvedJavaMethod method; |
37 | | - |
38 | | - private boolean isMature; |
39 | | - private int position; |
40 | | - private int hintPosition; |
41 | | - private int hintBCI; |
42 | | - private HotSpotMethodDataAccessor dataAccessor; |
43 | | - |
44 | | - private boolean includeNormal; |
45 | | - private boolean includeOSR; |
46 | | - |
47 | | - HotSpotProfilingInfo(HotSpotMethodData methodData, HotSpotResolvedJavaMethod method, boolean includeNormal, boolean includeOSR) { |
48 | | - this.methodData = methodData; |
49 | | - this.method = method; |
50 | | - if (!method.getDeclaringClass().isLinked()) { |
51 | | - throw new IllegalArgumentException(method.format("%H.%n(%p) must be linked")); |
52 | | - } |
53 | | - this.includeNormal = includeNormal; |
54 | | - this.includeOSR = includeOSR; |
55 | | - this.isMature = methodData.isProfileMature(); |
56 | | - hintPosition = 0; |
57 | | - hintBCI = -1; |
58 | | - } |
59 | | - |
60 | | - @Override |
61 | | - public int getCodeSize() { |
62 | | - return method.getCodeSize(); |
63 | | - } |
64 | | - |
65 | | - public int getDecompileCount() { |
66 | | - return methodData.getDecompileCount(); |
67 | | - } |
68 | | - |
69 | | - public int getOverflowRecompileCount() { |
70 | | - return methodData.getOverflowRecompileCount(); |
71 | | - } |
72 | | - |
73 | | - public int getOverflowTrapCount() { |
74 | | - return methodData.getOverflowTrapCount(); |
75 | | - } |
76 | | - |
77 | | - @Override |
78 | | - public JavaTypeProfile getTypeProfile(int bci) { |
79 | | - if (!isMature) { |
80 | | - return null; |
81 | | - } |
82 | | - findBCI(bci); |
83 | | - return dataAccessor.getTypeProfile(methodData, position); |
84 | | - } |
85 | | - |
86 | | - @Override |
87 | | - public JavaMethodProfile getMethodProfile(int bci) { |
88 | | - if (!isMature) { |
89 | | - return null; |
90 | | - } |
91 | | - findBCI(bci); |
92 | | - return dataAccessor.getMethodProfile(methodData, position); |
93 | | - } |
94 | | - |
95 | | - @Override |
96 | | - public double getBranchTakenProbability(int bci) { |
97 | | - if (!isMature) { |
98 | | - return -1; |
99 | | - } |
100 | | - findBCI(bci); |
101 | | - return dataAccessor.getBranchTakenProbability(methodData, position); |
102 | | - } |
103 | | - |
104 | | - @Override |
105 | | - public double[] getSwitchProbabilities(int bci) { |
106 | | - if (!isMature) { |
107 | | - return null; |
108 | | - } |
109 | | - findBCI(bci); |
110 | | - return dataAccessor.getSwitchProbabilities(methodData, position); |
111 | | - } |
112 | | - |
113 | | - @Override |
114 | | - public TriState getExceptionSeen(int bci) { |
115 | | - if (!findBCI(bci)) { |
116 | | - // There might data in the extra data section but all accesses to that memory must be |
117 | | - // under a lock so go into VM to get the data. |
118 | | - int exceptionSeen = compilerToVM().methodDataExceptionSeen(methodData.methodDataPointer, bci); |
119 | | - if (exceptionSeen == -1) { |
120 | | - return TriState.UNKNOWN; |
121 | | - } |
122 | | - return TriState.get(exceptionSeen != 0); |
123 | | - } |
124 | | - return dataAccessor.getExceptionSeen(methodData, position); |
125 | | - } |
126 | | - |
127 | | - @Override |
128 | | - public TriState getNullSeen(int bci) { |
129 | | - findBCI(bci); |
130 | | - return dataAccessor.getNullSeen(methodData, position); |
131 | | - } |
132 | 26 |
|
133 | | - @Override |
134 | | - public int getExecutionCount(int bci) { |
135 | | - if (!isMature) { |
136 | | - return -1; |
137 | | - } |
138 | | - findBCI(bci); |
139 | | - return dataAccessor.getExecutionCount(methodData, position); |
140 | | - } |
141 | | - |
142 | | - @Override |
143 | | - public int getDeoptimizationCount(DeoptimizationReason reason) { |
144 | | - int count = 0; |
145 | | - if (includeNormal) { |
146 | | - count += methodData.getDeoptimizationCount(reason); |
147 | | - } |
148 | | - if (includeOSR) { |
149 | | - count += methodData.getOSRDeoptimizationCount(reason); |
150 | | - } |
151 | | - return count; |
152 | | - } |
153 | | - |
154 | | - private boolean findBCI(int targetBCI) { |
155 | | - assert targetBCI >= 0 : "invalid BCI"; |
156 | | - |
157 | | - if (methodData.hasNormalData()) { |
158 | | - int currentPosition = targetBCI < hintBCI ? 0 : hintPosition; |
159 | | - HotSpotMethodDataAccessor currentAccessor; |
160 | | - while ((currentAccessor = methodData.getNormalData(currentPosition)) != null) { |
161 | | - int currentBCI = currentAccessor.getBCI(methodData, currentPosition); |
162 | | - if (currentBCI == targetBCI) { |
163 | | - normalDataFound(currentAccessor, currentPosition, currentBCI); |
164 | | - return true; |
165 | | - } else if (currentBCI > targetBCI) { |
166 | | - break; |
167 | | - } |
168 | | - currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition); |
169 | | - } |
170 | | - } |
171 | | - noDataFound(false); |
172 | | - return false; |
173 | | - } |
174 | | - |
175 | | - private void normalDataFound(HotSpotMethodDataAccessor data, int pos, int bci) { |
176 | | - setCurrentData(data, pos); |
177 | | - this.hintPosition = position; |
178 | | - this.hintBCI = bci; |
179 | | - } |
180 | | - |
181 | | - private void noDataFound(boolean exceptionPossiblyNotRecorded) { |
182 | | - HotSpotMethodDataAccessor accessor = HotSpotMethodData.getNoDataAccessor(exceptionPossiblyNotRecorded); |
183 | | - setCurrentData(accessor, -1); |
184 | | - } |
185 | | - |
186 | | - private void setCurrentData(HotSpotMethodDataAccessor dataAccessor, int position) { |
187 | | - this.dataAccessor = dataAccessor; |
188 | | - this.position = position; |
189 | | - } |
190 | | - |
191 | | - @Override |
192 | | - public boolean isMature() { |
193 | | - return isMature; |
194 | | - } |
195 | | - |
196 | | - public void ignoreMature() { |
197 | | - isMature = true; |
198 | | - } |
199 | | - |
200 | | - @Override |
201 | | - public String toString() { |
202 | | - return "HotSpotProfilingInfo<" + this.toString(null, "; ") + ">"; |
203 | | - } |
204 | | - |
205 | | - @Override |
206 | | - public void setMature() { |
207 | | - isMature = true; |
208 | | - } |
| 27 | +/** |
| 28 | + * Extends {@link ProfilingInfo} with HotSpot specific profiling info. |
| 29 | + */ |
| 30 | +public interface HotSpotProfilingInfo extends ProfilingInfo { |
209 | 31 |
|
210 | 32 | /** |
211 | | - * {@code MethodData::_jvmci_ir_size} (currently) supports at most one JVMCI compiler IR type |
212 | | - * which will be determined by the first JVMCI compiler that calls |
213 | | - * {@link #setCompilerIRSize(Class, int)}. |
| 33 | + * Returns {@code MethodData::_compiler_counters._nof_decompiles}. |
214 | 34 | */ |
215 | | - private static volatile Class<?> supportedCompilerIRType; |
| 35 | + int getDecompileCount(); |
216 | 36 |
|
217 | | - @Override |
218 | | - public boolean setCompilerIRSize(Class<?> irType, int size) { |
219 | | - if (supportedCompilerIRType == null) { |
220 | | - synchronized (HotSpotProfilingInfo.class) { |
221 | | - if (supportedCompilerIRType == null) { |
222 | | - supportedCompilerIRType = irType; |
223 | | - } |
224 | | - } |
225 | | - } |
226 | | - if (supportedCompilerIRType != irType) { |
227 | | - return false; |
228 | | - } |
229 | | - methodData.setCompiledIRSize(size); |
230 | | - return true; |
231 | | - } |
| 37 | + /** |
| 38 | + * Returns {@code MethodData::_compiler_counters._nof_overflow_recompiles}. |
| 39 | + */ |
| 40 | + int getOverflowRecompileCount(); |
232 | 41 |
|
233 | | - @Override |
234 | | - public int getCompilerIRSize(Class<?> irType) { |
235 | | - if (irType == supportedCompilerIRType) { |
236 | | - return methodData.getCompiledIRSize(); |
237 | | - } |
238 | | - return -1; |
239 | | - } |
| 42 | + /** |
| 43 | + * Returns {@code MethodData::_compiler_counters._nof_overflow_traps}. |
| 44 | + */ |
| 45 | + int getOverflowTrapCount(); |
240 | 46 | } |
0 commit comments