1 /* 2 * Copyright (c) 2013, 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.virtual.phases.ea; 26 27 import static org.graalvm.compiler.core.common.GraalOptions.TraceEscapeAnalysis; 28 29 import java.util.List; 30 31 import jdk.internal.vm.compiler.collections.EconomicMap; 32 import jdk.internal.vm.compiler.collections.Equivalence; 33 import org.graalvm.compiler.debug.DebugContext; 34 import org.graalvm.compiler.debug.GraalError; 35 import org.graalvm.compiler.debug.TTY; 36 import org.graalvm.compiler.graph.Node; 37 import org.graalvm.compiler.graph.NodeFlood; 38 import org.graalvm.compiler.nodes.AbstractEndNode; 39 import org.graalvm.compiler.nodes.FixedNode; 40 import org.graalvm.compiler.nodes.StructuredGraph; 41 import org.graalvm.compiler.options.OptionValues; 42 43 import jdk.vm.ci.meta.ResolvedJavaMethod; 44 45 public final class VirtualUtil { 46 VirtualUtil()47 private VirtualUtil() { 48 GraalError.shouldNotReachHere(); 49 } 50 assertNonReachable(StructuredGraph graph, List<Node> obsoleteNodes)51 public static boolean assertNonReachable(StructuredGraph graph, List<Node> obsoleteNodes) { 52 // Helper code that determines the paths that keep obsolete nodes alive. 53 // Nodes with support for GVN can be kept alive by GVN and are therefore not part of the 54 // assertion. 55 56 DebugContext debug = graph.getDebug(); 57 NodeFlood flood = graph.createNodeFlood(); 58 EconomicMap<Node, Node> path = EconomicMap.create(Equivalence.IDENTITY); 59 flood.add(graph.start()); 60 for (Node current : flood) { 61 if (current instanceof AbstractEndNode) { 62 AbstractEndNode end = (AbstractEndNode) current; 63 flood.add(end.merge()); 64 if (!path.containsKey(end.merge())) { 65 path.put(end.merge(), end); 66 } 67 } else { 68 for (Node successor : current.successors()) { 69 flood.add(successor); 70 if (!path.containsKey(successor)) { 71 path.put(successor, current); 72 } 73 } 74 } 75 } 76 77 for (Node node : obsoleteNodes) { 78 if (node instanceof FixedNode && !node.isDeleted()) { 79 assert !flood.isMarked(node) : node; 80 } 81 } 82 83 for (Node node : graph.getNodes()) { 84 if (flood.isMarked(node)) { 85 for (Node input : node.inputs()) { 86 flood.add(input); 87 if (!path.containsKey(input)) { 88 path.put(input, node); 89 } 90 } 91 } 92 } 93 for (Node current : flood) { 94 for (Node input : current.inputs()) { 95 flood.add(input); 96 if (!path.containsKey(input)) { 97 path.put(input, current); 98 } 99 } 100 } 101 boolean success = true; 102 for (Node node : obsoleteNodes) { 103 if (!node.isDeleted() && flood.isMarked(node) && !node.getNodeClass().valueNumberable()) { 104 TTY.println("offending node path:"); 105 Node current = node; 106 TTY.print(current.toString()); 107 while (true) { 108 current = path.get(current); 109 if (current != null) { 110 TTY.print(" -> " + current.toString()); 111 if (current instanceof FixedNode && !obsoleteNodes.contains(current)) { 112 break; 113 } 114 } 115 } 116 success = false; 117 } 118 } 119 if (!success) { 120 TTY.println(); 121 debug.forceDump(graph, "assertNonReachable"); 122 } 123 return success; 124 } 125 trace(OptionValues options, DebugContext debug, String msg)126 public static void trace(OptionValues options, DebugContext debug, String msg) { 127 if (debug.areScopesEnabled() && TraceEscapeAnalysis.getValue(options) && debug.isLogEnabled()) { 128 debug.log(msg); 129 } 130 } 131 trace(OptionValues options, DebugContext debug, String format, Object obj)132 public static void trace(OptionValues options, DebugContext debug, String format, Object obj) { 133 if (debug.areScopesEnabled() && TraceEscapeAnalysis.getValue(options) && debug.isLogEnabled()) { 134 debug.logv(format, obj); 135 } 136 } 137 trace(OptionValues options, DebugContext debug, String format, Object obj, Object obj2)138 public static void trace(OptionValues options, DebugContext debug, String format, Object obj, Object obj2) { 139 if (debug.areScopesEnabled() && TraceEscapeAnalysis.getValue(options) && debug.isLogEnabled()) { 140 debug.logv(format, obj, obj2); 141 } 142 } 143 trace(OptionValues options, DebugContext debug, String format, Object obj, Object obj2, Object obj3)144 public static void trace(OptionValues options, DebugContext debug, String format, Object obj, Object obj2, Object obj3) { 145 if (debug.areScopesEnabled() && TraceEscapeAnalysis.getValue(options) && debug.isLogEnabled()) { 146 debug.logv(format, obj, obj2, obj3); 147 } 148 } 149 trace(OptionValues options, DebugContext debug, String format, Object obj, Object obj2, Object obj3, Object obj4)150 public static void trace(OptionValues options, DebugContext debug, String format, Object obj, Object obj2, Object obj3, Object obj4) { 151 if (debug.areScopesEnabled() && TraceEscapeAnalysis.getValue(options) && debug.isLogEnabled()) { 152 debug.logv(format, obj, obj2, obj3, obj4); 153 } 154 } 155 matches(StructuredGraph graph, String filter)156 public static boolean matches(StructuredGraph graph, String filter) { 157 if (filter != null) { 158 return matchesHelper(graph, filter); 159 } 160 return true; 161 } 162 matchesHelper(StructuredGraph graph, String filter)163 private static boolean matchesHelper(StructuredGraph graph, String filter) { 164 if (filter.startsWith("~")) { 165 ResolvedJavaMethod method = graph.method(); 166 return method == null || !method.format("%H.%n").contains(filter.substring(1)); 167 } else { 168 ResolvedJavaMethod method = graph.method(); 169 return method != null && method.format("%H.%n").contains(filter); 170 } 171 } 172 } 173