48 import org.graalvm.compiler.nodes.calc.IsNullNode; |
48 import org.graalvm.compiler.nodes.calc.IsNullNode; |
49 import org.graalvm.compiler.nodes.extended.NullCheckNode; |
49 import org.graalvm.compiler.nodes.extended.NullCheckNode; |
50 import org.graalvm.compiler.nodes.memory.FixedAccessNode; |
50 import org.graalvm.compiler.nodes.memory.FixedAccessNode; |
51 import org.graalvm.compiler.nodes.memory.address.AddressNode; |
51 import org.graalvm.compiler.nodes.memory.address.AddressNode; |
52 import org.graalvm.compiler.nodes.util.GraphUtil; |
52 import org.graalvm.compiler.nodes.util.GraphUtil; |
|
53 import org.graalvm.compiler.options.Option; |
|
54 import org.graalvm.compiler.options.OptionKey; |
|
55 import org.graalvm.compiler.options.OptionType; |
53 import org.graalvm.compiler.phases.BasePhase; |
56 import org.graalvm.compiler.phases.BasePhase; |
54 import org.graalvm.compiler.phases.tiers.LowTierContext; |
57 import org.graalvm.compiler.phases.tiers.LowTierContext; |
55 |
58 |
56 import jdk.vm.ci.meta.DeoptimizationReason; |
59 import jdk.vm.ci.meta.DeoptimizationReason; |
57 import jdk.vm.ci.meta.JavaConstant; |
60 import jdk.vm.ci.meta.JavaConstant; |
62 private static final CounterKey counterTrappingNullCheck = DebugContext.counter("TrappingNullCheck"); |
65 private static final CounterKey counterTrappingNullCheck = DebugContext.counter("TrappingNullCheck"); |
63 private static final CounterKey counterTrappingNullCheckExistingRead = DebugContext.counter("TrappingNullCheckExistingRead"); |
66 private static final CounterKey counterTrappingNullCheckExistingRead = DebugContext.counter("TrappingNullCheckExistingRead"); |
64 private static final CounterKey counterTrappingNullCheckUnreached = DebugContext.counter("TrappingNullCheckUnreached"); |
67 private static final CounterKey counterTrappingNullCheckUnreached = DebugContext.counter("TrappingNullCheckUnreached"); |
65 private static final CounterKey counterTrappingNullCheckDynamicDeoptimize = DebugContext.counter("TrappingNullCheckDynamicDeoptimize"); |
68 private static final CounterKey counterTrappingNullCheckDynamicDeoptimize = DebugContext.counter("TrappingNullCheckDynamicDeoptimize"); |
66 |
69 |
|
70 public static class Options { |
|
71 |
|
72 // @formatter:off |
|
73 @Option(help = "Use traps for null checks instead of explicit null-checks", type = OptionType.Expert) |
|
74 public static final OptionKey<Boolean> UseTrappingNullChecks = new OptionKey<>(true); |
|
75 // @formatter:on |
|
76 } |
|
77 |
67 @Override |
78 @Override |
68 protected void run(StructuredGraph graph, LowTierContext context) { |
79 protected void run(StructuredGraph graph, LowTierContext context) { |
69 if (context.getTarget().implicitNullCheckLimit <= 0) { |
80 if (!Options.UseTrappingNullChecks.getValue(graph.getOptions()) || context.getTarget().implicitNullCheckLimit <= 0) { |
70 return; |
81 return; |
71 } |
82 } |
72 assert graph.getGuardsStage().areFrameStatesAtDeopts(); |
83 assert graph.getGuardsStage().areFrameStatesAtDeopts(); |
73 |
84 |
74 long implicitNullCheckLimit = context.getTarget().implicitNullCheckLimit; |
85 long implicitNullCheckLimit = context.getTarget().implicitNullCheckLimit; |
75 for (DeoptimizeNode deopt : graph.getNodes(DeoptimizeNode.TYPE)) { |
86 for (DeoptimizeNode deopt : graph.getNodes(DeoptimizeNode.TYPE)) { |
76 tryUseTrappingNullCheck(deopt, deopt.predecessor(), deopt.reason(), deopt.getSpeculation(), implicitNullCheckLimit); |
87 tryUseTrappingNullCheck(deopt, deopt.predecessor(), deopt.getReason(), deopt.getSpeculation(), implicitNullCheckLimit); |
77 } |
88 } |
78 for (DynamicDeoptimizeNode deopt : graph.getNodes(DynamicDeoptimizeNode.TYPE)) { |
89 for (DynamicDeoptimizeNode deopt : graph.getNodes(DynamicDeoptimizeNode.TYPE)) { |
79 tryUseTrappingNullCheck(context.getMetaAccess(), deopt, implicitNullCheckLimit); |
90 tryUseTrappingNullCheck(context.getMetaAccess(), deopt, implicitNullCheckLimit); |
80 } |
91 } |
81 |
92 |