22 */
23 package org.graalvm.compiler.nodes.extended;
24
25 import static org.graalvm.compiler.nodeinfo.InputType.State;
26 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
27 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
28
29 import org.graalvm.compiler.core.common.type.StampFactory;
30 import org.graalvm.compiler.graph.NodeClass;
31 import org.graalvm.compiler.nodeinfo.NodeInfo;
32 import org.graalvm.compiler.nodes.ConstantNode;
33 import org.graalvm.compiler.nodes.FrameState;
34 import org.graalvm.compiler.nodes.StateSplit;
35 import org.graalvm.compiler.nodes.ValueNode;
36 import org.graalvm.compiler.nodes.java.StoreFieldNode;
37 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
38 import org.graalvm.compiler.nodes.spi.Lowerable;
39 import org.graalvm.compiler.nodes.spi.LoweringTool;
40 import org.graalvm.compiler.nodes.spi.Virtualizable;
41 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
42 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
43 import org.graalvm.word.LocationIdentity;
44
45 import jdk.vm.ci.meta.Assumptions;
46 import jdk.vm.ci.meta.JavaConstant;
47 import jdk.vm.ci.meta.JavaKind;
48 import jdk.vm.ci.meta.ResolvedJavaField;
49
50 /**
51 * Store of a value at a location specified as an offset relative to an object. No null check is
52 * performed before the store.
53 */
54 @NodeInfo(cycles = CYCLES_2, size = SIZE_1)
55 public final class RawStoreNode extends UnsafeAccessNode implements StateSplit, Lowerable, Virtualizable, MemoryCheckpoint.Single {
56
57 public static final NodeClass<RawStoreNode> TYPE = NodeClass.create(RawStoreNode.class);
58 @Input ValueNode value;
59 @OptionalInput(State) FrameState stateAfter;
60 private final boolean needsBarrier;
61
107 public ValueNode value() {
108 return value;
109 }
110
111 @Override
112 public void lower(LoweringTool tool) {
113 tool.getLowerer().lower(this, tool);
114 }
115
116 @Override
117 public void virtualize(VirtualizerTool tool) {
118 ValueNode alias = tool.getAlias(object());
119 if (alias instanceof VirtualObjectNode) {
120 VirtualObjectNode virtual = (VirtualObjectNode) alias;
121 ValueNode indexValue = tool.getAlias(offset());
122 if (indexValue.isConstant()) {
123 long off = indexValue.asJavaConstant().asLong();
124 int entryIndex = virtual.entryIndexForOffset(off, accessKind());
125 if (entryIndex != -1) {
126 JavaKind entryKind = virtual.entryKind(entryIndex);
127 boolean canVirtualize = entryKind == accessKind() || entryKind == accessKind().getStackKind();
128 if (!canVirtualize) {
129 /*
130 * Special case: If the entryKind is long, allow arbitrary kinds as long as
131 * a value of the same kind is already there. This can only happen if some
132 * other node initialized the entry with a value of a different kind. One
133 * example where this happens is the Truffle NewFrameNode.
134 */
135 ValueNode entry = tool.getEntry(virtual, entryIndex);
136 if (entryKind == JavaKind.Long && entry.getStackKind() == value.getStackKind()) {
137 canVirtualize = true;
138 }
139 }
140 if (canVirtualize) {
141 tool.setVirtualEntry(virtual, entryIndex, value(), true);
142 tool.delete();
143 } else {
144 /*
145 * Special case: Allow storing a single long or double value into two
146 * consecutive int slots.
147 */
|
22 */
23 package org.graalvm.compiler.nodes.extended;
24
25 import static org.graalvm.compiler.nodeinfo.InputType.State;
26 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
27 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
28
29 import org.graalvm.compiler.core.common.type.StampFactory;
30 import org.graalvm.compiler.graph.NodeClass;
31 import org.graalvm.compiler.nodeinfo.NodeInfo;
32 import org.graalvm.compiler.nodes.ConstantNode;
33 import org.graalvm.compiler.nodes.FrameState;
34 import org.graalvm.compiler.nodes.StateSplit;
35 import org.graalvm.compiler.nodes.ValueNode;
36 import org.graalvm.compiler.nodes.java.StoreFieldNode;
37 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
38 import org.graalvm.compiler.nodes.spi.Lowerable;
39 import org.graalvm.compiler.nodes.spi.LoweringTool;
40 import org.graalvm.compiler.nodes.spi.Virtualizable;
41 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
42 import org.graalvm.compiler.nodes.type.StampTool;
43 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
44 import org.graalvm.word.LocationIdentity;
45
46 import jdk.vm.ci.meta.Assumptions;
47 import jdk.vm.ci.meta.JavaConstant;
48 import jdk.vm.ci.meta.JavaKind;
49 import jdk.vm.ci.meta.ResolvedJavaField;
50
51 /**
52 * Store of a value at a location specified as an offset relative to an object. No null check is
53 * performed before the store.
54 */
55 @NodeInfo(cycles = CYCLES_2, size = SIZE_1)
56 public final class RawStoreNode extends UnsafeAccessNode implements StateSplit, Lowerable, Virtualizable, MemoryCheckpoint.Single {
57
58 public static final NodeClass<RawStoreNode> TYPE = NodeClass.create(RawStoreNode.class);
59 @Input ValueNode value;
60 @OptionalInput(State) FrameState stateAfter;
61 private final boolean needsBarrier;
62
108 public ValueNode value() {
109 return value;
110 }
111
112 @Override
113 public void lower(LoweringTool tool) {
114 tool.getLowerer().lower(this, tool);
115 }
116
117 @Override
118 public void virtualize(VirtualizerTool tool) {
119 ValueNode alias = tool.getAlias(object());
120 if (alias instanceof VirtualObjectNode) {
121 VirtualObjectNode virtual = (VirtualObjectNode) alias;
122 ValueNode indexValue = tool.getAlias(offset());
123 if (indexValue.isConstant()) {
124 long off = indexValue.asJavaConstant().asLong();
125 int entryIndex = virtual.entryIndexForOffset(off, accessKind());
126 if (entryIndex != -1) {
127 JavaKind entryKind = virtual.entryKind(entryIndex);
128 boolean canVirtualize = entryKind == accessKind() || (entryKind == accessKind().getStackKind() && !StampTool.typeOrNull(object()).isArray());
129 if (!canVirtualize) {
130 /*
131 * Special case: If the entryKind is long, allow arbitrary kinds as long as
132 * a value of the same kind is already there. This can only happen if some
133 * other node initialized the entry with a value of a different kind. One
134 * example where this happens is the Truffle NewFrameNode.
135 */
136 ValueNode entry = tool.getEntry(virtual, entryIndex);
137 if (entryKind == JavaKind.Long && entry.getStackKind() == value.getStackKind()) {
138 canVirtualize = true;
139 }
140 }
141 if (canVirtualize) {
142 tool.setVirtualEntry(virtual, entryIndex, value(), true);
143 tool.delete();
144 } else {
145 /*
146 * Special case: Allow storing a single long or double value into two
147 * consecutive int slots.
148 */
|