private static ValueNode getValueWritten(FixedWithNextNode write) { if (write instanceof WriteNode) { return ((WriteNode) write).value(); } else if (write instanceof LogicCompareAndSwapNode) { return ((LogicCompareAndSwapNode) write).getNewValue(); } else if (write instanceof LoweredAtomicReadAndWriteNode) { return ((LoweredAtomicReadAndWriteNode) write).getNewValue(); } else { throw GraalError.shouldNotReachHere(String.format("unexpected write node %s", write)); } }
private void addAtomicReadWriteNodeBarriers(LoweredAtomicReadAndWriteNode node, StructuredGraph graph) { BarrierType barrierType = node.getBarrierType(); switch (barrierType) { case NONE: // nothing to do break; case IMPRECISE: case PRECISE: boolean precise = barrierType == BarrierType.PRECISE; if (config.useG1GC) { addG1PreWriteBarrier(node, node.getAddress(), null, true, node.getNullCheck(), graph); addG1PostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph); } else { addSerialPostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph); } break; default: throw new GraalError("unexpected barrier type: " + barrierType); } }
/** * LoweredAtomicReadAndWriteNode has * <ul> * <li>The object to which the write is done, in node.object(),</li> * <li>the value to be written, in node.getNewValue(),</li> * <li>the location within the object for the write, in node.location(),</li> * <li>whether a precise or imprecise barrier is needed, in node.getBarrierType(),</li>. * </ul> */ protected void rewriteWithBarriers(StructuredGraph graph, LoweredAtomicReadAndWriteNode node) { if (node.getBarrierType() == BarrierType.NONE) { // No barrier requested. return; } final ValueNode value = node.getNewValue(); if (!value.getStackKind().isObject()) { // Storing something other than an Object does not require a barrier. return; } if (StampTool.isPointerAlwaysNull(value)) { // Storing a null does not require a barrier. return; } // TODO: What about initializing writes, which I can check in node.isInitialization()? addPostWriteBarrier(graph, node, node.getAddress()); }
@Override public void generate(NodeLIRBuilderTool gen) { Value emitted = gen.operand(getNewValue()); // In case this node works with compressed objects, the newValue's kind must be used. ValueKind<? extends ValueKind<?>> actualKind = newValue.stamp(NodeView.DEFAULT).getStackKind().isObject() ? emitted.getValueKind() : this.valueKind; Value result = gen.getLIRGeneratorTool().emitAtomicReadAndWrite(gen.operand(getAddress()), actualKind, emitted); gen.setResult(this, result); }