1 /* 2 * Copyright (c) 2015, 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 package org.graalvm.compiler.nodes.virtual; 24 25 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0; 26 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0; 27 28 import org.graalvm.compiler.core.common.type.Stamp; 29 import org.graalvm.compiler.core.common.type.StampFactory; 30 import org.graalvm.compiler.graph.Node; 31 import org.graalvm.compiler.graph.NodeClass; 32 import org.graalvm.compiler.graph.VerificationError; 33 import org.graalvm.compiler.nodeinfo.NodeInfo; 34 import org.graalvm.compiler.nodes.AbstractEndNode; 35 import org.graalvm.compiler.nodes.FixedNode; 36 import org.graalvm.compiler.nodes.FixedWithNextNode; 37 import org.graalvm.compiler.nodes.Invoke; 38 import org.graalvm.compiler.nodes.ValueNode; 39 import org.graalvm.compiler.nodes.java.StoreFieldNode; 40 import org.graalvm.compiler.nodes.spi.Lowerable; 41 import org.graalvm.compiler.nodes.spi.LoweringTool; 42 import org.graalvm.compiler.nodes.spi.Virtualizable; 43 import org.graalvm.compiler.nodes.spi.VirtualizerTool; 44 import org.graalvm.compiler.nodes.type.StampTool; 45 import org.graalvm.compiler.nodes.util.GraphUtil; 46 47 @NodeInfo(cycles = CYCLES_0, size = SIZE_0) 48 public final class EnsureVirtualizedNode extends FixedWithNextNode implements Virtualizable, Lowerable { 49 50 public static final NodeClass<EnsureVirtualizedNode> TYPE = NodeClass.create(EnsureVirtualizedNode.class); 51 52 @Input ValueNode object; 53 private final boolean localOnly; 54 55 public EnsureVirtualizedNode(ValueNode object, boolean localOnly) { 56 super(TYPE, StampFactory.forVoid()); 57 this.object = object; 58 this.localOnly = localOnly; 59 } 60 61 @Override 62 public void virtualize(VirtualizerTool tool) { 63 ValueNode alias = tool.getAlias(object); 64 if (alias instanceof VirtualObjectNode) { 65 VirtualObjectNode virtual = (VirtualObjectNode) alias; 66 if (virtual instanceof VirtualBoxingNode) { 67 Throwable exception = new VerificationError("ensureVirtual is not valid for boxing objects: %s", virtual.type().getName()); 68 throw GraphUtil.approxSourceException(this, exception); 69 } 70 if (!localOnly) { 71 tool.setEnsureVirtualized(virtual, true); 72 } 73 tool.delete(); 74 } 75 } 76 77 @Override 78 public void lower(LoweringTool tool) { 79 ensureVirtualFailure(this, object.stamp()); 80 } 81 82 public static void ensureVirtualFailure(Node location, Stamp stamp) { 83 String additionalReason = ""; 84 if (location instanceof FixedWithNextNode && !(location instanceof EnsureVirtualizedNode)) { 85 FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) location; 86 FixedNode next = fixedWithNextNode.next(); 87 if (next instanceof StoreFieldNode) { 88 additionalReason = " (must not store virtual object into a field)"; 89 } else if (next instanceof Invoke) { 90 additionalReason = " (must not pass virtual object into an invoke that cannot be inlined)"; 91 } else { 92 additionalReason = " (must not let virtual object escape at node " + next + ")"; 93 } 94 } 95 Throwable exception = new VerificationError("Object of type %s should not be materialized%s:", StampTool.typeOrNull(stamp).getName(), additionalReason); 96 97 Node pos; 98 if (location instanceof FixedWithNextNode) { 99 pos = ((FixedWithNextNode) location).next(); 100 } else if (location instanceof AbstractEndNode) { 101 pos = ((AbstractEndNode) location).merge(); 102 } else { 103 pos = location; 104 } 105 throw GraphUtil.approxSourceException(pos, exception); 106 } 107 }