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