# HG changeset patch # User Doug Simon # Date 1432567239 -7200 # Node ID c1e2fdb5fea38fd9faa40eac3b71533449a6fe92 # Parent ca14581fadc4302cd817b751678293120d4f1ca4 removed more dependencies from JVMCI classes to non-JVMCI classes (JBS:GRAAL-53) diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Mon May 25 17:20:39 2015 +0200 @@ -34,9 +34,8 @@ import sun.reflect.ConstantPool; +import com.oracle.graal.api.meta.Assumptions.AssumptionResult; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.Assumptions.AssumptionResult; -import com.oracle.graal.compiler.common.*; /** * Tests for {@link ResolvedJavaType}. @@ -417,13 +416,13 @@ assertEquals(aSai2, iSai2.getSingleImplementor()); } - @Test(expected = GraalInternalError.class) + @Test(expected = InternalError.class) public void getSingleImplementorTestClassReceiver() { ResolvedJavaType base = metaAccess.lookupJavaType(Base.class); base.getSingleImplementor(); } - @Test(expected = GraalInternalError.class) + @Test(expected = InternalError.class) public void getSingleImplementorTestPrimitiveReceiver() { ResolvedJavaType primitive = metaAccess.lookupJavaType(int.class); primitive.getSingleImplementor(); diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Graal.java --- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Graal.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Graal.java Mon May 25 17:20:39 2015 +0200 @@ -24,6 +24,8 @@ import java.util.*; +import com.oracle.jvmci.runtime.*; + import sun.reflect.*; /** diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntimeFactory.java --- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntimeFactory.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntimeFactory.java Mon May 25 17:20:39 2015 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.api.runtime; +import com.oracle.jvmci.runtime.*; + public interface GraalRuntimeFactory extends Service { GraalRuntime getRuntime(); diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/OptionsParsed.java --- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/OptionsParsed.java Mon May 25 17:09:00 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2015, 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; - -/** - * Extension for doing post-processing once all JVMCI options have been parsed and initialized. - */ -public interface OptionsParsed extends Service { - - /** - * Notifies this service that all JVMCI options have been parsed and initialized. - */ - void apply(); -} diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Service.java --- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Service.java Mon May 25 17:09:00 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +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 com.oracle.graal.api.runtime; - -/** - * Denotes a service that may be efficiently loaded by {@link Services#load(Class)}. - */ -public interface Service { -} diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/ServiceProvider.java --- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/ServiceProvider.java Mon May 25 17:09:00 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +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 com.oracle.graal.api.runtime; - -import java.lang.annotation.*; - -@Retention(RetentionPolicy.CLASS) -@Target(ElementType.TYPE) -public @interface ServiceProvider { - - Class value(); -} diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Services.java --- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Services.java Mon May 25 17:09:00 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * 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> cache = new ClassValue>() { - @Override - protected List 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 and that in suite.py the \"annotationProcessors\" attribute for the project enclosing %s includes \"com.oracle.graal.service.processor\")", - type.getSimpleName(), type.getSimpleName(), Service.class, type.getSimpleName())); - } - return Arrays.asList(names); - } - }; - - /** - * Gets an {@link Iterable} of the implementations available for a given service. - */ - @SuppressWarnings("unchecked") - public static Iterable load(Class service) { - if (Service.class.isAssignableFrom(service)) { - try { - return (Iterable) cache.get(service); - } catch (UnsatisfiedLinkError e) { - // Fall back to standard SerivceLoader - } - } - return ServiceLoader.load(service, Services.class.getClassLoader()); - } - - private static native S[] getServiceImpls(Class service); -} diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Mon May 25 17:20:39 2015 +0200 @@ -309,12 +309,6 @@ @Option(help = "Allow backend to match complex expressions.", type = OptionType.Debug) public static final OptionValue MatchExpressions = new OptionValue<>(true); - @Option(help = "Constant fold final fields with default values.", type = OptionType.Debug) - public static final OptionValue TrustFinalDefaultFields = new OptionValue<>(true); - - @Option(help = "Mark well-known stable fields as such.", type = OptionType.Debug) - public static final OptionValue ImplicitStableValues = new OptionValue<>(true); - @Option(help = "Generate SSA LIR.", type = OptionType.Debug) public static final OptionValue SSA_LIR = new OptionValue<>(false); diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfigOptionsParsed.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfigOptionsParsed.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfigOptionsParsed.java Mon May 25 17:20:39 2015 +0200 @@ -22,8 +22,8 @@ */ package com.oracle.graal.compiler; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.debug.*; +import com.oracle.jvmci.runtime.*; /** * Implementation of {@link OptionsParsed} for setting system properties used in the initialization diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java Mon May 25 17:20:39 2015 +0200 @@ -23,15 +23,16 @@ package com.oracle.graal.compiler.match; import static com.oracle.graal.compiler.GraalDebugConfig.*; + import java.util.*; import java.util.Map.Entry; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; +import com.oracle.jvmci.runtime.*; public class MatchRuleRegistry { diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatementSet.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatementSet.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatementSet.java Mon May 25 17:20:39 2015 +0200 @@ -24,8 +24,8 @@ import java.util.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.gen.*; +import com.oracle.jvmci.runtime.*; public interface MatchStatementSet extends Service { /** diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/BasicCompilerConfiguration.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/BasicCompilerConfiguration.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/BasicCompilerConfiguration.java Mon May 25 17:20:39 2015 +0200 @@ -22,13 +22,13 @@ */ package com.oracle.graal.compiler.phases; -import com.oracle.graal.api.runtime.*; +import com.oracle.graal.lir.phases.AllocationPhase.AllocationContext; import com.oracle.graal.lir.phases.*; -import com.oracle.graal.lir.phases.PreAllocationOptimizationPhase.*; -import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.*; -import com.oracle.graal.lir.phases.AllocationPhase.*; +import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.PostAllocationOptimizationContext; +import com.oracle.graal.lir.phases.PreAllocationOptimizationPhase.PreAllocationOptimizationContext; import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; +import com.oracle.jvmci.runtime.*; @ServiceProvider(CompilerConfiguration.class) public class BasicCompilerConfiguration implements CompilerConfiguration { diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EconomyCompilerConfiguration.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EconomyCompilerConfiguration.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EconomyCompilerConfiguration.java Mon May 25 17:20:39 2015 +0200 @@ -22,13 +22,13 @@ */ package com.oracle.graal.compiler.phases; -import com.oracle.graal.api.runtime.*; +import com.oracle.graal.lir.phases.AllocationPhase.AllocationContext; import com.oracle.graal.lir.phases.*; -import com.oracle.graal.lir.phases.PreAllocationOptimizationPhase.*; -import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.*; -import com.oracle.graal.lir.phases.AllocationPhase.*; +import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.PostAllocationOptimizationContext; +import com.oracle.graal.lir.phases.PreAllocationOptimizationPhase.PreAllocationOptimizationContext; import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; +import com.oracle.jvmci.runtime.*; @ServiceProvider(CompilerConfiguration.class) public class EconomyCompilerConfiguration implements CompilerConfiguration { diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Mon May 25 17:20:39 2015 +0200 @@ -30,7 +30,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.jvmci.*; @@ -51,7 +50,7 @@ HotSpotRegistersProvider registers; HotSpotCodeCacheProvider codeCache = (HotSpotCodeCacheProvider) jvmci.getCodeCache(); TargetDescription target = codeCache.getTarget(); - HotSpotConstantReflectionProvider constantReflection = (HotSpotConstantReflectionProvider) jvmci.getConstantReflection(); + HotSpotConstantReflectionProvider constantReflection = new HotSpotGraalConstantReflectionProvider(runtime.getJVMCIRuntime()); HotSpotHostForeignCallsProvider foreignCalls; Value[] nativeABICallerSaveRegisters; HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) jvmci.getMetaAccess(); diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/jvmci/AMD64HotSpotJVMCIBackendFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/jvmci/AMD64HotSpotJVMCIBackendFactory.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/jvmci/AMD64HotSpotJVMCIBackendFactory.java Mon May 25 17:20:39 2015 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.amd64.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.amd64.*; import com.oracle.graal.hotspot.jvmci.*; @@ -146,7 +147,7 @@ RegisterConfig regConfig; HotSpotCodeCacheProvider codeCache; - HotSpotConstantReflectionProvider constantReflection; + ConstantReflectionProvider constantReflection; HotSpotMetaAccessProvider metaAccess; try (InitTimer t = timer("create providers")) { try (InitTimer rt = timer("create MetaAccess provider")) { @@ -167,7 +168,7 @@ } } - protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, HotSpotConstantReflectionProvider constantReflection) { + protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection) { return new JVMCIBackend(metaAccess, codeCache, constantReflection); } diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot.jfr/src/com/oracle/graal/hotspot/jfr/events/JFREventProvider.java --- a/graal/com.oracle.graal.hotspot.jfr/src/com/oracle/graal/hotspot/jfr/events/JFREventProvider.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.jfr/src/com/oracle/graal/hotspot/jfr/events/JFREventProvider.java Mon May 25 17:20:39 2015 +0200 @@ -24,9 +24,9 @@ import java.net.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.hotspot.events.*; import com.oracle.jrockit.jfr.*; +import com.oracle.jvmci.runtime.*; /** * A JFR implementation for {@link EventProvider}. This implementation is used when Flight Recorder diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot.sourcegen/src/com/oracle/graal/hotspot/sourcegen/GenGraalRuntimeInlineHpp.java --- a/graal/com.oracle.graal.hotspot.sourcegen/src/com/oracle/graal/hotspot/sourcegen/GenGraalRuntimeInlineHpp.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sourcegen/src/com/oracle/graal/hotspot/sourcegen/GenGraalRuntimeInlineHpp.java Mon May 25 17:20:39 2015 +0200 @@ -28,9 +28,9 @@ import java.util.stream.*; import java.util.zip.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.options.*; +import com.oracle.jvmci.runtime.*; /** * Command line utility for generating the source code of {@code graalRuntime.inline.hpp}. The diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Mon May 25 17:20:39 2015 +0200 @@ -26,7 +26,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.jvmci.*; @@ -49,7 +48,7 @@ HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) jvmci.getMetaAccess(); HotSpotCodeCacheProvider codeCache = (HotSpotCodeCacheProvider) jvmci.getCodeCache(); TargetDescription target = codeCache.getTarget(); - HotSpotConstantReflectionProvider constantReflection = (HotSpotConstantReflectionProvider) jvmci.getConstantReflection(); + HotSpotConstantReflectionProvider constantReflection = new HotSpotGraalConstantReflectionProvider(runtime.getJVMCIRuntime()); Value[] nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(runtime.getConfig(), codeCache.getRegisterConfig()); HotSpotForeignCallsProvider foreignCalls = new SPARCHotSpotForeignCallsProvider(runtime, metaAccess, codeCache, nativeABICallerSaveRegisters); LoweringProvider lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, target); diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackendFactory.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackendFactory.java Mon May 25 17:20:39 2015 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.hotspot.jvmci.HotSpotJVMCIRuntime.Options; import com.oracle.jvmci.runtime.*; diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntimeFactory.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntimeFactory.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntimeFactory.java Mon May 25 17:20:39 2015 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot; import com.oracle.graal.api.runtime.*; +import com.oracle.jvmci.runtime.*; @ServiceProvider(GraalRuntimeFactory.class) public class HotSpotGraalRuntimeFactory implements GraalRuntimeFactory { diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalVMEventListener.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalVMEventListener.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalVMEventListener.java Mon May 25 17:20:39 2015 +0200 @@ -24,10 +24,10 @@ import static com.oracle.graal.hotspot.CompileTheWorld.Options.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.debug.*; import com.oracle.graal.hotspot.CompileTheWorld.Config; import com.oracle.graal.hotspot.jvmci.*; +import com.oracle.jvmci.runtime.*; @ServiceProvider(HotSpotVMEventListener.class) public class HotSpotGraalVMEventListener implements HotSpotVMEventListener { diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java Mon May 25 17:20:39 2015 +0200 @@ -26,13 +26,13 @@ import static com.oracle.graal.hotspot.jvmci.InitTimer.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.hotspot.jvmci.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.jvmci.runtime.*; /** * Common functionality of HotSpot host backends. diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HexCodeFile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HexCodeFile.java Mon May 25 17:20:39 2015 +0200 @@ -0,0 +1,431 @@ +/* + * Copyright (c) 2009, 2011, 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.jvmci; + +import java.io.*; +import java.util.*; +import java.util.regex.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CompilationResult.CodeAnnotation; +import com.oracle.graal.api.code.CompilationResult.CodeComment; +import com.oracle.graal.api.code.CompilationResult.JumpTable; + +/** + * A HexCodeFile is a textual format for representing a chunk of machine code along with extra + * information that can be used to enhance a disassembly of the code. + * + * A pseudo grammar for a HexCodeFile is given below. + * + *
+ *     HexCodeFile ::= Platform Delim HexCode Delim (OptionalSection Delim)*
+ *
+ *     OptionalSection ::= Comment | OperandComment | JumpTable | LookupTable
+ *
+ *     Platform ::= "Platform" ISA WordWidth
+ *
+ *     HexCode ::= "HexCode" StartAddress HexDigits
+ *
+ *     Comment ::= "Comment" Position String
+ *
+ *     OperandComment ::= "OperandComment" Position String
+ *
+ *     JumpTable ::= "JumpTable" Position EntrySize Low High
+ *
+ *     LookupTable ::= "LookupTable" Position NPairs KeySize OffsetSize
+ *
+ *     Position, EntrySize, Low, High, NPairs KeySize OffsetSize ::= int
+ *
+ *     Delim := "<||@"
+ * 
+ * + * There must be exactly one HexCode and Platform part in a HexCodeFile. The length of HexDigits + * must be even as each pair of digits represents a single byte. + *

