22 */ |
22 */ |
23 package org.graalvm.compiler.nodes.virtual; |
23 package org.graalvm.compiler.nodes.virtual; |
24 |
24 |
25 import java.nio.ByteOrder; |
25 import java.nio.ByteOrder; |
26 |
26 |
|
27 import org.graalvm.compiler.core.common.spi.ArrayOffsetProvider; |
27 import org.graalvm.compiler.graph.NodeClass; |
28 import org.graalvm.compiler.graph.NodeClass; |
28 import org.graalvm.compiler.nodeinfo.NodeInfo; |
29 import org.graalvm.compiler.nodeinfo.NodeInfo; |
29 import org.graalvm.compiler.nodeinfo.Verbosity; |
30 import org.graalvm.compiler.nodeinfo.Verbosity; |
30 import org.graalvm.compiler.nodes.ConstantNode; |
31 import org.graalvm.compiler.nodes.ConstantNode; |
31 import org.graalvm.compiler.nodes.FixedNode; |
32 import org.graalvm.compiler.nodes.FixedNode; |
33 import org.graalvm.compiler.nodes.spi.ArrayLengthProvider; |
34 import org.graalvm.compiler.nodes.spi.ArrayLengthProvider; |
34 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; |
35 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; |
35 |
36 |
36 import jdk.vm.ci.meta.JavaKind; |
37 import jdk.vm.ci.meta.JavaKind; |
37 import jdk.vm.ci.meta.ResolvedJavaType; |
38 import jdk.vm.ci.meta.ResolvedJavaType; |
38 import sun.misc.Unsafe; |
|
39 |
39 |
40 @NodeInfo(nameTemplate = "VirtualArray({p#objectId}) {p#componentType/s}[{p#length}]") |
40 @NodeInfo(nameTemplate = "VirtualArray({p#objectId}) {p#componentType/s}[{p#length}]") |
41 public class VirtualArrayNode extends VirtualObjectNode implements ArrayLengthProvider { |
41 public class VirtualArrayNode extends VirtualObjectNode implements ArrayLengthProvider { |
42 |
42 |
43 public static final NodeClass<VirtualArrayNode> TYPE = NodeClass.create(VirtualArrayNode.class); |
43 public static final NodeClass<VirtualArrayNode> TYPE = NodeClass.create(VirtualArrayNode.class); |
86 public String entryName(int index) { |
86 public String entryName(int index) { |
87 return "[" + index + "]"; |
87 return "[" + index + "]"; |
88 } |
88 } |
89 |
89 |
90 @Override |
90 @Override |
91 public int entryIndexForOffset(long constantOffset, JavaKind expectedEntryKind) { |
91 public int entryIndexForOffset(ArrayOffsetProvider arrayOffsetProvider, long constantOffset, JavaKind expectedEntryKind) { |
92 return entryIndexForOffset(constantOffset, expectedEntryKind, componentType, length); |
92 return entryIndexForOffset(arrayOffsetProvider, constantOffset, expectedEntryKind, componentType, length); |
93 } |
93 } |
94 |
94 |
95 public static int entryIndexForOffset(long constantOffset, JavaKind expectedEntryKind, ResolvedJavaType componentType, int length) { |
95 public static int entryIndexForOffset(ArrayOffsetProvider arrayOffsetProvider, long constantOffset, JavaKind expectedEntryKind, ResolvedJavaType componentType, int length) { |
96 int baseOffset; |
96 int baseOffset = arrayOffsetProvider.arrayBaseOffset(componentType.getJavaKind()); |
97 int indexScale; |
97 int indexScale = arrayOffsetProvider.arrayScalingFactor(componentType.getJavaKind()); |
98 switch (componentType.getJavaKind()) { |
98 |
99 case Boolean: |
|
100 baseOffset = Unsafe.ARRAY_BOOLEAN_BASE_OFFSET; |
|
101 indexScale = Unsafe.ARRAY_BOOLEAN_INDEX_SCALE; |
|
102 break; |
|
103 case Byte: |
|
104 baseOffset = Unsafe.ARRAY_BYTE_BASE_OFFSET; |
|
105 indexScale = Unsafe.ARRAY_BYTE_INDEX_SCALE; |
|
106 break; |
|
107 case Short: |
|
108 baseOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET; |
|
109 indexScale = Unsafe.ARRAY_SHORT_INDEX_SCALE; |
|
110 break; |
|
111 case Char: |
|
112 baseOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET; |
|
113 indexScale = Unsafe.ARRAY_CHAR_INDEX_SCALE; |
|
114 break; |
|
115 case Int: |
|
116 baseOffset = Unsafe.ARRAY_INT_BASE_OFFSET; |
|
117 indexScale = Unsafe.ARRAY_INT_INDEX_SCALE; |
|
118 break; |
|
119 case Long: |
|
120 baseOffset = Unsafe.ARRAY_LONG_BASE_OFFSET; |
|
121 indexScale = Unsafe.ARRAY_LONG_INDEX_SCALE; |
|
122 break; |
|
123 case Float: |
|
124 baseOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET; |
|
125 indexScale = Unsafe.ARRAY_FLOAT_INDEX_SCALE; |
|
126 break; |
|
127 case Double: |
|
128 baseOffset = Unsafe.ARRAY_DOUBLE_BASE_OFFSET; |
|
129 indexScale = Unsafe.ARRAY_DOUBLE_INDEX_SCALE; |
|
130 break; |
|
131 case Object: |
|
132 baseOffset = Unsafe.ARRAY_OBJECT_BASE_OFFSET; |
|
133 indexScale = Unsafe.ARRAY_OBJECT_INDEX_SCALE; |
|
134 break; |
|
135 default: |
|
136 return -1; |
|
137 } |
|
138 long offset; |
99 long offset; |
139 if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN && componentType.isPrimitive()) { |
100 if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN && componentType.isPrimitive()) { |
140 // On big endian, we expect the value to be correctly aligned in memory |
101 // On big endian, we expect the value to be correctly aligned in memory |
141 int componentByteCount = componentType.getJavaKind().getByteCount(); |
102 int componentByteCount = componentType.getJavaKind().getByteCount(); |
142 offset = constantOffset - (componentByteCount - Math.min(componentByteCount, 4 + expectedEntryKind.getByteCount())); |
103 offset = constantOffset - (componentByteCount - Math.min(componentByteCount, 4 + expectedEntryKind.getByteCount())); |