HotSpotProfilingInfo.java revision 12651:6ef01bd40ce2
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 */
23package jdk.vm.ci.hotspot;
24
25import jdk.vm.ci.meta.DeoptimizationReason;
26import jdk.vm.ci.meta.JavaMethodProfile;
27import jdk.vm.ci.meta.JavaTypeProfile;
28import jdk.vm.ci.meta.ProfilingInfo;
29import jdk.vm.ci.meta.TriState;
30
31public 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}
250