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
24
25 package org.graalvm.compiler.hotspot.replacements.profiling;
26
27 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
28 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.config;
29 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.SLOW_PATH_PROBABILITY;
30 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
31 import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER;
32
33 import org.graalvm.compiler.api.replacements.Snippet;
34 import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
35 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
36 import org.graalvm.compiler.debug.DebugHandlersFactory;
37 import org.graalvm.compiler.debug.GraalError;
38 import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
39 import org.graalvm.compiler.graph.Node.NodeIntrinsic;
40 import org.graalvm.compiler.hotspot.HotSpotBackend;
41 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
42 import org.graalvm.compiler.hotspot.nodes.aot.LoadMethodCountersNode;
43 import org.graalvm.compiler.hotspot.nodes.profiling.ProfileBranchNode;
44 import org.graalvm.compiler.hotspot.nodes.profiling.ProfileInvokeNode;
45 import org.graalvm.compiler.hotspot.nodes.profiling.ProfileNode;
46 import org.graalvm.compiler.hotspot.word.MethodCountersPointer;
47 import org.graalvm.compiler.nodes.ConstantNode;
48 import org.graalvm.compiler.nodes.StructuredGraph;
62 public class ProbabilisticProfileSnippets implements Snippets {
63 @Snippet
64 public static boolean shouldProfile(@ConstantParameter int probLog, int random) {
65 int probabilityMask = (1 << probLog) - 1;
66 return (random & probabilityMask) == 0;
67 }
68
69 @Snippet
70 public static int notificationMask(int freqLog, int probLog, int stepLog) {
71 int frequencyMask = (1 << freqLog) - 1;
72 int stepMask = (1 << (stepLog + probLog)) - 1;
73 return frequencyMask & ~stepMask;
74 }
75
76 @NodeIntrinsic(ForeignCallNode.class)
77 public static native void methodInvocationEvent(@ConstantNodeParameter ForeignCallDescriptor descriptor, MethodCountersPointer counters);
78
79 @Snippet
80 public static void profileMethodEntryWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog, @ConstantParameter int probLog) {
81 if (probability(1.0 / (1 << probLog), shouldProfile(probLog, random))) {
82 int counterValue = counters.readInt(config(INJECTED_VMCONFIG).invocationCounterOffset) + ((config(INJECTED_VMCONFIG).invocationCounterIncrement * step) << probLog);
83 counters.writeInt(config(INJECTED_VMCONFIG).invocationCounterOffset, counterValue);
84 if (freqLog >= 0) {
85 int mask = notificationMask(freqLog, probLog, stepLog);
86 if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
87 methodInvocationEvent(HotSpotBackend.INVOCATION_EVENT, counters);
88 }
89 }
90 }
91 }
92
93 @NodeIntrinsic(ForeignCallNode.class)
94 public static native void methodBackedgeEvent(@ConstantNodeParameter ForeignCallDescriptor descriptor, MethodCountersPointer counters, int bci, int targetBci);
95
96 @Snippet
97 public static void profileBackedgeWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog, @ConstantParameter int probLog, int bci,
98 int targetBci) {
99 if (probability(1.0 / (1 << probLog), shouldProfile(probLog, random))) {
100 int counterValue = counters.readInt(config(INJECTED_VMCONFIG).backedgeCounterOffset) + ((config(INJECTED_VMCONFIG).invocationCounterIncrement * step) << probLog);
101 counters.writeInt(config(INJECTED_VMCONFIG).backedgeCounterOffset, counterValue);
102 int mask = notificationMask(freqLog, probLog, stepLog);
103 if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
104 methodBackedgeEvent(HotSpotBackend.BACKEDGE_EVENT, counters, bci, targetBci);
105 }
106 }
107 }
108
109 @Snippet
110 public static void profileConditionalBackedgeWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog,
111 @ConstantParameter int probLog, boolean branchCondition,
112 int bci, int targetBci) {
113 if (branchCondition) {
114 profileBackedgeWithProbability(counters, random, step, stepLog, freqLog, probLog, bci, targetBci);
115 }
116 }
117
118 public static class Templates extends AbstractTemplates {
119 private final SnippetInfo profileMethodEntryWithProbability = snippet(ProbabilisticProfileSnippets.class, "profileMethodEntryWithProbability");
120 private final SnippetInfo profileBackedgeWithProbability = snippet(ProbabilisticProfileSnippets.class, "profileBackedgeWithProbability");
121 private final SnippetInfo profileConditionalBackedgeWithProbability = snippet(ProbabilisticProfileSnippets.class, "profileConditionalBackedgeWithProbability");
122
123 public Templates(OptionValues options, Iterable<DebugHandlersFactory> factories, HotSpotProviders providers, TargetDescription target) {
|
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
24
25 package org.graalvm.compiler.hotspot.replacements.profiling;
26
27 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
28 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.backedgeCounterOffset;
29 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.invocationCounterIncrement;
30 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.invocationCounterOffset;
31 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.invocationCounterShift;
32 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.SLOW_PATH_PROBABILITY;
33 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
34 import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER;
35
36 import org.graalvm.compiler.api.replacements.Snippet;
37 import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
38 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
39 import org.graalvm.compiler.debug.DebugHandlersFactory;
40 import org.graalvm.compiler.debug.GraalError;
41 import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
42 import org.graalvm.compiler.graph.Node.NodeIntrinsic;
43 import org.graalvm.compiler.hotspot.HotSpotBackend;
44 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
45 import org.graalvm.compiler.hotspot.nodes.aot.LoadMethodCountersNode;
46 import org.graalvm.compiler.hotspot.nodes.profiling.ProfileBranchNode;
47 import org.graalvm.compiler.hotspot.nodes.profiling.ProfileInvokeNode;
48 import org.graalvm.compiler.hotspot.nodes.profiling.ProfileNode;
49 import org.graalvm.compiler.hotspot.word.MethodCountersPointer;
50 import org.graalvm.compiler.nodes.ConstantNode;
51 import org.graalvm.compiler.nodes.StructuredGraph;
65 public class ProbabilisticProfileSnippets implements Snippets {
66 @Snippet
67 public static boolean shouldProfile(@ConstantParameter int probLog, int random) {
68 int probabilityMask = (1 << probLog) - 1;
69 return (random & probabilityMask) == 0;
70 }
71
72 @Snippet
73 public static int notificationMask(int freqLog, int probLog, int stepLog) {
74 int frequencyMask = (1 << freqLog) - 1;
75 int stepMask = (1 << (stepLog + probLog)) - 1;
76 return frequencyMask & ~stepMask;
77 }
78
79 @NodeIntrinsic(ForeignCallNode.class)
80 public static native void methodInvocationEvent(@ConstantNodeParameter ForeignCallDescriptor descriptor, MethodCountersPointer counters);
81
82 @Snippet
83 public static void profileMethodEntryWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog, @ConstantParameter int probLog) {
84 if (probability(1.0 / (1 << probLog), shouldProfile(probLog, random))) {
85 int counterValue = counters.readInt(invocationCounterOffset(INJECTED_VMCONFIG)) + ((invocationCounterIncrement(INJECTED_VMCONFIG) * step) << probLog);
86 counters.writeInt(invocationCounterOffset(INJECTED_VMCONFIG), counterValue);
87 if (freqLog >= 0) {
88 int mask = notificationMask(freqLog, probLog, stepLog);
89 if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << invocationCounterShift(INJECTED_VMCONFIG))) == 0)) {
90 methodInvocationEvent(HotSpotBackend.INVOCATION_EVENT, counters);
91 }
92 }
93 }
94 }
95
96 @NodeIntrinsic(ForeignCallNode.class)
97 public static native void methodBackedgeEvent(@ConstantNodeParameter ForeignCallDescriptor descriptor, MethodCountersPointer counters, int bci, int targetBci);
98
99 @Snippet
100 public static void profileBackedgeWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog, @ConstantParameter int probLog, int bci,
101 int targetBci) {
102 if (probability(1.0 / (1 << probLog), shouldProfile(probLog, random))) {
103 int counterValue = counters.readInt(backedgeCounterOffset(INJECTED_VMCONFIG)) + ((invocationCounterIncrement(INJECTED_VMCONFIG) * step) << probLog);
104 counters.writeInt(backedgeCounterOffset(INJECTED_VMCONFIG), counterValue);
105 int mask = notificationMask(freqLog, probLog, stepLog);
106 if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << invocationCounterShift(INJECTED_VMCONFIG))) == 0)) {
107 methodBackedgeEvent(HotSpotBackend.BACKEDGE_EVENT, counters, bci, targetBci);
108 }
109 }
110 }
111
112 @Snippet
113 public static void profileConditionalBackedgeWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog,
114 @ConstantParameter int probLog, boolean branchCondition,
115 int bci, int targetBci) {
116 if (branchCondition) {
117 profileBackedgeWithProbability(counters, random, step, stepLog, freqLog, probLog, bci, targetBci);
118 }
119 }
120
121 public static class Templates extends AbstractTemplates {
122 private final SnippetInfo profileMethodEntryWithProbability = snippet(ProbabilisticProfileSnippets.class, "profileMethodEntryWithProbability");
123 private final SnippetInfo profileBackedgeWithProbability = snippet(ProbabilisticProfileSnippets.class, "profileBackedgeWithProbability");
124 private final SnippetInfo profileConditionalBackedgeWithProbability = snippet(ProbabilisticProfileSnippets.class, "profileConditionalBackedgeWithProbability");
125
126 public Templates(OptionValues options, Iterable<DebugHandlersFactory> factories, HotSpotProviders providers, TargetDescription target) {
|