+ * Below is an example of a valid Code input: + * + *

+ *
+ *  Platform AMD64 64  <||@
+ *  HexCode 0 e8000000009090904883ec084889842410d0ffff48893c24e800000000488b3c24488bf0e8000000004883c408c3  <||@
+ *  Comment 24 frame-ref-map: +0 {0}
+ *  at java.lang.String.toLowerCase(String.java:2496) [bci: 1]
+ *              |0
+ *     locals:  |stack:0:a
+ *     stack:   |stack:0:a
+ *    <||@
+ *  OperandComment 24 {java.util.Locale.getDefault()}  <||@
+ *  Comment 36 frame-ref-map: +0 {0}
+ *  at java.lang.String.toLowerCase(String.java:2496) [bci: 4]
+ *              |0
+ *     locals:  |stack:0:a
+ *    <||@
+ *  OperandComment 36 {java.lang.String.toLowerCase(Locale)}  lt;||@
+ *
+ * 
+ */ +public class HexCodeFile { + + public static final String NEW_LINE = CodeUtil.NEW_LINE; + public static final String SECTION_DELIM = " <||@"; + public static final String COLUMN_END = " <|@"; + public static final Pattern SECTION = Pattern.compile("(\\S+)\\s+(.*)", Pattern.DOTALL); + public static final Pattern COMMENT = Pattern.compile("(\\d+)\\s+(.*)", Pattern.DOTALL); + public static final Pattern OPERAND_COMMENT = COMMENT; + public static final Pattern JUMP_TABLE = Pattern.compile("(\\d+)\\s+(\\d+)\\s+(-{0,1}\\d+)\\s+(-{0,1}\\d+)\\s*"); + public static final Pattern LOOKUP_TABLE = Pattern.compile("(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s*"); + public static final Pattern HEX_CODE = Pattern.compile("(\\p{XDigit}+)(?:\\s+(\\p{XDigit}*))?"); + public static final Pattern PLATFORM = Pattern.compile("(\\S+)\\s+(\\S+)", Pattern.DOTALL); + + /** + * Delimiter placed before a HexCodeFile when embedded in a string/stream. + */ + public static final String EMBEDDED_HCF_OPEN = "<<> comments = new TreeMap<>(); + + /** + * Map from a machine code position to a comment for the operands of the instruction at the + * position. + */ + public final Map operandComments = new TreeMap<>(); + + public final byte[] code; + + public final ArrayList jumpTables = new ArrayList<>(); + + public final String isa; + + public final int wordWidth; + + public final long startAddress; + + public HexCodeFile(byte[] code, long startAddress, String isa, int wordWidth) { + this.code = code; + this.startAddress = startAddress; + this.isa = isa; + this.wordWidth = wordWidth; + } + + /** + * Parses a string in the format produced by {@link #toString()} to produce a + * {@link HexCodeFile} object. + */ + public static HexCodeFile parse(String input, int sourceOffset, String source, String sourceName) { + return new Parser(input, sourceOffset, source, sourceName).hcf; + } + + /** + * Formats this HexCodeFile as a string that can be parsed with + * {@link #parse(String, int, String, String)}. + */ + @Override + public String toString() { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + writeTo(baos); + return baos.toString(); + } + + public String toEmbeddedString() { + return EMBEDDED_HCF_OPEN + NEW_LINE + toString() + EMBEDDED_HCF_CLOSE; + } + + public void writeTo(OutputStream out) { + PrintStream ps = out instanceof PrintStream ? (PrintStream) out : new PrintStream(out); + ps.printf("Platform %s %d %s%n", isa, wordWidth, SECTION_DELIM); + ps.printf("HexCode %x %s %s%n", startAddress, HexCodeFile.hexCodeString(code), SECTION_DELIM); + + for (JumpTable table : jumpTables) { + ps.printf("JumpTable %d %d %d %d %s%n", table.position, table.entrySize, table.low, table.high, SECTION_DELIM); + } + + for (Map.Entry> e : comments.entrySet()) { + int pos = e.getKey(); + for (String comment : e.getValue()) { + ps.printf("Comment %d %s %s%n", pos, comment, SECTION_DELIM); + } + } + + for (Map.Entry e : operandComments.entrySet()) { + ps.printf("OperandComment %d %s %s%n", e.getKey(), e.getValue(), SECTION_DELIM); + } + ps.flush(); + } + + /** + * Formats a byte array as a string of hex digits. + */ + public static String hexCodeString(byte[] code) { + if (code == null) { + return ""; + } else { + StringBuilder sb = new StringBuilder(code.length * 2); + for (int b : code) { + String hex = Integer.toHexString(b & 0xff); + if (hex.length() == 1) { + sb.append('0'); + } + sb.append(hex); + } + return sb.toString(); + } + } + + /** + * Adds a comment to the list of comments for a given position. + */ + public void addComment(int pos, String comment) { + List list = comments.get(pos); + if (list == null) { + list = new ArrayList<>(); + comments.put(pos, list); + } + list.add(encodeString(comment)); + } + + /** + * Sets an operand comment for a given position. + * + * @return the previous operand comment for {@code pos} + */ + public String addOperandComment(int pos, String comment) { + return operandComments.put(pos, encodeString(comment)); + } + + /** + * Adds any jump tables, lookup tables or code comments from a list of code annotations. + */ + public static void addAnnotations(HexCodeFile hcf, List annotations) { + if (annotations == null || annotations.isEmpty()) { + return; + } + for (CodeAnnotation a : annotations) { + if (a instanceof JumpTable) { + JumpTable table = (JumpTable) a; + hcf.jumpTables.add(table); + } else if (a instanceof CodeComment) { + CodeComment comment = (CodeComment) a; + hcf.addComment(comment.position, comment.value); + } + } + } + + /** + * Modifies a string to mangle any substrings matching {@link #SECTION_DELIM} and + * {@link #COLUMN_END}. + */ + public static String encodeString(String input) { + int index; + String s = input; + while ((index = s.indexOf(SECTION_DELIM)) != -1) { + s = s.substring(0, index) + " < |@" + s.substring(index + SECTION_DELIM.length()); + } + while ((index = s.indexOf(COLUMN_END)) != -1) { + s = s.substring(0, index) + " < @" + s.substring(index + COLUMN_END.length()); + } + return s; + } + + /** + * Helper class to parse a string in the format produced by {@link HexCodeFile#toString()} and + * produce a {@link HexCodeFile} object. + */ + static class Parser { + + final String input; + final String inputSource; + String isa; + int wordWidth; + byte[] code; + long startAddress; + HexCodeFile hcf; + + Parser(String input, int sourceOffset, String source, String sourceName) { + this.input = input; + this.inputSource = sourceName; + parseSections(sourceOffset, source); + } + + void makeHCF() { + if (hcf == null) { + if (isa != null && wordWidth != 0 && code != null) { + hcf = new HexCodeFile(code, startAddress, isa, wordWidth); + } + } + } + + void checkHCF(String section, int offset) { + check(hcf != null, offset, section + " section must be after Platform and HexCode section"); + } + + void check(boolean condition, int offset, String message) { + if (!condition) { + error(offset, message); + } + } + + Error error(int offset, String message) { + throw new Error(errorMessage(offset, message)); + } + + void warning(int offset, String message) { + PrintStream err = System.err; + err.println("Warning: " + errorMessage(offset, message)); + } + + String errorMessage(int offset, String message) { + assert offset < input.length(); + InputPos inputPos = filePos(offset); + int lineEnd = input.indexOf(HexCodeFile.NEW_LINE, offset); + int lineStart = offset - inputPos.col; + String line = lineEnd == -1 ? input.substring(lineStart) : input.substring(lineStart, lineEnd); + return String.format("%s:%d: %s%n%s%n%" + (inputPos.col + 1) + "s", inputSource, inputPos.line, message, line, "^"); + } + + static class InputPos { + + final int line; + final int col; + + public InputPos(int line, int col) { + this.line = line; + this.col = col; + } + } + + InputPos filePos(int index) { + assert input != null; + int lineStart = input.lastIndexOf(HexCodeFile.NEW_LINE, index) + 1; + + String l = input.substring(lineStart, lineStart + 10); + PrintStream out = System.out; + out.println("YYY" + input.substring(index, index + 10) + "..."); + out.println("XXX" + l + "..."); + + int pos = input.indexOf(HexCodeFile.NEW_LINE, 0); + int line = 1; + while (pos > 0 && pos < index) { + line++; + pos = input.indexOf(HexCodeFile.NEW_LINE, pos + 1); + } + return new InputPos(line, index - lineStart); + } + + void parseSections(int offset, String source) { + assert input.startsWith(source, offset); + int index = 0; + int endIndex = source.indexOf(SECTION_DELIM); + while (endIndex != -1) { + while (source.charAt(index) <= ' ') { + index++; + } + String section = source.substring(index, endIndex).trim(); + parseSection(offset + index, section); + index = endIndex + SECTION_DELIM.length(); + endIndex = source.indexOf(SECTION_DELIM, index); + } + } + + int parseInt(int offset, String value) { + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + throw error(offset, "Not a valid integer: " + value); + } + } + + void parseSection(int offset, String section) { + if (section.isEmpty()) { + return; + } + assert input.startsWith(section, offset); + Matcher m = HexCodeFile.SECTION.matcher(section); + check(m.matches(), offset, "Section does not match pattern " + HexCodeFile.SECTION); + + String header = m.group(1); + String body = m.group(2); + int headerOffset = offset + m.start(1); + int bodyOffset = offset + m.start(2); + + if (header.equals("Platform")) { + check(isa == null, bodyOffset, "Duplicate Platform section found"); + m = HexCodeFile.PLATFORM.matcher(body); + check(m.matches(), bodyOffset, "Platform does not match pattern " + HexCodeFile.PLATFORM); + isa = m.group(1); + wordWidth = parseInt(bodyOffset + m.start(2), m.group(2)); + makeHCF(); + } else if (header.equals("HexCode")) { + check(code == null, bodyOffset, "Duplicate Code section found"); + m = HexCodeFile.HEX_CODE.matcher(body); + check(m.matches(), bodyOffset, "Code does not match pattern " + HexCodeFile.HEX_CODE); + String hexAddress = m.group(1); + startAddress = Long.valueOf(hexAddress, 16); + String hexCode = m.group(2); + if (hexCode == null) { + code = new byte[0]; + } else { + check((hexCode.length() % 2) == 0, bodyOffset, "Hex code length must be even"); + code = new byte[hexCode.length() / 2]; + for (int i = 0; i < code.length; i++) { + String hexByte = hexCode.substring(i * 2, (i + 1) * 2); + code[i] = (byte) Integer.parseInt(hexByte, 16); + } + } + makeHCF(); + } else if (header.equals("Comment")) { + checkHCF("Comment", headerOffset); + m = HexCodeFile.COMMENT.matcher(body); + check(m.matches(), bodyOffset, "Comment does not match pattern " + HexCodeFile.COMMENT); + int pos = parseInt(bodyOffset + m.start(1), m.group(1)); + String comment = m.group(2); + hcf.addComment(pos, comment); + } else if (header.equals("OperandComment")) { + checkHCF("OperandComment", headerOffset); + m = HexCodeFile.OPERAND_COMMENT.matcher(body); + check(m.matches(), bodyOffset, "OperandComment does not match pattern " + HexCodeFile.OPERAND_COMMENT); + int pos = parseInt(bodyOffset + m.start(1), m.group(1)); + String comment = m.group(2); + hcf.addOperandComment(pos, comment); + } else if (header.equals("JumpTable")) { + checkHCF("JumpTable", headerOffset); + m = HexCodeFile.JUMP_TABLE.matcher(body); + check(m.matches(), bodyOffset, "JumpTable does not match pattern " + HexCodeFile.JUMP_TABLE); + int pos = parseInt(bodyOffset + m.start(1), m.group(1)); + int entrySize = parseInt(bodyOffset + m.start(2), m.group(2)); + int low = parseInt(bodyOffset + m.start(3), m.group(3)); + int high = parseInt(bodyOffset + m.start(4), m.group(4)); + hcf.jumpTables.add(new JumpTable(pos, low, high, entrySize)); + } else { + error(offset, "Unknown section header: " + header); + } + } + } +} diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotCodeCacheProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotCodeCacheProvider.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotCodeCacheProvider.java Mon May 25 17:20:39 2015 +0200 @@ -38,9 +38,7 @@ import com.oracle.graal.api.code.DataSection.Data; import com.oracle.graal.api.code.DataSection.DataBuilder; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; -import com.oracle.graal.printer.*; /** * HotSpot implementation of {@link CodeCacheProvider}. @@ -121,7 +119,7 @@ return (String) processMethod.invoke(null, hcfEmbeddedString); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { // If the tool is available, for now let's be noisy when it fails - throw new GraalInternalError(e); + throw new InternalError(e); } } return hcfEmbeddedString; @@ -281,7 +279,7 @@ compressed = meta.isCompressed(); raw = meta.rawValue(); } else { - throw GraalInternalError.shouldNotReachHere(); + throw new InternalError(String.valueOf(constant)); } size = target.getSizeInBytes(compressed ? Kind.Int : target.wordKind); @@ -306,7 +304,7 @@ size = s.getSerializedSize(); builder = DataBuilder.serializable(s); } else { - throw GraalInternalError.shouldNotReachHere(); + throw new InternalError(String.valueOf(constant)); } return new Data(size, size, builder); diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotConstantPool.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotConstantPool.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotConstantPool.java Mon May 25 17:20:39 2015 +0200 @@ -28,8 +28,6 @@ import java.lang.invoke.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.bytecode.*; -import com.oracle.graal.compiler.common.*; /** * Implementation of {@link ConstantPool} for HotSpot. @@ -37,6 +35,43 @@ public class HotSpotConstantPool implements ConstantPool, HotSpotProxified { /** + * Subset of JVM bytecode opcodes used by {@link HotSpotConstantPool}. + */ + static class Bytecodes { + public static final int LDC = 18; // 0x12 + public static final int LDC_W = 19; // 0x13 + public static final int LDC2_W = 20; // 0x14 + public static final int GETSTATIC = 178; // 0xB2 + public static final int PUTSTATIC = 179; // 0xB3 + public static final int GETFIELD = 180; // 0xB4 + public static final int PUTFIELD = 181; // 0xB5 + public static final int INVOKEVIRTUAL = 182; // 0xB6 + public static final int INVOKESPECIAL = 183; // 0xB7 + public static final int INVOKESTATIC = 184; // 0xB8 + public static final int INVOKEINTERFACE = 185; // 0xB9 + public static final int INVOKEDYNAMIC = 186; // 0xBA + public static final int NEW = 187; // 0xBB + public static final int NEWARRAY = 188; // 0xBC + public static final int ANEWARRAY = 189; // 0xBD + public static final int CHECKCAST = 192; // 0xC0 + public static final int INSTANCEOF = 193; // 0xC1 + public static final int MULTIANEWARRAY = 197; // 0xC5 + + static boolean isInvoke(int opcode) { + switch (opcode) { + case INVOKEVIRTUAL: + case INVOKESPECIAL: + case INVOKESTATIC: + case INVOKEINTERFACE: + case INVOKEDYNAMIC: + return true; + default: + return false; + } + } + } + + /** * Enum of all {@code JVM_CONSTANT} constants used in the VM. This includes the public and * internal ones. */ @@ -103,7 +138,7 @@ if (res != null) { return res; } - throw GraalInternalError.shouldNotReachHere("unknown JVM_CONSTANT tag " + tag); + throw new InternalError("Unknown JVM_CONSTANT tag " + tag); } } @@ -161,7 +196,7 @@ assert index < 0 : "not an invokedynamic constant pool index " + index; } else { assert opcode == Bytecodes.GETFIELD || opcode == Bytecodes.PUTFIELD || opcode == Bytecodes.GETSTATIC || opcode == Bytecodes.PUTSTATIC || opcode == Bytecodes.INVOKEINTERFACE || - opcode == Bytecodes.INVOKEVIRTUAL || opcode == Bytecodes.INVOKESPECIAL || opcode == Bytecodes.INVOKESTATIC : "unexpected invoke opcode " + Bytecodes.nameOf(opcode); + opcode == Bytecodes.INVOKEVIRTUAL || opcode == Bytecodes.INVOKESPECIAL || opcode == Bytecodes.INVOKESTATIC : "unexpected invoke opcode " + opcode; index = rawIndex + runtime().getConfig().constantPoolCpCacheIndexTag; } return index; @@ -416,7 +451,7 @@ Object obj = runtime().getCompilerToVM().resolveConstantInPool(metaspaceConstantPool, cpi); return HotSpotObjectConstantImpl.forObject(obj); default: - throw GraalInternalError.shouldNotReachHere("unknown constant pool tag " + tag); + throw new InternalError("Unknown constant pool tag " + tag); } } diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotConstantReflectionProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotConstantReflectionProvider.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotConstantReflectionProvider.java Mon May 25 17:20:39 2015 +0200 @@ -22,32 +22,29 @@ */ package com.oracle.graal.hotspot.jvmci; -import static com.oracle.graal.compiler.common.GraalOptions.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static com.oracle.graal.hotspot.stubs.SnippetStub.*; +import static com.oracle.graal.hotspot.jvmci.HotSpotConstantReflectionProvider.Options.*; import java.lang.reflect.*; -import java.util.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.graph.*; import com.oracle.graal.options.*; -import com.oracle.graal.replacements.*; -import com.oracle.graal.replacements.SnippetTemplate.Arguments; /** * HotSpot implementation of {@link ConstantReflectionProvider}. */ public class HotSpotConstantReflectionProvider implements ConstantReflectionProvider, HotSpotProxified { - private static final String SystemClassName = "Ljava/lang/System;"; + + static class Options { + //@formatter:off + @Option(help = "Constant fold final fields with default values.", type = OptionType.Debug) + public static final OptionValue TrustFinalDefaultFields = new OptionValue<>(true); + //@formatter:on + } protected final HotSpotJVMCIRuntimeProvider runtime; protected final HotSpotMethodHandleAccessProvider methodHandleAccess; protected final HotSpotMemoryAccessProviderImpl memoryAccess; - public static final ThreadLocal FieldReadEnabledInImmutableCode = new ThreadLocal<>(); - public HotSpotConstantReflectionProvider(HotSpotJVMCIRuntimeProvider runtime) { this.runtime = runtime; this.methodHandleAccess = new HotSpotMethodHandleAccessProvider(this); @@ -222,6 +219,49 @@ return null; } + private static final String SystemClassName = "Ljava/lang/System;"; + + /** + * Determines if a static field is constant for the purpose of + * {@link #readConstantFieldValue(JavaField, JavaConstant)}. + */ + protected boolean isStaticFieldConstant(HotSpotResolvedJavaField staticField) { + if (staticField.isFinal() || staticField.isStable()) { + ResolvedJavaType holder = staticField.getDeclaringClass(); + if (holder.isInitialized() && !holder.getName().equals(SystemClassName)) { + return true; + } + } + return false; + } + + /** + * Determines if a value read from a {@code final} instance field is considered constant. The + * implementation in {@link HotSpotConstantReflectionProvider} returns true if {@code value} is + * not the {@link JavaConstant#isDefaultForKind default value} for its kind or if + * {@link Options#TrustFinalDefaultFields} is true. + * + * @param value a value read from a {@code final} instance field + * @param receiverClass the {@link Object#getClass() class} of object from which the + * {@code value} was read + */ + protected boolean isFinalInstanceFieldValueConstant(JavaConstant value, Class receiverClass) { + return !value.isDefaultForKind() || TrustFinalDefaultFields.getValue(); + } + + /** + * Determines if a value read from a {@link Stable} instance field is considered constant. The + * implementation in {@link HotSpotConstantReflectionProvider} returns true if {@code value} is + * not the {@link JavaConstant#isDefaultForKind default value} for its kind. + * + * @param value a value read from a {@link Stable} field + * @param receiverClass the {@link Object#getClass() class} of object from which the + * {@code value} was read + */ + protected boolean isStableInstanceFieldValueConstant(JavaConstant value, Class receiverClass) { + return !value.isDefaultForKind(); + } + /** * {@inheritDoc} *

@@ -229,18 +269,13 @@ * {@code receiver} is (assignable to) {@link StableOptionValue}. */ public JavaConstant readConstantFieldValue(JavaField field, JavaConstant receiver) { - assert !ImmutableCode.getValue() || isCalledForSnippets() || SnippetGraphUnderConstruction.get() != null || - HotSpotConstantReflectionProvider.FieldReadEnabledInImmutableCode.get() == Boolean.TRUE : receiver; HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field; if (hotspotField.isStatic()) { - if (hotspotField.isFinal() || hotspotField.isStable()) { - ResolvedJavaType holder = hotspotField.getDeclaringClass(); - if (holder.isInitialized() && !holder.getName().equals(SystemClassName) && isEmbeddable(hotspotField)) { - JavaConstant value = readFieldValue(field, receiver); - if (hotspotField.isFinal() || !value.isDefaultForKind()) { - return value; - } + if (isStaticFieldConstant(hotspotField)) { + JavaConstant value = readFieldValue(field, receiver); + if (hotspotField.isFinal() || !value.isDefaultForKind()) { + return value; } } } else { @@ -257,14 +292,14 @@ if (hotspotField.isFinal()) { if (hotspotField.isInObject(object)) { JavaConstant value = readFieldValue(field, receiver); - if (!value.isDefaultForKind() || assumeNonStaticFinalDefaultFieldsAsFinal(object.getClass())) { + if (isFinalInstanceFieldValueConstant(value, object.getClass())) { return value; } } } else if (hotspotField.isStable()) { if (hotspotField.isInObject(object)) { JavaConstant value = readFieldValue(field, receiver); - if (assumeDefaultStableFieldsAsFinal(object.getClass()) || !value.isDefaultForKind()) { + if (isStableInstanceFieldValueConstant(value, object.getClass())) { return value; } } @@ -326,119 +361,4 @@ } return dimensions; } - - /** - * Compares two {@link StackTraceElement}s for equality, ignoring differences in - * {@linkplain StackTraceElement#getLineNumber() line number}. - */ - private static boolean equalsIgnoringLine(StackTraceElement left, StackTraceElement right) { - return left.getClassName().equals(right.getClassName()) && left.getMethodName().equals(right.getMethodName()) && left.getFileName().equals(right.getFileName()); - } - - /** - * If the compiler is configured for AOT mode, - * {@link #readConstantFieldValue(JavaField, JavaConstant)} should be only called for snippets - * or replacements. - */ - private static boolean isCalledForSnippets() { - MetaAccessProvider metaAccess = runtime().getHostProviders().getMetaAccess(); - ResolvedJavaMethod makeGraphMethod = null; - ResolvedJavaMethod initMethod = null; - try { - Class rjm = ResolvedJavaMethod.class; - makeGraphMethod = metaAccess.lookupJavaMethod(ReplacementsImpl.class.getDeclaredMethod("makeGraph", rjm, Object[].class, rjm)); - initMethod = metaAccess.lookupJavaMethod(SnippetTemplate.AbstractTemplates.class.getDeclaredMethod("template", Arguments.class)); - } catch (NoSuchMethodException | SecurityException e) { - throw new GraalInternalError(e); - } - StackTraceElement makeGraphSTE = makeGraphMethod.asStackTraceElement(0); - StackTraceElement initSTE = initMethod.asStackTraceElement(0); - - StackTraceElement[] stackTrace = new Exception().getStackTrace(); - for (StackTraceElement element : stackTrace) { - // Ignoring line numbers should not weaken this check too much while at - // the same time making it more robust against source code changes - if (equalsIgnoringLine(makeGraphSTE, element) || equalsIgnoringLine(initSTE, element)) { - return true; - } - } - return false; - } - - private static boolean assumeNonStaticFinalDefaultFieldsAsFinal(Class clazz) { - if (TrustFinalDefaultFields.getValue()) { - return true; - } - return clazz == SnippetCounter.class || clazz == NodeClass.class; - } - - /** - * Usually {@link Stable} fields are not considered constant if the value is the - * {@link JavaConstant#isDefaultForKind default value}. For some special classes we want to - * override this behavior. - */ - private static boolean assumeDefaultStableFieldsAsFinal(Class clazz) { - // HotSpotVMConfig has a lot of zero-value fields which we know are stable and want to be - // considered as constants. - if (clazz == HotSpotVMConfig.class) { - return true; - } - return false; - } - - /** - * in AOT mode, some fields should never be embedded even for snippets/replacements. - */ - private static boolean isEmbeddable(HotSpotResolvedJavaField field) { - return Embeddable.test(field); - } - - /** - * Separate out the static initialization to eliminate cycles between clinit and other locks - * that could lead to deadlock. Static code that doesn't call back into type or field machinery - * is probably ok but anything else should be made lazy. - */ - static class Embeddable { - - /** - * @return Return true if it's ok to embed the value of {@code field}. - */ - public static boolean test(HotSpotResolvedJavaField field) { - return !ImmutableCode.getValue() || !fields.contains(field); - } - - private static final List fields = new ArrayList<>(); - static { - try { - MetaAccessProvider metaAccess = runtime().getHostProviders().getMetaAccess(); - fields.add(metaAccess.lookupJavaField(Boolean.class.getDeclaredField("TRUE"))); - fields.add(metaAccess.lookupJavaField(Boolean.class.getDeclaredField("FALSE"))); - - Class characterCacheClass = Character.class.getDeclaredClasses()[0]; - assert "java.lang.Character$CharacterCache".equals(characterCacheClass.getName()); - fields.add(metaAccess.lookupJavaField(characterCacheClass.getDeclaredField("cache"))); - - Class byteCacheClass = Byte.class.getDeclaredClasses()[0]; - assert "java.lang.Byte$ByteCache".equals(byteCacheClass.getName()); - fields.add(metaAccess.lookupJavaField(byteCacheClass.getDeclaredField("cache"))); - - Class shortCacheClass = Short.class.getDeclaredClasses()[0]; - assert "java.lang.Short$ShortCache".equals(shortCacheClass.getName()); - fields.add(metaAccess.lookupJavaField(shortCacheClass.getDeclaredField("cache"))); - - Class integerCacheClass = Integer.class.getDeclaredClasses()[0]; - assert "java.lang.Integer$IntegerCache".equals(integerCacheClass.getName()); - fields.add(metaAccess.lookupJavaField(integerCacheClass.getDeclaredField("cache"))); - - Class longCacheClass = Long.class.getDeclaredClasses()[0]; - assert "java.lang.Long$LongCache".equals(longCacheClass.getName()); - fields.add(metaAccess.lookupJavaField(longCacheClass.getDeclaredField("cache"))); - - fields.add(metaAccess.lookupJavaField(Throwable.class.getDeclaredField("UNASSIGNED_STACK"))); - fields.add(metaAccess.lookupJavaField(Throwable.class.getDeclaredField("SUPPRESSED_SENTINEL"))); - } catch (SecurityException | NoSuchFieldException e) { - throw new GraalInternalError(e); - } - } - } } diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotJVMCIBackendFactory.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotJVMCIBackendFactory.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotJVMCIBackendFactory.java Mon May 25 17:20:39 2015 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot.jvmci; -import com.oracle.graal.api.runtime.*; import com.oracle.jvmci.runtime.*; public interface HotSpotJVMCIBackendFactory extends Service { diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotJVMCIRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotJVMCIRuntime.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotJVMCIRuntime.java Mon May 25 17:20:39 2015 +0200 @@ -30,7 +30,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.debug.*; import com.oracle.graal.hotspot.jvmci.logging.*; import com.oracle.graal.options.*; diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotMethodData.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotMethodData.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotMethodData.java Mon May 25 17:20:39 2015 +0200 @@ -23,7 +23,7 @@ package com.oracle.graal.hotspot.jvmci; import static com.oracle.graal.compiler.common.UnsafeAccess.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import static com.oracle.graal.hotspot.jvmci.HotSpotJVMCIRuntime.*; import static java.lang.String.*; import java.util.*; @@ -109,13 +109,13 @@ } public int getDeoptimizationCount(DeoptimizationReason reason) { - HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) runtime().getHostProviders().getMetaAccess(); + HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) runtime().getHostJVMCIBackend().getMetaAccess(); int reasonIndex = metaAccess.convertDeoptReason(reason); return unsafe.getByte(metaspaceMethodData + config.methodDataOopTrapHistoryOffset + reasonIndex) & 0xFF; } public int getOSRDeoptimizationCount(DeoptimizationReason reason) { - HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) runtime().getHostProviders().getMetaAccess(); + HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) runtime().getHostJVMCIBackend().getMetaAccess(); int reasonIndex = metaAccess.convertDeoptReason(reason); return unsafe.getByte(metaspaceMethodData + config.methodDataOopTrapHistoryOffset + config.deoptReasonOSROffset + reasonIndex) & 0xFF; } diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotMethodHandleAccessProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotMethodHandleAccessProvider.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotMethodHandleAccessProvider.java Mon May 25 17:20:39 2015 +0200 @@ -27,7 +27,6 @@ import static com.oracle.graal.hotspot.jvmci.HotSpotResolvedObjectTypeImpl.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProvider, HotSpotProxified { @@ -88,7 +87,7 @@ lambdaFormCompileToBytecodeMethod = findMethodInClass("java.lang.invoke.LambdaForm", "compileToBytecode"); memberNameVmtargetField = findFieldInClass("java.lang.invoke.MemberName", "vmtarget"); } catch (Throwable ex) { - throw GraalInternalError.shouldNotReachHere(); + throw new InternalError(ex); } } } diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotOptions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotOptions.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotOptions.java Mon May 25 17:20:39 2015 +0200 @@ -25,7 +25,6 @@ import static com.oracle.graal.hotspot.jvmci.HotSpotOptionsLoader.*; import static java.lang.Double.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.debug.*; import com.oracle.graal.options.*; import com.oracle.graal.options.OptionUtils.OptionConsumer; diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotOptionsLoader.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotOptionsLoader.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotOptionsLoader.java Mon May 25 17:20:39 2015 +0200 @@ -24,8 +24,8 @@ import java.util.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.options.*; +import com.oracle.jvmci.runtime.*; /** * Helper class for separating loading of options from option initialization at runtime. diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotResolvedJavaFieldImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotResolvedJavaFieldImpl.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotResolvedJavaFieldImpl.java Mon May 25 17:20:39 2015 +0200 @@ -22,21 +22,29 @@ */ package com.oracle.graal.hotspot.jvmci; -import static com.oracle.graal.compiler.common.GraalOptions.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +//import static com.oracle.graal.compiler.common.GraalOptions.*; +import static com.oracle.graal.hotspot.jvmci.HotSpotJVMCIRuntime.*; +import static com.oracle.graal.hotspot.jvmci.HotSpotResolvedJavaFieldImpl.Options.*; import static com.oracle.graal.hotspot.jvmci.HotSpotResolvedObjectTypeImpl.*; import java.lang.annotation.*; import java.lang.reflect.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; +import com.oracle.graal.options.*; /** * Represents a field in a HotSpot type. */ public class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotProxified { + static class Options { + //@formatter:off + @Option(help = "Mark well-known stable fields as such.", type = OptionType.Debug) + public static final OptionValue ImplicitStableValues = new OptionValue<>(true); + //@formatter:on + } + private final HotSpotResolvedObjectTypeImpl holder; private final String name; private JavaType type; @@ -267,10 +275,10 @@ private static final ResolvedJavaField STRING_VALUE_FIELD; static { try { - MetaAccessProvider metaAccess = runtime().getHostProviders().getMetaAccess(); + MetaAccessProvider metaAccess = runtime().getHostJVMCIBackend().getMetaAccess(); STRING_VALUE_FIELD = metaAccess.lookupJavaField(String.class.getDeclaredField("value")); } catch (SecurityException | NoSuchFieldException e) { - throw new GraalInternalError(e); + throw new InternalError(e); } } } diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotResolvedObjectTypeImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotResolvedObjectTypeImpl.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotResolvedObjectTypeImpl.java Mon May 25 17:20:39 2015 +0200 @@ -38,7 +38,6 @@ import com.oracle.graal.api.meta.Assumptions.LeafType; import com.oracle.graal.api.meta.Assumptions.NoFinalizableSubclass; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; /** * Implementation of {@link JavaType} for resolved non-primitive HotSpot classes. @@ -232,7 +231,7 @@ @Override public HotSpotResolvedObjectTypeImpl getSingleImplementor() { if (!isInterface()) { - throw new GraalInternalError("Cannot call getImplementor() on a non-interface type: " + this); + throw new InternalError("Cannot call getSingleImplementor() on a non-interface type: " + this); } final long implementorMetaspaceKlass = runtime().getCompilerToVM().getKlassImplementor(getMetaspaceKlass()); diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotResolvedPrimitiveType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotResolvedPrimitiveType.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotResolvedPrimitiveType.java Mon May 25 17:20:39 2015 +0200 @@ -30,7 +30,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.Assumptions.AssumptionResult; -import com.oracle.graal.compiler.common.*; /** * Implementation of {@link JavaType} for primitive HotSpot types. @@ -95,7 +94,7 @@ @Override public ResolvedJavaType getSingleImplementor() { - throw new GraalInternalError("Cannot call getImplementor() on a non-interface type: " + this); + throw new InternalError("Cannot call getSingleImplementor() on a non-interface type: " + this); } @Override @@ -105,12 +104,12 @@ @Override public JavaConstant getObjectHub() { - throw GraalInternalError.unimplemented("HotSpotResolvedPrimitiveType.getObjectHub"); + throw new InternalError(); } @Override public JavaConstant getJavaClass() { - throw GraalInternalError.unimplemented("HotSpotResolvedPrimitiveType.getJavaClass"); + throw new InternalError(); } @Override @@ -230,7 +229,7 @@ @Override public String getSourceFileName() { - throw GraalInternalError.shouldNotReachHere(); + throw new InternalError(); } @Override diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotSignature.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotSignature.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotSignature.java Mon May 25 17:20:39 2015 +0200 @@ -25,7 +25,6 @@ import java.util.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; /** * Represents a method signature. @@ -101,7 +100,7 @@ case 'Z': break; default: - throw new GraalInternalError("Invalid character at index " + cur + " in signature: " + signature); + throw new InternalError("Invalid character at index " + cur + " in signature: " + signature); } return cur; } diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotVMConfig.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotVMConfig.java Mon May 25 17:20:39 2015 +0200 @@ -27,7 +27,6 @@ import java.lang.reflect.*; import java.util.*; -import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspotvmconfig.*; //JaCoCo Exclude @@ -171,7 +170,7 @@ checkField(f, entry.getValue()); break; default: - throw GraalInternalError.shouldNotReachHere("unknown kind " + annotation.get()); + throw new InternalError("unknown kind " + annotation.get()); } } else if (f.isAnnotationPresent(HotSpotVMType.class)) { HotSpotVMType annotation = f.getAnnotation(HotSpotVMType.class); @@ -185,7 +184,7 @@ checkField(f, entry.getSize()); break; default: - throw GraalInternalError.shouldNotReachHere("unknown kind " + annotation.get()); + throw new InternalError("unknown kind " + annotation.get()); } } else if (f.isAnnotationPresent(HotSpotVMConstant.class)) { HotSpotVMConstant annotation = f.getAnnotation(HotSpotVMConstant.class); @@ -237,7 +236,7 @@ } else if (value instanceof Long) { assert field.getBoolean(this) == (((long) value) != 0) : field + " " + value + " " + field.getBoolean(this); } else { - GraalInternalError.shouldNotReachHere(value.getClass().getSimpleName()); + throw new InternalError(value.getClass().getSimpleName()); } } else if (fieldType == int.class) { if (value instanceof Integer) { @@ -245,15 +244,15 @@ } else if (value instanceof Long) { assert field.getInt(this) == (int) (long) value : field + " " + value + " " + field.getInt(this); } else { - GraalInternalError.shouldNotReachHere(value.getClass().getSimpleName()); + throw new InternalError(value.getClass().getSimpleName()); } } else if (fieldType == long.class) { assert field.getLong(this) == (long) value : field + " " + value + " " + field.getLong(this); } else { - GraalInternalError.shouldNotReachHere(field.toString()); + throw new InternalError(field.toString()); } } catch (IllegalAccessException e) { - throw GraalInternalError.shouldNotReachHere(field.toString() + ": " + e); + throw new InternalError(field.toString() + ": " + e); } } @@ -316,11 +315,6 @@ index++; return entry; } - - @Override - public void remove() { - throw GraalInternalError.unimplemented(); - } }; } @@ -378,7 +372,7 @@ if (type.endsWith("*")) { return unsafe.getAddress(getAddress()); } - throw GraalInternalError.shouldNotReachHere(type); + throw new InternalError(type); } } @@ -432,11 +426,6 @@ index++; return entry; } - - @Override - public void remove() { - throw GraalInternalError.unimplemented(); - } }; } @@ -540,11 +529,6 @@ index++; return entry; } - - @Override - public void remove() { - throw GraalInternalError.unimplemented(); - } }; } @@ -604,11 +588,6 @@ index++; return entry; } - - @Override - public void remove() { - throw GraalInternalError.unimplemented(); - } }; } @@ -672,11 +651,6 @@ index++; return entry; } - - @Override - public void remove() { - throw GraalInternalError.unimplemented(); - } }; } @@ -716,7 +690,7 @@ case "ccstrlist": return readCString(getAddr()); default: - throw GraalInternalError.shouldNotReachHere(getType()); + throw new InternalError(getType()); } } @@ -1194,14 +1168,14 @@ public long cardtableStartAddress() { if (cardtableStartAddress == -1) { - throw GraalInternalError.shouldNotReachHere(); + throw new InternalError(); } return cardtableStartAddress; } public int cardtableShift() { if (cardtableShift == -1) { - throw GraalInternalError.shouldNotReachHere(); + throw new InternalError(); } return cardtableShift; } diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotVMConfigVerifier.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotVMConfigVerifier.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotVMConfigVerifier.java Mon May 25 17:20:39 2015 +0200 @@ -28,8 +28,6 @@ import java.lang.reflect.*; import java.util.*; -import com.oracle.graal.compiler.common.*; - import jdk.internal.org.objectweb.asm.*; import jdk.internal.org.objectweb.asm.Type; import sun.misc.*; @@ -53,7 +51,7 @@ cr.accept(cv, 0); return true; } catch (IOException e) { - throw new GraalInternalError(e); + throw new InternalError(e); } } diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotVMEventListener.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotVMEventListener.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/jvmci/HotSpotVMEventListener.java Mon May 25 17:20:39 2015 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.jvmci; -import com.oracle.graal.api.runtime.*; +import com.oracle.jvmci.runtime.*; public interface HotSpotVMEventListener extends Service { diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraalConstantReflectionProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraalConstantReflectionProvider.java Mon May 25 17:20:39 2015 +0200 @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2015, 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.meta; + +import static com.oracle.graal.compiler.common.GraalOptions.*; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import static com.oracle.graal.hotspot.meta.HotSpotGraalConstantReflectionProvider.ImmutableCodeLazy.*; +import static com.oracle.graal.hotspot.stubs.SnippetStub.*; + +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.jvmci.*; +import com.oracle.graal.replacements.*; +import com.oracle.graal.replacements.SnippetTemplate.Arguments; + +/** + * Extends {@link HotSpotConstantReflectionProvider} to override the implementation of + * {@link #readConstantFieldValue(JavaField, JavaConstant)} with Graal specific semantics. + */ +public class HotSpotGraalConstantReflectionProvider extends HotSpotConstantReflectionProvider { + + public HotSpotGraalConstantReflectionProvider(HotSpotJVMCIRuntimeProvider runtime) { + super(runtime); + } + + @Override + public JavaConstant readConstantFieldValue(JavaField field, JavaConstant receiver) { + assert !ImmutableCode.getValue() || isCalledForSnippets() || SnippetGraphUnderConstruction.get() != null || FieldReadEnabledInImmutableCode.get() == Boolean.TRUE : receiver; + return super.readConstantFieldValue(field, receiver); + } + + /** + * In AOT mode, some fields should never be embedded even for snippets/replacements. + */ + @Override + protected boolean isStaticFieldConstant(HotSpotResolvedJavaField field) { + return super.isStaticFieldConstant(field) && (!ImmutableCode.getValue() || ImmutableCodeLazy.isEmbeddable(field)); + + } + + @SuppressWarnings("all") + private static boolean assertionsEnabled() { + boolean enabled = false; + assert enabled = true; + return enabled; + } + + public static final ThreadLocal FieldReadEnabledInImmutableCode = assertionsEnabled() ? new ThreadLocal<>() : null; + + /** + * Compares two {@link StackTraceElement}s for equality, ignoring differences in + * {@linkplain StackTraceElement#getLineNumber() line number}. + */ + private static boolean equalsIgnoringLine(StackTraceElement left, StackTraceElement right) { + return left.getClassName().equals(right.getClassName()) && left.getMethodName().equals(right.getMethodName()) && left.getFileName().equals(right.getFileName()); + } + + @Override + protected boolean isFinalInstanceFieldValueConstant(JavaConstant value, Class receiverClass) { + return super.isFinalInstanceFieldValueConstant(value, receiverClass) || receiverClass == SnippetCounter.class || receiverClass == NodeClass.class; + } + + /** + * {@inheritDoc} + * + * {@link HotSpotVMConfig} has a lot of zero-value fields which we know are stable and want to + * be considered as constants. + */ + @Override + protected boolean isStableInstanceFieldValueConstant(JavaConstant value, Class receiverClass) { + return super.isStableInstanceFieldValueConstant(value, receiverClass) || receiverClass == HotSpotVMConfig.class; + } + + /** + * Separate out the static initialization of + * {@linkplain #isEmbeddable(HotSpotResolvedJavaField) embeddable fields} to eliminate cycles + * between clinit and other locks that could lead to deadlock. Static code that doesn't call + * back into type or field machinery is probably ok but anything else should be made lazy. + */ + static class ImmutableCodeLazy { + + /** + * If the compiler is configured for AOT mode, + * {@link #readConstantFieldValue(JavaField, JavaConstant)} should be only called for + * snippets or replacements. + */ + static boolean isCalledForSnippets() { + assert ImmutableCode.getValue(); + MetaAccessProvider metaAccess = runtime().getHostProviders().getMetaAccess(); + ResolvedJavaMethod makeGraphMethod = null; + ResolvedJavaMethod initMethod = null; + try { + Class rjm = ResolvedJavaMethod.class; + makeGraphMethod = metaAccess.lookupJavaMethod(ReplacementsImpl.class.getDeclaredMethod("makeGraph", rjm, Object[].class, rjm)); + initMethod = metaAccess.lookupJavaMethod(SnippetTemplate.AbstractTemplates.class.getDeclaredMethod("template", Arguments.class)); + } catch (NoSuchMethodException | SecurityException e) { + throw new GraalInternalError(e); + } + StackTraceElement makeGraphSTE = makeGraphMethod.asStackTraceElement(0); + StackTraceElement initSTE = initMethod.asStackTraceElement(0); + + StackTraceElement[] stackTrace = new Exception().getStackTrace(); + for (StackTraceElement element : stackTrace) { + // Ignoring line numbers should not weaken this check too much while at + // the same time making it more robust against source code changes + if (equalsIgnoringLine(makeGraphSTE, element) || equalsIgnoringLine(initSTE, element)) { + return true; + } + } + return false; + } + + /** + * Determine if it's ok to embed the value of {@code field}. + */ + static boolean isEmbeddable(HotSpotResolvedJavaField field) { + assert ImmutableCode.getValue(); + return !embeddableFields.contains(field); + } + + private static final List embeddableFields = new ArrayList<>(); + static { + try { + MetaAccessProvider metaAccess = runtime().getHostProviders().getMetaAccess(); + embeddableFields.add(metaAccess.lookupJavaField(Boolean.class.getDeclaredField("TRUE"))); + embeddableFields.add(metaAccess.lookupJavaField(Boolean.class.getDeclaredField("FALSE"))); + + Class characterCacheClass = Character.class.getDeclaredClasses()[0]; + assert "java.lang.Character$CharacterCache".equals(characterCacheClass.getName()); + embeddableFields.add(metaAccess.lookupJavaField(characterCacheClass.getDeclaredField("cache"))); + + Class byteCacheClass = Byte.class.getDeclaredClasses()[0]; + assert "java.lang.Byte$ByteCache".equals(byteCacheClass.getName()); + embeddableFields.add(metaAccess.lookupJavaField(byteCacheClass.getDeclaredField("cache"))); + + Class shortCacheClass = Short.class.getDeclaredClasses()[0]; + assert "java.lang.Short$ShortCache".equals(shortCacheClass.getName()); + embeddableFields.add(metaAccess.lookupJavaField(shortCacheClass.getDeclaredField("cache"))); + + Class integerCacheClass = Integer.class.getDeclaredClasses()[0]; + assert "java.lang.Integer$IntegerCache".equals(integerCacheClass.getName()); + embeddableFields.add(metaAccess.lookupJavaField(integerCacheClass.getDeclaredField("cache"))); + + Class longCacheClass = Long.class.getDeclaredClasses()[0]; + assert "java.lang.Long$LongCache".equals(longCacheClass.getName()); + embeddableFields.add(metaAccess.lookupJavaField(longCacheClass.getDeclaredField("cache"))); + + embeddableFields.add(metaAccess.lookupJavaField(Throwable.class.getDeclaredField("UNASSIGNED_STACK"))); + embeddableFields.add(metaAccess.lookupJavaField(Throwable.class.getDeclaredField("SUPPRESSED_SENTINEL"))); + } catch (SecurityException | NoSuchFieldException e) { + throw new GraalInternalError(e); + } + } + } + +} diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java Mon May 25 17:20:39 2015 +0200 @@ -23,10 +23,10 @@ package com.oracle.graal.hotspot.meta; import static com.oracle.graal.compiler.common.GraalOptions.*; +import static com.oracle.graal.hotspot.meta.HotSpotGraalConstantReflectionProvider.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graphbuilderconf.*; -import com.oracle.graal.hotspot.jvmci.*; import com.oracle.graal.nodes.*; public final class HotSpotLoadFieldPlugin implements LoadFieldPlugin { @@ -49,15 +49,16 @@ } private boolean tryReadField(GraphBuilderContext b, ResolvedJavaField field, JavaConstant receiver) { - if (ImmutableCode.getValue()) { - HotSpotConstantReflectionProvider.FieldReadEnabledInImmutableCode.set(Boolean.TRUE); - } - try { + // FieldReadEnabledInImmutableCode is non null only if assertions are enabled + if (FieldReadEnabledInImmutableCode != null && ImmutableCode.getValue()) { + FieldReadEnabledInImmutableCode.set(Boolean.TRUE); + try { + return tryConstantFold(b, metaAccess, constantReflection, field, receiver); + } finally { + FieldReadEnabledInImmutableCode.set(null); + } + } else { return tryConstantFold(b, metaAccess, constantReflection, field, receiver); - } finally { - if (ImmutableCode.getValue()) { - HotSpotConstantReflectionProvider.FieldReadEnabledInImmutableCode.set(null); - } } } diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java Mon May 25 17:20:39 2015 +0200 @@ -28,10 +28,10 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.hotspot.jvmci.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.*; +import com.oracle.jvmci.runtime.*; @ServiceProvider(ReplacementsProvider.class) public class HotSpotSubstitutions implements ReplacementsProvider { diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java Mon May 25 17:20:39 2015 +0200 @@ -78,7 +78,14 @@ this.method = providers.getMetaAccess().lookupJavaMethod(javaMethod); } - public static final ThreadLocal SnippetGraphUnderConstruction = new ThreadLocal<>(); + @SuppressWarnings("all") + private static boolean assertionsEnabled() { + boolean enabled = false; + assert enabled = true; + return enabled; + } + + public static final ThreadLocal SnippetGraphUnderConstruction = assertionsEnabled() ? new ThreadLocal<>() : null; @Override protected StructuredGraph getGraph() { @@ -94,11 +101,17 @@ final StructuredGraph graph = new StructuredGraph(method, AllowAssumptions.NO); graph.disableInlinedMethodRecording(); - assert SnippetGraphUnderConstruction.get() == null; - SnippetGraphUnderConstruction.set(graph); + if (SnippetGraphUnderConstruction != null) { + assert SnippetGraphUnderConstruction.get() == null; + SnippetGraphUnderConstruction.set(graph); + } + IntrinsicContext initialIntrinsicContext = new IntrinsicContext(method, method, INLINE_AFTER_PARSING); new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), config, OptimisticOptimizations.NONE, initialIntrinsicContext).apply(graph); - SnippetGraphUnderConstruction.set(null); + + if (SnippetGraphUnderConstruction != null) { + SnippetGraphUnderConstruction.set(null); + } graph.setGuardsStage(GuardsStage.FLOATING_GUARDS); try (Scope s = Debug.scope("LoweringStub", graph)) { diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ReplacementsProvider.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ReplacementsProvider.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ReplacementsProvider.java Mon May 25 17:20:39 2015 +0200 @@ -25,7 +25,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.api.runtime.*; +import com.oracle.jvmci.runtime.*; /** * Interface for service providers that register replacements with the compiler. diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/CompilerConfiguration.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/CompilerConfiguration.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/CompilerConfiguration.java Mon May 25 17:20:39 2015 +0200 @@ -22,12 +22,12 @@ */ package com.oracle.graal.phases.tiers; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.lir.phases.*; import com.oracle.graal.lir.phases.PreAllocationOptimizationPhase.*; import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.*; import com.oracle.graal.lir.phases.AllocationPhase.*; import com.oracle.graal.phases.*; +import com.oracle.jvmci.runtime.*; public interface CompilerConfiguration extends Service { diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java Mon May 25 17:20:39 2015 +0200 @@ -26,11 +26,11 @@ import java.util.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.phases.*; import com.oracle.graal.options.*; import com.oracle.graal.phases.*; +import com.oracle.jvmci.runtime.*; public final class Suites { diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/HexCodeFile.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/HexCodeFile.java Mon May 25 17:09:00 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,431 +0,0 @@ -/* - * Copyright (c) 2009, 2011, 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.printer; - -import java.io.*; -import java.util.*; -import java.util.regex.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.CompilationResult.CodeAnnotation; -import com.oracle.graal.api.code.CompilationResult.CodeComment; -import com.oracle.graal.api.code.CompilationResult.JumpTable; - -/** - * A HexCodeFile is a textual format for representing a chunk of machine code along with extra - * information that can be used to enhance a disassembly of the code. - * - * A pseudo grammar for a HexCodeFile is given below. - * - *

- *     HexCodeFile ::= Platform Delim HexCode Delim (OptionalSection Delim)*
- *
- *     OptionalSection ::= Comment | OperandComment | JumpTable | LookupTable
- *
- *     Platform ::= "Platform" ISA WordWidth
- *
- *     HexCode ::= "HexCode" StartAddress HexDigits
- *
- *     Comment ::= "Comment" Position String
- *
- *     OperandComment ::= "OperandComment" Position String
- *
- *     JumpTable ::= "JumpTable" Position EntrySize Low High
- *
- *     LookupTable ::= "LookupTable" Position NPairs KeySize OffsetSize
- *
- *     Position, EntrySize, Low, High, NPairs KeySize OffsetSize ::= int
- *
- *     Delim := "<||@"
- * 
- * - * There must be exactly one HexCode and Platform part in a HexCodeFile. The length of HexDigits - * must be even as each pair of digits represents a single byte. - *

- * Below is an example of a valid Code input: - * - *

- *
- *  Platform AMD64 64  <||@
- *  HexCode 0 e8000000009090904883ec084889842410d0ffff48893c24e800000000488b3c24488bf0e8000000004883c408c3  <||@
- *  Comment 24 frame-ref-map: +0 {0}
- *  at java.lang.String.toLowerCase(String.java:2496) [bci: 1]
- *              |0
- *     locals:  |stack:0:a
- *     stack:   |stack:0:a
- *    <||@
- *  OperandComment 24 {java.util.Locale.getDefault()}  <||@
- *  Comment 36 frame-ref-map: +0 {0}
- *  at java.lang.String.toLowerCase(String.java:2496) [bci: 4]
- *              |0
- *     locals:  |stack:0:a
- *    <||@
- *  OperandComment 36 {java.lang.String.toLowerCase(Locale)}  lt;||@
- *
- * 
- */ -public class HexCodeFile { - - public static final String NEW_LINE = CodeUtil.NEW_LINE; - public static final String SECTION_DELIM = " <||@"; - public static final String COLUMN_END = " <|@"; - public static final Pattern SECTION = Pattern.compile("(\\S+)\\s+(.*)", Pattern.DOTALL); - public static final Pattern COMMENT = Pattern.compile("(\\d+)\\s+(.*)", Pattern.DOTALL); - public static final Pattern OPERAND_COMMENT = COMMENT; - public static final Pattern JUMP_TABLE = Pattern.compile("(\\d+)\\s+(\\d+)\\s+(-{0,1}\\d+)\\s+(-{0,1}\\d+)\\s*"); - public static final Pattern LOOKUP_TABLE = Pattern.compile("(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s*"); - public static final Pattern HEX_CODE = Pattern.compile("(\\p{XDigit}+)(?:\\s+(\\p{XDigit}*))?"); - public static final Pattern PLATFORM = Pattern.compile("(\\S+)\\s+(\\S+)", Pattern.DOTALL); - - /** - * Delimiter placed before a HexCodeFile when embedded in a string/stream. - */ - public static final String EMBEDDED_HCF_OPEN = "<<> comments = new TreeMap<>(); - - /** - * Map from a machine code position to a comment for the operands of the instruction at the - * position. - */ - public final Map operandComments = new TreeMap<>(); - - public final byte[] code; - - public final ArrayList jumpTables = new ArrayList<>(); - - public final String isa; - - public final int wordWidth; - - public final long startAddress; - - public HexCodeFile(byte[] code, long startAddress, String isa, int wordWidth) { - this.code = code; - this.startAddress = startAddress; - this.isa = isa; - this.wordWidth = wordWidth; - } - - /** - * Parses a string in the format produced by {@link #toString()} to produce a - * {@link HexCodeFile} object. - */ - public static HexCodeFile parse(String input, int sourceOffset, String source, String sourceName) { - return new Parser(input, sourceOffset, source, sourceName).hcf; - } - - /** - * Formats this HexCodeFile as a string that can be parsed with - * {@link #parse(String, int, String, String)}. - */ - @Override - public String toString() { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - writeTo(baos); - return baos.toString(); - } - - public String toEmbeddedString() { - return EMBEDDED_HCF_OPEN + NEW_LINE + toString() + EMBEDDED_HCF_CLOSE; - } - - public void writeTo(OutputStream out) { - PrintStream ps = out instanceof PrintStream ? (PrintStream) out : new PrintStream(out); - ps.printf("Platform %s %d %s%n", isa, wordWidth, SECTION_DELIM); - ps.printf("HexCode %x %s %s%n", startAddress, HexCodeFile.hexCodeString(code), SECTION_DELIM); - - for (JumpTable table : jumpTables) { - ps.printf("JumpTable %d %d %d %d %s%n", table.position, table.entrySize, table.low, table.high, SECTION_DELIM); - } - - for (Map.Entry> e : comments.entrySet()) { - int pos = e.getKey(); - for (String comment : e.getValue()) { - ps.printf("Comment %d %s %s%n", pos, comment, SECTION_DELIM); - } - } - - for (Map.Entry e : operandComments.entrySet()) { - ps.printf("OperandComment %d %s %s%n", e.getKey(), e.getValue(), SECTION_DELIM); - } - ps.flush(); - } - - /** - * Formats a byte array as a string of hex digits. - */ - public static String hexCodeString(byte[] code) { - if (code == null) { - return ""; - } else { - StringBuilder sb = new StringBuilder(code.length * 2); - for (int b : code) { - String hex = Integer.toHexString(b & 0xff); - if (hex.length() == 1) { - sb.append('0'); - } - sb.append(hex); - } - return sb.toString(); - } - } - - /** - * Adds a comment to the list of comments for a given position. - */ - public void addComment(int pos, String comment) { - List list = comments.get(pos); - if (list == null) { - list = new ArrayList<>(); - comments.put(pos, list); - } - list.add(encodeString(comment)); - } - - /** - * Sets an operand comment for a given position. - * - * @return the previous operand comment for {@code pos} - */ - public String addOperandComment(int pos, String comment) { - return operandComments.put(pos, encodeString(comment)); - } - - /** - * Adds any jump tables, lookup tables or code comments from a list of code annotations. - */ - public static void addAnnotations(HexCodeFile hcf, List annotations) { - if (annotations == null || annotations.isEmpty()) { - return; - } - for (CodeAnnotation a : annotations) { - if (a instanceof JumpTable) { - JumpTable table = (JumpTable) a; - hcf.jumpTables.add(table); - } else if (a instanceof CodeComment) { - CodeComment comment = (CodeComment) a; - hcf.addComment(comment.position, comment.value); - } - } - } - - /** - * Modifies a string to mangle any substrings matching {@link #SECTION_DELIM} and - * {@link #COLUMN_END}. - */ - public static String encodeString(String input) { - int index; - String s = input; - while ((index = s.indexOf(SECTION_DELIM)) != -1) { - s = s.substring(0, index) + " < |@" + s.substring(index + SECTION_DELIM.length()); - } - while ((index = s.indexOf(COLUMN_END)) != -1) { - s = s.substring(0, index) + " < @" + s.substring(index + COLUMN_END.length()); - } - return s; - } - - /** - * Helper class to parse a string in the format produced by {@link HexCodeFile#toString()} and - * produce a {@link HexCodeFile} object. - */ - static class Parser { - - final String input; - final String inputSource; - String isa; - int wordWidth; - byte[] code; - long startAddress; - HexCodeFile hcf; - - Parser(String input, int sourceOffset, String source, String sourceName) { - this.input = input; - this.inputSource = sourceName; - parseSections(sourceOffset, source); - } - - void makeHCF() { - if (hcf == null) { - if (isa != null && wordWidth != 0 && code != null) { - hcf = new HexCodeFile(code, startAddress, isa, wordWidth); - } - } - } - - void checkHCF(String section, int offset) { - check(hcf != null, offset, section + " section must be after Platform and HexCode section"); - } - - void check(boolean condition, int offset, String message) { - if (!condition) { - error(offset, message); - } - } - - Error error(int offset, String message) { - throw new Error(errorMessage(offset, message)); - } - - void warning(int offset, String message) { - PrintStream err = System.err; - err.println("Warning: " + errorMessage(offset, message)); - } - - String errorMessage(int offset, String message) { - assert offset < input.length(); - InputPos inputPos = filePos(offset); - int lineEnd = input.indexOf(HexCodeFile.NEW_LINE, offset); - int lineStart = offset - inputPos.col; - String line = lineEnd == -1 ? input.substring(lineStart) : input.substring(lineStart, lineEnd); - return String.format("%s:%d: %s%n%s%n%" + (inputPos.col + 1) + "s", inputSource, inputPos.line, message, line, "^"); - } - - static class InputPos { - - final int line; - final int col; - - public InputPos(int line, int col) { - this.line = line; - this.col = col; - } - } - - InputPos filePos(int index) { - assert input != null; - int lineStart = input.lastIndexOf(HexCodeFile.NEW_LINE, index) + 1; - - String l = input.substring(lineStart, lineStart + 10); - PrintStream out = System.out; - out.println("YYY" + input.substring(index, index + 10) + "..."); - out.println("XXX" + l + "..."); - - int pos = input.indexOf(HexCodeFile.NEW_LINE, 0); - int line = 1; - while (pos > 0 && pos < index) { - line++; - pos = input.indexOf(HexCodeFile.NEW_LINE, pos + 1); - } - return new InputPos(line, index - lineStart); - } - - void parseSections(int offset, String source) { - assert input.startsWith(source, offset); - int index = 0; - int endIndex = source.indexOf(SECTION_DELIM); - while (endIndex != -1) { - while (source.charAt(index) <= ' ') { - index++; - } - String section = source.substring(index, endIndex).trim(); - parseSection(offset + index, section); - index = endIndex + SECTION_DELIM.length(); - endIndex = source.indexOf(SECTION_DELIM, index); - } - } - - int parseInt(int offset, String value) { - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - throw error(offset, "Not a valid integer: " + value); - } - } - - void parseSection(int offset, String section) { - if (section.isEmpty()) { - return; - } - assert input.startsWith(section, offset); - Matcher m = HexCodeFile.SECTION.matcher(section); - check(m.matches(), offset, "Section does not match pattern " + HexCodeFile.SECTION); - - String header = m.group(1); - String body = m.group(2); - int headerOffset = offset + m.start(1); - int bodyOffset = offset + m.start(2); - - if (header.equals("Platform")) { - check(isa == null, bodyOffset, "Duplicate Platform section found"); - m = HexCodeFile.PLATFORM.matcher(body); - check(m.matches(), bodyOffset, "Platform does not match pattern " + HexCodeFile.PLATFORM); - isa = m.group(1); - wordWidth = parseInt(bodyOffset + m.start(2), m.group(2)); - makeHCF(); - } else if (header.equals("HexCode")) { - check(code == null, bodyOffset, "Duplicate Code section found"); - m = HexCodeFile.HEX_CODE.matcher(body); - check(m.matches(), bodyOffset, "Code does not match pattern " + HexCodeFile.HEX_CODE); - String hexAddress = m.group(1); - startAddress = Long.valueOf(hexAddress, 16); - String hexCode = m.group(2); - if (hexCode == null) { - code = new byte[0]; - } else { - check((hexCode.length() % 2) == 0, bodyOffset, "Hex code length must be even"); - code = new byte[hexCode.length() / 2]; - for (int i = 0; i < code.length; i++) { - String hexByte = hexCode.substring(i * 2, (i + 1) * 2); - code[i] = (byte) Integer.parseInt(hexByte, 16); - } - } - makeHCF(); - } else if (header.equals("Comment")) { - checkHCF("Comment", headerOffset); - m = HexCodeFile.COMMENT.matcher(body); - check(m.matches(), bodyOffset, "Comment does not match pattern " + HexCodeFile.COMMENT); - int pos = parseInt(bodyOffset + m.start(1), m.group(1)); - String comment = m.group(2); - hcf.addComment(pos, comment); - } else if (header.equals("OperandComment")) { - checkHCF("OperandComment", headerOffset); - m = HexCodeFile.OPERAND_COMMENT.matcher(body); - check(m.matches(), bodyOffset, "OperandComment does not match pattern " + HexCodeFile.OPERAND_COMMENT); - int pos = parseInt(bodyOffset + m.start(1), m.group(1)); - String comment = m.group(2); - hcf.addOperandComment(pos, comment); - } else if (header.equals("JumpTable")) { - checkHCF("JumpTable", headerOffset); - m = HexCodeFile.JUMP_TABLE.matcher(body); - check(m.matches(), bodyOffset, "JumpTable does not match pattern " + HexCodeFile.JUMP_TABLE); - int pos = parseInt(bodyOffset + m.start(1), m.group(1)); - int entrySize = parseInt(bodyOffset + m.start(2), m.group(2)); - int low = parseInt(bodyOffset + m.start(3), m.group(3)); - int high = parseInt(bodyOffset + m.start(4), m.group(4)); - hcf.jumpTables.add(new JumpTable(pos, low, high, entrySize)); - } else { - error(offset, "Unknown section header: " + header); - } - } - } -} diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.service.processor/src/com/oracle/graal/service/processor/ServiceProviderProcessor.java --- a/graal/com.oracle.graal.service.processor/src/com/oracle/graal/service/processor/ServiceProviderProcessor.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.service.processor/src/com/oracle/graal/service/processor/ServiceProviderProcessor.java Mon May 25 17:20:39 2015 +0200 @@ -32,9 +32,9 @@ import javax.tools.Diagnostic.Kind; import javax.tools.*; -import com.oracle.graal.api.runtime.*; +import com.oracle.jvmci.runtime.*; -@SupportedAnnotationTypes("com.oracle.graal.api.runtime.ServiceProvider") +@SupportedAnnotationTypes("com.oracle.jvmci.runtime.ServiceProvider") public class ServiceProviderProcessor extends AbstractProcessor { private final Set processed = new HashSet<>(); diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64OptimizedCallTargetInstrumentationFactory.java --- a/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64OptimizedCallTargetInstrumentationFactory.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64OptimizedCallTargetInstrumentationFactory.java Mon May 25 17:20:39 2015 +0200 @@ -26,7 +26,6 @@ import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; @@ -36,6 +35,7 @@ import com.oracle.graal.lir.framemap.*; import com.oracle.graal.truffle.*; import com.oracle.graal.truffle.hotspot.*; +import com.oracle.jvmci.runtime.*; @ServiceProvider(OptimizedCallTargetInstrumentationFactory.class) public class AMD64OptimizedCallTargetInstrumentationFactory implements OptimizedCallTargetInstrumentationFactory { diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64RawNativeCallNodeFactory.java --- a/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64RawNativeCallNodeFactory.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64RawNativeCallNodeFactory.java Mon May 25 17:20:39 2015 +0200 @@ -23,10 +23,10 @@ package com.oracle.graal.truffle.hotspot.amd64; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.hotspot.amd64.*; import com.oracle.graal.nodes.*; import com.oracle.graal.truffle.hotspot.nfi.*; +import com.oracle.jvmci.runtime.*; @ServiceProvider(RawNativeCallNodeFactory.class) public class AMD64RawNativeCallNodeFactory implements RawNativeCallNodeFactory { diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java --- a/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java Mon May 25 17:20:39 2015 +0200 @@ -32,7 +32,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister; @@ -42,6 +41,7 @@ import com.oracle.graal.lir.framemap.*; import com.oracle.graal.truffle.*; import com.oracle.graal.truffle.hotspot.*; +import com.oracle.jvmci.runtime.*; @ServiceProvider(OptimizedCallTargetInstrumentationFactory.class) public class SPARCOptimizedCallTargetInstumentationFactory implements OptimizedCallTargetInstrumentationFactory { diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Mon May 25 17:20:39 2015 +0200 @@ -59,6 +59,7 @@ import com.oracle.graal.runtime.*; import com.oracle.graal.truffle.*; import com.oracle.graal.truffle.hotspot.nfi.*; +import com.oracle.jvmci.runtime.*; import com.oracle.nfi.api.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.*; diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/RawNativeCallNodeFactory.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/RawNativeCallNodeFactory.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/RawNativeCallNodeFactory.java Mon May 25 17:20:39 2015 +0200 @@ -23,8 +23,8 @@ package com.oracle.graal.truffle.hotspot.nfi; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.nodes.*; +import com.oracle.jvmci.runtime.*; /** * Factory for creating a node that makes a direct call to a native function pointer. diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultLoopNodeFactory.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultLoopNodeFactory.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultLoopNodeFactory.java Mon May 25 17:20:39 2015 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.truffle; -import com.oracle.graal.api.runtime.*; +import com.oracle.jvmci.runtime.*; import com.oracle.truffle.api.nodes.*; @ServiceProvider(LoopNodeFactory.class) diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetInstrumentationFactory.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetInstrumentationFactory.java Mon May 25 17:09:00 2015 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetInstrumentationFactory.java Mon May 25 17:20:39 2015 +0200 @@ -23,8 +23,8 @@ package com.oracle.graal.truffle; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.lir.asm.*; +import com.oracle.jvmci.runtime.*; /** * A service for creating a specialized {@link CompilationResultBuilder} used to inject code into diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.jvmci.runtime/src/com/oracle/jvmci/runtime/OptionsParsed.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.runtime/src/com/oracle/jvmci/runtime/OptionsParsed.java Mon May 25 17:20:39 2015 +0200 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2015, 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.jvmci.runtime; + +/** + * Extension for doing post-processing once all JVMCI options have been parsed and initialized. + */ +public interface OptionsParsed extends Service { + + /** + * Notifies this service that all JVMCI options have been parsed and initialized. + */ + void apply(); +} diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.jvmci.runtime/src/com/oracle/jvmci/runtime/Service.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.runtime/src/com/oracle/jvmci/runtime/Service.java Mon May 25 17:20:39 2015 +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.jvmci.runtime; + +/** + * Denotes a service that may be efficiently loaded by {@link Services#load(Class)}. + */ +public interface Service { +} diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.jvmci.runtime/src/com/oracle/jvmci/runtime/ServiceProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.runtime/src/com/oracle/jvmci/runtime/ServiceProvider.java Mon May 25 17:20:39 2015 +0200 @@ -0,0 +1,32 @@ +/* + * 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.jvmci.runtime; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.TYPE) +public @interface ServiceProvider { + + Class value(); +} diff -r ca14581fadc4 -r c1e2fdb5fea3 graal/com.oracle.jvmci.runtime/src/com/oracle/jvmci/runtime/Services.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.runtime/src/com/oracle/jvmci/runtime/Services.java Mon May 25 17:20:39 2015 +0200 @@ -0,0 +1,65 @@ +/* + * 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.jvmci.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> cache = new ClassValue>() { + @Override + protected List 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 and that in suite.py the \"annotationProcessors\" attribute for the project enclosing %s includes \"com.oracle.graal.service.processor\")", + type.getSimpleName(), type.getSimpleName(), Service.class, type.getSimpleName())); + } + return Arrays.asList(names); + } + }; + + /** + * Gets an {@link Iterable} of the implementations available for a given service. + */ + @SuppressWarnings("unchecked") + public static Iterable load(Class service) { + if (Service.class.isAssignableFrom(service)) { + try { + return (Iterable) cache.get(service); + } catch (UnsatisfiedLinkError e) { + // Fall back to standard SerivceLoader + } + } + return ServiceLoader.load(service, Services.class.getClassLoader()); + } + + private static native S[] getServiceImpls(Class service); +} diff -r ca14581fadc4 -r c1e2fdb5fea3 mx/suite.py --- a/mx/suite.py Mon May 25 17:09:00 2015 +0200 +++ b/mx/suite.py Mon May 25 17:20:39 2015 +0200 @@ -208,6 +208,9 @@ "com.oracle.graal.api.runtime" : { "subDir" : "graal", "sourceDirs" : ["src"], + "dependencies" : [ + "com.oracle.jvmci.runtime", + ], "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", "workingSets" : "API,Graal", @@ -268,7 +271,7 @@ "com.oracle.graal.service.processor" : { "subDir" : "graal", "sourceDirs" : ["src"], - "dependencies" : ["com.oracle.graal.api.runtime"], + "dependencies" : ["com.oracle.jvmci.runtime"], "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", "workingSets" : "Codegen,HotSpot", @@ -313,10 +316,9 @@ "subDir" : "graal", "sourceDirs" : ["src"], "dependencies" : [ - "com.oracle.jvmci.runtime", "com.oracle.graal.replacements", + "com.oracle.graal.printer", "com.oracle.graal.runtime", - "com.oracle.graal.printer", "com.oracle.graal.hotspotvmconfig", ], "checkstyle" : "com.oracle.graal.graph",