1 /* 2 * Copyright (c) 2011, 2020, 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 */ 23 24 25 package org.graalvm.compiler.nodes.extended; 26 27 import static org.graalvm.compiler.nodeinfo.InputType.State; 28 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; 29 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; 30 31 import org.graalvm.compiler.core.common.type.StampFactory; 32 import org.graalvm.compiler.graph.NodeClass; 33 import org.graalvm.compiler.nodeinfo.NodeInfo; 34 import org.graalvm.compiler.nodes.FrameState; 35 import org.graalvm.compiler.nodes.StateSplit; 36 import org.graalvm.compiler.nodes.ValueNode; 37 import org.graalvm.compiler.nodes.java.StoreFieldNode; 38 import org.graalvm.compiler.nodes.memory.SingleMemoryKill; 39 import org.graalvm.compiler.nodes.spi.Lowerable; 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 jdk.internal.vm.compiler.word.LocationIdentity; 44 45 import jdk.vm.ci.meta.Assumptions; 46 import jdk.vm.ci.meta.JavaKind; 47 import jdk.vm.ci.meta.ResolvedJavaField; 48 49 /** 50 * Store of a value at a location specified as an offset relative to an object. No null check is 51 * performed before the store. 52 */ 53 @NodeInfo(cycles = CYCLES_2, size = SIZE_1) 54 public final class RawStoreNode extends UnsafeAccessNode implements StateSplit, Lowerable, Virtualizable, SingleMemoryKill { 55 56 public static final NodeClass<RawStoreNode> TYPE = NodeClass.create(RawStoreNode.class); 57 @Input ValueNode value; 58 @OptionalInput(State) FrameState stateAfter; 59 private final boolean needsBarrier; 60 private boolean isVolatile; 61 RawStoreNode(ValueNode object, ValueNode offset, ValueNode value, JavaKind accessKind, LocationIdentity locationIdentity)62 public RawStoreNode(ValueNode object, ValueNode offset, ValueNode value, JavaKind accessKind, LocationIdentity locationIdentity) { 63 this(object, offset, value, accessKind, locationIdentity, true, false, null, false); 64 } 65 RawStoreNode(ValueNode object, ValueNode offset, ValueNode value, JavaKind accessKind, LocationIdentity locationIdentity, boolean needsBarrier)66 public RawStoreNode(ValueNode object, ValueNode offset, ValueNode value, JavaKind accessKind, LocationIdentity locationIdentity, boolean needsBarrier) { 67 this(object, offset, value, accessKind, locationIdentity, needsBarrier, false, null, false); 68 } 69 RawStoreNode(ValueNode object, ValueNode offset, ValueNode value, JavaKind accessKind, LocationIdentity locationIdentity, boolean needsBarrier, boolean isVolatile)70 public RawStoreNode(ValueNode object, ValueNode offset, ValueNode value, JavaKind accessKind, LocationIdentity locationIdentity, boolean needsBarrier, boolean isVolatile) { 71 this(object, offset, value, accessKind, locationIdentity, needsBarrier, isVolatile, null, false); 72 } 73 RawStoreNode(ValueNode object, ValueNode offset, ValueNode value, JavaKind accessKind, LocationIdentity locationIdentity, boolean needsBarrier, FrameState stateAfter, boolean forceAnyLocation)74 public RawStoreNode(ValueNode object, ValueNode offset, ValueNode value, JavaKind accessKind, LocationIdentity locationIdentity, boolean needsBarrier, FrameState stateAfter, 75 boolean forceAnyLocation) { 76 this(object, offset, value, accessKind, locationIdentity, needsBarrier, false, stateAfter, forceAnyLocation); 77 } 78 RawStoreNode(ValueNode object, ValueNode offset, ValueNode value, JavaKind accessKind, LocationIdentity locationIdentity, boolean needsBarrier, boolean isVolatile, FrameState stateAfter, boolean forceAnyLocation)79 public RawStoreNode(ValueNode object, ValueNode offset, ValueNode value, JavaKind accessKind, LocationIdentity locationIdentity, boolean needsBarrier, boolean isVolatile, FrameState stateAfter, 80 boolean forceAnyLocation) { 81 super(TYPE, StampFactory.forVoid(), object, offset, accessKind, locationIdentity, forceAnyLocation); 82 this.value = value; 83 this.needsBarrier = needsBarrier; 84 this.stateAfter = stateAfter; 85 this.isVolatile = isVolatile; 86 assert accessKind != JavaKind.Void && accessKind != JavaKind.Illegal; 87 } 88 89 @NodeIntrinsic storeObject(Object object, long offset, Object value, @ConstantNodeParameter JavaKind kind, @ConstantNodeParameter LocationIdentity locationIdentity, @ConstantNodeParameter boolean needsBarrier)90 public static native Object storeObject(Object object, long offset, Object value, @ConstantNodeParameter JavaKind kind, @ConstantNodeParameter LocationIdentity locationIdentity, 91 @ConstantNodeParameter boolean needsBarrier); 92 93 @NodeIntrinsic storeChar(Object object, long offset, char value, @ConstantNodeParameter JavaKind kind, @ConstantNodeParameter LocationIdentity locationIdentity)94 public static native Object storeChar(Object object, long offset, char value, @ConstantNodeParameter JavaKind kind, @ConstantNodeParameter LocationIdentity locationIdentity); 95 96 @NodeIntrinsic storeByte(Object object, long offset, byte value, @ConstantNodeParameter JavaKind kind, @ConstantNodeParameter LocationIdentity locationIdentity)97 public static native Object storeByte(Object object, long offset, byte value, @ConstantNodeParameter JavaKind kind, @ConstantNodeParameter LocationIdentity locationIdentity); 98 needsBarrier()99 public boolean needsBarrier() { 100 return needsBarrier; 101 } 102 103 @Override stateAfter()104 public FrameState stateAfter() { 105 return stateAfter; 106 } 107 108 @Override setStateAfter(FrameState x)109 public void setStateAfter(FrameState x) { 110 assert x == null || x.isAlive() : "frame state must be in a graph"; 111 updateUsages(stateAfter, x); 112 stateAfter = x; 113 } 114 115 @Override hasSideEffect()116 public boolean hasSideEffect() { 117 return true; 118 } 119 value()120 public ValueNode value() { 121 return value; 122 } 123 124 @Override virtualize(VirtualizerTool tool)125 public void virtualize(VirtualizerTool tool) { 126 ValueNode alias = tool.getAlias(object()); 127 if (alias instanceof VirtualObjectNode) { 128 VirtualObjectNode virtual = (VirtualObjectNode) alias; 129 ValueNode indexValue = tool.getAlias(offset()); 130 if (indexValue.isConstant()) { 131 long off = indexValue.asJavaConstant().asLong(); 132 int entryIndex = virtual.entryIndexForOffset(tool.getMetaAccess(), off, accessKind()); 133 if (entryIndex != -1 && tool.setVirtualEntry(virtual, entryIndex, value(), accessKind(), off)) { 134 tool.delete(); 135 } 136 } 137 } 138 } 139 140 @Override isVolatile()141 public boolean isVolatile() { 142 return isVolatile; 143 } 144 145 @Override cloneAsFieldAccess(Assumptions assumptions, ResolvedJavaField field, boolean volatileAccess)146 protected ValueNode cloneAsFieldAccess(Assumptions assumptions, ResolvedJavaField field, boolean volatileAccess) { 147 return new StoreFieldNode(field.isStatic() ? null : object(), field, value(), stateAfter(), volatileAccess); 148 } 149 150 @Override cloneAsArrayAccess(ValueNode location, LocationIdentity identity, boolean volatileAccess)151 protected ValueNode cloneAsArrayAccess(ValueNode location, LocationIdentity identity, boolean volatileAccess) { 152 return new RawStoreNode(object(), location, value, accessKind(), identity, needsBarrier, volatileAccess, stateAfter(), isAnyLocationForced()); 153 } 154 getState()155 public FrameState getState() { 156 return stateAfter; 157 } 158 159 @Override getKilledLocationIdentity()160 public LocationIdentity getKilledLocationIdentity() { 161 if (isVolatile()) { 162 return LocationIdentity.any(); 163 } 164 return getLocationIdentity(); 165 } 166 } 167