25 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
26 import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.VERIFY_OOP;
27 import static org.graalvm.compiler.hotspot.replacements.UnsafeAccess.UNSAFE;
28 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
29 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
30
31 import org.graalvm.compiler.api.replacements.Fold;
32 import org.graalvm.compiler.api.replacements.Fold.InjectedParameter;
33 import org.graalvm.compiler.core.common.LocationIdentity;
34 import org.graalvm.compiler.core.common.SuppressFBWarnings;
35 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
36 import org.graalvm.compiler.core.common.type.ObjectStamp;
37 import org.graalvm.compiler.core.common.type.TypeReference;
38 import org.graalvm.compiler.debug.GraalError;
39 import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
40 import org.graalvm.compiler.graph.Node.NodeIntrinsic;
41 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
42 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
43 import org.graalvm.compiler.hotspot.nodes.CompressionNode;
44 import org.graalvm.compiler.hotspot.nodes.ComputeObjectAddressNode;
45 import org.graalvm.compiler.hotspot.nodes.SnippetAnchorNode;
46 import org.graalvm.compiler.hotspot.word.KlassPointer;
47 import org.graalvm.compiler.nodes.CanonicalizableLocation;
48 import org.graalvm.compiler.nodes.ConstantNode;
49 import org.graalvm.compiler.nodes.NamedLocationIdentity;
50 import org.graalvm.compiler.nodes.ValueNode;
51 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
52 import org.graalvm.compiler.nodes.extended.GuardingNode;
53 import org.graalvm.compiler.nodes.extended.LoadHubNode;
54 import org.graalvm.compiler.nodes.extended.StoreHubNode;
55 import org.graalvm.compiler.nodes.extended.UnsafeLoadNode;
56 import org.graalvm.compiler.nodes.memory.Access;
57 import org.graalvm.compiler.nodes.memory.address.AddressNode;
58 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
59 import org.graalvm.compiler.nodes.type.StampTool;
60 import org.graalvm.compiler.replacements.ReplacementsUtil;
61 import org.graalvm.compiler.replacements.nodes.ReadRegisterNode;
62 import org.graalvm.compiler.replacements.nodes.WriteRegisterNode;
63 import org.graalvm.compiler.word.Word;
64
65 import jdk.vm.ci.code.CodeUtil;
66 import jdk.vm.ci.code.Register;
67 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
68 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider;
69 import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
70 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
71 import jdk.vm.ci.meta.Assumptions;
72 import jdk.vm.ci.meta.Assumptions.AssumptionResult;
73 import jdk.vm.ci.meta.JavaKind;
74 import jdk.vm.ci.meta.ResolvedJavaType;
75
372 ValueNode javaObject = findReadHub(object);
373 if (javaObject != null) {
374 if (javaObject.stamp() instanceof ObjectStamp) {
375 ObjectStamp stamp = (ObjectStamp) javaObject.stamp();
376 HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) stamp.javaType(tool.getMetaAccess());
377 if (type.isArray() && !type.getComponentType().isPrimitive()) {
378 int layout = type.layoutHelper();
379 return ConstantNode.forInt(layout);
380 }
381 }
382 }
383 return read;
384 }
385 };
386
387 @Fold
388 public static int klassLayoutHelperOffset(@InjectedParameter GraalHotSpotVMConfig config) {
389 return config.klassLayoutHelperOffset;
390 }
391
392 public static int readLayoutHelper(KlassPointer hub) {
393 // return hub.readInt(klassLayoutHelperOffset(), KLASS_LAYOUT_HELPER_LOCATION);
394 GuardingNode anchorNode = SnippetAnchorNode.anchor();
395 return loadKlassLayoutHelperIntrinsic(hub, anchorNode);
396 }
397
398 @NodeIntrinsic(value = KlassLayoutHelperNode.class)
399 public static native int loadKlassLayoutHelperIntrinsic(KlassPointer object, GuardingNode anchor);
400
401 @NodeIntrinsic(value = KlassLayoutHelperNode.class)
402 public static native int loadKlassLayoutHelperIntrinsic(KlassPointer object);
403
404 /**
405 * Checks if class {@code klass} is an array.
406 *
407 * See: Klass::layout_helper_is_array
408 *
409 * @param klass the class to be checked
410 * @return true if klass is an array, false otherwise
411 */
412 public static boolean klassIsArray(KlassPointer klass) {
413 /*
414 * The less-than check only works if both values are ints. We use local variables to make
415 * sure these are still ints and haven't changed.
416 */
417 final int layoutHelper = readLayoutHelper(klass);
418 final int layoutHelperNeutralValue = config(INJECTED_VMCONFIG).klassLayoutHelperNeutralValue;
419 return (layoutHelper < layoutHelperNeutralValue);
420 }
421
422 public static final LocationIdentity ARRAY_KLASS_COMPONENT_MIRROR = NamedLocationIdentity.immutable("ArrayKlass::_component_mirror");
423
424 @Fold
425 public static int arrayKlassComponentMirrorOffset(@InjectedParameter GraalHotSpotVMConfig config) {
426 return config.getFieldOffset("ArrayKlass::_component_mirror", Integer.class, "oop");
427 }
428
429 public static final LocationIdentity KLASS_SUPER_KLASS_LOCATION = NamedLocationIdentity.immutable("Klass::_super");
430
431 @Fold
432 public static int klassSuperKlassOffset(@InjectedParameter GraalHotSpotVMConfig config) {
433 return config.klassSuperKlassOffset;
434 }
435
436 public static final LocationIdentity MARK_WORD_LOCATION = NamedLocationIdentity.mutable("MarkWord");
437
462 }
463 return read;
464 }
465 };
466
467 @Fold
468 static int hubOffset(@InjectedParameter GraalHotSpotVMConfig config) {
469 return config.hubOffset;
470 }
471
472 public static void initializeObjectHeader(Word memory, Word markWord, KlassPointer hub) {
473 memory.writeWord(markOffset(INJECTED_VMCONFIG), markWord, MARK_WORD_LOCATION);
474 StoreHubNode.write(memory, hub);
475 }
476
477 @Fold
478 public static int unlockedMask(@InjectedParameter GraalHotSpotVMConfig config) {
479 return config.unlockedMask;
480 }
481
482 /**
483 * Mask for a biasable, locked or unlocked mark word.
484 *
485 * <pre>
486 * +----------------------------------+-+-+
487 * | 1|1|1|
488 * +----------------------------------+-+-+
489 * </pre>
490 *
491 */
492 @Fold
493 public static int biasedLockMaskInPlace(@InjectedParameter GraalHotSpotVMConfig config) {
494 return config.biasedLockMaskInPlace;
495 }
496
497 @Fold
498 public static int epochMaskInPlace(@InjectedParameter GraalHotSpotVMConfig config) {
499 return config.epochMaskInPlace;
500 }
501
609 public static int superCheckOffsetOffset(@InjectedParameter GraalHotSpotVMConfig config) {
610 return config.superCheckOffsetOffset;
611 }
612
613 public static final LocationIdentity SECONDARY_SUPER_CACHE_LOCATION = NamedLocationIdentity.mutable("SecondarySuperCache");
614
615 @Fold
616 public static int secondarySuperCacheOffset(@InjectedParameter GraalHotSpotVMConfig config) {
617 return config.secondarySuperCacheOffset;
618 }
619
620 public static final LocationIdentity SECONDARY_SUPERS_LOCATION = NamedLocationIdentity.immutable("SecondarySupers");
621
622 @Fold
623 public static int secondarySupersOffset(@InjectedParameter GraalHotSpotVMConfig config) {
624 return config.secondarySupersOffset;
625 }
626
627 public static final LocationIdentity DISPLACED_MARK_WORD_LOCATION = NamedLocationIdentity.mutable("DisplacedMarkWord");
628
629 @Fold
630 public static int lockDisplacedMarkOffset(@InjectedParameter GraalHotSpotVMConfig config) {
631 return config.basicLockDisplacedHeaderOffset;
632 }
633
634 @Fold
635 public static boolean useBiasedLocking(@InjectedParameter GraalHotSpotVMConfig config) {
636 return config.useBiasedLocking;
637 }
638
639 @Fold
640 public static boolean useDeferredInitBarriers(@InjectedParameter GraalHotSpotVMConfig config) {
641 return config.useDeferredInitBarriers;
642 }
643
644 @Fold
645 public static boolean useG1GC(@InjectedParameter GraalHotSpotVMConfig config) {
646 return config.useG1GC;
647 }
648
692 ReplacementsUtil.staticAssert(offset != hubOffset(INJECTED_VMCONFIG), "Use loadHubIntrinsic instead of loadWordFromObject");
693 return loadKlassFromObjectIntrinsic(object, offset, getWordKind(), identity);
694 }
695
696 /**
697 * Reads the value of a given register.
698 *
699 * @param register a register which must not be available to the register allocator
700 * @return the value of {@code register} as a word
701 */
702 public static Word registerAsWord(@ConstantNodeParameter Register register) {
703 return registerAsWord(register, true, false);
704 }
705
706 @NodeIntrinsic(value = ReadRegisterNode.class, setStampFromReturnType = true)
707 public static native Word registerAsWord(@ConstantNodeParameter Register register, @ConstantNodeParameter boolean directUse, @ConstantNodeParameter boolean incoming);
708
709 @NodeIntrinsic(value = WriteRegisterNode.class, setStampFromReturnType = true)
710 public static native void writeRegisterAsWord(@ConstantNodeParameter Register register, Word value);
711
712 @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true)
713 private static native Word loadWordFromObjectIntrinsic(Object object, long offset, @ConstantNodeParameter JavaKind wordKind, @ConstantNodeParameter LocationIdentity locationIdentity);
714
715 @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true)
716 private static native KlassPointer loadKlassFromObjectIntrinsic(Object object, long offset, @ConstantNodeParameter JavaKind wordKind, @ConstantNodeParameter LocationIdentity locationIdentity);
717
718 @NodeIntrinsic(value = LoadHubNode.class)
719 public static native KlassPointer loadHubIntrinsic(Object object);
720
721 @Fold
722 public static int log2WordSize() {
723 return CodeUtil.log2(wordSize());
724 }
725
726 public static final LocationIdentity CLASS_STATE_LOCATION = NamedLocationIdentity.mutable("ClassState");
727
728 @Fold
729 public static int instanceKlassInitStateOffset(@InjectedParameter GraalHotSpotVMConfig config) {
730 return config.instanceKlassInitStateOffset;
731 }
732
733 @Fold
734 public static int instanceKlassStateFullyInitialized(@InjectedParameter GraalHotSpotVMConfig config) {
735 return config.instanceKlassStateFullyInitialized;
|
25 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
26 import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.VERIFY_OOP;
27 import static org.graalvm.compiler.hotspot.replacements.UnsafeAccess.UNSAFE;
28 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
29 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
30
31 import org.graalvm.compiler.api.replacements.Fold;
32 import org.graalvm.compiler.api.replacements.Fold.InjectedParameter;
33 import org.graalvm.compiler.core.common.LocationIdentity;
34 import org.graalvm.compiler.core.common.SuppressFBWarnings;
35 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
36 import org.graalvm.compiler.core.common.type.ObjectStamp;
37 import org.graalvm.compiler.core.common.type.TypeReference;
38 import org.graalvm.compiler.debug.GraalError;
39 import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
40 import org.graalvm.compiler.graph.Node.NodeIntrinsic;
41 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
42 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
43 import org.graalvm.compiler.hotspot.nodes.CompressionNode;
44 import org.graalvm.compiler.hotspot.nodes.ComputeObjectAddressNode;
45 import org.graalvm.compiler.hotspot.word.KlassPointer;
46 import org.graalvm.compiler.nodes.CanonicalizableLocation;
47 import org.graalvm.compiler.nodes.ConstantNode;
48 import org.graalvm.compiler.nodes.NamedLocationIdentity;
49 import org.graalvm.compiler.nodes.ValueNode;
50 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
51 import org.graalvm.compiler.nodes.extended.LoadHubNode;
52 import org.graalvm.compiler.nodes.extended.StoreHubNode;
53 import org.graalvm.compiler.nodes.extended.RawLoadNode;
54 import org.graalvm.compiler.nodes.memory.Access;
55 import org.graalvm.compiler.nodes.memory.address.AddressNode;
56 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
57 import org.graalvm.compiler.nodes.type.StampTool;
58 import org.graalvm.compiler.replacements.ReplacementsUtil;
59 import org.graalvm.compiler.replacements.nodes.ReadRegisterNode;
60 import org.graalvm.compiler.replacements.nodes.WriteRegisterNode;
61 import org.graalvm.compiler.word.Word;
62
63 import jdk.vm.ci.code.CodeUtil;
64 import jdk.vm.ci.code.Register;
65 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
66 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider;
67 import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
68 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
69 import jdk.vm.ci.meta.Assumptions;
70 import jdk.vm.ci.meta.Assumptions.AssumptionResult;
71 import jdk.vm.ci.meta.JavaKind;
72 import jdk.vm.ci.meta.ResolvedJavaType;
73
370 ValueNode javaObject = findReadHub(object);
371 if (javaObject != null) {
372 if (javaObject.stamp() instanceof ObjectStamp) {
373 ObjectStamp stamp = (ObjectStamp) javaObject.stamp();
374 HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) stamp.javaType(tool.getMetaAccess());
375 if (type.isArray() && !type.getComponentType().isPrimitive()) {
376 int layout = type.layoutHelper();
377 return ConstantNode.forInt(layout);
378 }
379 }
380 }
381 return read;
382 }
383 };
384
385 @Fold
386 public static int klassLayoutHelperOffset(@InjectedParameter GraalHotSpotVMConfig config) {
387 return config.klassLayoutHelperOffset;
388 }
389
390 @NodeIntrinsic(value = KlassLayoutHelperNode.class)
391 public static native int readLayoutHelper(KlassPointer object);
392
393 /**
394 * Checks if class {@code klass} is an array.
395 *
396 * See: Klass::layout_helper_is_array
397 *
398 * @param klassNonNull the class to be checked
399 * @return true if klassNonNull is an array, false otherwise
400 */
401 public static boolean klassIsArray(KlassPointer klassNonNull) {
402 /*
403 * The less-than check only works if both values are ints. We use local variables to make
404 * sure these are still ints and haven't changed.
405 */
406 final int layoutHelper = readLayoutHelper(klassNonNull);
407 final int layoutHelperNeutralValue = config(INJECTED_VMCONFIG).klassLayoutHelperNeutralValue;
408 return (layoutHelper < layoutHelperNeutralValue);
409 }
410
411 public static final LocationIdentity ARRAY_KLASS_COMPONENT_MIRROR = NamedLocationIdentity.immutable("ArrayKlass::_component_mirror");
412
413 @Fold
414 public static int arrayKlassComponentMirrorOffset(@InjectedParameter GraalHotSpotVMConfig config) {
415 return config.getFieldOffset("ArrayKlass::_component_mirror", Integer.class, "oop");
416 }
417
418 public static final LocationIdentity KLASS_SUPER_KLASS_LOCATION = NamedLocationIdentity.immutable("Klass::_super");
419
420 @Fold
421 public static int klassSuperKlassOffset(@InjectedParameter GraalHotSpotVMConfig config) {
422 return config.klassSuperKlassOffset;
423 }
424
425 public static final LocationIdentity MARK_WORD_LOCATION = NamedLocationIdentity.mutable("MarkWord");
426
451 }
452 return read;
453 }
454 };
455
456 @Fold
457 static int hubOffset(@InjectedParameter GraalHotSpotVMConfig config) {
458 return config.hubOffset;
459 }
460
461 public static void initializeObjectHeader(Word memory, Word markWord, KlassPointer hub) {
462 memory.writeWord(markOffset(INJECTED_VMCONFIG), markWord, MARK_WORD_LOCATION);
463 StoreHubNode.write(memory, hub);
464 }
465
466 @Fold
467 public static int unlockedMask(@InjectedParameter GraalHotSpotVMConfig config) {
468 return config.unlockedMask;
469 }
470
471 @Fold
472 public static int monitorMask(@InjectedParameter GraalHotSpotVMConfig config) {
473 return config.monitorMask;
474 }
475
476 @Fold
477 public static int objectMonitorOwnerOffset(@InjectedParameter GraalHotSpotVMConfig config) {
478 return config.objectMonitorOwner;
479 }
480
481 @Fold
482 public static int objectMonitorRecursionsOffset(@InjectedParameter GraalHotSpotVMConfig config) {
483 return config.objectMonitorRecursions;
484 }
485
486 @Fold
487 public static int objectMonitorCxqOffset(@InjectedParameter GraalHotSpotVMConfig config) {
488 return config.objectMonitorCxq;
489 }
490
491 @Fold
492 public static int objectMonitorEntryListOffset(@InjectedParameter GraalHotSpotVMConfig config) {
493 return config.objectMonitorEntryList;
494 }
495
496 /**
497 * Mask for a biasable, locked or unlocked mark word.
498 *
499 * <pre>
500 * +----------------------------------+-+-+
501 * | 1|1|1|
502 * +----------------------------------+-+-+
503 * </pre>
504 *
505 */
506 @Fold
507 public static int biasedLockMaskInPlace(@InjectedParameter GraalHotSpotVMConfig config) {
508 return config.biasedLockMaskInPlace;
509 }
510
511 @Fold
512 public static int epochMaskInPlace(@InjectedParameter GraalHotSpotVMConfig config) {
513 return config.epochMaskInPlace;
514 }
515
623 public static int superCheckOffsetOffset(@InjectedParameter GraalHotSpotVMConfig config) {
624 return config.superCheckOffsetOffset;
625 }
626
627 public static final LocationIdentity SECONDARY_SUPER_CACHE_LOCATION = NamedLocationIdentity.mutable("SecondarySuperCache");
628
629 @Fold
630 public static int secondarySuperCacheOffset(@InjectedParameter GraalHotSpotVMConfig config) {
631 return config.secondarySuperCacheOffset;
632 }
633
634 public static final LocationIdentity SECONDARY_SUPERS_LOCATION = NamedLocationIdentity.immutable("SecondarySupers");
635
636 @Fold
637 public static int secondarySupersOffset(@InjectedParameter GraalHotSpotVMConfig config) {
638 return config.secondarySupersOffset;
639 }
640
641 public static final LocationIdentity DISPLACED_MARK_WORD_LOCATION = NamedLocationIdentity.mutable("DisplacedMarkWord");
642
643 public static final LocationIdentity OBJECT_MONITOR_OWNER_LOCATION = NamedLocationIdentity.mutable("ObjectMonitor::_owner");
644
645 public static final LocationIdentity OBJECT_MONITOR_RECURSION_LOCATION = NamedLocationIdentity.mutable("ObjectMonitor::_recursions");
646
647 public static final LocationIdentity OBJECT_MONITOR_CXQ_LOCATION = NamedLocationIdentity.mutable("ObjectMonitor::_cxq");
648
649 public static final LocationIdentity OBJECT_MONITOR_ENTRY_LIST_LOCATION = NamedLocationIdentity.mutable("ObjectMonitor::_EntryList");
650
651 @Fold
652 public static int lockDisplacedMarkOffset(@InjectedParameter GraalHotSpotVMConfig config) {
653 return config.basicLockDisplacedHeaderOffset;
654 }
655
656 @Fold
657 public static boolean useBiasedLocking(@InjectedParameter GraalHotSpotVMConfig config) {
658 return config.useBiasedLocking;
659 }
660
661 @Fold
662 public static boolean useDeferredInitBarriers(@InjectedParameter GraalHotSpotVMConfig config) {
663 return config.useDeferredInitBarriers;
664 }
665
666 @Fold
667 public static boolean useG1GC(@InjectedParameter GraalHotSpotVMConfig config) {
668 return config.useG1GC;
669 }
670
714 ReplacementsUtil.staticAssert(offset != hubOffset(INJECTED_VMCONFIG), "Use loadHubIntrinsic instead of loadWordFromObject");
715 return loadKlassFromObjectIntrinsic(object, offset, getWordKind(), identity);
716 }
717
718 /**
719 * Reads the value of a given register.
720 *
721 * @param register a register which must not be available to the register allocator
722 * @return the value of {@code register} as a word
723 */
724 public static Word registerAsWord(@ConstantNodeParameter Register register) {
725 return registerAsWord(register, true, false);
726 }
727
728 @NodeIntrinsic(value = ReadRegisterNode.class, setStampFromReturnType = true)
729 public static native Word registerAsWord(@ConstantNodeParameter Register register, @ConstantNodeParameter boolean directUse, @ConstantNodeParameter boolean incoming);
730
731 @NodeIntrinsic(value = WriteRegisterNode.class, setStampFromReturnType = true)
732 public static native void writeRegisterAsWord(@ConstantNodeParameter Register register, Word value);
733
734 @NodeIntrinsic(value = RawLoadNode.class, setStampFromReturnType = true)
735 private static native Word loadWordFromObjectIntrinsic(Object object, long offset, @ConstantNodeParameter JavaKind wordKind, @ConstantNodeParameter LocationIdentity locationIdentity);
736
737 @NodeIntrinsic(value = RawLoadNode.class, setStampFromReturnType = true)
738 private static native KlassPointer loadKlassFromObjectIntrinsic(Object object, long offset, @ConstantNodeParameter JavaKind wordKind, @ConstantNodeParameter LocationIdentity locationIdentity);
739
740 @NodeIntrinsic(value = LoadHubNode.class)
741 public static native KlassPointer loadHubIntrinsic(Object object);
742
743 @Fold
744 public static int log2WordSize() {
745 return CodeUtil.log2(wordSize());
746 }
747
748 public static final LocationIdentity CLASS_STATE_LOCATION = NamedLocationIdentity.mutable("ClassState");
749
750 @Fold
751 public static int instanceKlassInitStateOffset(@InjectedParameter GraalHotSpotVMConfig config) {
752 return config.instanceKlassInitStateOffset;
753 }
754
755 @Fold
756 public static int instanceKlassStateFullyInitialized(@InjectedParameter GraalHotSpotVMConfig config) {
757 return config.instanceKlassStateFullyInitialized;
|