Mercurial > hg > truffle
comparison graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java @ 21925:64475dbf6aec
Move instantiation checks from methods substitutions to the lowering of DynamicNewInstanceNode and DynamicNewArrayNode, so that Unsafe.allocateInstance and Array.newInstance can be intrinsified to a single node.
author | Christian Wimmer <christian.wimmer@oracle.com> |
---|---|
date | Wed, 10 Jun 2015 17:23:19 -0700 |
parents | a858c5f56d8a |
children |
comparison
equal
deleted
inserted
replaced
21907:f6fd9fb11816 | 21925:64475dbf6aec |
---|---|
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 com.oracle.jvmci.code.Register; | 25 import static com.oracle.graal.replacements.ReplacementsUtil.*; |
26 import com.oracle.jvmci.code.CodeUtil; | |
27 import com.oracle.jvmci.code.TargetDescription; | |
28 import com.oracle.jvmci.meta.NamedLocationIdentity; | |
29 import com.oracle.jvmci.meta.ResolvedJavaType; | |
30 import com.oracle.jvmci.meta.LocationIdentity; | |
31 import com.oracle.jvmci.meta.ForeignCallDescriptor; | |
32 import com.oracle.jvmci.meta.Kind; | |
33 import static com.oracle.jvmci.code.UnsignedMath.*; | |
34 import static com.oracle.graal.compiler.common.GraalOptions.*; | 26 import static com.oracle.graal.compiler.common.GraalOptions.*; |
35 import static com.oracle.graal.hotspot.nodes.CStringNode.*; | 27 import static com.oracle.graal.hotspot.nodes.CStringNode.*; |
36 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; | 28 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; |
37 import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.Options.*; | 29 import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.Options.*; |
38 import static com.oracle.graal.nodes.PiArrayNode.*; | 30 import static com.oracle.graal.nodes.PiArrayNode.*; |
39 import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; | 31 import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; |
40 import static com.oracle.graal.replacements.SnippetTemplate.*; | 32 import static com.oracle.graal.replacements.SnippetTemplate.*; |
41 import static com.oracle.graal.replacements.nodes.ExplodeLoopNode.*; | 33 import static com.oracle.graal.replacements.nodes.ExplodeLoopNode.*; |
34 import static com.oracle.jvmci.code.UnsignedMath.*; | |
42 import static com.oracle.jvmci.hotspot.HotSpotMetaAccessProvider.*; | 35 import static com.oracle.jvmci.hotspot.HotSpotMetaAccessProvider.*; |
43 | 36 |
44 import com.oracle.graal.api.replacements.*; | 37 import com.oracle.graal.api.replacements.*; |
45 import com.oracle.graal.compiler.common.type.*; | 38 import com.oracle.graal.compiler.common.type.*; |
46 import com.oracle.graal.graph.Node.ConstantNodeParameter; | 39 import com.oracle.graal.graph.Node.ConstantNodeParameter; |
63 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; | 56 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; |
64 import com.oracle.graal.replacements.SnippetTemplate.Arguments; | 57 import com.oracle.graal.replacements.SnippetTemplate.Arguments; |
65 import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo; | 58 import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo; |
66 import com.oracle.graal.replacements.nodes.*; | 59 import com.oracle.graal.replacements.nodes.*; |
67 import com.oracle.graal.word.*; | 60 import com.oracle.graal.word.*; |
61 import com.oracle.jvmci.code.*; | |
68 import com.oracle.jvmci.common.*; | 62 import com.oracle.jvmci.common.*; |
69 import com.oracle.jvmci.debug.*; | 63 import com.oracle.jvmci.debug.*; |
70 import com.oracle.jvmci.hotspot.*; | 64 import com.oracle.jvmci.hotspot.*; |
65 import com.oracle.jvmci.meta.*; | |
71 import com.oracle.jvmci.options.*; | 66 import com.oracle.jvmci.options.*; |
72 | 67 |
73 /** | 68 /** |
74 * Snippets used for implementing NEW, ANEWARRAY and NEWARRAY. | 69 * Snippets used for implementing NEW, ANEWARRAY and NEWARRAY. |
75 */ | 70 */ |
165 @NodeIntrinsic(ForeignCallNode.class) | 160 @NodeIntrinsic(ForeignCallNode.class) |
166 public static native Object newInstance(@ConstantNodeParameter ForeignCallDescriptor descriptor, KlassPointer hub); | 161 public static native Object newInstance(@ConstantNodeParameter ForeignCallDescriptor descriptor, KlassPointer hub); |
167 | 162 |
168 @Snippet | 163 @Snippet |
169 public static Object allocateInstanceDynamic(Class<?> type, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister) { | 164 public static Object allocateInstanceDynamic(Class<?> type, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister) { |
165 if (probability(SLOW_PATH_PROBABILITY, type == null || DynamicNewInstanceNode.throwsInstantiationException(type))) { | |
166 DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); | |
167 } | |
168 | |
170 KlassPointer hub = ClassGetHubNode.readClass(type); | 169 KlassPointer hub = ClassGetHubNode.readClass(type); |
171 if (probability(FAST_PATH_PROBABILITY, !hub.isNull())) { | 170 if (probability(FAST_PATH_PROBABILITY, !hub.isNull())) { |
172 if (probability(FAST_PATH_PROBABILITY, isInstanceKlassFullyInitialized(hub))) { | 171 if (probability(FAST_PATH_PROBABILITY, isInstanceKlassFullyInitialized(hub))) { |
173 int layoutHelper = readLayoutHelper(hub); | 172 int layoutHelper = readLayoutHelper(hub); |
174 /* | 173 /* |
238 | 237 |
239 @NodeIntrinsic(ForeignCallNode.class) | 238 @NodeIntrinsic(ForeignCallNode.class) |
240 public static native Object dynamicNewInstanceStubCall(@ConstantNodeParameter ForeignCallDescriptor descriptor, Class<?> elementType); | 239 public static native Object dynamicNewInstanceStubCall(@ConstantNodeParameter ForeignCallDescriptor descriptor, Class<?> elementType); |
241 | 240 |
242 @Snippet | 241 @Snippet |
243 public static Object allocateArrayDynamic(Class<?> elementType, int length, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister) { | 242 public static Object allocateArrayDynamic(Class<?> elementType, int length, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, |
243 @ConstantParameter Kind knownElementKind) { | |
244 /* | |
245 * We only need the dynamic check for void when we have no static information from | |
246 * knownElementKind. | |
247 */ | |
248 staticAssert(knownElementKind != Kind.Void, "unsupported knownElementKind"); | |
249 if (knownElementKind == Kind.Illegal && probability(SLOW_PATH_PROBABILITY, elementType == null || DynamicNewArrayNode.throwsIllegalArgumentException(elementType))) { | |
250 DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); | |
251 } | |
252 | |
244 Word hub = loadWordFromObject(elementType, arrayKlassOffset(), CLASS_ARRAY_KLASS_LOCATION); | 253 Word hub = loadWordFromObject(elementType, arrayKlassOffset(), CLASS_ARRAY_KLASS_LOCATION); |
245 if (probability(BranchProbabilityNode.NOT_FREQUENT_PROBABILITY, hub.equal(Word.zero()) || !belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH))) { | 254 if (probability(BranchProbabilityNode.NOT_FREQUENT_PROBABILITY, hub.equal(Word.zero()) || !belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH))) { |
246 return dynamicNewArrayStub(DYNAMIC_NEW_ARRAY, elementType, length); | 255 return dynamicNewArrayStub(DYNAMIC_NEW_ARRAY, elementType, length); |
247 } | 256 } |
248 | 257 |
476 args.add("elementType", newArrayNode.getElementType()); | 485 args.add("elementType", newArrayNode.getElementType()); |
477 ValueNode length = newArrayNode.length(); | 486 ValueNode length = newArrayNode.length(); |
478 args.add("length", length.isAlive() ? length : graph.addOrUniqueWithInputs(length)); | 487 args.add("length", length.isAlive() ? length : graph.addOrUniqueWithInputs(length)); |
479 args.addConst("fillContents", newArrayNode.fillContents()); | 488 args.addConst("fillContents", newArrayNode.fillContents()); |
480 args.addConst("threadRegister", registers.getThreadRegister()); | 489 args.addConst("threadRegister", registers.getThreadRegister()); |
490 /* | |
491 * We use Kind.Illegal as a marker value instead of null because constant snippet | |
492 * parameters cannot be null. | |
493 */ | |
494 args.addConst("knownElementKind", newArrayNode.getKnownElementKind() == null ? Kind.Illegal : newArrayNode.getKnownElementKind()); | |
481 | 495 |
482 SnippetTemplate template = template(args); | 496 SnippetTemplate template = template(args); |
483 template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args); | 497 template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args); |
484 } | 498 } |
485 | 499 |