changeset 15919:0bfce5328510

Merge.
author Doug Simon <doug.simon@oracle.com>
date Mon, 26 May 2014 20:27:28 +0200
parents 2977687e6db0 (diff) 88a6017687c9 (current diff)
children 4b835260c746
files
diffstat 17 files changed, 498 insertions(+), 168 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Service.java	Mon May 26 20:27:28 2014 +0200
@@ -0,0 +1,29 @@
+/*
+ * 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.api.runtime;
+
+/**
+ * Denotes a service that may be efficiently loaded by {@link Services#load(Class)}.
+ */
+public interface Service {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Services.java	Mon May 26 20:27:28 2014 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014, 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.api.runtime;
+
+import static java.lang.String.*;
+
+import java.util.*;
+
+/**
+ * A mechanism on top of the standard {@link ServiceLoader} that enables a runtime to efficiently
+ * load services marked by {@link Service}. This may be important for services loaded early in the
+ * runtime initialization process.
+ */
+public class Services {
+
+    private static final ClassValue<List<Service>> cache = new ClassValue<List<Service>>() {
+        @Override
+        protected List<Service> computeValue(Class<?> type) {
+            Service[] names = getServiceImpls(type);
+            if (names == null || names.length == 0) {
+                throw new InternalError(format("No implementations for %s found (ensure %s extends %s)", type.getSimpleName(), type.getSimpleName(), Service.class));
+            }
+            return Arrays.asList(names);
+        }
+    };
+
+    /**
+     * Gets an {@link Iterable} of the implementations available for a given service.
+     */
+    @SuppressWarnings("unchecked")
+    public static <S> Iterable<S> load(Class<S> service) {
+        if (Service.class.isAssignableFrom(service)) {
+            try {
+                return (Iterable<S>) cache.get(service);
+            } catch (UnsatisfiedLinkError e) {
+                // Fall back to standard SerivceLoader
+            }
+        }
+        return ServiceLoader.loadInstalled(service);
+    }
+
+    private static native <S> S[] getServiceImpls(Class<?> service);
+}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java	Wed May 21 18:40:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java	Mon May 26 20:27:28 2014 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot.amd64;
 
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.InitTimer.*;
+
 import java.util.*;
 
 import com.oracle.graal.amd64.*;
@@ -30,6 +32,7 @@
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.util.*;
@@ -98,26 +101,65 @@
         assert host == null;
         TargetDescription target = createTarget(runtime.getConfig());
 
-        HotSpotRegistersProvider registers = createRegisters();
-        HotSpotMetaAccessProvider metaAccess = createMetaAccess(runtime);
-        HotSpotCodeCacheProvider codeCache = createCodeCache(runtime, target);
-        HotSpotConstantReflectionProvider constantReflection = createConstantReflection(runtime);
-        Value[] nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(runtime.getConfig(), codeCache.getRegisterConfig());
-        HotSpotHostForeignCallsProvider foreignCalls = createForeignCalls(runtime, metaAccess, codeCache, nativeABICallerSaveRegisters);
-        HotSpotLoweringProvider lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, target);
-        // Replacements cannot have speculative optimizations since they have
-        // to be valid for the entire run of the VM.
-        Assumptions assumptions = new Assumptions(false);
-        Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null);
-        HotSpotSnippetReflectionProvider snippetReflection = createSnippetReflection();
-        Replacements replacements = createReplacements(runtime, assumptions, p, snippetReflection);
-        HotSpotDisassemblerProvider disassembler = createDisassembler(runtime);
-        HotSpotSuitesProvider suites = createSuites(runtime);
-        HotSpotMethodHandleAccessProvider methodHandleAccess = new HotSpotMethodHandleAccessProvider();
-        HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection,
-                        methodHandleAccess);
-
-        return createBackend(runtime, providers);
+        HotSpotProviders providers;
+        HotSpotRegistersProvider registers;
+        HotSpotCodeCacheProvider codeCache;
+        HotSpotConstantReflectionProvider constantReflection;
+        HotSpotHostForeignCallsProvider foreignCalls;
+        Value[] nativeABICallerSaveRegisters;
+        HotSpotMetaAccessProvider metaAccess;
+        HotSpotLoweringProvider lowerer;
+        HotSpotSnippetReflectionProvider snippetReflection;
+        Replacements replacements;
+        HotSpotDisassemblerProvider disassembler;
+        HotSpotSuitesProvider suites;
+        HotSpotMethodHandleAccessProvider methodHandleAccess;
+        try (InitTimer t = timer("create providers")) {
+            try (InitTimer rt = timer("create HotSpotRegisters provider")) {
+                registers = createRegisters();
+            }
+            try (InitTimer rt = timer("create MetaAccess provider")) {
+                metaAccess = createMetaAccess(runtime);
+            }
+            try (InitTimer rt = timer("create CodeCache provider")) {
+                codeCache = createCodeCache(runtime, target);
+            }
+            try (InitTimer rt = timer("create ConstantReflection provider")) {
+                constantReflection = createConstantReflection(runtime);
+            }
+            try (InitTimer rt = timer("create NativeABICallerSaveRegisters")) {
+                nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(runtime.getConfig(), codeCache.getRegisterConfig());
+            }
+            try (InitTimer rt = timer("create ForeignCalls provider")) {
+                foreignCalls = createForeignCalls(runtime, metaAccess, codeCache, nativeABICallerSaveRegisters);
+            }
+            try (InitTimer rt = timer("create Lowerer provider")) {
+                lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, target);
+            }
+            // Replacements cannot have speculative optimizations since they have
+            // to be valid for the entire run of the VM.
+            Assumptions assumptions = new Assumptions(false);
+            Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null);
+            try (InitTimer rt = timer("create SnippetReflection provider")) {
+                snippetReflection = createSnippetReflection();
+            }
+            try (InitTimer rt = timer("create Replacements provider")) {
+                replacements = createReplacements(runtime, assumptions, p, snippetReflection);
+            }
+            try (InitTimer rt = timer("create Disassembler provider")) {
+                disassembler = createDisassembler(runtime);
+            }
+            try (InitTimer rt = timer("create Suites provider")) {
+                suites = createSuites(runtime);
+            }
+            try (InitTimer rt = timer("create MethodHandleAccess provider")) {
+                methodHandleAccess = new HotSpotMethodHandleAccessProvider();
+            }
+            providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection, methodHandleAccess);
+        }
+        try (InitTimer rt = timer("instantiate backend")) {
+            return createBackend(runtime, providers);
+        }
     }
 
     protected AMD64HotSpotBackend createBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.codegen/src/com/oracle/graal/hotspot/codegen/GenGraalRuntimeInlineHpp.java	Mon May 26 20:27:28 2014 +0200
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2014, 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.hotspot.codegen;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.zip.*;
+
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.options.*;
+
+/**
+ * Command line utility for generating the source code of {@code GraalRuntime.inline.hpp}.
+ */
+public class GenGraalRuntimeInlineHpp {
+
+    public static void main(String[] args) {
+        PrintStream out = System.out;
+        try {
+            genGetServiceImpls(out);
+            genSetOption(out);
+        } catch (Throwable t) {
+            t.printStackTrace(out);
+        }
+        out.flush();
+    }
+
+    /**
+     * Generates code for {@code GraalRuntime::get_service_impls()}.
+     */
+    private static void genGetServiceImpls(PrintStream out) throws Exception {
+        String graalJar = null;
+        String classPath = System.getProperty("java.class.path");
+        for (String e : classPath.split(File.pathSeparator)) {
+            if (e.endsWith("graal.jar")) {
+                graalJar = e;
+                break;
+            }
+        }
+        final List<Class<? extends Service>> services = new ArrayList<>();
+        final ZipFile zipFile = new ZipFile(new File(Objects.requireNonNull(graalJar, "Could not find graal.jar on class path: " + classPath)));
+        for (final Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements();) {
+            final ZipEntry zipEntry = e.nextElement();
+            String name = zipEntry.getName();
+            if (name.startsWith("META-INF/services/")) {
+                String serviceName = name.substring("META-INF/services/".length());
+                Class<?> c = Class.forName(serviceName);
+                if (Service.class.isAssignableFrom(c)) {
+                    @SuppressWarnings("unchecked")
+                    Class<? extends Service> sc = (Class<? extends Service>) c;
+
+                    services.add(sc);
+                }
+            }
+        }
+
+        out.println("Handle GraalRuntime::get_service_impls(KlassHandle serviceKlass, TRAPS) {");
+        for (Class<?> service : services) {
+            out.printf("  if (serviceKlass->name()->equals(\"%s\")) {%n", toInternalName(service));
+            List<Class<?>> impls = new ArrayList<>();
+            for (Object impl : ServiceLoader.load(service)) {
+                impls.add(impl.getClass());
+            }
+
+            out.printf("    objArrayOop servicesOop = oopFactory::new_objArray(serviceKlass(), %d, CHECK_NH);%n", impls.size());
+            out.println("    objArrayHandle services(THREAD, servicesOop);");
+            for (int i = 0; i < impls.size(); i++) {
+                String name = toInternalName(impls.get(i));
+                out.printf("    %sservice = create_Service(\"%s\", CHECK_NH);%n", (i == 0 ? "Handle " : ""), name);
+                out.printf("    services->obj_at_put(%d, service());%n", i);
+            }
+            out.println("    return services;");
+            out.println("  }");
+        }
+        out.println("  return Handle();");
+        out.println("}");
+    }
+
+    /**
+     * Generates code for {@code GraalRuntime::set_option()}.
+     */
+    private static void genSetOption(PrintStream out) throws Exception {
+        SortedMap<String, OptionDescriptor> options = getOptions();
+
+        Set<Integer> lengths = new TreeSet<>();
+        for (String s : options.keySet()) {
+            lengths.add(s.length());
+        }
+        lengths.add("PrintFlags".length());
+
+        out.println("bool GraalRuntime::set_option(KlassHandle hotSpotOptionsClass, const char* name, int name_len, Handle name_handle, const char* value, TRAPS) {");
+        out.println("  if (value[0] == '+' || value[0] == '-') {");
+        out.println("    // boolean options");
+        genMatchers(out, lengths, options, true);
+        out.println("  } else {");
+        out.println("    // non-boolean options");
+        genMatchers(out, lengths, options, false);
+        out.println("  }");
+        out.println("  return false;");
+        out.println("}");
+    }
+
+    protected static void genMatchers(PrintStream out, Set<Integer> lengths, SortedMap<String, OptionDescriptor> options, boolean isBoolean) throws Exception {
+        out.println("    switch (name_len) {");
+        for (int len : lengths) {
+            boolean printedCase = false;
+
+            // The use of strncmp is required (instead of strcmp) as the option name will not be
+            // null terminated for <name>=<value> style options.
+            if (len == "PrintFlags".length() && isBoolean) {
+                printedCase = true;
+                out.println("    case " + len + ":");
+                out.printf("      if (strncmp(name, \"PrintFlags\", %d) == 0) {%n", len);
+                out.println("        if (value[0] == '+') {");
+                out.println("          VMToCompiler::setOption(hotSpotOptionsClass, name_handle, Handle(), '?', Handle(), 0L);");
+                out.println("        }");
+                out.println("        return true;");
+                out.println("      }");
+            }
+            for (Map.Entry<String, OptionDescriptor> e : options.entrySet()) {
+                OptionDescriptor desc = e.getValue();
+                if (e.getKey().length() == len && ((desc.getType() == Boolean.class) == isBoolean)) {
+                    if (!printedCase) {
+                        printedCase = true;
+                        out.println("    case " + len + ":");
+                    }
+                    out.printf("      if (strncmp(name, \"%s\", %d) == 0) {%n", e.getKey(), len);
+                    Class<?> declaringClass = desc.getDeclaringClass();
+                    out.printf("        Handle option = get_OptionValue(\"L%s;\", \"%s\", \"L%s;\", CHECK_(true));%n", toInternalName(declaringClass), desc.getFieldName(),
+                                    toInternalName(getFieldType(desc)));
+                    if (isBoolean) {
+                        out.println("        VMToCompiler::setOption(hotSpotOptionsClass, name_handle, option, value[0], Handle(), 0L);");
+                    } else if (desc.getType() == String.class) {
+                        out.println("        Handle stringValue = java_lang_String::create_from_str(value, CHECK_(true));");
+                        out.println("        VMToCompiler::setOption(hotSpotOptionsClass, name_handle, option, 's', stringValue, 0L);");
+                    } else {
+                        char spec = getPrimitiveSpecChar(desc);
+                        out.println("        jlong primitiveValue = parse_primitive_option_value('" + spec + "', name_handle, value, CHECK_(true));");
+                        out.println("        VMToCompiler::setOption(hotSpotOptionsClass, name_handle, option, '" + spec + "', Handle(), primitiveValue);");
+                    }
+                    out.println("        return true;");
+                    out.println("      }");
+                }
+            }
+        }
+        out.println("    }");
+    }
+
+    @SuppressWarnings("unchecked")
+    static SortedMap<String, OptionDescriptor> getOptions() throws Exception {
+        Field field = Class.forName("com.oracle.graal.hotspot.HotSpotOptionsLoader").getDeclaredField("options");
+        field.setAccessible(true);
+        return (SortedMap<String, OptionDescriptor>) field.get(null);
+    }
+
+    private static Class<?> getFieldType(OptionDescriptor desc) throws Exception {
+        return desc.getDeclaringClass().getDeclaredField(desc.getFieldName()).getType();
+    }
+
+    private static String toInternalName(Class<?> c) {
+        return c.getName().replace('.', '/');
+    }
+
+    /**
+     * @see HotSpotOptions#setOption(String, OptionValue, char, String, long)
+     */
+    @SuppressWarnings("javadoc")
+    private static char getPrimitiveSpecChar(OptionDescriptor desc) {
+        if (desc.getType() == Integer.class) {
+            return 'i';
+        }
+        if (desc.getType() == Float.class) {
+            return 'f';
+        }
+        if (desc.getType() == Double.class) {
+            return 'd';
+        }
+        throw GraalInternalError.shouldNotReachHere("Unexpected primitive option type: " + desc.getType().getName());
+    }
+}
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java	Wed May 21 18:40:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java	Mon May 26 20:27:28 2014 +0200
@@ -22,10 +22,13 @@
  */
 package com.oracle.graal.hotspot.ptx;
 
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.InitTimer.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.spi.*;
@@ -37,19 +40,50 @@
 
     public HotSpotBackend createBackend(HotSpotGraalRuntime runtime, HotSpotBackend hostBackend) {
         HotSpotProviders host = hostBackend.getProviders();
-
-        HotSpotMetaAccessProvider metaAccess = host.getMetaAccess();
-        PTXHotSpotCodeCacheProvider codeCache = new PTXHotSpotCodeCacheProvider(runtime, createTarget());
-        ConstantReflectionProvider constantReflection = host.getConstantReflection();
-        HotSpotForeignCallsProvider foreignCalls = new PTXHotSpotForeignCallsProvider();
-        LoweringProvider lowerer = new PTXHotSpotLoweringProvider(host.getLowerer());
-        Replacements replacements = host.getReplacements();
-        HotSpotDisassemblerProvider disassembler = host.getDisassembler();
-        SuitesProvider suites = new DefaultSuitesProvider();
-        HotSpotRegistersProvider registers = new HotSpotRegisters(PTX.tid, Register.None, Register.None);
-        HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, host.getSnippetReflection(),
-                        host.getMethodHandleAccess());
-        return new PTXHotSpotBackend(runtime, providers);
+        HotSpotMetaAccessProvider metaAccess;
+        PTXHotSpotCodeCacheProvider codeCache;
+        ConstantReflectionProvider constantReflection;
+        HotSpotForeignCallsProvider foreignCalls;
+        LoweringProvider lowerer;
+        Replacements replacements;
+        HotSpotDisassemblerProvider disassembler;
+        SuitesProvider suites;
+        HotSpotRegistersProvider registers;
+        HotSpotProviders providers;
+        try (InitTimer t = timer("create providers")) {
+            try (InitTimer rt = timer("create MetaAccess provider")) {
+                metaAccess = host.getMetaAccess();
+            }
+            try (InitTimer rt = timer("create CodeCache provider")) {
+                codeCache = new PTXHotSpotCodeCacheProvider(runtime, createTarget());
+            }
+            try (InitTimer rt = timer("create ConstantReflection provider")) {
+                constantReflection = host.getConstantReflection();
+            }
+            try (InitTimer rt = timer("create ForeignCalls provider")) {
+                foreignCalls = new PTXHotSpotForeignCallsProvider();
+            }
+            try (InitTimer rt = timer("create Lowerer provider")) {
+                lowerer = new PTXHotSpotLoweringProvider(host.getLowerer());
+            }
+            try (InitTimer rt = timer("create Replacements provider")) {
+                replacements = host.getReplacements();
+            }
+            try (InitTimer rt = timer("create Disassembler provider")) {
+                disassembler = host.getDisassembler();
+            }
+            try (InitTimer rt = timer("create Suites provider")) {
+                suites = new DefaultSuitesProvider();
+            }
+            try (InitTimer rt = timer("create HotSpotRegisters provider")) {
+                registers = new HotSpotRegisters(PTX.tid, Register.None, Register.None);
+            }
+            providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, host.getSnippetReflection(),
+                            host.getMethodHandleAccess());
+        }
+        try (InitTimer rt = timer("instantiate backend")) {
+            return new PTXHotSpotBackend(runtime, providers);
+        }
     }
 
     protected Architecture createArchitecture() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackendFactory.java	Wed May 21 18:40:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackendFactory.java	Mon May 26 20:27:28 2014 +0200
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.hotspot;
 
