001/* 002 * Copyright (c) 2011, 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.graphbuilderconf; 024 025import java.util.*; 026 027import jdk.internal.jvmci.meta.*; 028 029import com.oracle.graal.compiler.common.*; 030import com.oracle.graal.nodes.*; 031 032public class GraphBuilderConfiguration { 033 034 public static class Plugins { 035 private final InvocationPlugins invocationPlugins; 036 private NodePlugin[] nodePlugins; 037 private ParameterPlugin[] parameterPlugins; 038 private InlineInvokePlugin[] inlineInvokePlugins; 039 private LoopExplosionPlugin loopExplosionPlugin; 040 041 /** 042 * Creates a copy of a given set of plugins. The {@link InvocationPlugins} in 043 * {@code copyFrom} become the {@linkplain InvocationPlugins#getParent() default} 044 * {@linkplain #getInvocationPlugins() invocation plugins} in this object. 045 */ 046 public Plugins(Plugins copyFrom) { 047 this.invocationPlugins = new InvocationPlugins(copyFrom.invocationPlugins); 048 this.nodePlugins = copyFrom.nodePlugins; 049 this.parameterPlugins = copyFrom.parameterPlugins; 050 this.inlineInvokePlugins = copyFrom.inlineInvokePlugins; 051 this.loopExplosionPlugin = copyFrom.loopExplosionPlugin; 052 } 053 054 /** 055 * Creates a new set of plugins. 056 * 057 * @param invocationPlugins the {@linkplain #getInvocationPlugins() invocation plugins} in 058 * this object 059 */ 060 public Plugins(InvocationPlugins invocationPlugins) { 061 this.invocationPlugins = invocationPlugins; 062 this.nodePlugins = new NodePlugin[0]; 063 this.parameterPlugins = new ParameterPlugin[0]; 064 this.inlineInvokePlugins = new InlineInvokePlugin[0]; 065 } 066 067 public InvocationPlugins getInvocationPlugins() { 068 return invocationPlugins; 069 } 070 071 public NodePlugin[] getNodePlugins() { 072 return nodePlugins; 073 } 074 075 public void appendNodePlugin(NodePlugin plugin) { 076 nodePlugins = Arrays.copyOf(nodePlugins, nodePlugins.length + 1); 077 nodePlugins[nodePlugins.length - 1] = plugin; 078 } 079 080 public void prependNodePlugin(NodePlugin plugin) { 081 NodePlugin[] newPlugins = new NodePlugin[nodePlugins.length + 1]; 082 System.arraycopy(nodePlugins, 0, newPlugins, 1, nodePlugins.length); 083 newPlugins[0] = plugin; 084 nodePlugins = newPlugins; 085 } 086 087 public void clearNodePlugin() { 088 nodePlugins = new NodePlugin[0]; 089 } 090 091 public ParameterPlugin[] getParameterPlugins() { 092 return parameterPlugins; 093 } 094 095 public void appendParameterPlugin(ParameterPlugin plugin) { 096 parameterPlugins = Arrays.copyOf(parameterPlugins, parameterPlugins.length + 1); 097 parameterPlugins[parameterPlugins.length - 1] = plugin; 098 } 099 100 public void prependParameterPlugin(ParameterPlugin plugin) { 101 ParameterPlugin[] newPlugins = new ParameterPlugin[parameterPlugins.length + 1]; 102 System.arraycopy(parameterPlugins, 0, newPlugins, 1, parameterPlugins.length); 103 newPlugins[0] = plugin; 104 parameterPlugins = newPlugins; 105 } 106 107 public void clearParameterPlugin() { 108 parameterPlugins = new ParameterPlugin[0]; 109 } 110 111 public InlineInvokePlugin[] getInlineInvokePlugins() { 112 return inlineInvokePlugins; 113 } 114 115 public void appendInlineInvokePlugin(InlineInvokePlugin plugin) { 116 inlineInvokePlugins = Arrays.copyOf(inlineInvokePlugins, inlineInvokePlugins.length + 1); 117 inlineInvokePlugins[inlineInvokePlugins.length - 1] = plugin; 118 } 119 120 public void prependInlineInvokePlugin(InlineInvokePlugin plugin) { 121 InlineInvokePlugin[] newPlugins = new InlineInvokePlugin[inlineInvokePlugins.length + 1]; 122 System.arraycopy(inlineInvokePlugins, 0, newPlugins, 1, inlineInvokePlugins.length); 123 newPlugins[0] = plugin; 124 inlineInvokePlugins = newPlugins; 125 } 126 127 public void clearInlineInvokePlugins() { 128 inlineInvokePlugins = new InlineInvokePlugin[0]; 129 } 130 131 public LoopExplosionPlugin getLoopExplosionPlugin() { 132 return loopExplosionPlugin; 133 } 134 135 public void setLoopExplosionPlugin(LoopExplosionPlugin plugin) { 136 this.loopExplosionPlugin = plugin; 137 } 138 } 139 140 private static final ResolvedJavaType[] EMPTY = new ResolvedJavaType[]{}; 141 142 private final boolean eagerResolving; 143 private final boolean omitAllExceptionEdges; 144 private final boolean omitAssertions; 145 private final ResolvedJavaType[] skippedExceptionTypes; 146 private final DebugInfoMode debugInfoMode; 147 private final boolean clearNonLiveLocals; 148 private boolean useProfiling; 149 private final Plugins plugins; 150 151 public static enum DebugInfoMode { 152 SafePointsOnly, 153 /** 154 * This mode inserts {@link SimpleInfopointNode}s in places where no safepoints would be 155 * inserted: inlining boundaries, and line number switches. 156 * <p> 157 * In this mode the infopoint only have a location (method and bytecode index) and no 158 * values. 159 * <p> 160 * This is useful to have better program counter to bci mapping and has no influence on the 161 * generated code. However it can increase the amount of metadata and does not allow access 162 * to accessing values at runtime. 163 */ 164 Simple, 165 /** 166 * In this mode, {@link FullInfopointNode}s are generated in the same locations as in 167 * {@link #Simple} mode but the infopoints have access to the runtime values. 168 * <p> 169 * This is relevant when code is to be generated for native, machine-code level debugging 170 * but can have a limit the amount of optimization applied to the code. 171 */ 172 Full, 173 } 174 175 protected GraphBuilderConfiguration(boolean eagerResolving, boolean omitAllExceptionEdges, boolean omitAssertions, DebugInfoMode debugInfoMode, ResolvedJavaType[] skippedExceptionTypes, 176 boolean clearNonLiveLocals, Plugins plugins) { 177 this.eagerResolving = eagerResolving; 178 this.omitAllExceptionEdges = omitAllExceptionEdges; 179 this.omitAssertions = omitAssertions; 180 this.debugInfoMode = debugInfoMode; 181 this.skippedExceptionTypes = skippedExceptionTypes; 182 this.clearNonLiveLocals = clearNonLiveLocals; 183 this.useProfiling = true; 184 this.plugins = plugins; 185 } 186 187 /** 188 * Creates a copy of this configuration with all its plugins. The {@link InvocationPlugins} in 189 * this configuration become the {@linkplain InvocationPlugins#getParent() parent} of the 190 * {@link InvocationPlugins} in the copy. 191 */ 192 public GraphBuilderConfiguration copy() { 193 Plugins newPlugins = new Plugins(plugins); 194 GraphBuilderConfiguration result = new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, omitAssertions, debugInfoMode, skippedExceptionTypes, clearNonLiveLocals, newPlugins); 195 result.useProfiling = useProfiling; 196 return result; 197 } 198 199 public boolean getUseProfiling() { 200 return useProfiling; 201 } 202 203 public void setUseProfiling(boolean b) { 204 this.useProfiling = b; 205 } 206 207 public GraphBuilderConfiguration withEagerResolving(boolean newEagerResolving) { 208 return new GraphBuilderConfiguration(newEagerResolving, omitAllExceptionEdges, omitAssertions, debugInfoMode, skippedExceptionTypes, clearNonLiveLocals, plugins); 209 } 210 211 public GraphBuilderConfiguration withSkippedExceptionTypes(ResolvedJavaType[] newSkippedExceptionTypes) { 212 return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, omitAssertions, debugInfoMode, newSkippedExceptionTypes, clearNonLiveLocals, plugins); 213 } 214 215 public GraphBuilderConfiguration withOmitAllExceptionEdges(boolean newOmitAllExceptionEdges) { 216 return new GraphBuilderConfiguration(eagerResolving, newOmitAllExceptionEdges, omitAssertions, debugInfoMode, skippedExceptionTypes, clearNonLiveLocals, plugins); 217 } 218 219 public GraphBuilderConfiguration withOmitAssertions(boolean newOmitAssertions) { 220 return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, newOmitAssertions, debugInfoMode, skippedExceptionTypes, clearNonLiveLocals, plugins); 221 } 222 223 public GraphBuilderConfiguration withDebugInfoMode(DebugInfoMode newDebugInfoMode) { 224 ResolvedJavaType[] newSkippedExceptionTypes = skippedExceptionTypes == EMPTY ? EMPTY : Arrays.copyOf(skippedExceptionTypes, skippedExceptionTypes.length); 225 return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, omitAssertions, newDebugInfoMode, newSkippedExceptionTypes, clearNonLiveLocals, plugins); 226 } 227 228 public GraphBuilderConfiguration withClearNonLiveLocals(boolean newClearNonLiveLocals) { 229 return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, omitAssertions, debugInfoMode, skippedExceptionTypes, newClearNonLiveLocals, plugins); 230 } 231 232 public ResolvedJavaType[] getSkippedExceptionTypes() { 233 return skippedExceptionTypes; 234 } 235 236 public boolean eagerResolving() { 237 return eagerResolving; 238 } 239 240 public boolean omitAllExceptionEdges() { 241 return omitAllExceptionEdges; 242 } 243 244 public boolean omitAssertions() { 245 return omitAssertions; 246 } 247 248 public boolean insertNonSafepointDebugInfo() { 249 return debugInfoMode.ordinal() >= DebugInfoMode.Simple.ordinal(); 250 } 251 252 public boolean insertFullDebugInfo() { 253 return debugInfoMode.ordinal() >= DebugInfoMode.Full.ordinal(); 254 } 255 256 public boolean insertSimpleDebugInfo() { 257 return debugInfoMode == DebugInfoMode.Simple; 258 } 259 260 public boolean clearNonLiveLocals() { 261 return clearNonLiveLocals; 262 } 263 264 public static GraphBuilderConfiguration getDefault(Plugins plugins) { 265 return new GraphBuilderConfiguration(false, false, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptClearNonLiveLocals.getValue(), plugins); 266 } 267 268 public static GraphBuilderConfiguration getInfopointDefault(Plugins plugins) { 269 return new GraphBuilderConfiguration(true, false, false, DebugInfoMode.Simple, EMPTY, GraalOptions.OptClearNonLiveLocals.getValue(), plugins); 270 } 271 272 public static GraphBuilderConfiguration getEagerDefault(Plugins plugins) { 273 return new GraphBuilderConfiguration(true, false, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptClearNonLiveLocals.getValue(), plugins); 274 } 275 276 public static GraphBuilderConfiguration getInfopointEagerDefault(Plugins plugins) { 277 return new GraphBuilderConfiguration(true, false, false, DebugInfoMode.Simple, EMPTY, GraalOptions.OptClearNonLiveLocals.getValue(), plugins); 278 } 279 280 public static GraphBuilderConfiguration getSnippetDefault(Plugins plugins) { 281 return new GraphBuilderConfiguration(true, true, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptClearNonLiveLocals.getValue(), plugins); 282 } 283 284 public static GraphBuilderConfiguration getFullDebugDefault(Plugins plugins) { 285 return new GraphBuilderConfiguration(true, false, false, DebugInfoMode.Full, EMPTY, GraalOptions.OptClearNonLiveLocals.getValue(), plugins); 286 } 287 288 /** 289 * Returns {@code true} if it is an error for a class/field/method resolution to fail. The 290 * default is the same result as returned by {@link #eagerResolving()}. However, it may be 291 * overridden to allow failure even when {@link #eagerResolving} is {@code true}. 292 */ 293 public boolean unresolvedIsError() { 294 return eagerResolving; 295 } 296 297 public Plugins getPlugins() { 298 return plugins; 299 } 300}