@Override public void lower(LoweringTool tool) { if (graph().getGuardsStage().areFrameStatesAtDeopts()) { ForeignCallDescriptor desc = HotSpotHostForeignCallsProvider.lookupCheckcastArraycopyDescriptor(isUninit()); StructuredGraph graph = graph(); ValueNode srcAddr = computeBase(getSource(), getSourcePosition()); ValueNode destAddr = computeBase(getDestination(), getDestinationPosition()); ValueNode len = getLength(); if (len.stamp().getStackKind() != runtime.getTarget().wordJavaKind) { len = IntegerConvertNode.convert( len, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph()); } ForeignCallNode call = graph.add( new ForeignCallNode( runtime.getHostBackend().getForeignCalls(), desc, srcAddr, destAddr, len, superCheckOffset, destElemKlass)); call.setStateAfter(stateAfter()); graph.replaceFixedWithFixed(this, call); } }
public LoweredCompareAndSwapNode( AddressNode address, LocationIdentity location, ValueNode expectedValue, ValueNode newValue, BarrierType barrierType) { super( TYPE, address, location, StampFactory.forKind(JavaKind.Boolean.getStackKind()), barrierType); assert expectedValue.getStackKind() == newValue.getStackKind(); this.expectedValue = expectedValue; this.newValue = newValue; }
/** * Tries to find an original value of the given node by traversing through proxies and unambiguous * phis. Note that this method will perform an exhaustive search through phis. It is intended to * be used during graph building, when phi nodes aren't yet canonicalized. * * @param proxy The node whose original value should be determined. */ public static ValueNode originalValue(ValueNode proxy) { ValueNode v = proxy; do { if (v instanceof ValueProxy) { v = ((ValueProxy) v).getOriginalValue(); } else if (v instanceof PhiNode) { v = ((PhiNode) v).singleValue(); } else { break; } } while (v != null); // if the simple check fails (this can happen for complicated phi/proxy/phi constructs), we // do an exhaustive search if (v == null) { NodeWorkList worklist = proxy.graph().createNodeWorkList(); worklist.add(proxy); for (Node node : worklist) { if (node instanceof ValueProxy) { worklist.add(((ValueProxy) node).getOriginalValue()); } else if (node instanceof PhiNode) { worklist.addAll(((PhiNode) node).values()); } else { if (v == null) { v = (ValueNode) node; } else { return null; } } } } return v; }
private void processFixedGuardAndMerge( FixedGuardNode fixedGuard, PhaseContext context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi, AbstractMergeNode merge) { List<EndNode> mergePredecessors = merge.cfgPredecessors().snapshot(); for (int i = 0; i < mergePredecessors.size(); ++i) { AbstractEndNode mergePredecessor = mergePredecessors.get(i); if (!mergePredecessor.isAlive()) { break; } Constant xs; if (xPhi == null) { xs = x.asConstant(); } else { xs = xPhi.valueAt(mergePredecessor).asConstant(); } Constant ys; if (yPhi == null) { ys = y.asConstant(); } else { ys = yPhi.valueAt(mergePredecessor).asConstant(); } if (xs != null && ys != null && compare .condition() .foldCondition(xs, ys, context.getConstantReflection(), compare.unorderedIsTrue()) == fixedGuard.isNegated()) { visitDeoptBegin( AbstractBeginNode.prevBegin(mergePredecessor), fixedGuard.getAction(), fixedGuard.getReason(), fixedGuard.getSpeculation(), fixedGuard.graph()); } } }
@Override public void setVirtualEntry(State objectState, int index, ValueNode value) { ObjectState obj = (ObjectState) objectState; assert obj != null && obj.isVirtual() : "not virtual: " + obj; ObjectState valueState = state.getObjectState(value); ValueNode newValue = value; if (valueState == null) { newValue = getReplacedValue(value); assert obj.getEntry(index) == null || obj.getEntry(index).kind() == newValue.kind() || (isObjectEntry(obj.getEntry(index)) && isObjectEntry(newValue)); } else { if (valueState.getState() != EscapeState.Virtual) { newValue = valueState.getMaterializedValue(); assert newValue.kind() == Kind.Object; } else { newValue = valueState.getVirtualObject(); } assert obj.getEntry(index) == null || isObjectEntry(obj.getEntry(index)); } obj.setEntry(index, newValue); }
/** * Process a node as part of this search. * * @param node the next node encountered in the search * @param worklist if non-null, {@code node} will be added to this list. Otherwise, {@code node} * is treated as a candidate result. * @return true if the search should continue, false if a definitive {@link #result} has been * found */ private boolean process(ValueNode node, NodeWorkList worklist) { if (node.isAlive()) { if (worklist == null) { if (result == null) { // Initial candidate result: continue search result = node; } else if (result != node) { // Conflicts with existing candidate: stop search with null result result = null; return false; } } else { worklist.add(node); } } return true; }
public OriginalValueSearch(ValueNode proxy) { NodeWorkList worklist = proxy.graph().createNodeWorkList(); worklist.add(proxy); for (Node node : worklist) { if (node instanceof LimitedValueProxy) { ValueNode originalValue = ((LimitedValueProxy) node).getOriginalNode(); if (!process(originalValue, worklist)) { return; } } else if (node instanceof PhiNode) { for (Node value : ((PhiNode) node).values()) { if (!process((ValueNode) value, worklist)) { return; } } } else { if (!process((ValueNode) node, null)) { return; } } } }
private static boolean isObjectEntry(ValueNode value) { return value.kind() == Kind.Object || value instanceof VirtualObjectNode; }
private static boolean shouldUnroll(ValueNode length) { return length.isConstant() && length.asJavaConstant().asInt() <= 8 && length.asJavaConstant().asInt() != 0; }
@Override public long constantInit() { return op(base.constantInit(), offset.asJavaConstant().asLong()); }
@Override public boolean isConstantInit() { return offset.isConstant() && base.isConstantInit(); }
@Override public boolean isConstantExtremum() { return offset.isConstant() && base.isConstantExtremum(); }