Mercurial > hg > truffle
comparison graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java @ 10001:38d7b55f87b0
added instanceof snippets that for a profile with 100% precise coverage of seen types.
This snippet deoptimizes on any path that contradicts the profile.
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Tue, 11 Jun 2013 22:02:23 +0200 |
parents | 063a712fe8d8 |
children | 7709bb831916 |
comparison
equal
deleted
inserted
replaced
10000:d9c14b1828fc | 10001:38d7b55f87b0 |
---|---|
20 * or visit www.oracle.com if you need additional information or have any | 20 * or visit www.oracle.com if you need additional information or have any |
21 * questions. | 21 * questions. |
22 */ | 22 */ |
23 package com.oracle.graal.hotspot.replacements; | 23 package com.oracle.graal.hotspot.replacements; |
24 | 24 |
25 import static com.oracle.graal.api.code.DeoptimizationAction.*; | |
26 import static com.oracle.graal.api.meta.DeoptimizationReason.*; | |
27 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; | |
25 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; | 28 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; |
26 import static com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.*; | 29 import static com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.*; |
27 import static com.oracle.graal.phases.GraalOptions.*; | 30 import static com.oracle.graal.phases.GraalOptions.*; |
28 import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; | 31 import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; |
29 | 32 |
30 import com.oracle.graal.api.code.*; | 33 import com.oracle.graal.api.code.*; |
31 import com.oracle.graal.api.meta.*; | 34 import com.oracle.graal.api.meta.*; |
35 import com.oracle.graal.api.meta.ProfilingInfo.TriState; | |
32 import com.oracle.graal.hotspot.meta.*; | 36 import com.oracle.graal.hotspot.meta.*; |
33 import com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.Hints; | 37 import com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.Hints; |
34 import com.oracle.graal.nodes.*; | 38 import com.oracle.graal.nodes.*; |
35 import com.oracle.graal.nodes.java.*; | 39 import com.oracle.graal.nodes.java.*; |
36 import com.oracle.graal.nodes.spi.*; | 40 import com.oracle.graal.nodes.spi.*; |
52 * Cliff Click and John Rose. | 56 * Cliff Click and John Rose. |
53 */ | 57 */ |
54 public class InstanceOfSnippets implements Snippets { | 58 public class InstanceOfSnippets implements Snippets { |
55 | 59 |
56 /** | 60 /** |
57 * A test against a final type. | 61 * A test against a set of hints derived from a profile with 100% precise coverage of seen |
58 */ | 62 * types. This snippet deoptimizes on any path that contradicts the profile. |
59 @Snippet | 63 */ |
60 public static Object instanceofExact(Object object, Word exactHub, Object trueValue, Object falseValue, @ConstantParameter boolean checkNull) { | 64 @Snippet |
61 if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) { | 65 public static Object instanceofWithProfile(Object object, @VarargsParameter Word[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue, |
62 isNull.inc(); | 66 @ConstantParameter boolean checkNull, @ConstantParameter boolean nullSeen) { |
63 return falseValue; | 67 if (probability(NOT_FREQUENT_PROBABILITY, checkNull && object == null)) { |
64 } | 68 isNull.inc(); |
65 Word objectHub = loadHub(object); | 69 if (!nullSeen) { |
66 if (probability(LIKELY_PROBABILITY, objectHub.notEqual(exactHub))) { | 70 DeoptimizeNode.deopt(InvalidateReprofile, OptimizedTypeCheckViolated); |
67 exactMiss.inc(); | 71 } |
68 return falseValue; | |
69 } | |
70 exactHit.inc(); | |
71 return trueValue; | |
72 } | |
73 | |
74 /** | |
75 * A test against a primary type. | |
76 */ | |
77 @Snippet | |
78 public static Object instanceofPrimary(Word hub, Object object, @ConstantParameter int superCheckOffset, Object trueValue, Object falseValue, @ConstantParameter boolean checkNull) { | |
79 if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) { | |
80 isNull.inc(); | |
81 return falseValue; | |
82 } | |
83 Word objectHub = loadHub(object); | |
84 if (probability(NOT_LIKELY_PROBABILITY, objectHub.readWord(superCheckOffset, LocationIdentity.FINAL_LOCATION).notEqual(hub))) { | |
85 displayMiss.inc(); | |
86 return falseValue; | |
87 } | |
88 displayHit.inc(); | |
89 return trueValue; | |
90 } | |
91 | |
92 /** | |
93 * A test against a restricted secondary type type. | |
94 */ | |
95 @Snippet | |
96 public static Object instanceofSecondary(Word hub, Object object, @VarargsParameter Word[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue, | |
97 @ConstantParameter boolean checkNull) { | |
98 if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) { | |
99 isNull.inc(); | |
100 return falseValue; | 72 return falseValue; |
101 } | 73 } |
102 Word objectHub = loadHub(object); | 74 Word objectHub = loadHub(object); |
103 // if we get an exact match: succeed immediately | 75 // if we get an exact match: succeed immediately |
104 ExplodeLoopNode.explodeLoop(); | 76 ExplodeLoopNode.explodeLoop(); |
108 if (probability(NOT_FREQUENT_PROBABILITY, hintHub.equal(objectHub))) { | 80 if (probability(NOT_FREQUENT_PROBABILITY, hintHub.equal(objectHub))) { |
109 hintsHit.inc(); | 81 hintsHit.inc(); |
110 return positive ? trueValue : falseValue; | 82 return positive ? trueValue : falseValue; |
111 } | 83 } |
112 } | 84 } |
85 DeoptimizeNode.deopt(InvalidateReprofile, OptimizedTypeCheckViolated); | |
86 return falseValue; | |
87 } | |
88 | |
89 /** | |
90 * A test against a final type. | |
91 */ | |
92 @Snippet | |
93 public static Object instanceofExact(Object object, Word exactHub, Object trueValue, Object falseValue, @ConstantParameter boolean checkNull) { | |
94 if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) { | |
95 isNull.inc(); | |
96 return falseValue; | |
97 } | |
98 Word objectHub = loadHub(object); | |
99 if (probability(LIKELY_PROBABILITY, objectHub.notEqual(exactHub))) { | |
100 exactMiss.inc(); | |
101 return falseValue; | |
102 } | |
103 exactHit.inc(); | |
104 return trueValue; | |
105 } | |
106 | |
107 /** | |
108 * A test against a primary type. | |
109 */ | |
110 @Snippet | |
111 public static Object instanceofPrimary(Word hub, Object object, @ConstantParameter int superCheckOffset, Object trueValue, Object falseValue, @ConstantParameter boolean checkNull) { | |
112 if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) { | |
113 isNull.inc(); | |
114 return falseValue; | |
115 } | |
116 Word objectHub = loadHub(object); | |
117 if (probability(NOT_LIKELY_PROBABILITY, objectHub.readWord(superCheckOffset, LocationIdentity.FINAL_LOCATION).notEqual(hub))) { | |
118 displayMiss.inc(); | |
119 return falseValue; | |
120 } | |
121 displayHit.inc(); | |
122 return trueValue; | |
123 } | |
124 | |
125 /** | |
126 * A test against a restricted secondary type type. | |
127 */ | |
128 @Snippet | |
129 public static Object instanceofSecondary(Word hub, Object object, @VarargsParameter Word[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue, | |
130 @ConstantParameter boolean checkNull) { | |
131 if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) { | |
132 isNull.inc(); | |
133 return falseValue; | |
134 } | |
135 Word objectHub = loadHub(object); | |
136 // if we get an exact match: succeed immediately | |
137 ExplodeLoopNode.explodeLoop(); | |
138 for (int i = 0; i < hints.length; i++) { | |
139 Word hintHub = hints[i]; | |
140 boolean positive = hintIsPositive[i]; | |
141 if (probability(NOT_FREQUENT_PROBABILITY, hintHub.equal(objectHub))) { | |
142 hintsHit.inc(); | |
143 return positive ? trueValue : falseValue; | |
144 } | |
145 } | |
113 if (!checkSecondarySubType(hub, objectHub)) { | 146 if (!checkSecondarySubType(hub, objectHub)) { |
114 return falseValue; | 147 return falseValue; |
115 } | 148 } |
116 return trueValue; | 149 return trueValue; |
117 } | 150 } |
134 return trueValue; | 167 return trueValue; |
135 } | 168 } |
136 | 169 |
137 public static class Templates extends InstanceOfSnippetsTemplates { | 170 public static class Templates extends InstanceOfSnippetsTemplates { |
138 | 171 |
172 private final SnippetInfo instanceofWithProfile = snippet(InstanceOfSnippets.class, "instanceofWithProfile"); | |
139 private final SnippetInfo instanceofExact = snippet(InstanceOfSnippets.class, "instanceofExact"); | 173 private final SnippetInfo instanceofExact = snippet(InstanceOfSnippets.class, "instanceofExact"); |
140 private final SnippetInfo instanceofPrimary = snippet(InstanceOfSnippets.class, "instanceofPrimary"); | 174 private final SnippetInfo instanceofPrimary = snippet(InstanceOfSnippets.class, "instanceofPrimary"); |
141 private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary"); | 175 private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary"); |
142 private final SnippetInfo instanceofDynamic = snippet(InstanceOfSnippets.class, "instanceofDynamic"); | 176 private final SnippetInfo instanceofDynamic = snippet(InstanceOfSnippets.class, "instanceofDynamic"); |
143 | 177 |
153 TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), tool.assumptions(), InstanceOfMinHintHitProbability.getValue(), InstanceOfMaxHints.getValue()); | 187 TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), tool.assumptions(), InstanceOfMinHintHitProbability.getValue(), InstanceOfMaxHints.getValue()); |
154 final HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) instanceOf.type(); | 188 final HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) instanceOf.type(); |
155 ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, instanceOf.graph()); | 189 ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, instanceOf.graph()); |
156 | 190 |
157 Arguments args; | 191 Arguments args; |
158 if (hintInfo.exact) { | 192 if (hintInfo.hintHitProbability == 1.0D) { |
159 ConstantNode[] hints = createHints(hintInfo, runtime, true, hub.graph()).hubs; | 193 Hints hints = createHints(hintInfo, runtime, false, hub.graph()); |
160 assert hints.length == 1; | 194 args = new Arguments(instanceofWithProfile); |
195 args.add("object", object); | |
196 args.addVarargs("hints", Word.class, StampFactory.forKind(wordKind()), hints.hubs); | |
197 args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(Kind.Boolean), hints.isPositive); | |
198 } else if (hintInfo.exact != null) { | |
161 args = new Arguments(instanceofExact); | 199 args = new Arguments(instanceofExact); |
162 args.add("object", object); | 200 args.add("object", object); |
163 args.add("exactHub", hints[0]); | 201 args.add("exactHub", ConstantNode.forConstant(((HotSpotResolvedObjectType) hintInfo.exact).klass(), runtime, hub.graph())); |
164 } else if (type.isPrimaryType()) { | 202 } else if (type.isPrimaryType()) { |
165 args = new Arguments(instanceofPrimary); | 203 args = new Arguments(instanceofPrimary); |
166 args.add("hub", hub); | 204 args.add("hub", hub); |
167 args.add("object", object); | 205 args.add("object", object); |
168 args.addConst("superCheckOffset", type.superCheckOffset()); | 206 args.addConst("superCheckOffset", type.superCheckOffset()); |
175 args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(Kind.Boolean), hints.isPositive); | 213 args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(Kind.Boolean), hints.isPositive); |
176 } | 214 } |
177 args.add("trueValue", replacer.trueValue); | 215 args.add("trueValue", replacer.trueValue); |
178 args.add("falseValue", replacer.falseValue); | 216 args.add("falseValue", replacer.falseValue); |
179 args.addConst("checkNull", !object.stamp().nonNull()); | 217 args.addConst("checkNull", !object.stamp().nonNull()); |
218 if (hintInfo.hintHitProbability == 1.0D) { | |
219 args.addConst("nullSeen", hintInfo.profile.getNullSeen() != TriState.FALSE); | |
220 } | |
180 return args; | 221 return args; |
181 | 222 |
182 } else { | 223 } else { |
183 assert replacer.instanceOf instanceof InstanceOfDynamicNode; | 224 assert replacer.instanceOf instanceof InstanceOfDynamicNode; |
184 InstanceOfDynamicNode instanceOf = (InstanceOfDynamicNode) replacer.instanceOf; | 225 InstanceOfDynamicNode instanceOf = (InstanceOfDynamicNode) replacer.instanceOf; |