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;