package org.graalvm.compiler.nodes.java;
import static org.graalvm.compiler.nodeinfo.InputType.Memory;
import static org.graalvm.compiler.nodeinfo.InputType.State;
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2;
import org.graalvm.compiler.core.common.LocationIdentity;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.StateSplit;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.memory.FixedAccessNode;
import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
import org.graalvm.compiler.nodes.memory.address.AddressNode;
import org.graalvm.compiler.nodes.spi.LIRLowerable;
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
import jdk.vm.ci.meta.Value;
import sun.misc.Unsafe;
@NodeInfo(allowedUsageTypes = {Memory}, cycles = CYCLES_8, size = SIZE_2)
public final class LoweredAtomicReadAndWriteNode extends FixedAccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint.Single {
public static final NodeClass<LoweredAtomicReadAndWriteNode> TYPE = NodeClass.create(LoweredAtomicReadAndWriteNode.class);
@Input ValueNode newValue;
@OptionalInput(State) FrameState stateAfter;
public LoweredAtomicReadAndWriteNode(AddressNode address, LocationIdentity location, ValueNode newValue, BarrierType barrierType) {
super(TYPE, address, location, newValue.stamp().unrestricted(), barrierType);
this.newValue = newValue;
}
@Override
public FrameState stateAfter() {
return stateAfter;
}
@Override
public void setStateAfter(FrameState x) {
assert x == null || x.isAlive() : "frame state must be in a graph";
updateUsages(stateAfter, x);
stateAfter = x;
}
@Override
public boolean hasSideEffect() {
return true;
}
@Override
public void generate(NodeLIRBuilderTool gen) {
Value result = gen.getLIRGeneratorTool().emitAtomicReadAndWrite(gen.operand(getAddress()), gen.operand(getNewValue()));
gen.setResult(this, result);
}
@Override
public boolean canNullCheck() {
return false;
}
public ValueNode getNewValue() {
return newValue;
}
}