001/* 002 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.virtual.phases.ea; 024 025import static com.oracle.graal.compiler.common.GraalOptions.*; 026 027import java.util.*; 028 029import jdk.internal.jvmci.common.*; 030import com.oracle.graal.debug.*; 031 032import jdk.internal.jvmci.meta.*; 033 034import com.oracle.graal.graph.*; 035import com.oracle.graal.nodes.*; 036 037public final class VirtualUtil { 038 039 private VirtualUtil() { 040 JVMCIError.shouldNotReachHere(); 041 } 042 043 public static boolean assertNonReachable(StructuredGraph graph, List<Node> obsoleteNodes) { 044 // helper code that determines the paths that keep obsolete nodes alive: 045 046 NodeFlood flood = graph.createNodeFlood(); 047 Map<Node, Node> path = Node.newIdentityMap(); 048 flood.add(graph.start()); 049 for (Node current : flood) { 050 if (current instanceof AbstractEndNode) { 051 AbstractEndNode end = (AbstractEndNode) current; 052 flood.add(end.merge()); 053 if (!path.containsKey(end.merge())) { 054 path.put(end.merge(), end); 055 } 056 } else { 057 for (Node successor : current.successors()) { 058 flood.add(successor); 059 if (!path.containsKey(successor)) { 060 path.put(successor, current); 061 } 062 } 063 } 064 } 065 066 for (Node node : obsoleteNodes) { 067 if (node instanceof FixedNode && !node.isDeleted()) { 068 assert !flood.isMarked(node) : node; 069 } 070 } 071 072 for (Node node : graph.getNodes()) { 073 if (flood.isMarked(node)) { 074 for (Node input : node.inputs()) { 075 flood.add(input); 076 if (!path.containsKey(input)) { 077 path.put(input, node); 078 } 079 } 080 } 081 } 082 for (Node current : flood) { 083 for (Node input : current.inputs()) { 084 flood.add(input); 085 if (!path.containsKey(input)) { 086 path.put(input, current); 087 } 088 } 089 } 090 boolean success = true; 091 for (Node node : obsoleteNodes) { 092 if (!node.isDeleted() && flood.isMarked(node)) { 093 TTY.println("offending node path:"); 094 Node current = node; 095 TTY.print(current.toString()); 096 while (true) { 097 current = path.get(current); 098 if (current != null) { 099 TTY.print(" -> " + current.toString()); 100 if (current instanceof FixedNode && !obsoleteNodes.contains(current)) { 101 break; 102 } 103 } 104 } 105 success = false; 106 } 107 } 108 if (!success) { 109 TTY.println(); 110 Debug.dump(graph, "assertNonReachable"); 111 } 112 return success; 113 } 114 115 public static void trace(String format) { 116 if (Debug.isEnabled() && TraceEscapeAnalysis.getValue() && Debug.isLogEnabled()) { 117 Debug.logv(format); 118 } 119 } 120 121 public static void trace(String format, Object obj) { 122 if (Debug.isEnabled() && TraceEscapeAnalysis.getValue() && Debug.isLogEnabled()) { 123 Debug.logv(format, obj); 124 } 125 } 126 127 public static void trace(String format, Object obj, Object obj2) { 128 if (Debug.isEnabled() && TraceEscapeAnalysis.getValue() && Debug.isLogEnabled()) { 129 Debug.logv(format, obj, obj2); 130 } 131 } 132 133 public static void trace(String format, Object obj, Object obj2, Object obj3) { 134 if (Debug.isEnabled() && TraceEscapeAnalysis.getValue() && Debug.isLogEnabled()) { 135 Debug.logv(format, obj, obj2, obj3); 136 } 137 } 138 139 public static void trace(String format, Object obj, Object obj2, Object obj3, Object obj4) { 140 if (Debug.isEnabled() && TraceEscapeAnalysis.getValue() && Debug.isLogEnabled()) { 141 Debug.logv(format, obj, obj2, obj3, obj4); 142 } 143 } 144 145 public static boolean matches(StructuredGraph graph, String filter) { 146 if (filter != null) { 147 return matchesHelper(graph, filter); 148 } 149 return true; 150 } 151 152 private static boolean matchesHelper(StructuredGraph graph, String filter) { 153 if (filter.startsWith("~")) { 154 ResolvedJavaMethod method = graph.method(); 155 return method == null || !method.format("%H.%n").contains(filter.substring(1)); 156 } else { 157 ResolvedJavaMethod method = graph.method(); 158 return method != null && method.format("%H.%n").contains(filter); 159 } 160 } 161}