VerifyNodeCosts.java revision 13017:134219a5b0ec
1215911Sjfv/* 2215911Sjfv * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3320897Serj * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4215911Sjfv * 5215911Sjfv * This code is free software; you can redistribute it and/or modify it 6215911Sjfv * under the terms of the GNU General Public License version 2 only, as 7215911Sjfv * published by the Free Software Foundation. 8215911Sjfv * 9215911Sjfv * This code is distributed in the hope that it will be useful, but WITHOUT 10215911Sjfv * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11215911Sjfv * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12215911Sjfv * version 2 for more details (a copy is included in the LICENSE file that 13215911Sjfv * accompanied this code). 14215911Sjfv * 15215911Sjfv * You should have received a copy of the GNU General Public License version 16215911Sjfv * 2 along with this work; if not, write to the Free Software Foundation, 17215911Sjfv * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18215911Sjfv * 19215911Sjfv * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20215911Sjfv * or visit www.oracle.com if you need additional information or have any 21215911Sjfv * questions. 22215911Sjfv */ 23215911Sjfvpackage org.graalvm.compiler.phases.contract; 24215911Sjfv 25215911Sjfvimport java.lang.reflect.Field; 26215911Sjfvimport java.lang.reflect.Modifier; 27215911Sjfvimport java.util.function.Predicate; 28215911Sjfv 29215911Sjfvimport org.graalvm.compiler.graph.Node; 30215911Sjfvimport org.graalvm.compiler.graph.NodeClass; 31215911Sjfvimport org.graalvm.compiler.nodeinfo.NodeCycles; 32215911Sjfvimport org.graalvm.compiler.nodeinfo.NodeInfo; 33215911Sjfvimport org.graalvm.compiler.nodeinfo.NodeSize; 34215911Sjfvimport org.graalvm.compiler.phases.VerifyPhase; 35320897Serj 36320897Serj/** 37215911Sjfv * Utility class that verifies that every {@link Class} extending {@link Node} specifies non default 38230775Sjfv * values for {@link NodeCycles} and {@link NodeSize} in its {@link NodeInfo} annotation. 39230775Sjfv */ 40230775Sjfvpublic class VerifyNodeCosts { 41215911Sjfv 42247822Sjfv public static void verifyNodeClass(Class<?> clazz) { 43247822Sjfv Class<?> nodeClass = Node.class; 44247822Sjfv if (nodeClass.isAssignableFrom(clazz)) { 45230775Sjfv if (!clazz.isAnnotationPresent(NodeInfo.class)) { 46230775Sjfv throw new VerifyPhase.VerificationError("%s.java extends Node.java but does not specify a NodeInfo annotation.", clazz.getName()); 47230775Sjfv } 48230775Sjfv 49230775Sjfv if (!Modifier.isAbstract(clazz.getModifiers())) { 50230775Sjfv boolean cyclesSet = walkCHUntil(getType(clazz), getType(nodeClass), cur -> { 51230775Sjfv return cur.cycles() != NodeCycles.CYCLES_UNSET; 52230775Sjfv }); 53230775Sjfv boolean sizeSet = walkCHUntil(getType(clazz), getType(nodeClass), cur -> { 54230775Sjfv return cur.size() != NodeSize.SIZE_UNSET; 55230775Sjfv }); 56230775Sjfv if (!cyclesSet) { 57230775Sjfv throw new VerifyPhase.VerificationError("%s.java does not specify a NodeCycles value in its class hierarchy.", clazz.getName()); 58230775Sjfv } 59230775Sjfv if (!sizeSet) { 60215911Sjfv throw new VerifyPhase.VerificationError("%s.java does not specify a NodeSize value in its class hierarchy.", clazz.getName()); 61230775Sjfv } 62230775Sjfv } 63230775Sjfv } 64230775Sjfv } 65230775Sjfv 66230775Sjfv private static NodeClass<?> getType(Class<?> c) { 67230775Sjfv Field f; 68230775Sjfv try { 69230775Sjfv f = c.getField("TYPE"); 70230775Sjfv f.setAccessible(true); 71230775Sjfv Object val = f.get(null); 72230775Sjfv NodeClass<?> nodeType = (NodeClass<?>) val; 73230775Sjfv return nodeType; 74230775Sjfv } catch (Throwable t) { 75230775Sjfv throw new VerifyPhase.VerificationError("%s.java does not specify a TYPE field.", c.getName()); 76230775Sjfv } 77230775Sjfv } 78230775Sjfv 79230775Sjfv private static boolean walkCHUntil(NodeClass<?> start, NodeClass<?> until, Predicate<NodeClass<?>> p) { 80230775Sjfv NodeClass<?> cur = start; 81230775Sjfv while (cur != until && cur != null) { 82230775Sjfv if (p.test(cur)) { 83230775Sjfv return true; 84230775Sjfv } 85230775Sjfv cur = cur.getSuperNodeClass(); 86230775Sjfv } 87280182Sjfv return false; 88280182Sjfv } 89280182Sjfv 90215911Sjfv} 91215911Sjfv