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;"