< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java

Print this page
rev 52509 : [mq]: graal2


 252                     @ConstantParameter Counters counters) {
 253         // Klass must be initialized by the time the first instance is allocated, therefore we can
 254         // just load it from the corresponding cell and avoid the resolution check. We have to use a
 255         // fixed load though, to prevent it from floating above the initialization.
 256         KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub);
 257         return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, picHub, prototypeMarkWord, fillContents, threadRegister, constantSize, typeContext, options, counters));
 258     }
 259 
 260     @Snippet
 261     public static Object allocateInstanceDynamic(Class<?> type, Class<?> classClass, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister,
 262                     @ConstantParameter OptionValues options, @ConstantParameter Counters counters) {
 263         if (probability(SLOW_PATH_PROBABILITY, type == null)) {
 264             DeoptimizeNode.deopt(None, RuntimeConstraint);
 265         }
 266         Class<?> nonNullType = PiNode.piCastNonNullClass(type, SnippetAnchorNode.anchor());
 267 
 268         if (probability(SLOW_PATH_PROBABILITY, DynamicNewInstanceNode.throwsInstantiationException(type, classClass))) {
 269             DeoptimizeNode.deopt(None, RuntimeConstraint);
 270         }
 271 
 272         return PiNode.piCastToSnippetReplaceeStamp(allocateInstanceDynamicHelper(fillContents, threadRegister, options, counters, nonNullType));
 273     }
 274 
 275     private static Object allocateInstanceDynamicHelper(boolean fillContents, Register threadRegister, OptionValues options, Counters counters, Class<?> nonNullType) {
 276         KlassPointer hub = ClassGetHubNode.readClass(nonNullType);
 277         if (probability(FAST_PATH_PROBABILITY, !hub.isNull())) {
 278             KlassPointer nonNullHub = ClassGetHubNode.piCastNonNull(hub, SnippetAnchorNode.anchor());
 279 
 280             if (probability(FAST_PATH_PROBABILITY, isInstanceKlassFullyInitialized(nonNullHub))) {
 281                 int layoutHelper = readLayoutHelper(nonNullHub);
 282                 /*
 283                  * src/share/vm/oops/klass.hpp: For instances, layout helper is a positive number,
 284                  * the instance size. This size is already passed through align_object_size and
 285                  * scaled to bytes. The low order bit is set if instances of this class cannot be
 286                  * allocated using the fastpath.
 287                  */
 288                 if (probability(FAST_PATH_PROBABILITY, (layoutHelper & 1) == 0)) {
 289                     Word prototypeMarkWord = nonNullHub.readWord(prototypeMarkWordOffset(INJECTED_VMCONFIG), PROTOTYPE_MARK_WORD_LOCATION);
 290                     /*
 291                      * FIXME(je,ds): we should actually pass typeContext instead of "" but late
 292                      * binding of parameters is not yet supported by the GraphBuilderPlugin system.
 293                      */
 294                     return allocateInstanceHelper(layoutHelper, nonNullHub, prototypeMarkWord, fillContents, threadRegister, false, "", options, counters);
 295                 }
 296             } else {
 297                 DeoptimizeNode.deopt(None, RuntimeConstraint);
 298             }
 299         }
 300         DeoptimizeNode.deopt(None, RuntimeConstraint);
 301         return null;
 302     }
 303 
 304     /**
 305      * Maximum array length for which fast path allocation is used.
 306      */
 307     public static final int MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH = 0x00FFFFFF;
 308 
 309     @Snippet
 310     public static Object allocatePrimitiveArrayPIC(KlassPointer hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize,
 311                     @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext,
 312                     @ConstantParameter OptionValues options, @ConstantParameter Counters counters) {
 313         // Primitive array types are eagerly pre-resolved. We can use a floating load.
 314         KlassPointer picHub = LoadConstantIndirectlyNode.loadKlass(hub);
 315         return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, false, options, counters);
 316     }
 317 
 318     @Snippet
 319     public static Object allocateArrayPIC(KlassPointer hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize,
 320                     @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext,
 321                     @ConstantParameter OptionValues options, @ConstantParameter Counters counters) {


 368         } else {
 369             result = newArrayStub(hub, length);
 370         }
 371         profileAllocation("array", allocationSize, typeContext, options);
 372         return result;
 373     }
 374 
 375     public static Object newArrayStub(KlassPointer hub, int length) {
 376         if (useNullAllocationStubs(INJECTED_VMCONFIG)) {
 377             return nonNullOrDeopt(newArrayOrNull(NEW_ARRAY_OR_NULL, hub, length));
 378         } else {
 379             return newArray(NEW_ARRAY, hub, length);
 380         }
 381     }
 382 
 383     @NodeIntrinsic(value = ForeignCallNode.class, injectedStampIsNonNull = true)
 384     private static native Object newArray(@ConstantNodeParameter ForeignCallDescriptor descriptor, KlassPointer hub, int length);
 385 
 386     @NodeIntrinsic(value = ForeignCallNode.class, injectedStampIsNonNull = false)
 387     private static native Object newArrayOrNull(@ConstantNodeParameter ForeignCallDescriptor descriptor, KlassPointer hub, int length);


















 388 
 389     /**
 390      * Deoptimizes if {@code obj == null} otherwise returns {@code obj}.
 391      */
 392     private static Object nonNullOrDeopt(Object obj) {
 393         if (obj == null) {
 394             DeoptimizeNode.deopt(None, RuntimeConstraint);
 395         }
 396         return obj;
 397     }
 398 
 399     @NodeIntrinsic(value = ForeignCallNode.class, injectedStampIsNonNull = true)
 400     public static native Object dynamicNewInstance(@ConstantNodeParameter ForeignCallDescriptor descriptor, Class<?> elementType);
 401 
 402     @NodeIntrinsic(value = ForeignCallNode.class, injectedStampIsNonNull = false)
 403     public static native Object dynamicNewInstanceOrNull(@ConstantNodeParameter ForeignCallDescriptor descriptor, Class<?> elementType);
 404 
 405     @Snippet
 406     public static Object allocateArrayDynamic(Class<?> elementType, Class<?> voidClass, int length, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister,
 407                     @ConstantParameter JavaKind knownElementKind, @ConstantParameter int knownLayoutHelper, Word prototypeMarkWord, @ConstantParameter OptionValues options,




 252                     @ConstantParameter Counters counters) {
 253         // Klass must be initialized by the time the first instance is allocated, therefore we can
 254         // just load it from the corresponding cell and avoid the resolution check. We have to use a
 255         // fixed load though, to prevent it from floating above the initialization.
 256         KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub);
 257         return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, picHub, prototypeMarkWord, fillContents, threadRegister, constantSize, typeContext, options, counters));
 258     }
 259 
 260     @Snippet
 261     public static Object allocateInstanceDynamic(Class<?> type, Class<?> classClass, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister,
 262                     @ConstantParameter OptionValues options, @ConstantParameter Counters counters) {
 263         if (probability(SLOW_PATH_PROBABILITY, type == null)) {
 264             DeoptimizeNode.deopt(None, RuntimeConstraint);
 265         }
 266         Class<?> nonNullType = PiNode.piCastNonNullClass(type, SnippetAnchorNode.anchor());
 267 
 268         if (probability(SLOW_PATH_PROBABILITY, DynamicNewInstanceNode.throwsInstantiationException(type, classClass))) {
 269             DeoptimizeNode.deopt(None, RuntimeConstraint);
 270         }
 271 
 272         return PiNode.piCastToSnippetReplaceeStamp(allocateInstanceDynamicHelper(type, fillContents, threadRegister, options, counters, nonNullType));
 273     }
 274 
 275     private static Object allocateInstanceDynamicHelper(Class<?> type, boolean fillContents, Register threadRegister, OptionValues options, Counters counters, Class<?> nonNullType) {
 276         KlassPointer hub = ClassGetHubNode.readClass(nonNullType);
 277         if (probability(FAST_PATH_PROBABILITY, !hub.isNull())) {
 278             KlassPointer nonNullHub = ClassGetHubNode.piCastNonNull(hub, SnippetAnchorNode.anchor());
 279 
 280             if (probability(FAST_PATH_PROBABILITY, isInstanceKlassFullyInitialized(nonNullHub))) {
 281                 int layoutHelper = readLayoutHelper(nonNullHub);
 282                 /*
 283                  * src/share/vm/oops/klass.hpp: For instances, layout helper is a positive number,
 284                  * the instance size. This size is already passed through align_object_size and
 285                  * scaled to bytes. The low order bit is set if instances of this class cannot be
 286                  * allocated using the fastpath.
 287                  */
 288                 if (probability(FAST_PATH_PROBABILITY, (layoutHelper & 1) == 0)) {
 289                     Word prototypeMarkWord = nonNullHub.readWord(prototypeMarkWordOffset(INJECTED_VMCONFIG), PROTOTYPE_MARK_WORD_LOCATION);
 290                     /*
 291                      * FIXME(je,ds): we should actually pass typeContext instead of "" but late
 292                      * binding of parameters is not yet supported by the GraphBuilderPlugin system.
 293                      */
 294                     return allocateInstanceHelper(layoutHelper, nonNullHub, prototypeMarkWord, fillContents, threadRegister, false, "", options, counters);
 295                 }
 296             } else {
 297                 DeoptimizeNode.deopt(None, RuntimeConstraint);
 298             }
 299         }
 300         return dynamicNewInstanceStub(type);

 301     }
 302 
 303     /**
 304      * Maximum array length for which fast path allocation is used.
 305      */
 306     public static final int MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH = 0x00FFFFFF;
 307 
 308     @Snippet
 309     public static Object allocatePrimitiveArrayPIC(KlassPointer hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize,
 310                     @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext,
 311                     @ConstantParameter OptionValues options, @ConstantParameter Counters counters) {
 312         // Primitive array types are eagerly pre-resolved. We can use a floating load.
 313         KlassPointer picHub = LoadConstantIndirectlyNode.loadKlass(hub);
 314         return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, false, options, counters);
 315     }
 316 
 317     @Snippet
 318     public static Object allocateArrayPIC(KlassPointer hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize,
 319                     @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext,
 320                     @ConstantParameter OptionValues options, @ConstantParameter Counters counters) {


 367         } else {
 368             result = newArrayStub(hub, length);
 369         }
 370         profileAllocation("array", allocationSize, typeContext, options);
 371         return result;
 372     }
 373 
 374     public static Object newArrayStub(KlassPointer hub, int length) {
 375         if (useNullAllocationStubs(INJECTED_VMCONFIG)) {
 376             return nonNullOrDeopt(newArrayOrNull(NEW_ARRAY_OR_NULL, hub, length));
 377         } else {
 378             return newArray(NEW_ARRAY, hub, length);
 379         }
 380     }
 381 
 382     @NodeIntrinsic(value = ForeignCallNode.class, injectedStampIsNonNull = true)
 383     private static native Object newArray(@ConstantNodeParameter ForeignCallDescriptor descriptor, KlassPointer hub, int length);
 384 
 385     @NodeIntrinsic(value = ForeignCallNode.class, injectedStampIsNonNull = false)
 386     private static native Object newArrayOrNull(@ConstantNodeParameter ForeignCallDescriptor descriptor, KlassPointer hub, int length);
 387 
 388     /**
 389      * New dynamic array stub that throws an {@link OutOfMemoryError} on allocation failure.
 390      */
 391     public static final ForeignCallDescriptor DYNAMIC_NEW_INSTANCE = new ForeignCallDescriptor("dynamic_new_instance", Object.class, Class.class);
 392 
 393     /**
 394      * New dynamic array stub that returns null on allocation failure.
 395      */
 396     public static final ForeignCallDescriptor DYNAMIC_NEW_INSTANCE_OR_NULL = new ForeignCallDescriptor("dynamic_new_instance_or_null", Object.class, Class.class);
 397 
 398     public static Object dynamicNewInstanceStub(Class<?> elementType) {
 399         if (useNullAllocationStubs(INJECTED_VMCONFIG)) {
 400             return nonNullOrDeopt(dynamicNewInstanceOrNull(DYNAMIC_NEW_INSTANCE_OR_NULL, elementType));
 401         } else {
 402             return dynamicNewInstance(DYNAMIC_NEW_INSTANCE, elementType);
 403         }
 404     }
 405 
 406     /**
 407      * Deoptimizes if {@code obj == null} otherwise returns {@code obj}.
 408      */
 409     private static Object nonNullOrDeopt(Object obj) {
 410         if (obj == null) {
 411             DeoptimizeNode.deopt(None, RuntimeConstraint);
 412         }
 413         return obj;
 414     }
 415 
 416     @NodeIntrinsic(value = ForeignCallNode.class, injectedStampIsNonNull = true)
 417     public static native Object dynamicNewInstance(@ConstantNodeParameter ForeignCallDescriptor descriptor, Class<?> elementType);
 418 
 419     @NodeIntrinsic(value = ForeignCallNode.class, injectedStampIsNonNull = false)
 420     public static native Object dynamicNewInstanceOrNull(@ConstantNodeParameter ForeignCallDescriptor descriptor, Class<?> elementType);
 421 
 422     @Snippet
 423     public static Object allocateArrayDynamic(Class<?> elementType, Class<?> voidClass, int length, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister,
 424                     @ConstantParameter JavaKind knownElementKind, @ConstantParameter int knownLayoutHelper, Word prototypeMarkWord, @ConstantParameter OptionValues options,


< prev index next >