1 /* 2 * Copyright (c) 2013, 2018, 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.hotspot.phases; 26 27 import static org.graalvm.compiler.nodes.ConstantNode.getConstantNodes; 28 29 import org.graalvm.compiler.nodes.ConstantNode; 30 import org.graalvm.compiler.nodes.StructuredGraph; 31 import org.graalvm.compiler.nodes.type.StampTool; 32 import org.graalvm.compiler.phases.VerifyPhase; 33 import org.graalvm.compiler.phases.tiers.PhaseContext; 34 35 import jdk.vm.ci.hotspot.HotSpotObjectConstant; 36 import jdk.vm.ci.meta.JavaKind; 37 38 /** 39 * Checks for {@link #isIllegalObjectConstant(ConstantNode) illegal} object constants in a graph 40 * processed for AOT compilation. 41 * 42 * @see LoadJavaMirrorWithKlassPhase 43 */ 44 public class AheadOfTimeVerificationPhase extends VerifyPhase<PhaseContext> { 45 46 @Override 47 protected void verify(StructuredGraph graph, PhaseContext context) { 48 for (ConstantNode node : getConstantNodes(graph)) { 49 if (isIllegalObjectConstant(node)) { 50 throw new VerificationError("illegal object constant: " + node); 51 } 52 } 53 } 54 55 public static boolean isIllegalObjectConstant(ConstantNode node) { 56 return isObject(node) && 57 !isNullReference(node) && 58 !isInternedString(node) && 59 !isDirectMethodHandle(node) && 60 !isBoundMethodHandle(node) && 61 !isVarHandle(node); 62 } 63 64 private static boolean isObject(ConstantNode node) { 65 return node.getStackKind() == JavaKind.Object; 66 } 67 68 private static boolean isNullReference(ConstantNode node) { 69 return isObject(node) && node.isNullConstant(); 70 } 71 72 private static boolean isDirectMethodHandle(ConstantNode node) { 73 if (!isObject(node)) { 74 return false; 75 } 76 return "Ljava/lang/invoke/DirectMethodHandle;".equals(StampTool.typeOrNull(node).getName()); 77 } 78 79 private static boolean isBoundMethodHandle(ConstantNode node) { 80 if (!isObject(node)) { 81 return false; 82 } 83 return StampTool.typeOrNull(node).getName().startsWith("Ljava/lang/invoke/BoundMethodHandle"); 84 } 85 86 private static boolean isVarHandle(ConstantNode node) { 87 if (!isObject(node)) { 88 return false; 89 } 90 String name = StampTool.typeOrNull(node).getName(); 91 return name.equals("Ljava/lang/invoke/VarHandle$AccessDescriptor;"); 92 } 93 94 private static boolean isInternedString(ConstantNode node) { 95 if (!isObject(node)) { 96 return false; 97 } 98 99 HotSpotObjectConstant c = (HotSpotObjectConstant) node.asConstant(); 100 return c.isInternedString(); 101 } 102 }