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 */
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
63 public RawStoreNode(ValueNode object, ValueNode offset, ValueNode value, JavaKind accessKind, LocationIdentity locationIdentity) {
64 this(object, offset, value, accessKind, locationIdentity, true);
65 }
66
67 public RawStoreNode(ValueNode object, ValueNode offset, ValueNode value, JavaKind accessKind, LocationIdentity locationIdentity, boolean needsBarrier) {
106 }
107
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 */
149 if ((accessKind() == JavaKind.Long || accessKind() == JavaKind.Double) && entryKind == JavaKind.Int) {
150 int nextIndex = virtual.entryIndexForOffset(off + 4, entryKind);
151 if (nextIndex != -1) {
152 JavaKind nextKind = virtual.entryKind(nextIndex);
153 if (nextKind == JavaKind.Int) {
154 tool.setVirtualEntry(virtual, entryIndex, value(), true);
155 tool.setVirtualEntry(virtual, nextIndex, ConstantNode.forConstant(JavaConstant.forIllegal(), tool.getMetaAccessProvider(), graph()), true);
156 tool.delete();
157 }
158 }
159 }
160 }
161 }
162 }
163 }
164 }
165
166 @Override
167 protected ValueNode cloneAsFieldAccess(Assumptions assumptions, ResolvedJavaField field) {
168 return new StoreFieldNode(object(), field, value(), stateAfter());
169 }
170
171 @Override
172 protected ValueNode cloneAsArrayAccess(ValueNode location, LocationIdentity identity) {
173 return new RawStoreNode(object(), location, value, accessKind(), identity, needsBarrier, stateAfter(), isAnyLocationForced());
174 }
175
176 public FrameState getState() {
177 return stateAfter;
178 }
179 }
|
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 */
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.FrameState;
33 import org.graalvm.compiler.nodes.StateSplit;
34 import org.graalvm.compiler.nodes.ValueNode;
35 import org.graalvm.compiler.nodes.java.StoreFieldNode;
36 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
37 import org.graalvm.compiler.nodes.spi.Lowerable;
38 import org.graalvm.compiler.nodes.spi.LoweringTool;
39 import org.graalvm.compiler.nodes.spi.Virtualizable;
40 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
41 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
42 import org.graalvm.word.LocationIdentity;
43
44 import jdk.vm.ci.meta.Assumptions;
45 import jdk.vm.ci.meta.JavaKind;
46 import jdk.vm.ci.meta.ResolvedJavaField;
47
48 /**
49 * Store of a value at a location specified as an offset relative to an object. No null check is
50 * performed before the store.
51 */
52 @NodeInfo(cycles = CYCLES_2, size = SIZE_1)
53 public final class RawStoreNode extends UnsafeAccessNode implements StateSplit, Lowerable, Virtualizable, MemoryCheckpoint.Single {
54
55 public static final NodeClass<RawStoreNode> TYPE = NodeClass.create(RawStoreNode.class);
56 @Input ValueNode value;
57 @OptionalInput(State) FrameState stateAfter;
58 private final boolean needsBarrier;
59
60 public RawStoreNode(ValueNode object, ValueNode offset, ValueNode value, JavaKind accessKind, LocationIdentity locationIdentity) {
61 this(object, offset, value, accessKind, locationIdentity, true);
62 }
63
64 public RawStoreNode(ValueNode object, ValueNode offset, ValueNode value, JavaKind accessKind, LocationIdentity locationIdentity, boolean needsBarrier) {
103 }
104
105 public ValueNode value() {
106 return value;
107 }
108
109 @Override
110 public void lower(LoweringTool tool) {
111 tool.getLowerer().lower(this, tool);
112 }
113
114 @Override
115 public void virtualize(VirtualizerTool tool) {
116 ValueNode alias = tool.getAlias(object());
117 if (alias instanceof VirtualObjectNode) {
118 VirtualObjectNode virtual = (VirtualObjectNode) alias;
119 ValueNode indexValue = tool.getAlias(offset());
120 if (indexValue.isConstant()) {
121 long off = indexValue.asJavaConstant().asLong();
122 int entryIndex = virtual.entryIndexForOffset(off, accessKind());
123 if (entryIndex != -1 && tool.setVirtualEntry(virtual, entryIndex, value(), accessKind(), off)) {
124 tool.delete();
125 }
126 }
127 }
128 }
129
130 @Override
131 protected ValueNode cloneAsFieldAccess(Assumptions assumptions, ResolvedJavaField field) {
132 return new StoreFieldNode(object(), field, value(), stateAfter());
133 }
134
135 @Override
136 protected ValueNode cloneAsArrayAccess(ValueNode location, LocationIdentity identity) {
137 return new RawStoreNode(object(), location, value, accessKind(), identity, needsBarrier, stateAfter(), isAnyLocationForced());
138 }
139
140 public FrameState getState() {
141 return stateAfter;
142 }
143 }
|