Mercurial > hg > graal-jvmci-8
changeset 22320:f5e2091867e0
Merge with basic-graal
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Fri, 24 Jul 2015 08:23:21 +0200 |
parents | 697b6b4a7f57 (current diff) e02fa353e88c (diff) |
children | f8795ce9154e |
files | jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/ForeignCallLinkage.java jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/ForeignCallsProvider.java jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/ForeignCallDescriptor.java jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/NamedLocationIdentity.java |
diffstat | 14 files changed, 673 insertions(+), 374 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/ForeignCallDescriptor.java Fri Jul 24 08:23:21 2015 +0200 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.common.spi; + +import java.util.*; + +/** + * The name and signature of a foreign call. A foreign call differs from a normal compiled Java call + * in at least one of these aspects: + * <ul> + * <li>The call is to C/C++/assembler code.</li> + * <li>The call uses different conventions for passing parameters or returning values.</li> + * <li>The callee has different register saving semantics. For example, the callee may save all + * registers (apart from some specified temporaries) in which case the register allocator doesn't + * not need to spill all live registers around the call site.</li> + * <li>The call does not occur at an INVOKE* bytecode. Such a call could be transformed into a + * standard Java call if the foreign routine is a normal Java method and the runtime supports + * linking Java calls at arbitrary bytecodes.</li> + * </ul> + */ +public class ForeignCallDescriptor { + + private final String name; + private final Class<?> resultType; + private final Class<?>[] argumentTypes; + + public ForeignCallDescriptor(String name, Class<?> resultType, Class<?>... argumentTypes) { + this.name = name; + this.resultType = resultType; + this.argumentTypes = argumentTypes; + } + + /** + * Gets the name of this foreign call. + */ + public String getName() { + return name; + } + + /** + * Gets the return type of this foreign call. + */ + public Class<?> getResultType() { + return resultType; + } + + /** + * Gets the argument types of this foreign call. + */ + public Class<?>[] getArgumentTypes() { + return argumentTypes.clone(); + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof ForeignCallDescriptor) { + ForeignCallDescriptor other = (ForeignCallDescriptor) obj; + return other.name.equals(name) && other.resultType.equals(resultType) && Arrays.equals(other.argumentTypes, argumentTypes); + } + return false; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(name).append('('); + String sep = ""; + for (Class<?> arg : argumentTypes) { + sb.append(sep).append(arg.getSimpleName()); + sep = ","; + } + return sb.append(')').append(resultType.getSimpleName()).toString(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/ForeignCallLinkage.java Fri Jul 24 08:23:21 2015 +0200 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.common.spi; + +import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.meta.*; + +/** + * The runtime specific details of a {@linkplain ForeignCallDescriptor foreign} call. + */ +public interface ForeignCallLinkage extends InvokeTarget { + + /** + * Gets the details of where parameters are passed and value(s) are returned from the caller's + * perspective. + */ + CallingConvention getOutgoingCallingConvention(); + + /** + * Gets the details of where parameters are passed and value(s) are returned from the callee's + * perspective. + */ + CallingConvention getIncomingCallingConvention(); + + /** + * Returns the maximum absolute offset of PC relative call to this stub from any position in the + * code cache or -1 when not applicable. Intended for determining the required size of + * address/offset fields. + */ + long getMaxCallTargetOffset(); + + ForeignCallDescriptor getDescriptor(); + + /** + * Gets the values used/killed by this foreign call. + */ + Value[] getTemporaries(); + + /** + * Determines if the foreign call target destroys all registers. + * + * @return {@code true} if the register allocator must save all live registers around a call to + * this target + */ + boolean destroysRegisters(); + + /** + * Determines if debug info needs to be associated with this call. Debug info is required if the + * function can raise an exception, try to lock, trigger GC or do anything else that requires + * the VM to be able to inspect the thread's execution state. + */ + boolean needsDebugInfo(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/ForeignCallsProvider.java Fri Jul 24 08:23:21 2015 +0200 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.common.spi; + +import jdk.internal.jvmci.meta.*; + +/** + * Details about a set of supported {@link ForeignCallDescriptor foreign calls}. + */ +public interface ForeignCallsProvider { + + /** + * Determines if a given foreign call is side-effect free. Deoptimization cannot return + * execution to a point before a foreign call that has a side effect. + */ + boolean isReexecutable(ForeignCallDescriptor descriptor); + + /** + * Gets the set of memory locations killed by a given foreign call. Returning the special value + * {@link LocationIdentity#any()} denotes that the call kills all memory locations. Returning + * any empty array denotes that the call does not kill any memory locations. + */ + LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor); + + /** + * Determines if deoptimization can occur during a given foreign call. + */ + boolean canDeoptimize(ForeignCallDescriptor descriptor); + + /** + * Gets the linkage for a foreign call. + */ + ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/GraalDebugConfig.java Fri Jul 24 08:23:21 2015 +0200 @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +import java.io.*; +import java.util.*; + +import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.meta.*; +import jdk.internal.jvmci.options.*; + +public class GraalDebugConfig implements DebugConfig { + @SuppressWarnings("all") + private static boolean assertionsEnabled() { + boolean assertionsEnabled = false; + assert assertionsEnabled = true; + return assertionsEnabled; + } + + // @formatter:off + @Option(help = "Pattern for scope(s) in which dumping is enabled (see DebugFilter and Debug.dump)", type = OptionType.Debug) + public static final OptionValue<String> Dump = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) in which metering is enabled (see DebugFilter and Debug.metric). " + + "An empty value enables all metrics unconditionally.", type = OptionType.Debug) + public static final OptionValue<String> Meter = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) in which verification is enabled (see DebugFilter and Debug.verify).", type = OptionType.Debug) + public static final OptionValue<String> Verify = new OptionValue<String>() { + @Override + protected String defaultValue() { + return assertionsEnabled() ? "" : null; + } + }; + @Option(help = "Pattern for scope(s) in which memory use tracking is enabled (see DebugFilter and Debug.metric). " + + "An empty value enables all memory use trackers unconditionally.", type = OptionType.Debug) + public static final OptionValue<String> TrackMemUse = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) in which timing is enabled (see DebugFilter and Debug.timer). " + + "An empty value enables all timers unconditionally.", type = OptionType.Debug) + public static final OptionValue<String> Time = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) in which logging is enabled (see DebugFilter and Debug.log)", type = OptionType.Debug) + public static final OptionValue<String> Log = new OptionValue<>(null); + @Option(help = "Pattern for filtering debug scope output based on method context (see MethodFilter)", type = OptionType.Debug) + public static final OptionValue<String> MethodFilter = new OptionValue<>(null); + @Option(help = "Only check MethodFilter against the root method in the context if true, otherwise check all methods", type = OptionType.Debug) + public static final OptionValue<Boolean> MethodFilterRootOnly = new OptionValue<>(false); + + @Option(help = "How to print metric and timing values:%n" + + "Name - aggregate by unqualified name%n" + + "Partial - aggregate by partially qualified name (e.g., A.B.C.D.Counter and X.Y.Z.D.Counter will be merged to D.Counter)%n" + + "Complete - aggregate by qualified name%n" + + "Thread - aggregate by qualified name and thread", type = OptionType.Debug) + public static final OptionValue<String> DebugValueSummary = new OptionValue<>("Name"); + @Option(help = "Omit reporting 0-value metrics", type = OptionType.Debug) + public static final OptionValue<Boolean> SuppressZeroDebugValues = new OptionValue<>(true); + @Option(help = "Only report debug values for maps which match the regular expression.", type = OptionType.Debug) + public static final OptionValue<String> DebugValueThreadFilter = new OptionValue<>(null); + @Option(help = "Send JVMCI compiler IR to dump handlers on error", type = OptionType.Debug) + public static final OptionValue<Boolean> DumpOnError = new OptionValue<>(false); + @Option(help = "Intercept also bailout exceptions", type = OptionType.Debug) + public static final OptionValue<Boolean> InterceptBailout = new OptionValue<>(false); + @Option(help = "Enable more verbose log output when available", type = OptionType.Debug) + public static final OptionValue<Boolean> LogVerbose = new OptionValue<>(false); + // @formatter:on + + static boolean isNotEmpty(OptionValue<String> option) { + return option.getValue() != null && !option.getValue().isEmpty(); + } + + public static boolean areDebugScopePatternsEnabled() { + return DumpOnError.getValue() || Dump.getValue() != null || Log.getValue() != null || areScopedMetricsOrTimersEnabled(); + } + + /** + * Determines if any of {@link #Meter}, {@link #Time} or {@link #TrackMemUse} has a non-null, + * non-empty value. + */ + public static boolean areScopedMetricsOrTimersEnabled() { + return isNotEmpty(Meter) || isNotEmpty(Time) || isNotEmpty(TrackMemUse); + } + + private final DebugFilter logFilter; + private final DebugFilter meterFilter; + private final DebugFilter trackMemUseFilter; + private final DebugFilter timerFilter; + private final DebugFilter dumpFilter; + private final DebugFilter verifyFilter; + private final MethodFilter[] methodFilter; + private final List<DebugDumpHandler> dumpHandlers; + private final List<DebugVerifyHandler> verifyHandlers; + private final PrintStream output; + private final Set<Object> extraFilters = new HashSet<>(); + + public GraalDebugConfig(String logFilter, String meterFilter, String trackMemUseFilter, String timerFilter, String dumpFilter, String verifyFilter, String methodFilter, PrintStream output, + List<DebugDumpHandler> dumpHandlers, List<DebugVerifyHandler> verifyHandlers) { + this.logFilter = DebugFilter.parse(logFilter); + this.meterFilter = DebugFilter.parse(meterFilter); + this.trackMemUseFilter = DebugFilter.parse(trackMemUseFilter); + this.timerFilter = DebugFilter.parse(timerFilter); + this.dumpFilter = DebugFilter.parse(dumpFilter); + this.verifyFilter = DebugFilter.parse(verifyFilter); + if (methodFilter == null || methodFilter.isEmpty()) { + this.methodFilter = null; + } else { + this.methodFilter = com.oracle.graal.debug.MethodFilter.parse(methodFilter); + } + + // Report the filters that have been configured so the user can verify it's what they expect + if (logFilter != null || meterFilter != null || timerFilter != null || dumpFilter != null || methodFilter != null) { + // TTY.println(Thread.currentThread().getName() + ": " + toString()); + } + this.dumpHandlers = dumpHandlers; + this.verifyHandlers = verifyHandlers; + this.output = output; + } + + public int getLogLevel() { + return getLevel(logFilter); + } + + public boolean isLogEnabledForMethod() { + return isEnabledForMethod(logFilter); + } + + public boolean isMeterEnabled() { + return isEnabled(meterFilter); + } + + public boolean isMemUseTrackingEnabled() { + return isEnabled(trackMemUseFilter); + } + + public int getDumpLevel() { + return getLevel(dumpFilter); + } + + public boolean isDumpEnabledForMethod() { + return isEnabledForMethod(dumpFilter); + } + + public boolean isVerifyEnabled() { + return isEnabled(verifyFilter); + } + + public boolean isVerifyEnabledForMethod() { + return isEnabledForMethod(verifyFilter); + } + + public boolean isTimeEnabled() { + return isEnabled(timerFilter); + } + + public PrintStream output() { + return output; + } + + private boolean isEnabled(DebugFilter filter) { + return getLevel(filter) > 0; + } + + private int getLevel(DebugFilter filter) { + int level; + if (filter == null) { + level = 0; + } else { + level = filter.matchLevel(Debug.currentScope()); + } + if (level > 0 && !checkMethodFilter()) { + level = 0; + } + return level; + } + + private boolean isEnabledForMethod(DebugFilter filter) { + return filter != null && checkMethodFilter(); + } + + /** + * Extracts a {@link JavaMethod} from an opaque debug context. + * + * @return the {@link JavaMethod} represented by {@code context} or null + */ + public static JavaMethod asJavaMethod(Object context) { + if (context instanceof JavaMethodContex) { + return ((JavaMethodContex) context).asJavaMethod(); + } + return null; + } + + private boolean checkMethodFilter() { + if (methodFilter == null && extraFilters.isEmpty()) { + return true; + } else { + JavaMethod lastMethod = null; + for (Object o : Debug.context()) { + if (extraFilters.contains(o)) { + return true; + } else if (methodFilter != null) { + JavaMethod method = asJavaMethod(o); + if (method != null) { + if (!MethodFilterRootOnly.getValue()) { + if (com.oracle.graal.debug.MethodFilter.matches(methodFilter, method)) { + return true; + } + } else { + /* + * The context values operate as a stack so if we want MethodFilter to + * only apply to the root method we have to check only the last method + * seen. + */ + lastMethod = method; + } + } + } + } + if (lastMethod != null && com.oracle.graal.debug.MethodFilter.matches(methodFilter, lastMethod)) { + return true; + } + return false; + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Debug config:"); + add(sb, "Log", logFilter); + add(sb, "Meter", meterFilter); + add(sb, "Time", timerFilter); + add(sb, "Dump", dumpFilter); + add(sb, "MethodFilter", methodFilter); + return sb.toString(); + } + + private static void add(StringBuilder sb, String name, Object filter) { + if (filter != null) { + sb.append(' '); + sb.append(name); + sb.append('='); + if (filter instanceof Object[]) { + sb.append(Arrays.toString((Object[]) filter)); + } else { + sb.append(String.valueOf(filter)); + } + } + } + + @Override + public RuntimeException interceptException(Throwable e) { + if (e instanceof BailoutException && !InterceptBailout.getValue()) { + return null; + } + Debug.setConfig(Debug.fixedConfig(Debug.DEFAULT_LOG_LEVEL, Debug.DEFAULT_LOG_LEVEL, false, false, false, false, dumpHandlers, verifyHandlers, output)); + Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope())); + for (Object o : Debug.context()) { + if (DumpOnError.getValue()) { + Debug.dump(o, "Exception: " + e.toString()); + } else { + Debug.log("Context obj %s", o); + } + + } + return null; + } + + @Override + public Collection<DebugDumpHandler> dumpHandlers() { + return dumpHandlers; + } + + @Override + public Collection<DebugVerifyHandler> verifyHandlers() { + return verifyHandlers; + } + + @Override + public void addToContext(Object o) { + extraFilters.add(o); + } + + @Override + public void removeFromContext(Object o) { + extraFilters.remove(o); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/NamedLocationIdentity.java Fri Jul 24 08:23:21 2015 +0200 @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +import java.util.*; + +import jdk.internal.jvmci.meta.*; +import jdk.internal.jvmci.meta.Kind.FormatWithToString; + +/** + * A {@link LocationIdentity} with a name. + */ +public class NamedLocationIdentity extends LocationIdentity implements FormatWithToString { + + /** + * Map for asserting all {@link NamedLocationIdentity} instances have a unique name. + */ + static class DB { + private static final HashSet<String> map = new HashSet<>(); + + static boolean checkUnique(String name) { + if (!map.add(name)) { + throw new AssertionError("identity " + name + " already exists"); + } + return true; + } + } + + /** + * Denotes the location of a value that is guaranteed to be unchanging. + */ + public static final LocationIdentity FINAL_LOCATION = NamedLocationIdentity.immutable("FINAL_LOCATION"); + + /** + * Denotes the location of the length field of a Java array. + */ + public static final LocationIdentity ARRAY_LENGTH_LOCATION = NamedLocationIdentity.immutable("[].length"); + + public static LocationIdentity any() { + return ANY_LOCATION; + } + + private final String name; + private final boolean immutable; + + protected NamedLocationIdentity(String name, boolean immutable) { + this.name = name; + this.immutable = immutable; + assert DB.checkUnique(name); + } + + /** + * Creates a named unique location identity for read and write operations against mutable + * memory. + * + * @param name the name of the new location identity + */ + public static NamedLocationIdentity mutable(String name) { + return create(name, false); + } + + /** + * Creates a named unique location identity for read operations against immutable memory. + * Immutable memory will never have a visible write in the graph, which is more restictive than + * Java final. + * + * @param name the name of the new location identity + */ + public static NamedLocationIdentity immutable(String name) { + return create(name, true); + } + + /** + * Creates a named unique location identity for read and write operations. + * + * @param name the name of the new location identity + * @param immutable true if the location is immutable + */ + private static NamedLocationIdentity create(String name, boolean immutable) { + return new NamedLocationIdentity(name, immutable); + } + + @Override + public boolean isImmutable() { + return immutable; + } + + @Override + public String toString() { + return name + (isImmutable() ? ":final" : ""); + } + + /** + * Returns the named location identity for an array of the given element kind. Array accesses of + * the same kind must have the same location identity unless an alias analysis guarantees that + * two distinct arrays are accessed. + */ + public static LocationIdentity getArrayLocation(Kind elementKind) { + return ARRAY_LOCATIONS.get(elementKind); + } + + private static final EnumMap<Kind, LocationIdentity> ARRAY_LOCATIONS = initArrayLocations(); + + private static EnumMap<Kind, LocationIdentity> initArrayLocations() { + EnumMap<Kind, LocationIdentity> result = new EnumMap<>(Kind.class); + for (Kind kind : Kind.values()) { + result.put(kind, NamedLocationIdentity.mutable("Array: " + kind.getJavaName())); + } + return result; + } +}
--- a/jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/ForeignCallLinkage.java Fri Jul 24 08:22:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.jvmci.code; - -import jdk.internal.jvmci.meta.*; - -/** - * The runtime specific details of a {@linkplain ForeignCallDescriptor foreign} call. - */ -public interface ForeignCallLinkage extends InvokeTarget { - - /** - * Gets the details of where parameters are passed and value(s) are returned from the caller's - * perspective. - */ - CallingConvention getOutgoingCallingConvention(); - - /** - * Gets the details of where parameters are passed and value(s) are returned from the callee's - * perspective. - */ - CallingConvention getIncomingCallingConvention(); - - /** - * Returns the maximum absolute offset of PC relative call to this stub from any position in the - * code cache or -1 when not applicable. Intended for determining the required size of - * address/offset fields. - */ - long getMaxCallTargetOffset(); - - ForeignCallDescriptor getDescriptor(); - - /** - * Gets the values used/killed by this foreign call. - */ - Value[] getTemporaries(); - - /** - * Determines if the foreign call target destroys all registers. - * - * @return {@code true} if the register allocator must save all live registers around a call to - * this target - */ - boolean destroysRegisters(); - - /** - * Determines if debug info needs to be associated with this call. Debug info is required if the - * function can raise an exception, try to lock, trigger GC or do anything else that requires - * the VM to be able to inspect the thread's execution state. - */ - boolean needsDebugInfo(); -}
--- a/jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/ForeignCallsProvider.java Fri Jul 24 08:22:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.jvmci.code; - -import jdk.internal.jvmci.meta.*; - -/** - * Details about a set of supported {@link ForeignCallDescriptor foreign calls}. - */ -public interface ForeignCallsProvider { - - /** - * Determines if a given foreign call is side-effect free. Deoptimization cannot return - * execution to a point before a foreign call that has a side effect. - */ - boolean isReexecutable(ForeignCallDescriptor descriptor); - - /** - * Gets the set of memory locations killed by a given foreign call. Returning the special value - * {@link LocationIdentity#any()} denotes that the call kills all memory locations. Returning - * any empty array denotes that the call does not kill any memory locations. - */ - LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor); - - /** - * Determines if deoptimization can occur during a given foreign call. - */ - boolean canDeoptimize(ForeignCallDescriptor descriptor); - - /** - * Gets the linkage for a foreign call. - */ - ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor); -}
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotForeignCallTarget.java Fri Jul 24 08:22:19 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotForeignCallTarget.java Fri Jul 24 08:23:21 2015 +0200 @@ -22,21 +22,14 @@ */ package jdk.internal.jvmci.hotspot; -import jdk.internal.jvmci.meta.*; - public class HotSpotForeignCallTarget { - /** - * The descriptor of the call. - */ - protected final ForeignCallDescriptor descriptor; /** * The entry point address of this call's target. */ protected long address; - public HotSpotForeignCallTarget(ForeignCallDescriptor descriptor, long address) { - this.descriptor = descriptor; + public HotSpotForeignCallTarget(long address) { this.address = address; } }
--- a/jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/ForeignCallDescriptor.java Fri Jul 24 08:22:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.jvmci.meta; - -import java.util.*; - -/** - * The name and signature of a foreign call. A foreign call differs from a normal compiled Java call - * in at least one of these aspects: - * <ul> - * <li>The call is to C/C++/assembler code.</li> - * <li>The call uses different conventions for passing parameters or returning values.</li> - * <li>The callee has different register saving semantics. For example, the callee may save all - * registers (apart from some specified temporaries) in which case the register allocator doesn't - * not need to spill all live registers around the call site.</li> - * <li>The call does not occur at an INVOKE* bytecode. Such a call could be transformed into a - * standard Java call if the foreign routine is a normal Java method and the runtime supports - * linking Java calls at arbitrary bytecodes.</li> - * </ul> - */ -public class ForeignCallDescriptor { - - private final String name; - private final Class<?> resultType; - private final Class<?>[] argumentTypes; - - public ForeignCallDescriptor(String name, Class<?> resultType, Class<?>... argumentTypes) { - this.name = name; - this.resultType = resultType; - this.argumentTypes = argumentTypes; - } - - /** - * Gets the name of this foreign call. - */ - public String getName() { - return name; - } - - /** - * Gets the return type of this foreign call. - */ - public Class<?> getResultType() { - return resultType; - } - - /** - * Gets the argument types of this foreign call. - */ - public Class<?>[] getArgumentTypes() { - return argumentTypes.clone(); - } - - @Override - public int hashCode() { - return name.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof ForeignCallDescriptor) { - ForeignCallDescriptor other = (ForeignCallDescriptor) obj; - return other.name.equals(name) && other.resultType.equals(resultType) && Arrays.equals(other.argumentTypes, argumentTypes); - } - return false; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(name).append('('); - String sep = ""; - for (Class<?> arg : argumentTypes) { - sb.append(sep).append(arg.getSimpleName()); - sep = ","; - } - return sb.append(')').append(resultType.getSimpleName()).toString(); - } -}
--- a/jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/LocationIdentity.java Fri Jul 24 08:22:19 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/LocationIdentity.java Fri Jul 24 08:23:21 2015 +0200 @@ -27,9 +27,8 @@ // JaCoCo Exclude /** - * Marker interface for location identities. Apart from the special values {@link #ANY_LOCATION} and - * {@link #FINAL_LOCATION}, a different location identity of two memory accesses guarantees that the - * two accesses do not interfere. + * Marker interface for location identities. A different location identity of two memory accesses + * guarantees that the two accesses do not interfere. * * Clients of {@link LocationIdentity} must use {@link #equals(Object)}, not {@code ==}, when * comparing two {@link LocationIdentity} values for equality. Likewise, they must not use @@ -37,22 +36,19 @@ */ public abstract class LocationIdentity { - /** - * Denotes any location. A write to such a location kills all values in a memory map during an - * analysis of memory accesses. A read from this location cannot be moved or coalesced with - * other reads because its interaction with other reads is not known. - */ - private static final LocationIdentity ANY_LOCATION = NamedLocationIdentity.mutable("ANY_LOCATION"); + private static final class AnyLocationIdentity extends LocationIdentity { + @Override + public boolean isImmutable() { + return false; + } - /** - * Denotes the location of a value that is guaranteed to be unchanging. - */ - public static final LocationIdentity FINAL_LOCATION = NamedLocationIdentity.immutable("FINAL_LOCATION"); + @Override + public String toString() { + return "ANY_LOCATION"; + } + } - /** - * Denotes the location of the length field of a Java array. - */ - public static final LocationIdentity ARRAY_LENGTH_LOCATION = NamedLocationIdentity.immutable("[].length"); + public static final LocationIdentity ANY_LOCATION = new AnyLocationIdentity(); public static LocationIdentity any() { return ANY_LOCATION;
--- a/jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/NamedLocationIdentity.java Fri Jul 24 08:22:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.jvmci.meta; - -import java.util.*; - -import jdk.internal.jvmci.meta.Kind.*; - -/** - * A {@link LocationIdentity} with a name. - */ -public class NamedLocationIdentity extends LocationIdentity implements FormatWithToString { - - /** - * Map for asserting all {@link NamedLocationIdentity} instances have a unique name. - */ - static class DB { - private static final HashSet<String> map = new HashSet<>(); - - static boolean checkUnique(String name) { - if (!map.add(name)) { - throw new AssertionError("identity " + name + " already exists"); - } - return true; - } - } - - private final String name; - private final boolean immutable; - - protected NamedLocationIdentity(String name, boolean immutable) { - this.name = name; - this.immutable = immutable; - assert DB.checkUnique(name); - } - - /** - * Creates a named unique location identity for read and write operations against mutable - * memory. - * - * @param name the name of the new location identity - */ - public static NamedLocationIdentity mutable(String name) { - return create(name, false); - } - - /** - * Creates a named unique location identity for read operations against immutable memory. - * Immutable memory will never have a visible write in the graph, which is more restictive than - * Java final. - * - * @param name the name of the new location identity - */ - public static NamedLocationIdentity immutable(String name) { - return create(name, true); - } - - /** - * Creates a named unique location identity for read and write operations. - * - * @param name the name of the new location identity - * @param immutable true if the location is immutable - */ - private static NamedLocationIdentity create(String name, boolean immutable) { - return new NamedLocationIdentity(name, immutable); - } - - @Override - public boolean isImmutable() { - return immutable; - } - - @Override - public String toString() { - return name + (isImmutable() ? ":final" : ""); - } - - /** - * Returns the named location identity for an array of the given element kind. Array accesses of - * the same kind must have the same location identity unless an alias analysis guarantees that - * two distinct arrays are accessed. - */ - public static LocationIdentity getArrayLocation(Kind elementKind) { - return ARRAY_LOCATIONS.get(elementKind); - } - - private static final EnumMap<Kind, LocationIdentity> ARRAY_LOCATIONS = initArrayLocations(); - - private static EnumMap<Kind, LocationIdentity> initArrayLocations() { - EnumMap<Kind, LocationIdentity> result = new EnumMap<>(Kind.class); - for (Kind kind : Kind.values()) { - result.put(kind, NamedLocationIdentity.mutable("Array: " + kind.getJavaName())); - } - return result; - } -}
--- a/src/share/vm/classfile/systemDictionary.hpp Fri Jul 24 08:22:19 2015 +0200 +++ b/src/share/vm/classfile/systemDictionary.hpp Fri Jul 24 08:23:21 2015 +0200 @@ -234,7 +234,6 @@ JVMCI_ONLY(do_klass(code_Location_klass, jdk_internal_jvmci_code_Location, Jvmci)) \ JVMCI_ONLY(do_klass(code_Register_klass, jdk_internal_jvmci_code_Register, Jvmci)) \ JVMCI_ONLY(do_klass(RegisterValue_klass, jdk_internal_jvmci_code_RegisterValue, Jvmci)) \ - JVMCI_ONLY(do_klass(RegisterCategory_klass, jdk_internal_jvmci_code_Register_RegisterCategory, Jvmci)) \ JVMCI_ONLY(do_klass(StackSlot_klass, jdk_internal_jvmci_code_StackSlot, Jvmci)) \ JVMCI_ONLY(do_klass(StackLockValue_klass, jdk_internal_jvmci_code_StackLockValue, Jvmci)) \ JVMCI_ONLY(do_klass(VirtualObject_klass, jdk_internal_jvmci_code_VirtualObject, Jvmci)) \ @@ -246,8 +245,6 @@ JVMCI_ONLY(do_klass(ExceptionHandler_klass, jdk_internal_jvmci_meta_ExceptionHandler, Jvmci)) \ JVMCI_ONLY(do_klass(Kind_klass, jdk_internal_jvmci_meta_Kind, Jvmci)) \ JVMCI_ONLY(do_klass(LIRKind_klass, jdk_internal_jvmci_meta_LIRKind, Jvmci)) \ - JVMCI_ONLY(do_klass(JavaMethod_klass, jdk_internal_jvmci_meta_JavaMethod, Jvmci)) \ - JVMCI_ONLY(do_klass(JavaType_klass, jdk_internal_jvmci_meta_JavaType, Jvmci)) \ JVMCI_ONLY(do_klass(AbstractValue_klass, jdk_internal_jvmci_meta_AbstractValue, Jvmci)) \ /*end*/
--- a/src/share/vm/classfile/vmSymbols.hpp Fri Jul 24 08:22:19 2015 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Fri Jul 24 08:23:21 2015 +0200 @@ -319,8 +319,6 @@ JVMCI_ONLY(template(jdk_internal_jvmci_meta_RawConstant, "jdk/internal/jvmci/meta/RawConstant")) \ JVMCI_ONLY(template(jdk_internal_jvmci_meta_NullConstant, "jdk/internal/jvmci/meta/NullConstant")) \ JVMCI_ONLY(template(jdk_internal_jvmci_meta_ExceptionHandler, "jdk/internal/jvmci/meta/ExceptionHandler")) \ - JVMCI_ONLY(template(jdk_internal_jvmci_meta_JavaMethod, "jdk/internal/jvmci/meta/JavaMethod")) \ - JVMCI_ONLY(template(jdk_internal_jvmci_meta_JavaType, "jdk/internal/jvmci/meta/JavaType")) \ JVMCI_ONLY(template(jdk_internal_jvmci_meta_Kind, "jdk/internal/jvmci/meta/Kind")) \ JVMCI_ONLY(template(jdk_internal_jvmci_meta_LIRKind, "jdk/internal/jvmci/meta/LIRKind")) \ JVMCI_ONLY(template(jdk_internal_jvmci_meta_AbstractValue, "jdk/internal/jvmci/meta/AbstractValue")) \ @@ -346,7 +344,6 @@ JVMCI_ONLY(template(jdk_internal_jvmci_code_Location, "jdk/internal/jvmci/code/Location")) \ JVMCI_ONLY(template(jdk_internal_jvmci_code_Register, "jdk/internal/jvmci/code/Register")) \ JVMCI_ONLY(template(jdk_internal_jvmci_code_RegisterValue, "jdk/internal/jvmci/code/RegisterValue")) \ - JVMCI_ONLY(template(jdk_internal_jvmci_code_Register_RegisterCategory, "jdk/internal/jvmci/code/Register$RegisterCategory")) \ JVMCI_ONLY(template(jdk_internal_jvmci_code_StackSlot, "jdk/internal/jvmci/code/StackSlot")) \ JVMCI_ONLY(template(jdk_internal_jvmci_code_StackLockValue, "jdk/internal/jvmci/code/StackLockValue")) \ JVMCI_ONLY(template(jdk_internal_jvmci_code_VirtualObject, "jdk/internal/jvmci/code/VirtualObject")) \
--- a/src/share/vm/jvmci/jvmciCompilerToVM.cpp Fri Jul 24 08:22:19 2015 +0200 +++ b/src/share/vm/jvmci/jvmciCompilerToVM.cpp Fri Jul 24 08:23:21 2015 +0200 @@ -1039,9 +1039,6 @@ #define CC (char*) /*cast a literal from (const char*)*/ #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f)) -#define TYPE "Ljdk/internal/jvmci/meta/JavaType;" -#define METHOD "Ljdk/internal/jvmci/meta/JavaMethod;" -#define FIELD "Ljdk/internal/jvmci/meta/JavaField;" #define SPECULATION_LOG "Ljdk/internal/jvmci/meta/SpeculationLog;" #define STRING "Ljava/lang/String;" #define OBJECT "Ljava/lang/Object;"