+import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.hotspot.HotSpotGraalRuntime.Options;
 
-public interface HotSpotBackendFactory {
+public interface HotSpotBackendFactory extends Service {
 
     HotSpotBackend createBackend(HotSpotGraalRuntime runtime, HotSpotBackend host);
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Wed May 21 18:40:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Mon May 26 20:27:28 2014 +0200
@@ -24,8 +24,8 @@
 
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.compiler.common.UnsafeAccess.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.InitTimer.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.Options.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.InitTimer.*;
 import static sun.reflect.Reflection.*;
 
 import java.lang.reflect.*;
@@ -70,23 +70,33 @@
         private InitTimer(String name) {
             this.name = name;
             this.start = System.currentTimeMillis();
-            System.out.println("START INIT: " + name);
+            System.out.println("START: " + SPACES.substring(0, timerDepth * 2) + name);
+            assert Thread.currentThread() == initializingThread;
+            timerDepth++;
         }
 
         public void close() {
             final long end = System.currentTimeMillis();
-            System.out.println(" DONE INIT: " + name + " [" + (end - start) + " ms]");
+            timerDepth--;
+            System.out.println(" DONE: " + SPACES.substring(0, timerDepth * 2) + name + " [" + (end - start) + " ms]");
         }
 
         public static InitTimer timer(String name) {
             return ENABLED ? new InitTimer(name) : null;
         }
 
+        public static InitTimer timer(String name, Object suffix) {
+            return ENABLED ? new InitTimer(name + suffix) : null;
+        }
+
         /**
          * Specified initialization timing is enabled. This must only be set via a system property
          * as the timing facility is used to time initialization of {@link HotSpotOptions}.
          */
         private static final boolean ENABLED = Boolean.getBoolean("graal.runtime.TimeInit");
+        public static int timerDepth = 0;
+        public static final String SPACES = "                                            ";
+        public static final Thread initializingThread = Thread.currentThread();
     }
 
     private static final HotSpotGraalRuntime instance;
@@ -179,7 +189,7 @@
         HotSpotBackendFactory nonBasic = null;
         int nonBasicCount = 0;
 
-        for (HotSpotBackendFactory factory : ServiceLoader.loadInstalled(HotSpotBackendFactory.class)) {
+        for (HotSpotBackendFactory factory : Services.load(HotSpotBackendFactory.class)) {
             if (factory.getArchitecture().equalsIgnoreCase(architecture)) {
                 if (factory.getGraalRuntimeName().equals(GraalRuntime.getValue())) {
                     assert selected == null || checkFactoryOverriding(selected, factory);
@@ -285,7 +295,9 @@
 
         compilerToVm = toVM;
         vmToCompiler = toCompiler;
-        config = new HotSpotVMConfig(compilerToVm);
+        try (InitTimer t = timer("HotSpotVMConfig<init>")) {
+            config = new HotSpotVMConfig(compilerToVm);
+        }
 
         CompileTheWorld.Options.overrideWithNativeOptions(config);
 
@@ -306,18 +318,31 @@
         }
 
         String hostArchitecture = config.getHostArchitectureName();
-        hostBackend = registerBackend(findFactory(hostArchitecture).createBackend(this, null));
+
+        HotSpotBackendFactory factory;
+        try (InitTimer t = timer("find factory:", hostArchitecture)) {
+            factory = findFactory(hostArchitecture);
+        }
+        try (InitTimer t = timer("create backend:", hostArchitecture)) {
+            hostBackend = registerBackend(factory.createBackend(this, null));
+        }
 
         String[] gpuArchitectures = getGPUArchitectureNames(compilerToVm);
         for (String arch : gpuArchitectures) {
-            HotSpotBackendFactory factory = findFactory(arch);
+            try (InitTimer t = timer("find factory:", arch)) {
+                factory = findFactory(arch);
+            }
             if (factory == null) {
                 throw new GraalInternalError("No backend available for specified GPU architecture \"%s\"", arch);
             }
-            registerBackend(factory.createBackend(this, hostBackend));
+            try (InitTimer t = timer("create backend:", arch)) {
+                registerBackend(factory.createBackend(this, hostBackend));
+            }
         }
 
-        eventProvider = createEventProvider();
+        try (InitTimer t = timer("createEventProvider")) {
+            eventProvider = createEventProvider();
+        }
     }
 
     private HotSpotBackend registerBackend(HotSpotBackend backend) {
@@ -427,7 +452,7 @@
 
     private EventProvider createEventProvider() {
         if (config.flightRecorder) {
-            ServiceLoader<EventProvider> sl = ServiceLoader.loadInstalled(EventProvider.class);
+            Iterable<EventProvider> sl = Services.load(EventProvider.class);
             EventProvider singleProvider = null;
             for (EventProvider ep : sl) {
                 assert singleProvider == null : String.format("multiple %s service implementations found: %s and %s", EventProvider.class.getName(), singleProvider.getClass().getName(),
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Wed May 21 18:40:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Mon May 26 20:27:28 2014 +0200
@@ -25,9 +25,8 @@
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.InitTimer.*;
 
-import java.util.*;
-
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
@@ -80,7 +79,7 @@
         if (Intrinsify.getValue()) {
             try (Scope s = Debug.scope("RegisterReplacements", new DebugDumpScope("RegisterReplacements"))) {
                 try (InitTimer st = timer("replacementsProviders.registerReplacements")) {
-                    ServiceLoader<ReplacementsProvider> sl = ServiceLoader.loadInstalled(ReplacementsProvider.class);
+                    Iterable<ReplacementsProvider> sl = Services.load(ReplacementsProvider.class);
                     for (ReplacementsProvider replacementsProvider : sl) {
                         replacementsProvider.registerReplacements(providers.getMetaAccess(), lowerer, providers.getSnippetReflection(), replacements, providers.getCodeCache().getTarget());
                     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptionsLoader.java	Wed May 21 18:40:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptionsLoader.java	Mon May 26 20:27:28 2014 +0200
@@ -22,10 +22,8 @@
  */
 package com.oracle.graal.hotspot;
 
-import java.io.*;
 import java.util.*;
 
-import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.options.*;
 
 /**
@@ -56,103 +54,4 @@
     private static boolean isHotSpotOption(OptionDescriptor desc) {
         return desc.getClass().getName().startsWith("com.oracle.graal");
     }
-
-    /**
-     * Command line utility for generating the source code of GraalRuntime::set_option() which is
-     * written {@link System#out}.
-     */
-    public static void main(String[] args) {
-        PrintStream out = System.out;
-        try {
-            Set<Integer> lengths = new TreeSet<>();
-            for (String s : options.keySet()) {
-                lengths.add(s.length());
-            }
-            lengths.add("PrintFlags".length());
-
-            out.println("bool GraalRuntime::set_option(KlassHandle hotSpotOptionsClass, const char* name, int name_len, Handle name_handle, const char* value, TRAPS) {");
-            out.println("  if (value[0] == '+' || value[0] == '-') {");
-            out.println("    // boolean options");
-            genMatchers(out, lengths, true);
-            out.println("  } else {");
-            out.println("    // non-boolean options");
-            genMatchers(out, lengths, false);
-            out.println("  }");
-            out.println("  return false;");
-            out.println("}");
-        } catch (Throwable t) {
-            t.printStackTrace(out);
-        }
-        out.flush();
-    }
-
-    protected static void genMatchers(PrintStream out, Set<Integer> lengths, boolean isBoolean) throws Exception {
-        out.println("    switch (name_len) {");
-        for (int len : lengths) {
-            boolean printedCase = false;
-
-            // The use of strncmp is required (instead of strcmp) as the option name will not be
-            // null terminated for <name>=<value> style options.
-            if (len == "PrintFlags".length() && isBoolean) {
-                printedCase = true;
-                out.println("    case " + len + ":");
-                out.printf("      if (strncmp(name, \"PrintFlags\", %d) == 0) {\n", len);
-                out.println("        if (value[0] == '+') {");
-                out.println("          VMToCompiler::setOption(hotSpotOptionsClass, name_handle, Handle(), '?', Handle(), 0L);");
-                out.println("        }");
-                out.println("        return true;");
-                out.println("      }");
-            }
-            for (Map.Entry<String, OptionDescriptor> e : options.entrySet()) {
-                OptionDescriptor desc = e.getValue();
-                if (e.getKey().length() == len && ((desc.getType() == Boolean.class) == isBoolean)) {
-                    if (!printedCase) {
-                        printedCase = true;
-                        out.println("    case " + len + ":");
-                    }
-                    out.printf("      if (strncmp(name, \"%s\", %d) == 0) {\n", e.getKey(), len);
-                    Class<?> declaringClass = desc.getDeclaringClass();
-                    out.printf("        Handle option = get_OptionValue(\"L%s;\", \"%s\", \"L%s;\", CHECK_(true));\n", toInternalName(declaringClass), desc.getFieldName(),
-                                    toInternalName(getFieldType(desc)));
-                    if (isBoolean) {
-                        out.println("        VMToCompiler::setOption(hotSpotOptionsClass, name_handle, option, value[0], Handle(), 0L);");
-                    } else if (desc.getType() == String.class) {
-                        out.println("        Handle stringValue = java_lang_String::create_from_str(value, CHECK_(true));");
-                        out.println("        VMToCompiler::setOption(hotSpotOptionsClass, name_handle, option, 's', stringValue, 0L);");
-                    } else {
-                        char spec = getPrimitiveSpecChar(desc);
-                        out.println("        jlong primitiveValue = parse_primitive_option_value('" + spec + "', name_handle, value, CHECK_(true));");
-                        out.println("        VMToCompiler::setOption(hotSpotOptionsClass, name_handle, option, '" + spec + "', Handle(), primitiveValue);");
-                    }
-                    out.println("        return true;");
-                    out.println("      }");
-                }
-            }
-        }
-        out.println("    }");
-    }
-
-    private static Class<?> getFieldType(OptionDescriptor desc) throws Exception {
-        return desc.getDeclaringClass().getDeclaredField(desc.getFieldName()).getType();
-    }
-
-    private static String toInternalName(Class<?> c) {
-        return c.getName().replace('.', '/');
-    }
-
-    /**
-     * @see HotSpotOptions#setOption(String, OptionValue, char, String, long)
-     */
-    private static char getPrimitiveSpecChar(OptionDescriptor desc) {
-        if (desc.getType() == Integer.class) {
-            return 'i';
-        }
-        if (desc.getType() == Float.class) {
-            return 'f';
-        }
-        if (desc.getType() == Double.class) {
-            return 'd';
-        }
-        throw GraalInternalError.shouldNotReachHere("Unexpected primitive option type: " + desc.getType().getName());
-    }
 }
\ No newline at end of file
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Wed May 21 18:40:48 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Mon May 26 20:27:28 2014 +0200
@@ -193,12 +193,12 @@
         assert VerifyOptionsPhase.checkOptions(hostProviders.getMetaAccess());
 
         // Complete initialization of backends
-        try (InitTimer st = timer(hostBackend.getClass().getSimpleName() + ".completeInitialization")) {
+        try (InitTimer st = timer(hostBackend.getTarget().arch.getName(), ".completeInitialization")) {
             hostBackend.completeInitialization();
         }
         for (HotSpotBackend backend : runtime.getBackends().values()) {
             if (backend != hostBackend) {
-                try (InitTimer st = timer(backend.getClass().getSimpleName() + ".completeInitialization")) {
+                try (InitTimer st = timer(backend.getTarget().arch.getName(), ".completeInitialization")) {
                     backend.completeInitialization();
                 }
             }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/CompilerConfiguration.java	Wed May 21 18:40:48 2014 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/CompilerConfiguration.java	Mon May 26 20:27:28 2014 +0200
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.phases.tiers;
 
+import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.phases.*;
 
-public interface CompilerConfiguration {
+public interface CompilerConfiguration extends Service {
 
     PhaseSuite<HighTierContext> createHighTier();
 
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java	Wed May 21 18:40:48 2014 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java	Mon May 26 20:27:28 2014 +0200
@@ -26,6 +26,7 @@
 
 import java.util.*;
 
+import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.options.*;
 import com.oracle.graal.phases.*;
@@ -65,7 +66,7 @@
         CompilerConfiguration nonBasic = null;
         int nonBasicCount = 0;
 
-        for (CompilerConfiguration config : ServiceLoader.loadInstalled(CompilerConfiguration.class)) {
+        for (CompilerConfiguration config : Services.load(CompilerConfiguration.class)) {
             String name = config.getClass().getSimpleName();
             if (name.endsWith("CompilerConfiguration")) {
                 name = name.substring(0, name.length() - "CompilerConfiguration".length());
--- a/mx/mx_graal.py	Wed May 21 18:40:48 2014 +0200
+++ b/mx/mx_graal.py	Mon May 26 20:27:28 2014 +0200
@@ -484,27 +484,21 @@
         if exists(toDelete):
             os.unlink(toDelete)
 
-def _update_HotSpotOptions_inline_hpp(graalJar):
-    p = mx.project('com.oracle.graal.hotspot')
-    mainClass = 'com.oracle.graal.hotspot.HotSpotOptionsLoader'
-    assert exists(join(p.source_dirs()[0], mainClass.replace('.', os.sep) + '.java'))
-
-    def mainClassExists():
-        with zipfile.ZipFile(graalJar, 'r') as zf:
-            mainClassFile = mainClass.replace('.', '/') + '.class'
-            return mainClassFile in zf.namelist()
-
-    if mainClassExists():
-        hsSrcGenDir = join(p.source_gen_dir(), 'hotspot')
+def _update_graalRuntime_inline_hpp(graalJar):
+    p = mx.project('com.oracle.graal.hotspot.codegen')
+    mainClass = 'com.oracle.graal.hotspot.codegen.GenGraalRuntimeInlineHpp'
+    if exists(join(p.output_dir(), mainClass.replace('.', os.sep) + '.class')):
+        hsSrcGenDir = join(mx.project('com.oracle.graal.hotspot').source_gen_dir(), 'hotspot')
         if not exists(hsSrcGenDir):
             os.makedirs(hsSrcGenDir)
+
         tmp = StringIO.StringIO()
-        mx.run_java(['-cp', graalJar, mainClass], out=tmp.write)
-        mx.update_file(join(hsSrcGenDir, 'HotSpotOptions.inline.hpp'), tmp.getvalue())
+        mx.run_java(['-cp', '{}{}{}'.format(graalJar, os.pathsep, p.output_dir()), mainClass], out=tmp.write)
+        mx.update_file(join(hsSrcGenDir, 'graalRuntime.inline.hpp'), tmp.getvalue())
 
 def _installGraalJarInJdks(graalDist):
     graalJar = graalDist.path
-    _update_HotSpotOptions_inline_hpp(graalJar)
+    _update_graalRuntime_inline_hpp(graalJar)
     jdks = _jdksDir()
 
     if exists(jdks):
--- a/mx/projects	Wed May 21 18:40:48 2014 +0200
+++ b/mx/projects	Mon May 26 20:27:28 2014 +0200
@@ -204,6 +204,14 @@
 project@com.oracle.graal.hotspot@javaCompliance=1.8
 project@com.oracle.graal.hotspot@workingSets=Graal,HotSpot
 
+# graal.hotspot.codegen
+project@com.oracle.graal.hotspot.codegen@subDir=graal
+project@com.oracle.graal.hotspot.codegen@sourceDirs=src
+project@com.oracle.graal.hotspot.codegen@dependencies=com.oracle.graal.hotspot
+project@com.oracle.graal.hotspot.codegen@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.hotspot.codegen@javaCompliance=1.8
+project@com.oracle.graal.hotspot.codegen@workingSets=Graal,HotSpot
+
 # graal.hotspot.jfr
 project@com.oracle.graal.hotspot.jfr@subDir=graal
 project@com.oracle.graal.hotspot.jfr@sourceDirs=src
--- a/src/share/vm/graal/graalRuntime.cpp	Wed May 21 18:40:48 2014 +0200
+++ b/src/share/vm/graal/graalRuntime.cpp	Mon May 26 20:27:28 2014 +0200
@@ -641,6 +641,13 @@
   return VMToCompiler::get_HotSpotGraalRuntime_jobject();
 JVM_END
 
+// private static String[] Graal.getServiceImpls(Class service)
+JVM_ENTRY(jobject, JVM_GetGraalServiceImpls(JNIEnv *env, jclass c, jclass serviceClass))
+  HandleMark hm;
+  KlassHandle serviceKlass(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(serviceClass)));
+  return JNIHandles::make_local(THREAD, GraalRuntime::get_service_impls(serviceKlass, THREAD)());
+JVM_END
+
 // private static TruffleRuntime Truffle.createRuntime()
 JVM_ENTRY(jobject, JVM_CreateTruffleRuntime(JNIEnv *env, jclass c))
   return JNIHandles::make_local(VMToCompiler::create_HotSpotTruffleRuntime()());
@@ -813,4 +820,16 @@
   return ret;
 }
 
-#include "HotSpotOptions.inline.hpp"
+Handle GraalRuntime::create_Service(const char* name, TRAPS) {
+  TempNewSymbol kname = SymbolTable::new_symbol(name, THREAD);
+  Klass* k = SystemDictionary::resolve_or_fail(kname, true, CHECK_NH);
+  instanceKlassHandle klass(THREAD, k);
+  klass->initialize(CHECK_NH);
+  klass->check_valid_for_instantiation(true, CHECK_NH);
+  JavaValue result(T_VOID);
+  instanceHandle service = klass->allocate_instance_handle(CHECK_NH);
+  JavaCalls::call_special(&result, service, klass, vmSymbols::object_initializer_name(), vmSymbols::void_method_signature(), THREAD);
+  return service;
+}
+
+#include "graalRuntime.inline.hpp"
--- a/src/share/vm/graal/graalRuntime.hpp	Wed May 21 18:40:48 2014 +0200
+++ b/src/share/vm/graal/graalRuntime.hpp	Mon May 26 20:27:28 2014 +0200
@@ -73,9 +73,19 @@
    */
   static bool set_option(KlassHandle hotSpotOptionsClass, const char* name, int name_len, Handle name_handle, const char* value, TRAPS);
 
+  /**
+   * Instantiates Service object, calls its default constructor and returns it.
+   *
+   * @param name the name of a class implementing com.oracle.graal.api.runtime.Service
+   */
+  static Handle create_Service(const char* name, TRAPS);
+
  public:
 
   static void initialize_natives(JNIEnv *env, jclass c2vmClass);
+
+  static Handle get_service_impls(KlassHandle serviceKlass, TRAPS);
+
   static BufferBlob* initialize_buffer_blob();
 
   static bool parse_arguments(KlassHandle hotSpotOptionsClass, TRAPS);
--- a/src/share/vm/prims/nativeLookup.cpp	Wed May 21 18:40:48 2014 +0200
+++ b/src/share/vm/prims/nativeLookup.cpp	Mon May 26 20:27:28 2014 +0200
@@ -126,6 +126,7 @@
 #ifdef GRAAL
   void     JNICALL JVM_InitializeGraalNatives(JNIEnv *env, jclass c, jclass compilerToVMClass);
   jobject  JNICALL JVM_GetGraalRuntime(JNIEnv *env, jclass c);
+  jobject  JNICALL JVM_GetGraalServiceImpls(JNIEnv *env, jclass c);
   jobject  JNICALL JVM_CreateTruffleRuntime(JNIEnv *env, jclass c);
   jboolean JNICALL JVM_ParseGraalOptions(JNIEnv *env, jclass hotspotOptionsClass);
 #endif
@@ -141,6 +142,7 @@
   { CC"Java_sun_hotspot_WhiteBox_registerNatives",                 NULL, FN_PTR(JVM_RegisterWhiteBoxMethods)     },
 #ifdef GRAAL
   { CC"Java_com_oracle_graal_api_runtime_Graal_initializeRuntime",   NULL, FN_PTR(JVM_GetGraalRuntime)             },
+  { CC"Java_com_oracle_graal_api_runtime_Services_getServiceImpls",  NULL, FN_PTR(JVM_GetGraalServiceImpls)        },
   { CC"Java_com_oracle_truffle_api_Truffle_createRuntime",           NULL, FN_PTR(JVM_CreateTruffleRuntime)        },
   { CC"Java_com_oracle_graal_hotspot_HotSpotGraalRuntime_init",      NULL, FN_PTR(JVM_InitializeGraalNatives)      },
   { CC"Java_com_oracle_graal_hotspot_HotSpotOptions_parseVMOptions", NULL, FN_PTR(JVM_ParseGraalOptions)           },