1 /*
2 * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
121 * @param object
122 * @param otherLocation
123 * @return an earlier read or the original {@code read}
124 */
125 protected static ValueNode foldIndirection(ValueNode read, ValueNode object, LocationIdentity otherLocation) {
126 if (object instanceof Access) {
127 Access access = (Access) object;
128 if (access.getLocationIdentity().equals(otherLocation)) {
129 AddressNode address = access.getAddress();
130 if (address instanceof OffsetAddressNode) {
131 OffsetAddressNode offset = (OffsetAddressNode) address;
132 assert offset.getBase().stamp(NodeView.DEFAULT).isCompatible(read.stamp(NodeView.DEFAULT));
133 return offset.getBase();
134 }
135 }
136 }
137 return read;
138 }
139 }
140
141 public static ResolvedJavaType methodHolderClass(@Fold.InjectedParameter IntrinsicContext context) {
142 return context.getOriginalMethod().getDeclaringClass();
143 }
144
145 static ResolvedJavaType getType(@Fold.InjectedParameter IntrinsicContext context, String typeName) {
146 try {
147 UnresolvedJavaType unresolved = UnresolvedJavaType.create(typeName);
148 return unresolved.resolve(methodHolderClass(context));
149 } catch (LinkageError e) {
150 throw new GraalError(e);
151 }
152 }
153
154 static int getFieldOffset(ResolvedJavaType type, String fieldName) {
155 for (ResolvedJavaField field : type.getInstanceFields(true)) {
156 if (field.getName().equals(fieldName)) {
157 return field.getOffset();
158 }
159 }
160 throw new GraalError("missing field " + fieldName);
161 }
162
163 public static HotSpotJVMCIRuntime runtime() {
164 return HotSpotJVMCIRuntime.runtime();
165 }
166
167 @Fold
168 public static int getHeapWordSize(@InjectedParameter GraalHotSpotVMConfig injectedVMConfig) {
169 return injectedVMConfig.heapWordSize;
170 }
171
172 @Fold
173 public static int klassLayoutHelperNeutralValue(@InjectedParameter GraalHotSpotVMConfig config) {
567 public static int arrayLengthOffset(@InjectedParameter GraalHotSpotVMConfig config) {
568 return config.arrayOopDescLengthOffset();
569 }
570
571 public static Word arrayStart(int[] a) {
572 return WordFactory.unsigned(ComputeObjectAddressNode.get(a, ReplacementsUtil.getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Int)));
573 }
574
575 /**
576 * Idiom for making {@link GraalHotSpotVMConfig} a constant.
577 */
578 @Fold
579 public static int objectAlignment(@InjectedParameter GraalHotSpotVMConfig config) {
580 return config.objectAlignment;
581 }
582
583 /**
584 * Calls {@link #arrayAllocationSize(int, int, int, int)} using an injected VM configuration
585 * object.
586 */
587 public static int arrayAllocationSize(int length, int headerSize, int log2ElementSize) {
588 return arrayAllocationSize(length, headerSize, log2ElementSize, objectAlignment(INJECTED_VMCONFIG));
589 }
590
591 /**
592 * Computes the size of the memory chunk allocated for an array. This size accounts for the
593 * array header size, body size and any padding after the last element to satisfy object
594 * alignment requirements.
595 *
596 * @param length the number of elements in the array
597 * @param headerSize the size of the array header
598 * @param log2ElementSize log2 of the size of an element in the array
599 * @param alignment the {@linkplain GraalHotSpotVMConfig#objectAlignment object alignment
600 * requirement}
601 * @return the size of the memory chunk
602 */
603 public static int arrayAllocationSize(int length, int headerSize, int log2ElementSize, int alignment) {
604 int size = (length << log2ElementSize) + headerSize + (alignment - 1);
605 int mask = ~(alignment - 1);
606 return size & mask;
607 }
608
609 @Fold
610 public static int instanceHeaderSize(@InjectedParameter GraalHotSpotVMConfig config) {
611 return config.useCompressedClassPointers ? (2 * wordSize()) - 4 : 2 * wordSize();
612 }
613
614 @Fold
615 public static byte dirtyCardValue(@InjectedParameter GraalHotSpotVMConfig config) {
616 return config.dirtyCardValue;
617 }
618
619 @Fold
620 public static byte g1YoungCardValue(@InjectedParameter GraalHotSpotVMConfig config) {
621 return config.g1YoungCardValue;
622 }
623
624 @Fold
625 public static int cardTableShift(@InjectedParameter GraalHotSpotVMConfig config) {
713 if (verifyOops(INJECTED_VMCONFIG)) {
714 verifyOopStub(VERIFY_OOP, object);
715 }
716 return object;
717 }
718
719 @NodeIntrinsic(ForeignCallNode.class)
720 private static native Object verifyOopStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object);
721
722 public static Word loadWordFromObject(Object object, int offset) {
723 ReplacementsUtil.staticAssert(offset != hubOffset(INJECTED_VMCONFIG), "Use loadHubIntrinsic instead of loadWordFromObject");
724 return loadWordFromObjectIntrinsic(object, offset, LocationIdentity.any(), getWordKind());
725 }
726
727 public static Word loadWordFromObject(Object object, int offset, LocationIdentity identity) {
728 ReplacementsUtil.staticAssert(offset != hubOffset(INJECTED_VMCONFIG), "Use loadHubIntrinsic instead of loadWordFromObject");
729 return loadWordFromObjectIntrinsic(object, offset, identity, getWordKind());
730 }
731
732 public static KlassPointer loadKlassFromObject(Object object, int offset, LocationIdentity identity) {
733 ReplacementsUtil.staticAssert(offset != hubOffset(INJECTED_VMCONFIG), "Use loadHubIntrinsic instead of loadWordFromObject");
734 return loadKlassFromObjectIntrinsic(object, offset, identity, getWordKind());
735 }
736
737 /**
738 * Reads the value of a given register.
739 *
740 * @param register a register which must not be available to the register allocator
741 * @return the value of {@code register} as a word
742 */
743 public static Word registerAsWord(@ConstantNodeParameter Register register) {
744 return registerAsWord(register, true, false);
745 }
746
747 @NodeIntrinsic(value = ReadRegisterNode.class)
748 public static native Word registerAsWord(@ConstantNodeParameter Register register, @ConstantNodeParameter boolean directUse, @ConstantNodeParameter boolean incoming);
749
750 @NodeIntrinsic(value = WriteRegisterNode.class)
751 public static native void writeRegisterAsWord(@ConstantNodeParameter Register register, Word value);
752
753 @NodeIntrinsic(value = RawLoadNode.class)
|
1 /*
2 * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
121 * @param object
122 * @param otherLocation
123 * @return an earlier read or the original {@code read}
124 */
125 protected static ValueNode foldIndirection(ValueNode read, ValueNode object, LocationIdentity otherLocation) {
126 if (object instanceof Access) {
127 Access access = (Access) object;
128 if (access.getLocationIdentity().equals(otherLocation)) {
129 AddressNode address = access.getAddress();
130 if (address instanceof OffsetAddressNode) {
131 OffsetAddressNode offset = (OffsetAddressNode) address;
132 assert offset.getBase().stamp(NodeView.DEFAULT).isCompatible(read.stamp(NodeView.DEFAULT));
133 return offset.getBase();
134 }
135 }
136 }
137 return read;
138 }
139 }
140
141 @Fold
142 public static ResolvedJavaType methodHolderClass(@InjectedParameter IntrinsicContext context) {
143 return context.getOriginalMethod().getDeclaringClass();
144 }
145
146 @Fold
147 static ResolvedJavaType getType(@Fold.InjectedParameter IntrinsicContext context, String typeName) {
148 try {
149 UnresolvedJavaType unresolved = UnresolvedJavaType.create(typeName);
150 return unresolved.resolve(methodHolderClass(context));
151 } catch (LinkageError e) {
152 throw new GraalError(e);
153 }
154 }
155
156 @Fold
157 static int getFieldOffset(ResolvedJavaType type, String fieldName) {
158 for (ResolvedJavaField field : type.getInstanceFields(true)) {
159 if (field.getName().equals(fieldName)) {
160 return field.getOffset();
161 }
162 }
163 throw new GraalError("missing field " + fieldName);
164 }
165
166 public static HotSpotJVMCIRuntime runtime() {
167 return HotSpotJVMCIRuntime.runtime();
168 }
169
170 @Fold
171 public static int getHeapWordSize(@InjectedParameter GraalHotSpotVMConfig injectedVMConfig) {
172 return injectedVMConfig.heapWordSize;
173 }
174
175 @Fold
176 public static int klassLayoutHelperNeutralValue(@InjectedParameter GraalHotSpotVMConfig config) {
570 public static int arrayLengthOffset(@InjectedParameter GraalHotSpotVMConfig config) {
571 return config.arrayOopDescLengthOffset();
572 }
573
574 public static Word arrayStart(int[] a) {
575 return WordFactory.unsigned(ComputeObjectAddressNode.get(a, ReplacementsUtil.getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Int)));
576 }
577
578 /**
579 * Idiom for making {@link GraalHotSpotVMConfig} a constant.
580 */
581 @Fold
582 public static int objectAlignment(@InjectedParameter GraalHotSpotVMConfig config) {
583 return config.objectAlignment;
584 }
585
586 /**
587 * Calls {@link #arrayAllocationSize(int, int, int, int)} using an injected VM configuration
588 * object.
589 */
590 public static long arrayAllocationSize(int length, int headerSize, int log2ElementSize) {
591 return arrayAllocationSize(length, headerSize, log2ElementSize, objectAlignment(INJECTED_VMCONFIG));
592 }
593
594 /**
595 * Computes the size of the memory chunk allocated for an array. This size accounts for the
596 * array header size, body size and any padding after the last element to satisfy object
597 * alignment requirements.
598 *
599 * @param length the number of elements in the array
600 * @param headerSize the size of the array header
601 * @param log2ElementSize log2 of the size of an element in the array
602 * @param alignment the {@linkplain GraalHotSpotVMConfig#objectAlignment object alignment
603 * requirement}
604 * @return the size of the memory chunk
605 */
606 public static long arrayAllocationSize(int length, int headerSize, int log2ElementSize, int alignment) {
607 long size = ((long) length << log2ElementSize) + headerSize + (alignment - 1);
608 long mask = ~(alignment - 1);
609 return size & mask;
610 }
611
612 @Fold
613 public static int instanceHeaderSize(@InjectedParameter GraalHotSpotVMConfig config) {
614 return config.useCompressedClassPointers ? (2 * wordSize()) - 4 : 2 * wordSize();
615 }
616
617 @Fold
618 public static byte dirtyCardValue(@InjectedParameter GraalHotSpotVMConfig config) {
619 return config.dirtyCardValue;
620 }
621
622 @Fold
623 public static byte g1YoungCardValue(@InjectedParameter GraalHotSpotVMConfig config) {
624 return config.g1YoungCardValue;
625 }
626
627 @Fold
628 public static int cardTableShift(@InjectedParameter GraalHotSpotVMConfig config) {
716 if (verifyOops(INJECTED_VMCONFIG)) {
717 verifyOopStub(VERIFY_OOP, object);
718 }
719 return object;
720 }
721
722 @NodeIntrinsic(ForeignCallNode.class)
723 private static native Object verifyOopStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object);
724
725 public static Word loadWordFromObject(Object object, int offset) {
726 ReplacementsUtil.staticAssert(offset != hubOffset(INJECTED_VMCONFIG), "Use loadHubIntrinsic instead of loadWordFromObject");
727 return loadWordFromObjectIntrinsic(object, offset, LocationIdentity.any(), getWordKind());
728 }
729
730 public static Word loadWordFromObject(Object object, int offset, LocationIdentity identity) {
731 ReplacementsUtil.staticAssert(offset != hubOffset(INJECTED_VMCONFIG), "Use loadHubIntrinsic instead of loadWordFromObject");
732 return loadWordFromObjectIntrinsic(object, offset, identity, getWordKind());
733 }
734
735 public static KlassPointer loadKlassFromObject(Object object, int offset, LocationIdentity identity) {
736 ReplacementsUtil.staticAssert(offset != hubOffset(INJECTED_VMCONFIG), "Use loadHubIntrinsic instead of loadKlassFromObject");
737 return loadKlassFromObjectIntrinsic(object, offset, identity, getWordKind());
738 }
739
740 /**
741 * Reads the value of a given register.
742 *
743 * @param register a register which must not be available to the register allocator
744 * @return the value of {@code register} as a word
745 */
746 public static Word registerAsWord(@ConstantNodeParameter Register register) {
747 return registerAsWord(register, true, false);
748 }
749
750 @NodeIntrinsic(value = ReadRegisterNode.class)
751 public static native Word registerAsWord(@ConstantNodeParameter Register register, @ConstantNodeParameter boolean directUse, @ConstantNodeParameter boolean incoming);
752
753 @NodeIntrinsic(value = WriteRegisterNode.class)
754 public static native void writeRegisterAsWord(@ConstantNodeParameter Register register, Word value);
755
756 @NodeIntrinsic(value = RawLoadNode.class)
|