# HG changeset patch # User Lukas Stadler # Date 1365087539 -7200 # Node ID 54a373881da6a1b650c5633051ef9f83123c2653 # Parent b6491ee579d305edc230ae8856b5319ebfcea7fe# Parent c4bca84d86d7f41dfd45a884ee05ac11b044b5fb Merge diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/MacroSubstitution.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/MacroSubstitution.java Thu Apr 04 16:58:59 2013 +0200 @@ -0,0 +1,69 @@ +/* + * 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.replacements; + +import java.lang.annotation.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; + +/** + * Denotes a macro substitute method. This replaces a method invocation with an instance of the + * specified node class. + * + * A macro substitution can be combined with a normal substitution, so that the macro node can be + * replaced with the actual substitution code during lowering. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface MacroSubstitution { + + /** + * Gets the name of the substituted method. + *

+ * If the default value is specified for this element, then the name of the substituted method + * is same as the substitute method. + */ + String value() default ""; + + /** + * Determines if the substituted method is static. + */ + boolean isStatic() default true; + + /** + * Gets the {@linkplain MetaUtil#signatureToMethodDescriptor signature} of the substituted + * method. + *

+ * If the default value is specified for this element, then the signature of the substituted + * method is the same as the substitute method. + */ + String signature() default ""; + + /** + * The node class with which the method invocation should be replaced. It needs to be a subclass + * of {@link FixedWithNextNode}, and it is expected to provide a public constructor that takes + * an {@link InvokeNode} as a parameter. + */ + Class macro(); +} diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/Replacements.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/Replacements.java Thu Apr 04 16:58:59 2013 +0200 @@ -0,0 +1,72 @@ +/* + * 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.replacements; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; + +/** + * Interface for managing replacements. + */ +public interface Replacements { + + /** + * Gets the snippet graph derived from a given method. + * + * @return the snippet graph, if any, that is derived from {@code method} + */ + StructuredGraph getSnippet(ResolvedJavaMethod method); + + /** + * Gets the graph that is a substitution for a given method. + * + * @return the graph, if any, that is a substitution for {@code method} + */ + StructuredGraph getMethodSubstitution(ResolvedJavaMethod method); + + /** + * Gets the node class with which a method invocation should be replaced. + * + * @param method target of an invocation + * @return the {@linkplain MacroSubstitution#macro() macro node class} associated with + * {@code method} or null if there is no such association + */ + Class getMacroSubstitution(ResolvedJavaMethod method); + + /** + * Gets the assumptions with which replacement graphs are preprocessed. + */ + Assumptions getAssumptions(); + + /** + * Registers all the snippet methods defined by a given class. + */ + void registerSnippets(Class snippets); + + /** + * Registers all the {@linkplain MethodSubstitution method} and {@linkplain MacroSubstitution + * macro} substitutions defined by a given class. + */ + void registerSubstitutions(Class substitutions); +} diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Thu Apr 04 16:58:59 2013 +0200 @@ -37,23 +37,22 @@ import static com.oracle.graal.hotspot.nodes.ThreadIsInterruptedStubCall.*; import static com.oracle.graal.hotspot.nodes.VMErrorNode.*; import static com.oracle.graal.hotspot.nodes.VerifyOopStubCall.*; +import static com.oracle.graal.hotspot.nodes.WriteBarrierPostStubCall.*; +import static com.oracle.graal.hotspot.nodes.WriteBarrierPreStubCall.*; import static com.oracle.graal.hotspot.replacements.AESCryptSubstitutions.DecryptBlockStubCall.*; import static com.oracle.graal.hotspot.replacements.AESCryptSubstitutions.EncryptBlockStubCall.*; import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.DecryptAESCryptStubCall.*; import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.EncryptAESCryptStubCall.*; -import static com.oracle.graal.hotspot.nodes.WriteBarrierPostStubCall.*; -import static com.oracle.graal.hotspot.nodes.WriteBarrierPreStubCall.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.target.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.amd64.*; -import com.oracle.graal.replacements.*; public class AMD64HotSpotRuntime extends HotSpotRuntime { @@ -208,10 +207,10 @@ private AMD64ConvertSnippets.Templates convertSnippets; @Override - public void installReplacements(Backend backend, ReplacementsInstaller installer, Assumptions assumptions) { - installer.installSnippets(AMD64ConvertSnippets.class); - convertSnippets = new AMD64ConvertSnippets.Templates(this, assumptions, graalRuntime.getTarget()); - super.installReplacements(backend, installer, assumptions); + public void registerReplacements(Replacements replacements) { + replacements.registerSnippets(AMD64ConvertSnippets.class); + convertSnippets = new AMD64ConvertSnippets.Templates(this, replacements, graalRuntime.getTarget()); + super.registerReplacements(replacements); } @Override diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Thu Apr 04 16:58:59 2013 +0200 @@ -29,6 +29,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.graal.compiler.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.internal.*; @@ -143,7 +144,8 @@ @Override public CompilationResult call() throws Exception { graalRuntime.evictDeoptedGraphs(); - StructuredGraph graph = (StructuredGraph) method.getCompilerStorage().get(MethodSubstitution.class); + Replacements replacements = Graal.getRequiredCapability(Replacements.class); + StructuredGraph graph = replacements.getMethodSubstitution(method); if (graph == null || entryBCI != INVOCATION_ENTRY_BCI) { graph = new StructuredGraph(method, entryBCI); } else { diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Thu Apr 04 16:58:59 2013 +0200 @@ -29,6 +29,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.graal.compiler.target.*; import com.oracle.graal.hotspot.bridge.*; @@ -119,6 +120,7 @@ protected final HotSpotRuntime runtime; protected final TargetDescription target; + protected final Replacements replacements; private HotSpotRuntimeInterpreterInterface runtimeInterpreterInterface; private volatile HotSpotGraphCache cache; @@ -148,6 +150,11 @@ runtime = createRuntime(); + // Replacements cannot have speculative optimizations since they have + // to be valid for the entire run of the VM. + Assumptions assumptions = new Assumptions(false); + replacements = new HotSpotReplacementsImpl(runtime, assumptions, runtime.getGraalRuntime().getTarget()); + backend = createBackend(); GraalOptions.StackShadowPages = config.stackShadowPages; if (GraalOptions.CacheGraphs) { @@ -269,6 +276,9 @@ if (clazz == HotSpotRuntime.class) { return (T) runtime; } + if (clazz == Replacements.class) { + return (T) replacements; + } if (clazz == Backend.class) { return (T) getBackend(); } diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Thu Apr 04 16:58:59 2013 +0200 @@ -0,0 +1,63 @@ +/* + * 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.hotspot; + +import java.lang.reflect.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.replacements.*; +import com.oracle.graal.replacements.*; + +/** + * Filters certain method substitutions based on whether there is underlying hardware support for them. + */ +public class HotSpotReplacementsImpl extends ReplacementsImpl { + + private final HotSpotVMConfig config; + + public HotSpotReplacementsImpl(HotSpotRuntime runtime, Assumptions assumptions, TargetDescription target) { + super(runtime, assumptions, target); + this.config = runtime.config; + } + + @Override + protected void registerMethodSubstitution(Member originalMethod, Method substituteMethod) { + if (substituteMethod.getDeclaringClass() == IntegerSubstitutions.class || substituteMethod.getDeclaringClass() == LongSubstitutions.class) { + if (substituteMethod.getName().equals("bitCount")) { + if (!config.usePopCountInstruction) { + return; + } + } + } else if (substituteMethod.getDeclaringClass() == AESCryptSubstitutions.class || substituteMethod.getDeclaringClass() == CipherBlockChainingSubstitutions.class) { + if (!config.useAESIntrinsics) { + return; + } + assert config.aescryptEncryptBlockStub != 0L; + assert config.aescryptDecryptBlockStub != 0L; + assert config.cipherBlockChainingEncryptAESCryptStub != 0L; + assert config.cipherBlockChainingDecryptAESCryptStub != 0L; + } + super.registerMethodSubstitution(originalMethod, substituteMethod); + } +} diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsInstaller.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsInstaller.java Thu Apr 04 15:31:27 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +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.hotspot; - -import java.lang.reflect.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.replacements.*; -import com.oracle.graal.replacements.*; - -/** - * Filters certain method substitutions based on whether there is underlying hardware support for them. - */ -public class HotSpotReplacementsInstaller extends ReplacementsInstaller { - - private final HotSpotVMConfig config; - - public HotSpotReplacementsInstaller(HotSpotRuntime runtime, Assumptions assumptions, TargetDescription target) { - super(runtime, assumptions, target); - this.config = runtime.config; - } - - @Override - protected void installMethodSubstitution(Member originalMethod, Method substituteMethod) { - if (substituteMethod.getDeclaringClass() == IntegerSubstitutions.class || substituteMethod.getDeclaringClass() == LongSubstitutions.class) { - if (substituteMethod.getName().equals("bitCount")) { - if (!config.usePopCountInstruction) { - return; - } - } - } else if (substituteMethod.getDeclaringClass() == AESCryptSubstitutions.class || substituteMethod.getDeclaringClass() == CipherBlockChainingSubstitutions.class) { - if (!config.useAESIntrinsics) { - return; - } - assert config.aescryptEncryptBlockStub != 0L; - assert config.aescryptDecryptBlockStub != 0L; - assert config.cipherBlockChainingEncryptAESCryptStub != 0L; - assert config.cipherBlockChainingDecryptAESCryptStub != 0L; - } - super.installMethodSubstitution(originalMethod, substituteMethod); - } -} diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java Thu Apr 04 16:58:59 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.stubs.*; @@ -79,17 +80,14 @@ } public void setStub(Stub stub) { - assert address == 0L : "cannot stub for linkage that already has an address: " + this; + assert address == 0L : "cannot set stub for linkage that already has an address: " + this; this.stub = stub; } - public void setAddress(long address) { - assert this.address == 0L : "cannot re-initialize address of " + this; - this.address = address; - } - - public long getAddress() { - assert address != 0L : "address not yet initialized for " + this; - return address; + public void finalizeAddress(Backend backend) { + if (address == 0) { + assert stub != null : "linkage without an address must be a stub"; + address = stub.getAddress(backend); + } } } diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Thu Apr 04 16:58:59 2013 +0200 @@ -34,8 +34,8 @@ import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.internal.*; import com.oracle.graal.hotspot.*; @@ -146,19 +146,16 @@ // Install intrinsics. final HotSpotRuntime runtime = graalRuntime.getCapability(HotSpotRuntime.class); + final Replacements replacements = graalRuntime.getCapability(Replacements.class); if (GraalOptions.Intrinsify) { - Debug.scope("InstallReplacements", new Object[]{new DebugDumpScope("InstallReplacements")}, new Runnable() { + Debug.scope("RegisterReplacements", new Object[]{new DebugDumpScope("RegisterReplacements")}, new Runnable() { @Override public void run() { - // Replacements cannot have speculative optimizations since they have - // to be valid for the entire run of the VM. - Assumptions assumptions = new Assumptions(false); - ReplacementsInstaller installer = new HotSpotReplacementsInstaller(runtime, assumptions, runtime.getGraalRuntime().getTarget()); for (ReplacementsProvider provider : ServiceLoader.loadInstalled(ReplacementsProvider.class)) { - provider.installReplacements(installer); + provider.registerReplacements(replacements); } - runtime.installReplacements(graalRuntime.getBackend(), installer, assumptions); + runtime.registerReplacements(replacements); } }); diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Apr 04 16:58:59 2013 +0200 @@ -30,12 +30,14 @@ import static com.oracle.graal.api.meta.Value.*; import static com.oracle.graal.graph.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import static com.oracle.graal.hotspot.nodes.NewArrayStubCall.*; +import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*; import static com.oracle.graal.hotspot.replacements.SystemSubstitutions.*; import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*; import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*; import static com.oracle.graal.replacements.Log.*; import static com.oracle.graal.replacements.MathSubstitutionsX86.*; -import com.oracle.graal.replacements.*; + import java.lang.reflect.*; import java.util.*; @@ -50,7 +52,7 @@ import com.oracle.graal.api.code.Register.RegisterFlag; import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.target.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; @@ -69,6 +71,7 @@ import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; import com.oracle.graal.printer.*; +import com.oracle.graal.replacements.*; import com.oracle.graal.word.*; /** @@ -88,9 +91,6 @@ private MonitorSnippets.Templates monitorSnippets; private WriteBarrierSnippets.Templates writeBarrierSnippets; - private NewInstanceStub newInstanceStub; - private NewArrayStub newArrayStub; - private final Map runtimeCalls = new HashMap<>(); private final Map stubs = new HashMap<>(); @@ -303,67 +303,57 @@ return kind == Kind.fromJavaClass(spec); } - /** - * Binds a snippet-base {@link Stub} to a runtime call descriptor. - * - * @return the linkage information for a call to the stub - */ - public HotSpotRuntimeCallTarget registerStub(Descriptor descriptor, Stub stub) { - HotSpotRuntimeCallTarget linkage = runtimeCalls.get(descriptor); - assert linkage != null; - linkage.setStub(stub); - stubs.put(stub.getMethod(), stub); - return linkage; - } - protected abstract RegisterConfig createRegisterConfig(boolean globalStubConfig); - public void installReplacements(Backend backend, ReplacementsInstaller installer, Assumptions assumptions) { + public void registerReplacements(Replacements replacements) { if (GraalOptions.IntrinsifyObjectMethods) { - installer.installSubstitutions(ObjectSubstitutions.class); + replacements.registerSubstitutions(ObjectSubstitutions.class); } if (GraalOptions.IntrinsifySystemMethods) { - installer.installSubstitutions(SystemSubstitutions.class); + replacements.registerSubstitutions(SystemSubstitutions.class); } if (GraalOptions.IntrinsifyThreadMethods) { - installer.installSubstitutions(ThreadSubstitutions.class); + replacements.registerSubstitutions(ThreadSubstitutions.class); } if (GraalOptions.IntrinsifyUnsafeMethods) { - installer.installSubstitutions(UnsafeSubstitutions.class); + replacements.registerSubstitutions(UnsafeSubstitutions.class); } if (GraalOptions.IntrinsifyClassMethods) { - installer.installSubstitutions(ClassSubstitutions.class); + replacements.registerSubstitutions(ClassSubstitutions.class); } if (GraalOptions.IntrinsifyAESMethods) { - installer.installSubstitutions(AESCryptSubstitutions.class); - installer.installSubstitutions(CipherBlockChainingSubstitutions.class); + replacements.registerSubstitutions(AESCryptSubstitutions.class); + replacements.registerSubstitutions(CipherBlockChainingSubstitutions.class); } if (GraalOptions.IntrinsifyArrayCopy) { - installer.installSnippets(ArrayCopySnippets.class); + replacements.registerSnippets(ArrayCopySnippets.class); } if (GraalOptions.IntrinsifyObjectClone) { - installer.installSnippets(ObjectCloneSnippets.class); + replacements.registerSnippets(ObjectCloneSnippets.class); } - installer.installSnippets(CheckCastSnippets.class); - installer.installSnippets(InstanceOfSnippets.class); - installer.installSnippets(NewObjectSnippets.class); - installer.installSnippets(MonitorSnippets.class); + replacements.registerSnippets(CheckCastSnippets.class); + replacements.registerSnippets(InstanceOfSnippets.class); + replacements.registerSnippets(NewObjectSnippets.class); + replacements.registerSnippets(MonitorSnippets.class); - installer.installSnippets(NewInstanceStub.class); - installer.installSnippets(NewArrayStub.class); - installer.installSnippets(WriteBarrierSnippets.class); + replacements.registerSnippets(NewInstanceStub.class); + replacements.registerSnippets(NewArrayStub.class); + replacements.registerSnippets(WriteBarrierSnippets.class); - checkcastSnippets = new CheckCastSnippets.Templates(this, assumptions, graalRuntime.getTarget()); - instanceofSnippets = new InstanceOfSnippets.Templates(this, assumptions, graalRuntime.getTarget()); - newObjectSnippets = new NewObjectSnippets.Templates(this, assumptions, graalRuntime.getTarget(), config.useTLAB); - monitorSnippets = new MonitorSnippets.Templates(this, assumptions, graalRuntime.getTarget(), config.useFastLocking); - writeBarrierSnippets = new WriteBarrierSnippets.Templates(this, assumptions, graalRuntime.getTarget()); + checkcastSnippets = new CheckCastSnippets.Templates(this, replacements, graalRuntime.getTarget()); + instanceofSnippets = new InstanceOfSnippets.Templates(this, replacements, graalRuntime.getTarget()); + newObjectSnippets = new NewObjectSnippets.Templates(this, replacements, graalRuntime.getTarget(), config.useTLAB); + monitorSnippets = new MonitorSnippets.Templates(this, replacements, graalRuntime.getTarget(), config.useFastLocking); + writeBarrierSnippets = new WriteBarrierSnippets.Templates(this, replacements, graalRuntime.getTarget()); - newInstanceStub = new NewInstanceStub(this, assumptions, graalRuntime.getTarget()); - newArrayStub = new NewArrayStub(this, assumptions, graalRuntime.getTarget()); - newInstanceStub.install(backend); - newArrayStub.install(backend); + registerStub(new NewInstanceStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_INSTANCE))); + registerStub(new NewArrayStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_ARRAY))); + } + + private void registerStub(Stub stub) { + stub.getLinkage().setStub(stub); + stubs.put(stub.getMethod(), stub); } public HotSpotGraalRuntime getGraalRuntime() { @@ -827,8 +817,10 @@ } public HotSpotRuntimeCallTarget lookupRuntimeCall(Descriptor descriptor) { - assert runtimeCalls.containsKey(descriptor) : descriptor; - return runtimeCalls.get(descriptor); + HotSpotRuntimeCallTarget callTarget = runtimeCalls.get(descriptor); + assert runtimeCalls != null : descriptor; + callTarget.finalizeAddress(graalRuntime.getBackend()); + return callTarget; } public ResolvedJavaMethod lookupJavaMethod(Method reflectionMethod) { diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Thu Apr 04 16:58:59 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.hotspot.replacements; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.api.runtime.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.Node.IterableNodeType; import com.oracle.graal.loop.phases.*; @@ -31,7 +33,6 @@ import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; -import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.nodes.*; public class ArrayCopyNode extends MacroNode implements Virtualizable, IterableNodeType, Lowerable { @@ -60,7 +61,7 @@ return arguments.get(4); } - private StructuredGraph selectSnippet(LoweringTool tool) { + private StructuredGraph selectSnippet(LoweringTool tool, Replacements replacements) { ResolvedJavaType srcType = getSource().objectStamp().type(); ResolvedJavaType destType = getDestination().objectStamp().type(); @@ -72,7 +73,7 @@ } Kind componentKind = srcType.getComponentType().getKind(); ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(ArrayCopySnippets.getSnippetForKind(componentKind)); - return (StructuredGraph) snippetMethod.getCompilerStorage().get(Snippet.class); + return replacements.getSnippet(snippetMethod); } private static void unrollFixedLengthLoop(StructuredGraph snippetGraph, int length, LoweringTool tool) { @@ -93,12 +94,11 @@ return null; } - StructuredGraph snippetGraph = selectSnippet(tool); + Replacements replacements = Graal.getRequiredCapability(Replacements.class); + StructuredGraph snippetGraph = selectSnippet(tool, replacements); if (snippetGraph == null) { ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(ArrayCopySnippets.genericArraycopySnippet); - snippetGraph = ((StructuredGraph) snippetMethod.getCompilerStorage().get(Snippet.class)).copy(); - assert snippetGraph != null : "ArrayCopySnippets should be installed"; - + snippetGraph = replacements.getSnippet(snippetMethod).copy(); replaceSnippetInvokes(snippetGraph); } else { assert snippetGraph != null : "ArrayCopySnippets should be installed"; diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Thu Apr 04 16:58:59 2013 +0200 @@ -33,6 +33,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.meta.*; @@ -179,8 +180,8 @@ private final ResolvedJavaMethod secondary; private final ResolvedJavaMethod dynamic; - public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target) { - super(runtime, assumptions, target, CheckCastSnippets.class); + public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) { + super(runtime, replacements, target, CheckCastSnippets.class); exact = snippet("checkcastExact", Object.class, Word.class, boolean.class); primary = snippet("checkcastPrimary", Word.class, Object.class, boolean.class, int.class); secondary = snippet("checkcastSecondary", Word.class, Object.class, Word[].class, boolean.class); @@ -215,7 +216,7 @@ arguments = arguments("hub", hub).add("object", object).add("hints", hints); } - SnippetTemplate template = cache.get(key, assumptions); + SnippetTemplate template = cache.get(key); Debug.log("Lowering checkcast in %s: node=%s, template=%s, arguments=%s", graph, checkcast, template, arguments); template.instantiate(runtime, checkcast, DEFAULT_REPLACER, arguments); } @@ -232,7 +233,7 @@ Key key = new Key(dynamic).add("checkNull", checkNull); Arguments arguments = arguments("hub", hub).add("object", object); - SnippetTemplate template = cache.get(key, assumptions); + SnippetTemplate template = cache.get(key); Debug.log("Lowering dynamic checkcast in %s: node=%s, template=%s, arguments=%s", graph, checkcast, template, arguments); template.instantiate(runtime, checkcast, DEFAULT_REPLACER, arguments); } diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotInstalledCodeIntrinsics.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotInstalledCodeIntrinsics.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotInstalledCodeIntrinsics.java Thu Apr 04 16:58:59 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.hotspot.replacements; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.phases.*; import com.oracle.graal.replacements.*; @@ -30,9 +31,9 @@ public class HotSpotInstalledCodeIntrinsics implements ReplacementsProvider { @Override - public void installReplacements(ReplacementsInstaller installer) { + public void registerReplacements(Replacements replacements) { if (GraalOptions.IntrinsifyInstalledCodeMethods) { - installer.installSubstitutions(HotSpotInstalledCodeSubstitutions.class); + replacements.registerSubstitutions(HotSpotInstalledCodeSubstitutions.class); } } } diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Thu Apr 04 16:58:59 2013 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; @@ -170,8 +171,8 @@ private final ResolvedJavaMethod instanceofSecondary; private final ResolvedJavaMethod instanceofDynamic; - public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target) { - super(runtime, assumptions, target, InstanceOfSnippets.class); + public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) { + super(runtime, replacements, target, InstanceOfSnippets.class); instanceofExact = snippet("instanceofExact", Object.class, Word.class, Object.class, Object.class, boolean.class); instanceofPrimary = snippet("instanceofPrimary", Word.class, Object.class, Object.class, Object.class, boolean.class, int.class); instanceofSecondary = snippet("instanceofSecondary", Word.class, Object.class, Object.class, Object.class, Word[].class, boolean.class); diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Thu Apr 04 16:58:59 2013 +0200 @@ -34,6 +34,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.graph.iterators.*; @@ -410,8 +411,8 @@ private final ResolvedJavaMethod checkCounter; private final boolean useFastLocking; - public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target, boolean useFastLocking) { - super(runtime, assumptions, target, MonitorSnippets.class); + public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target, boolean useFastLocking) { + super(runtime, replacements, target, MonitorSnippets.class); monitorenter = snippet("monitorenter", Object.class, boolean.class, boolean.class); monitorexit = snippet("monitorexit", Object.class, boolean.class); monitorenterStub = snippet("monitorenterStub", Object.class, boolean.class, boolean.class); @@ -444,7 +445,7 @@ if (!eliminated) { arguments.add("object", monitorenterNode.object()); } - SnippetTemplate template = cache.get(key, assumptions); + SnippetTemplate template = cache.get(key); Map nodes = template.instantiate(runtime, monitorenterNode, DEFAULT_REPLACER, arguments); for (Node n : nodes.values()) { if (n instanceof BeginLockScopeNode) { @@ -470,7 +471,7 @@ if (!eliminated) { arguments.add("object", monitorexitNode.object()); } - SnippetTemplate template = cache.get(key, assumptions); + SnippetTemplate template = cache.get(key); Map nodes = template.instantiate(runtime, monitorexitNode, DEFAULT_REPLACER, arguments); for (Node n : nodes.values()) { if (n instanceof EndLockScopeNode) { @@ -526,7 +527,8 @@ InvokeNode invoke = graph.add(new InvokeNode(callTarget, 0)); invoke.setStateAfter(graph.start().stateAfter()); graph.addAfterFixed(graph.start(), invoke); - StructuredGraph inlineeGraph = (StructuredGraph) initCounter.getCompilerStorage().get(Snippet.class); + + StructuredGraph inlineeGraph = replacements.getSnippet(initCounter); InliningUtil.inline(invoke, inlineeGraph, false); List rets = graph.getNodes().filter(ReturnNode.class).snapshot(); @@ -540,7 +542,7 @@ FrameState stateAfter = new FrameState(graph.method(), FrameState.AFTER_BCI, new ValueNode[0], stack, new ValueNode[0], false, false); invoke.setStateAfter(graph.add(stateAfter)); graph.addBeforeFixed(ret, invoke); - inlineeGraph = (StructuredGraph) checkCounter.getCompilerStorage().get(Snippet.class); + inlineeGraph = replacements.getSnippet(checkCounter); InliningUtil.inline(invoke, inlineeGraph, false); } } diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Thu Apr 04 16:58:59 2013 +0200 @@ -34,6 +34,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.debug.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; @@ -234,8 +235,8 @@ private final TargetDescription target; private final boolean useTLAB; - public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target, boolean useTLAB) { - super(runtime, assumptions, target, NewObjectSnippets.class); + public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target, boolean useTLAB) { + super(runtime, replacements, target, NewObjectSnippets.class); this.target = target; this.useTLAB = useTLAB; allocate = snippet("allocate", int.class); @@ -303,7 +304,7 @@ Key key = new Key(allocateArrayAndInitialize).add("alignment", alignment).add("headerSize", headerSize).add("log2ElementSize", log2ElementSize).add("fillContents", newArrayNode.fillContents()).add("type", arrayType); Arguments arguments = new Arguments().add("length", lengthNode); - SnippetTemplate template = cache.get(key, assumptions); + SnippetTemplate template = cache.get(key); Debug.log("Lowering allocateArrayAndInitialize in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, arguments); template.instantiate(runtime, newArrayNode, DEFAULT_REPLACER, arguments); } @@ -315,7 +316,7 @@ ValueNode size = tlabAllocateNode.size(); Key key = new Key(allocate); Arguments arguments = arguments("size", size); - SnippetTemplate template = cache.get(key, assumptions); + SnippetTemplate template = cache.get(key); Debug.log("Lowering fastAllocate in %s: node=%s, template=%s, arguments=%s", graph, tlabAllocateNode, template, arguments); template.instantiate(runtime, tlabAllocateNode, DEFAULT_REPLACER, arguments); } @@ -330,7 +331,7 @@ Key key = new Key(initializeObject).add("size", size).add("fillContents", initializeNode.fillContents()).add("locked", initializeNode.locked()); ValueNode memory = initializeNode.memory(); Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeMarkWord", type.prototypeMarkWord()); - SnippetTemplate template = cache.get(key, assumptions); + SnippetTemplate template = cache.get(key); Debug.log("Lowering initializeObject in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments); template.instantiate(runtime, initializeNode, DEFAULT_REPLACER, arguments); } @@ -348,7 +349,7 @@ ValueNode memory = initializeNode.memory(); Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeMarkWord", type.prototypeMarkWord()).add("allocationSize", initializeNode.allocationSize()).add("length", initializeNode.length()); - SnippetTemplate template = cache.get(key, assumptions); + SnippetTemplate template = cache.get(key); Debug.log("Lowering initializeArray in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments); template.instantiate(runtime, initializeNode, DEFAULT_REPLACER, arguments); } @@ -365,7 +366,7 @@ ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph); Key key = new Key(newmultiarray).add("dimensions", vargargs(new int[rank], StampFactory.forKind(Kind.Int))).add("rank", rank); Arguments arguments = arguments("dimensions", dims).add("hub", hub); - SnippetTemplate template = cache.get(key, assumptions); + SnippetTemplate template = cache.get(key); template.instantiate(runtime, newmultiarrayNode, DEFAULT_REPLACER, arguments); } diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Thu Apr 04 16:58:59 2013 +0200 @@ -26,13 +26,14 @@ 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.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.*; -import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.nodes.*; public class ObjectCloneNode extends MacroNode implements VirtualizableAllocation, ArrayLengthProvider { @@ -70,7 +71,8 @@ method = ObjectCloneSnippets.instanceCloneMethod; } ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(method); - StructuredGraph snippetGraph = (StructuredGraph) snippetMethod.getCompilerStorage().get(Snippet.class); + Replacements replacements = Graal.getRequiredCapability(Replacements.class); + StructuredGraph snippetGraph = replacements.getSnippet(snippetMethod); assert snippetGraph != null : "ObjectCloneSnippets should be installed"; return snippetGraph; diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java Thu Apr 04 16:58:59 2013 +0200 @@ -28,7 +28,6 @@ import com.oracle.graal.api.replacements.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.replacements.*; import com.oracle.graal.word.*; /** diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java Thu Apr 04 16:58:59 2013 +0200 @@ -30,7 +30,6 @@ import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.replacements.*; /** * Substitutions for {@link java.lang.System} methods. diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Thu Apr 04 16:58:59 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.*; @@ -155,8 +156,8 @@ private final ResolvedJavaMethod g1PreWriteBarrier; private final ResolvedJavaMethod g1PostWriteBarrier; - public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target) { - super(runtime, assumptions, target, WriteBarrierSnippets.class); + public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) { + super(runtime, replacements, target, WriteBarrierSnippets.class); serialFieldWriteBarrier = snippet("serialFieldWriteBarrier", Object.class); serialArrayWriteBarrier = snippet("serialArrayWriteBarrier", Object.class, Object.class); g1PreWriteBarrier = snippet("g1PreWriteBarrier", Object.class, Object.class, Object.class, boolean.class); @@ -169,7 +170,7 @@ Arguments arguments = new Arguments(); arguments.add("object", arrayWriteBarrier.getObject()); arguments.add("location", arrayWriteBarrier.getLocation()); - SnippetTemplate template = cache.get(key, assumptions); + SnippetTemplate template = cache.get(key); template.instantiate(runtime, arrayWriteBarrier, DEFAULT_REPLACER, arguments); } @@ -178,7 +179,7 @@ Key key = new Key(method); Arguments arguments = new Arguments(); arguments.add("object", fieldWriteBarrier.getObject()); - SnippetTemplate template = cache.get(key, assumptions); + SnippetTemplate template = cache.get(key); template.instantiate(runtime, fieldWriteBarrier, DEFAULT_REPLACER, arguments); } @@ -190,7 +191,7 @@ arguments.add("object", writeBarrierPre.getObject()); arguments.add("expectedObject", writeBarrierPre.getExpectedObject()); arguments.add("location", writeBarrierPre.getLocation()); - SnippetTemplate template = cache.get(key, assumptions); + SnippetTemplate template = cache.get(key); template.instantiate(runtime, writeBarrierPre, DEFAULT_REPLACER, arguments); } @@ -202,7 +203,7 @@ arguments.add("object", writeBarrierPost.getObject()); arguments.add("location", writeBarrierPost.getLocation()); arguments.add("value", writeBarrierPost.getValue()); - SnippetTemplate template = cache.get(key, assumptions); + SnippetTemplate template = cache.get(key); template.instantiate(runtime, writeBarrierPost, DEFAULT_REPLACER, arguments); } diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java Thu Apr 04 16:58:59 2013 +0200 @@ -28,6 +28,8 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.replacements.*; @@ -44,8 +46,8 @@ */ public class NewArrayStub extends Stub { - public NewArrayStub(final HotSpotRuntime runtime, Assumptions assumptions, TargetDescription target) { - super(runtime, assumptions, target, NewArrayStubCall.NEW_ARRAY); + public NewArrayStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) { + super(runtime, replacements, target, linkage); } @Override diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Thu Apr 04 16:58:59 2013 +0200 @@ -23,18 +23,21 @@ package com.oracle.graal.hotspot.stubs; import static com.oracle.graal.hotspot.nodes.DirectCompareAndSwapNode.*; -import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*; import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*; import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.replacements.*; -import com.oracle.graal.replacements.Snippet.*; -import com.oracle.graal.replacements.SnippetTemplate.*; +import com.oracle.graal.replacements.Snippet.ConstantParameter; +import com.oracle.graal.replacements.Snippet.Fold; +import com.oracle.graal.replacements.Snippet.Parameter; +import com.oracle.graal.replacements.SnippetTemplate.Key; import com.oracle.graal.word.*; /** @@ -45,8 +48,8 @@ */ public class NewInstanceStub extends Stub { - public NewInstanceStub(final HotSpotRuntime runtime, Assumptions assumptions, TargetDescription target) { - super(runtime, assumptions, target, NEW_INSTANCE); + public NewInstanceStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) { + super(runtime, replacements, target, linkage); } @Override diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Thu Apr 04 16:58:59 2013 +0200 @@ -28,8 +28,8 @@ import java.util.concurrent.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; @@ -49,7 +49,7 @@ * snippet. A concrete stub is defined a subclass of this class. *

* Implementation detail: The stub classes re-use some of the functionality for {@link Snippet}s - * purely for convenience (e.g., can re-use the {@link ReplacementsInstaller}). + * purely for convenience (e.g., can re-use the {@link ReplacementsImpl}). */ public abstract class Stub extends AbstractTemplates implements Snippets { @@ -69,17 +69,17 @@ protected InstalledCode stubCode; /** - * Creates a new stub container. The new stub still needs to be {@linkplain #install(Backend) + * Creates a new stub container. The new stub still needs to be {@linkplain #getAddress(Backend) * installed}. * - * @param descriptor linkage details for a call to the stub + * @param linkage linkage details for a call to the stub */ @SuppressWarnings("unchecked") - public Stub(HotSpotRuntime runtime, Assumptions assumptions, TargetDescription target, Descriptor descriptor) { - super(runtime, assumptions, target, null); + public Stub(HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) { + super(runtime, replacements, target, null); stubMethod = findStubMethod(runtime, getClass()); - linkage = runtime.registerStub(descriptor, this); - assert linkage != null; + this.linkage = linkage; + } /** @@ -103,38 +103,41 @@ } /** - * Compiles the code for this stub, installs it and initializes the address used for calls to - * it. + * Ensures the code for this stub is installed. + * + * @return the entry point address for calls to this stub */ - public void install(Backend backend) { - StructuredGraph graph = (StructuredGraph) stubMethod.getCompilerStorage().get(Snippet.class); + public synchronized long getAddress(Backend backend) { + if (stubCode == null) { + StructuredGraph graph = replacements.getSnippet(stubMethod); - Key key = new Key(stubMethod); - populateKey(key); - SnippetTemplate template = cache.get(key, assumptions); - graph = template.copySpecializedGraph(); + Key key = new Key(stubMethod); + populateKey(key); + SnippetTemplate template = cache.get(key); + graph = template.copySpecializedGraph(); - PhasePlan phasePlan = new PhasePlan(); - GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); - phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); - final CompilationResult compResult = GraalCompiler.compileMethod(runtime(), backend, runtime().getTarget(), stubMethod, graph, null, phasePlan, OptimisticOptimizations.ALL, - new SpeculationLog()); + PhasePlan phasePlan = new PhasePlan(); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); + phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); + final CompilationResult compResult = GraalCompiler.compileMethod(runtime(), backend, runtime().getTarget(), stubMethod, graph, null, phasePlan, OptimisticOptimizations.ALL, + new SpeculationLog()); - stubCode = Debug.scope("CodeInstall", new Object[]{runtime(), stubMethod}, new Callable() { + stubCode = Debug.scope("CodeInstall", new Object[]{runtime(), stubMethod}, new Callable() { - @Override - public InstalledCode call() { - InstalledCode installedCode = runtime().addMethod(stubMethod, compResult); - assert installedCode != null : "error installing stub " + stubMethod; - if (Debug.isDumpEnabled()) { - Debug.dump(new Object[]{compResult, installedCode}, "After code installation"); + @Override + public InstalledCode call() { + InstalledCode installedCode = runtime().addMethod(stubMethod, compResult); + assert installedCode != null : "error installing stub " + stubMethod; + if (Debug.isDumpEnabled()) { + Debug.dump(new Object[]{compResult, installedCode}, "After code installation"); + } + return installedCode; } - return installedCode; - } - }); + }); - assert stubCode != null : "error installing stub " + stubMethod; - linkage.setAddress(stubCode.getStart()); + assert stubCode != null : "error installing stub " + stubMethod; + } + return stubCode.getStart(); } /** diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Thu Apr 04 16:58:59 2013 +0200 @@ -32,6 +32,7 @@ import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; import com.oracle.graal.api.meta.ResolvedJavaType.Representation; import com.oracle.graal.api.replacements.*; +import com.oracle.graal.api.runtime.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -1181,11 +1182,12 @@ } public static StructuredGraph getIntrinsicGraph(ResolvedJavaMethod target) { - return (StructuredGraph) target.getCompilerStorage().get(MethodSubstitution.class); + Replacements replacements = Graal.getRequiredCapability(Replacements.class); + return replacements.getMethodSubstitution(target); } public static Class getMacroNodeClass(ResolvedJavaMethod target) { - Object result = target.getCompilerStorage().get(Node.class); - return result == null ? null : ((Class) result).asSubclass(FixedWithNextNode.class); + Replacements replacements = Graal.getRequiredCapability(Replacements.class); + return replacements.getMacroSubstitution(target); } } diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java Thu Apr 04 16:58:59 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.debug.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -153,8 +154,8 @@ private final ResolvedJavaMethod d2i; private final ResolvedJavaMethod d2l; - public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target) { - super(runtime, assumptions, target, AMD64ConvertSnippets.class); + public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) { + super(runtime, replacements, target, AMD64ConvertSnippets.class); f2i = snippet("f2i", float.class, int.class); f2l = snippet("f2l", float.class, long.class); d2i = snippet("d2i", double.class, int.class); @@ -185,7 +186,7 @@ convert.replaceAtUsages(replacee); Key key = new Key(snippet); Arguments arguments = arguments("input", convert.value()).add("result", convert); - SnippetTemplate template = cache.get(key, assumptions); + SnippetTemplate template = cache.get(key); Debug.log("Lowering %s in %s: node=%s, template=%s, arguments=%s", convert.opcode, graph, convert, template, arguments); template.instantiate(runtime, replacee, DEFAULT_REPLACER, tool, arguments); } diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/PointerTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/PointerTest.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/PointerTest.java Thu Apr 04 16:58:59 2013 +0200 @@ -44,11 +44,11 @@ private static final Object ID = new Object(); private static final Kind[] KINDS = new Kind[]{Kind.Byte, Kind.Char, Kind.Short, Kind.Int, Kind.Long, Kind.Float, Kind.Double, Kind.Object}; private final TargetDescription target; - private final ReplacementsInstaller installer; + private final ReplacementsImpl installer; public PointerTest() { target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget(); - installer = new ReplacementsInstaller(runtime, new Assumptions(false), target); + installer = new ReplacementsImpl(runtime, new Assumptions(false), target); } private static final ThreadLocal inliningPolicy = new ThreadLocal<>(); @@ -56,7 +56,7 @@ @Override protected StructuredGraph parse(Method m) { ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m); - return installer.makeGraph(resolvedMethod, inliningPolicy.get()); + return installer.makeGraph(resolvedMethod, null, inliningPolicy.get()); } @Test diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/WordTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/WordTest.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/WordTest.java Thu Apr 04 16:58:59 2013 +0200 @@ -38,11 +38,11 @@ */ public class WordTest extends GraalCompilerTest implements Snippets { - private final ReplacementsInstaller installer; + private final ReplacementsImpl installer; public WordTest() { TargetDescription target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget(); - installer = new ReplacementsInstaller(runtime, new Assumptions(false), target); + installer = new ReplacementsImpl(runtime, new Assumptions(false), target); } private static final ThreadLocal inliningPolicy = new ThreadLocal<>(); @@ -50,7 +50,7 @@ @Override protected StructuredGraph parse(Method m) { ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m); - return installer.makeGraph(resolvedMethod, inliningPolicy.get()); + return installer.makeGraph(resolvedMethod, null, inliningPolicy.get()); } @LongTest diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java Thu Apr 04 16:58:59 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.replacements; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.phases.*; @@ -31,15 +32,15 @@ @ServiceProvider(ReplacementsProvider.class) public class GraalMethodSubstitutions implements ReplacementsProvider { - public void installReplacements(ReplacementsInstaller installer) { + public void registerReplacements(Replacements replacements) { if (GraalOptions.Intrinsify) { - installer.installSubstitutions(MathSubstitutionsX86.class); - installer.installSubstitutions(DoubleSubstitutions.class); - installer.installSubstitutions(FloatSubstitutions.class); - installer.installSubstitutions(NodeClassSubstitutions.class); - installer.installSubstitutions(LongSubstitutions.class); - installer.installSubstitutions(IntegerSubstitutions.class); - installer.installSubstitutions(UnsignedMathSubstitutions.class); + replacements.registerSubstitutions(MathSubstitutionsX86.class); + replacements.registerSubstitutions(DoubleSubstitutions.class); + replacements.registerSubstitutions(FloatSubstitutions.class); + replacements.registerSubstitutions(NodeClassSubstitutions.class); + replacements.registerSubstitutions(LongSubstitutions.class); + replacements.registerSubstitutions(IntegerSubstitutions.class); + replacements.registerSubstitutions(UnsignedMathSubstitutions.class); } } } diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Thu Apr 04 16:58:59 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -51,8 +52,8 @@ */ public abstract class InstanceOfSnippetsTemplates extends AbstractTemplates { - public InstanceOfSnippetsTemplates(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target, Class snippetsClass) { - super(runtime, assumptions, target, snippetsClass); + public InstanceOfSnippetsTemplates(MetaAccessProvider runtime, Replacements replacements, TargetDescription target, Class snippetsClass) { + super(runtime, replacements, target, snippetsClass); } /** @@ -91,7 +92,7 @@ replacer.replaceUsingInstantiation(); } else { KeyAndArguments keyAndArguments = getKeyAndArguments(replacer, tool); - SnippetTemplate template = cache.get(keyAndArguments.key, assumptions); + SnippetTemplate template = cache.get(keyAndArguments.key); template.instantiate(runtime, instanceOf, replacer, tool, keyAndArguments.arguments); } } diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MacroSubstitution.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MacroSubstitution.java Thu Apr 04 15:31:27 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +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.replacements; - -import java.lang.annotation.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.replacements.nodes.*; - -/** - * Denotes a macro substitute method. This replaces a method invocation with an instance of the - * specified node class. - * - * A macro substitution can be combined with a normal substitution, so that the macro node can be - * replaced with the actual substitution code during lowering. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface MacroSubstitution { - - /** - * Gets the name of the substituted method. - *

- * If the default value is specified for this element, then the name of the substituted method - * is same as the substitute method. - */ - String value() default ""; - - /** - * Determines if the substituted method is static. - */ - boolean isStatic() default true; - - /** - * Gets the {@linkplain MetaUtil#signatureToMethodDescriptor signature} of the substituted - * method. - *

- * If the default value is specified for this element, then the signature of the substituted - * method is the same as the substitute method. - */ - String signature() default ""; - - /** - * The node class with which the method invocation should be replaced. It needs to be a subclass - * of {@link FixedWithNextNode}, and it is expected to provide a public constructor that takes - * an InvokeNode as a parameter. For most cases this class should subclass {@link MacroNode} and - * use its constructor. - */ - Class macro(); -} diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Thu Apr 04 16:58:59 2013 +0200 @@ -0,0 +1,477 @@ +/* + * Copyright (c) 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.replacements; + +import static com.oracle.graal.api.meta.MetaUtil.*; + +import java.lang.reflect.*; +import java.util.*; +import java.util.concurrent.*; + +import sun.misc.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.java.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.replacements.Snippet.DefaultSnippetInliningPolicy; +import com.oracle.graal.replacements.Snippet.SnippetInliningPolicy; +import com.oracle.graal.word.phases.*; + +public class ReplacementsImpl implements Replacements { + + protected final MetaAccessProvider runtime; + protected final TargetDescription target; + protected final Assumptions assumptions; + + private BoxingMethodPool pool; + + /** + * The preprocessed replacement graphs. + */ + private final ConcurrentMap graphs; + + // These data structures are all fully initialized during single-threaded + // compiler startup and so do not need to be concurrent. + private final Map registeredMethodSubstitutions; + private final Set registeredSnippets; + private final Map> registerMacroSubstitutions; + + public ReplacementsImpl(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target) { + this.runtime = runtime; + this.target = target; + this.assumptions = assumptions; + this.graphs = new ConcurrentHashMap<>(); + this.registeredMethodSubstitutions = new HashMap<>(); + this.registeredSnippets = new HashSet<>(); + this.registerMacroSubstitutions = new HashMap<>(); + } + + public void registerSnippets(Class snippets) { + assert Snippets.class.isAssignableFrom(snippets); + for (Method method : snippets.getDeclaredMethods()) { + if (method.getAnnotation(Snippet.class) != null) { + int modifiers = method.getModifiers(); + if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { + throw new RuntimeException("Snippet must not be abstract or native"); + } + ResolvedJavaMethod snippet = runtime.lookupJavaMethod(method); + registeredSnippets.add(snippet); + } + } + } + + public StructuredGraph getSnippet(ResolvedJavaMethod method) { + if (!registeredSnippets.contains(method)) { + return null; + } + StructuredGraph graph = graphs.get(method); + if (graph == null) { + graphs.putIfAbsent(method, makeGraph(method, null, inliningPolicy(method))); + graph = graphs.get(method); + } + return graph; + + } + + public StructuredGraph getMethodSubstitution(ResolvedJavaMethod original) { + ResolvedJavaMethod substitute = registeredMethodSubstitutions.get(original); + if (substitute == null) { + return null; + } + StructuredGraph graph = graphs.get(substitute); + if (graph == null) { + graphs.putIfAbsent(substitute, makeGraph(substitute, original, inliningPolicy(substitute))); + graph = graphs.get(substitute); + } + return graph; + + } + + public Class getMacroSubstitution(ResolvedJavaMethod method) { + return registerMacroSubstitutions.get(method); + } + + public Assumptions getAssumptions() { + return assumptions; + } + + public void registerSubstitutions(Class substitutions) { + ClassSubstitution classSubstitution = substitutions.getAnnotation(ClassSubstitution.class); + assert classSubstitution != null; + assert !Snippets.class.isAssignableFrom(substitutions); + for (Method substituteMethod : substitutions.getDeclaredMethods()) { + MethodSubstitution methodSubstitution = substituteMethod.getAnnotation(MethodSubstitution.class); + MacroSubstitution macroSubstitution = substituteMethod.getAnnotation(MacroSubstitution.class); + if (methodSubstitution == null && macroSubstitution == null) { + continue; + } + + int modifiers = substituteMethod.getModifiers(); + if (!Modifier.isStatic(modifiers)) { + throw new RuntimeException("Substitution methods must be static: " + substituteMethod); + } + + if (methodSubstitution != null) { + if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { + throw new RuntimeException("Substitution method must not be abstract or native: " + substituteMethod); + } + String originalName = originalName(substituteMethod, methodSubstitution.value()); + Class[] originalParameters = originalParameters(substituteMethod, methodSubstitution.signature(), methodSubstitution.isStatic()); + Member originalMethod = originalMethod(classSubstitution, originalName, originalParameters); + if (originalMethod != null) { + registerMethodSubstitution(originalMethod, substituteMethod); + } + } + if (macroSubstitution != null) { + String originalName = originalName(substituteMethod, macroSubstitution.value()); + Class[] originalParameters = originalParameters(substituteMethod, macroSubstitution.signature(), macroSubstitution.isStatic()); + Member originalMethod = originalMethod(classSubstitution, originalName, originalParameters); + if (originalMethod != null) { + registerMacroSubstitution(originalMethod, macroSubstitution.macro()); + } + } + } + } + + /** + * Registers a method substitution. + * + * @param originalMember a method or constructor being substituted + * @param substituteMethod the substitute method + */ + protected void registerMethodSubstitution(Member originalMember, Method substituteMethod) { + ResolvedJavaMethod substitute = runtime.lookupJavaMethod(substituteMethod); + ResolvedJavaMethod original; + if (originalMember instanceof Method) { + original = runtime.lookupJavaMethod((Method) originalMember); + } else { + original = runtime.lookupJavaConstructor((Constructor) originalMember); + } + Debug.log("substitution: " + MetaUtil.format("%H.%n(%p)", original) + " --> " + MetaUtil.format("%H.%n(%p)", substitute)); + + registeredMethodSubstitutions.put(original, substitute); + } + + /** + * Registers a macro substitution. + * + * @param originalMethod a method or constructor being substituted + * @param macro the substitute macro node class + */ + protected void registerMacroSubstitution(Member originalMethod, Class macro) { + ResolvedJavaMethod originalJavaMethod; + if (originalMethod instanceof Method) { + originalJavaMethod = runtime.lookupJavaMethod((Method) originalMethod); + } else { + originalJavaMethod = runtime.lookupJavaConstructor((Constructor) originalMethod); + } + registerMacroSubstitutions.put(originalJavaMethod, macro); + } + + private SnippetInliningPolicy inliningPolicy(ResolvedJavaMethod method) { + Class policyClass = SnippetInliningPolicy.class; + Snippet snippet = method.getAnnotation(Snippet.class); + if (snippet != null) { + policyClass = snippet.inlining(); + } + if (policyClass == SnippetInliningPolicy.class) { + return new DefaultSnippetInliningPolicy(runtime, pool()); + } + try { + return policyClass.getConstructor().newInstance(); + } catch (Exception e) { + throw new GraalInternalError(e); + } + } + + /** + * Creates a preprocessed graph for a snippet or method substitution. + * + * @param method the snippet or method substitution for which a graph will be created + * @param original the original method if {@code method} is a {@linkplain MethodSubstitution + * substitution} otherwise null + * @param policy the inlining policy to use during preprocessing + */ + public StructuredGraph makeGraph(ResolvedJavaMethod method, ResolvedJavaMethod original, SnippetInliningPolicy policy) { + return createGraphMaker(method, original).makeGraph(policy); + } + + /** + * Can be overridden to return an object that specializes various parts of graph preprocessing. + */ + protected GraphMaker createGraphMaker(ResolvedJavaMethod substitute, ResolvedJavaMethod original) { + return new GraphMaker(substitute, original); + } + + /** + * Cache to speed up preprocessing of replacement graphs. + */ + final ConcurrentMap graphCache = new ConcurrentHashMap<>(); + + /** + * Creates and preprocesses a graph for a replacement. + */ + protected class GraphMaker { + + /** + * The method for which a graph is being created. + */ + protected final ResolvedJavaMethod method; + + /** + * The original method if {@link #method} is a {@linkplain MethodSubstitution substitution} + * otherwise null. + */ + protected final ResolvedJavaMethod original; + + boolean substituteCallsOriginal; + + protected GraphMaker(ResolvedJavaMethod substitute, ResolvedJavaMethod original) { + this.method = substitute; + this.original = original; + } + + public StructuredGraph makeGraph(final SnippetInliningPolicy policy) { + return Debug.scope("BuildSnippetGraph", new Object[]{method}, new Callable() { + + @Override + public StructuredGraph call() throws Exception { + StructuredGraph graph = parseGraph(method, policy); + + // Cannot have a finalized version of a graph in the cache + graph = graph.copy(); + + finalizeGraph(graph); + + Debug.dump(graph, "%s: Final", method.getName()); + + return graph; + } + }); + } + + /** + * Does final processing of a snippet graph. + */ + protected void finalizeGraph(StructuredGraph graph) { + new NodeIntrinsificationPhase(runtime, pool()).apply(graph); + assert SnippetTemplate.hasConstantParameter(method) || NodeIntrinsificationVerificationPhase.verify(graph); + + if (original == null) { + new SnippetFrameStateCleanupPhase().apply(graph); + new DeadCodeEliminationPhase().apply(graph); + new InsertStateAfterPlaceholderPhase().apply(graph); + } else { + new DeadCodeEliminationPhase().apply(graph); + } + } + + private StructuredGraph parseGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy) { + StructuredGraph graph = graphCache.get(methodToParse); + if (graph == null) { + graphCache.putIfAbsent(methodToParse, buildGraph(methodToParse, policy == null ? inliningPolicy(methodToParse) : policy)); + graph = graphCache.get(methodToParse); + assert graph != null; + } + return graph; + } + + /** + * Builds the initial graph for a snippet. + */ + protected StructuredGraph buildInitialGraph(final ResolvedJavaMethod methodToParse) { + final StructuredGraph graph = new StructuredGraph(methodToParse); + GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(); + GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, config, OptimisticOptimizations.NONE); + graphBuilder.apply(graph); + + Debug.dump(graph, "%s: %s", methodToParse.getName(), GraphBuilderPhase.class.getSimpleName()); + + new WordTypeVerificationPhase(runtime, target.wordKind).apply(graph); + new NodeIntrinsificationPhase(runtime, pool()).apply(graph); + + return graph; + } + + /** + * Called after a graph is inlined. + * + * @param caller the graph into which {@code callee} was inlined + * @param callee the graph that was inlined into {@code caller} + */ + protected void afterInline(StructuredGraph caller, StructuredGraph callee) { + if (GraalOptions.OptCanonicalizer) { + new WordTypeRewriterPhase(runtime, target.wordKind).apply(caller); + new CanonicalizerPhase(runtime, assumptions).apply(caller); + } + } + + /** + * Called after all inlining for a given graph is complete. + */ + protected void afterInlining(StructuredGraph graph) { + new NodeIntrinsificationPhase(runtime, pool()).apply(graph); + + new WordTypeRewriterPhase(runtime, target.wordKind).apply(graph); + + new DeadCodeEliminationPhase().apply(graph); + if (GraalOptions.OptCanonicalizer) { + new CanonicalizerPhase(runtime, assumptions).apply(graph); + } + } + + private StructuredGraph buildGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy) { + assert !Modifier.isAbstract(methodToParse.getModifiers()) && !Modifier.isNative(methodToParse.getModifiers()) : methodToParse; + final StructuredGraph graph = buildInitialGraph(methodToParse); + + for (Invoke invoke : graph.getInvokes()) { + MethodCallTargetNode callTarget = invoke.methodCallTarget(); + ResolvedJavaMethod callee = callTarget.targetMethod(); + if (callee == method) { + final StructuredGraph originalGraph = new StructuredGraph(original); + new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(originalGraph); + InliningUtil.inline(invoke, originalGraph, true); + + Debug.dump(graph, "after inlining %s", callee); + afterInline(graph, originalGraph); + substituteCallsOriginal = true; + } else { + if ((callTarget.invokeKind() == InvokeKind.Static || callTarget.invokeKind() == InvokeKind.Special) && policy.shouldInline(callee, methodToParse)) { + StructuredGraph targetGraph = parseGraph(callee, policy); + InliningUtil.inline(invoke, targetGraph, true); + Debug.dump(graph, "after inlining %s", callee); + afterInline(graph, targetGraph); + } + } + } + + afterInlining(graph); + + for (LoopEndNode end : graph.getNodes(LoopEndNode.class)) { + end.disableSafepoint(); + } + + if (GraalOptions.ProbabilityAnalysis) { + new DeadCodeEliminationPhase().apply(graph); + new ComputeProbabilityPhase().apply(graph); + } + return graph; + } + } + + private static String originalName(Method substituteMethod, String methodSubstitution) { + if (methodSubstitution.isEmpty()) { + return substituteMethod.getName(); + } else { + return methodSubstitution; + } + } + + /** + * Resolves a name to a class. + * + * @param className the name of the class to resolve + * @param optional if true, resolution failure returns null + * @return the resolved class or null if resolution fails and {@code optional} is true + */ + static Class resolveType(String className, boolean optional) { + try { + // Need to use launcher class path to handle classes + // that are not on the boot class path + ClassLoader cl = Launcher.getLauncher().getClassLoader(); + return Class.forName(className, false, cl); + } catch (ClassNotFoundException e) { + if (optional) { + return null; + } + throw new GraalInternalError("Could not resolve type " + className); + } + } + + private static Class resolveType(JavaType type) { + JavaType base = type; + int dimensions = 0; + while (base.getComponentType() != null) { + base = base.getComponentType(); + dimensions++; + } + + Class baseClass = base.getKind() != Kind.Object ? base.getKind().toJavaClass() : resolveType(toJavaName(base), false); + return dimensions == 0 ? baseClass : Array.newInstance(baseClass, new int[dimensions]).getClass(); + } + + private Class[] originalParameters(Method substituteMethod, String methodSubstitution, boolean isStatic) { + Class[] parameters; + if (methodSubstitution.isEmpty()) { + parameters = substituteMethod.getParameterTypes(); + if (!isStatic) { + assert parameters.length > 0 : "must be a static method with the 'this' object as its first parameter"; + parameters = Arrays.copyOfRange(parameters, 1, parameters.length); + } + } else { + Signature signature = runtime.parseMethodDescriptor(methodSubstitution); + parameters = new Class[signature.getParameterCount(false)]; + for (int i = 0; i < parameters.length; i++) { + parameters[i] = resolveType(signature.getParameterType(i, null)); + } + } + return parameters; + } + + private static Member originalMethod(ClassSubstitution classSubstitution, String name, Class[] parameters) { + Class originalClass = classSubstitution.value(); + if (originalClass == ClassSubstitution.class) { + originalClass = resolveType(classSubstitution.className(), classSubstitution.optional()); + if (originalClass == null) { + // optional class was not found + return null; + } + } + try { + if (name.equals("")) { + return originalClass.getDeclaredConstructor(parameters); + } else { + return originalClass.getDeclaredMethod(name, parameters); + } + } catch (NoSuchMethodException | SecurityException e) { + throw new GraalInternalError(e); + } + } + + protected BoxingMethodPool pool() { + if (pool == null) { + // A race to create the pool is ok + pool = new BoxingMethodPool(runtime); + } + return pool; + } +} diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsInstaller.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsInstaller.java Thu Apr 04 15:31:27 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,410 +0,0 @@ -/* - * Copyright (c) 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.replacements; - -import static com.oracle.graal.api.meta.MetaUtil.*; - -import java.lang.reflect.*; -import java.util.*; -import java.util.concurrent.*; - -import sun.misc.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.replacements.*; -import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.java.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; -import com.oracle.graal.phases.*; -import com.oracle.graal.phases.common.*; -import com.oracle.graal.replacements.Snippet.DefaultSnippetInliningPolicy; -import com.oracle.graal.replacements.Snippet.SnippetInliningPolicy; -import com.oracle.graal.word.phases.*; - -/** - * Utility for managing the pre-processing and installation of replacements. Replacements are either - * {@linkplain Snippets snippets}, {@linkplain MethodSubstitution method substitutions} or - * {@link MacroSubstitution macro substitutions}. - */ -public class ReplacementsInstaller { - - protected final MetaAccessProvider runtime; - protected final TargetDescription target; - protected final Assumptions assumptions; - protected final BoxingMethodPool pool; - private final Thread owner; - - /** - * A graph cache used by this installer to avoid using the compiler storage for each method - * processed during snippet installation. Without this, all processed methods are to be - * determined as {@linkplain InliningUtil#canIntrinsify intrinsifiable}. - */ - private final Map graphCache; - - public ReplacementsInstaller(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target) { - this.runtime = runtime; - this.target = target; - this.assumptions = assumptions; - this.pool = new BoxingMethodPool(runtime); - this.graphCache = new HashMap<>(); - this.owner = Thread.currentThread(); - } - - /** - * Finds all the snippet methods in a given class, builds a graph for them and installs the - * graph with the key value of {@code Snippet.class} in the - * {@linkplain ResolvedJavaMethod#getCompilerStorage() compiler storage} of each method. - */ - public void installSnippets(Class snippets) { - for (Method method : snippets.getDeclaredMethods()) { - if (method.getAnnotation(Snippet.class) != null) { - int modifiers = method.getModifiers(); - if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { - throw new RuntimeException("Snippet must not be abstract or native"); - } - ResolvedJavaMethod snippet = runtime.lookupJavaMethod(method); - assert snippet.getCompilerStorage().get(Snippet.class) == null : method; - StructuredGraph graph = makeGraph(snippet, inliningPolicy(snippet)); - // System.out.println("snippet: " + graph); - snippet.getCompilerStorage().put(Snippet.class, graph); - } - } - } - - /** - * Finds all the methods in a given class annotated with {@link MethodSubstitution} or - * {@link MacroSubstitution}. It builds graphs for the former and installs them in the - * {@linkplain ResolvedJavaMethod#getCompilerStorage() compiler storage} of the original (i.e., - * substituted) method with a key of {@code MethodSubstitution.class}. For the latter, the - * denoted {@linkplain MacroSubstitution#macro() macro} node type is install in the compiler - * storage with a key of {@code Node.class}. - */ - public void installSubstitutions(Class substitutions) { - assert owner == Thread.currentThread() : "substitution installation must be single threaded"; - ClassSubstitution classSubstitution = substitutions.getAnnotation(ClassSubstitution.class); - assert classSubstitution != null; - assert !Snippets.class.isAssignableFrom(substitutions); - for (Method substituteMethod : substitutions.getDeclaredMethods()) { - MethodSubstitution methodSubstitution = substituteMethod.getAnnotation(MethodSubstitution.class); - MacroSubstitution macroSubstitution = substituteMethod.getAnnotation(MacroSubstitution.class); - if (methodSubstitution == null && macroSubstitution == null) { - continue; - } - - int modifiers = substituteMethod.getModifiers(); - if (!Modifier.isStatic(modifiers)) { - throw new RuntimeException("Substitution methods must be static: " + substituteMethod); - } - - if (methodSubstitution != null) { - if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { - throw new RuntimeException("Substitution method must not be abstract or native: " + substituteMethod); - } - String originalName = originalName(substituteMethod, methodSubstitution.value()); - Class[] originalParameters = originalParameters(substituteMethod, methodSubstitution.signature(), methodSubstitution.isStatic()); - Member originalMethod = originalMethod(classSubstitution, originalName, originalParameters); - if (originalMethod != null) { - installMethodSubstitution(originalMethod, substituteMethod); - } - } - if (macroSubstitution != null) { - String originalName = originalName(substituteMethod, macroSubstitution.value()); - Class[] originalParameters = originalParameters(substituteMethod, macroSubstitution.signature(), macroSubstitution.isStatic()); - Member originalMethod = originalMethod(classSubstitution, originalName, originalParameters); - if (originalMethod != null) { - installMacroSubstitution(originalMethod, macroSubstitution.macro()); - } - } - } - } - - // These fields are used to detect calls from the substitute method to the original method. - ResolvedJavaMethod substitute; - ResolvedJavaMethod original; - boolean substituteCallsOriginal; - - /** - * Installs a method substitution. - * - * @param originalMember a method or constructor being substituted - * @param substituteMethod the substitute method - */ - protected void installMethodSubstitution(Member originalMember, Method substituteMethod) { - substitute = runtime.lookupJavaMethod(substituteMethod); - if (originalMember instanceof Method) { - original = runtime.lookupJavaMethod((Method) originalMember); - } else { - original = runtime.lookupJavaConstructor((Constructor) originalMember); - } - try { - Debug.log("substitution: " + MetaUtil.format("%H.%n(%p)", original) + " --> " + MetaUtil.format("%H.%n(%p)", substitute)); - StructuredGraph graph = makeGraph(substitute, inliningPolicy(substitute)); - Object oldValue = original.getCompilerStorage().put(MethodSubstitution.class, graph); - assert oldValue == null; - } finally { - substitute = null; - original = null; - substituteCallsOriginal = false; - } - } - - /** - * Installs a macro substitution. - * - * @param originalMethod a method or constructor being substituted - * @param macro the substitute macro node class - */ - protected void installMacroSubstitution(Member originalMethod, Class macro) { - ResolvedJavaMethod originalJavaMethod; - if (originalMethod instanceof Method) { - originalJavaMethod = runtime.lookupJavaMethod((Method) originalMethod); - } else { - originalJavaMethod = runtime.lookupJavaConstructor((Constructor) originalMethod); - } - Object oldValue = originalJavaMethod.getCompilerStorage().put(Node.class, macro); - assert oldValue == null; - } - - private SnippetInliningPolicy inliningPolicy(ResolvedJavaMethod method) { - Class policyClass = SnippetInliningPolicy.class; - Snippet snippet = method.getAnnotation(Snippet.class); - if (snippet != null) { - policyClass = snippet.inlining(); - } - if (policyClass == SnippetInliningPolicy.class) { - return new DefaultSnippetInliningPolicy(runtime, pool); - } - try { - return policyClass.getConstructor().newInstance(); - } catch (Exception e) { - throw new GraalInternalError(e); - } - } - - /** - * Does final processing of a snippet graph. - */ - protected void finalizeGraph(ResolvedJavaMethod method, StructuredGraph graph) { - new NodeIntrinsificationPhase(runtime, pool).apply(graph); - assert SnippetTemplate.hasConstantParameter(method) || NodeIntrinsificationVerificationPhase.verify(graph); - - if (substitute == null) { - new SnippetFrameStateCleanupPhase().apply(graph); - new DeadCodeEliminationPhase().apply(graph); - new InsertStateAfterPlaceholderPhase().apply(graph); - } else { - new DeadCodeEliminationPhase().apply(graph); - } - } - - public StructuredGraph makeGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy) { - return Debug.scope("BuildSnippetGraph", new Object[]{method}, new Callable() { - - @Override - public StructuredGraph call() throws Exception { - StructuredGraph graph = parseGraph(method, policy); - - finalizeGraph(method, graph); - - Debug.dump(graph, "%s: Final", method.getName()); - - return graph; - } - }); - } - - private StructuredGraph parseGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy) { - StructuredGraph graph = graphCache.get(method); - if (graph == null) { - graph = buildGraph(method, policy == null ? inliningPolicy(method) : policy); - graphCache.put(method, graph); - } - return graph; - } - - /** - * Builds the initial graph for a snippet. - */ - protected StructuredGraph buildInitialGraph(final ResolvedJavaMethod method) { - final StructuredGraph graph = new StructuredGraph(method); - GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(); - GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, config, OptimisticOptimizations.NONE); - graphBuilder.apply(graph); - - Debug.dump(graph, "%s: %s", method.getName(), GraphBuilderPhase.class.getSimpleName()); - - new WordTypeVerificationPhase(runtime, target.wordKind).apply(graph); - new NodeIntrinsificationPhase(runtime, pool).apply(graph); - - return graph; - } - - /** - * Called after a graph is inlined. - * - * @param caller the graph into which {@code callee} was inlined - * @param callee the graph that was inlined into {@code caller} - */ - protected void afterInline(StructuredGraph caller, StructuredGraph callee) { - if (GraalOptions.OptCanonicalizer) { - new WordTypeRewriterPhase(runtime, target.wordKind).apply(caller); - new CanonicalizerPhase(runtime, assumptions).apply(caller); - } - } - - /** - * Called after all inlining for a given graph is complete. - */ - protected void afterInlining(StructuredGraph graph) { - new NodeIntrinsificationPhase(runtime, pool).apply(graph); - - new WordTypeRewriterPhase(runtime, target.wordKind).apply(graph); - - new DeadCodeEliminationPhase().apply(graph); - if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase(runtime, assumptions).apply(graph); - } - } - - private StructuredGraph buildGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy) { - assert !Modifier.isAbstract(method.getModifiers()) && !Modifier.isNative(method.getModifiers()) : method; - final StructuredGraph graph = buildInitialGraph(method); - - for (Invoke invoke : graph.getInvokes()) { - MethodCallTargetNode callTarget = invoke.methodCallTarget(); - ResolvedJavaMethod callee = callTarget.targetMethod(); - if (callee == substitute) { - final StructuredGraph originalGraph = new StructuredGraph(original); - new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(originalGraph); - InliningUtil.inline(invoke, originalGraph, true); - - Debug.dump(graph, "after inlining %s", callee); - afterInline(graph, originalGraph); - substituteCallsOriginal = true; - } else { - if ((callTarget.invokeKind() == InvokeKind.Static || callTarget.invokeKind() == InvokeKind.Special) && policy.shouldInline(callee, method)) { - StructuredGraph targetGraph = parseGraph(callee, policy); - InliningUtil.inline(invoke, targetGraph, true); - Debug.dump(graph, "after inlining %s", callee); - afterInline(graph, targetGraph); - } - } - } - - afterInlining(graph); - - for (LoopEndNode end : graph.getNodes(LoopEndNode.class)) { - end.disableSafepoint(); - } - - if (GraalOptions.ProbabilityAnalysis) { - new DeadCodeEliminationPhase().apply(graph); - new ComputeProbabilityPhase().apply(graph); - } - return graph; - } - - private static String originalName(Method substituteMethod, String methodSubstitution) { - if (methodSubstitution.isEmpty()) { - return substituteMethod.getName(); - } else { - return methodSubstitution; - } - } - - /** - * Resolves a name to a class. - * - * @param className the name of the class to resolve - * @param optional if true, resolution failure returns null - * @return the resolved class or null if resolution fails and {@code optional} is true - */ - static Class resolveType(String className, boolean optional) { - try { - // Need to use launcher class path to handle classes - // that are not on the boot class path - ClassLoader cl = Launcher.getLauncher().getClassLoader(); - return Class.forName(className, false, cl); - } catch (ClassNotFoundException e) { - if (optional) { - return null; - } - throw new GraalInternalError("Could not resolve type " + className); - } - } - - private static Class resolveType(JavaType type) { - JavaType base = type; - int dimensions = 0; - while (base.getComponentType() != null) { - base = base.getComponentType(); - dimensions++; - } - - Class baseClass = base.getKind() != Kind.Object ? base.getKind().toJavaClass() : resolveType(toJavaName(base), false); - return dimensions == 0 ? baseClass : Array.newInstance(baseClass, new int[dimensions]).getClass(); - } - - private Class[] originalParameters(Method substituteMethod, String methodSubstitution, boolean isStatic) { - Class[] parameters; - if (methodSubstitution.isEmpty()) { - parameters = substituteMethod.getParameterTypes(); - if (!isStatic) { - assert parameters.length > 0 : "must be a static method with the 'this' object as its first parameter"; - parameters = Arrays.copyOfRange(parameters, 1, parameters.length); - } - } else { - Signature signature = runtime.parseMethodDescriptor(methodSubstitution); - parameters = new Class[signature.getParameterCount(false)]; - for (int i = 0; i < parameters.length; i++) { - parameters[i] = resolveType(signature.getParameterType(i, null)); - } - } - return parameters; - } - - private static Member originalMethod(ClassSubstitution classSubstitution, String name, Class[] parameters) { - Class originalClass = classSubstitution.value(); - if (originalClass == ClassSubstitution.class) { - originalClass = resolveType(classSubstitution.className(), classSubstitution.optional()); - if (originalClass == null) { - // optional class was not found - return null; - } - } - try { - if (name.equals("")) { - return originalClass.getDeclaredConstructor(parameters); - } else { - return originalClass.getDeclaredMethod(name, parameters); - } - } catch (NoSuchMethodException | SecurityException e) { - throw new GraalInternalError(e); - } - } -} diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsProvider.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsProvider.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsProvider.java Thu Apr 04 16:58:59 2013 +0200 @@ -22,10 +22,12 @@ */ package com.oracle.graal.replacements; +import com.oracle.graal.api.replacements.*; + /** - * Interface for service providers that install replacements into the compiler. + * Interface for service providers that register replacements with the compiler. */ public interface ReplacementsProvider { - void installReplacements(ReplacementsInstaller installer); + void registerReplacements(Replacements replacements); } diff -r b6491ee579d3 -r 54a373881da6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Thu Apr 04 15:31:27 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Thu Apr 04 16:58:59 2013 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.loop.*; @@ -41,7 +42,6 @@ import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.replacements.Snippet.*; -import com.oracle.graal.replacements.Snippet.Parameter; import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.word.*; import com.oracle.graal.word.phases.*; @@ -158,23 +158,25 @@ private final ConcurrentHashMap templates = new ConcurrentHashMap<>(); private final MetaAccessProvider runtime; private final TargetDescription target; + private final Replacements replacements; - public Cache(MetaAccessProvider runtime, TargetDescription target) { + public Cache(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) { this.runtime = runtime; + this.replacements = replacements; this.target = target; } /** * Gets a template for a given key, creating it first if necessary. */ - public SnippetTemplate get(final SnippetTemplate.Key key, final Assumptions assumptions) { + public SnippetTemplate get(final SnippetTemplate.Key key) { SnippetTemplate template = templates.get(key); if (template == null) { template = Debug.scope("SnippetSpecialization", key.method, new Callable() { @Override public SnippetTemplate call() throws Exception { - return new SnippetTemplate(runtime, assumptions, target, key); + return new SnippetTemplate(runtime, replacements, target, key); } }); // System.out.println(key + " -> " + template); @@ -188,19 +190,19 @@ protected final Cache cache; protected final MetaAccessProvider runtime; - protected final Assumptions assumptions; + protected final Replacements replacements; protected Class snippetsClass; - public AbstractTemplates(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target, Class snippetsClass) { + public AbstractTemplates(MetaAccessProvider runtime, Replacements replacements, TargetDescription target, Class snippetsClass) { this.runtime = runtime; - this.assumptions = assumptions; + this.replacements = replacements; if (snippetsClass == null) { assert this instanceof Snippets; this.snippetsClass = getClass(); } else { this.snippetsClass = snippetsClass; } - this.cache = new Cache(runtime, target); + this.cache = new Cache(runtime, replacements, target); } protected ResolvedJavaMethod snippet(String name, Class... parameterTypes) { @@ -231,16 +233,16 @@ /** * Creates a snippet template. */ - public SnippetTemplate(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target, SnippetTemplate.Key key) { + public SnippetTemplate(MetaAccessProvider runtime, Replacements replacements, TargetDescription target, SnippetTemplate.Key key) { ResolvedJavaMethod method = key.method; assert Modifier.isStatic(method.getModifiers()) : "snippet method must be static: " + method; Signature signature = method.getSignature(); // Copy snippet graph, replacing constant parameters with given arguments - StructuredGraph snippetGraph = (StructuredGraph) method.getCompilerStorage().get(Snippet.class); + StructuredGraph snippetGraph = replacements.getSnippet(method); StructuredGraph snippetCopy = new StructuredGraph(snippetGraph.name, snippetGraph.method()); - IdentityHashMap replacements = new IdentityHashMap<>(); - replacements.put(snippetGraph.start(), snippetCopy.start()); + IdentityHashMap nodeReplacements = new IdentityHashMap<>(); + nodeReplacements.put(snippetGraph.start(), snippetCopy.start()); int parameterCount = signature.getParameterCount(false); assert checkTemplate(runtime, key, parameterCount, method, signature); @@ -260,7 +262,7 @@ } else { constantArg = Constant.forBoxed(kind, arg); } - replacements.put(snippetGraph.getLocal(i), ConstantNode.forConstant(constantArg, runtime, snippetCopy)); + nodeReplacements.put(snippetGraph.getLocal(i), ConstantNode.forConstant(constantArg, runtime, snippetCopy)); } else { VarargsParameter vp = MetaUtil.getParameterAnnotation(VarargsParameter.class, i, method); if (vp != null) { @@ -268,7 +270,7 @@ Varargs varargs = (Varargs) key.get(name); Object array = varargs.getArray(); ConstantNode placeholder = ConstantNode.forObject(array, runtime, snippetCopy); - replacements.put(snippetGraph.getLocal(i), placeholder); + nodeReplacements.put(snippetGraph.getLocal(i), placeholder); placeholders[i] = placeholder; varargsParameterAnnotations[i] = vp; } else { @@ -276,15 +278,15 @@ } } } - snippetCopy.addDuplicates(snippetGraph.getNodes(), replacements); + snippetCopy.addDuplicates(snippetGraph.getNodes(), nodeReplacements); Debug.dump(snippetCopy, "Before specialization"); - if (!replacements.isEmpty()) { + if (!nodeReplacements.isEmpty()) { // Do deferred intrinsification of node intrinsics new NodeIntrinsificationPhase(runtime, new BoxingMethodPool(runtime)).apply(snippetCopy); new WordTypeRewriterPhase(runtime, target.wordKind).apply(snippetCopy); - new CanonicalizerPhase(runtime, assumptions, 0, null).apply(snippetCopy); + new CanonicalizerPhase(runtime, replacements.getAssumptions(), 0, null).apply(snippetCopy); } assert NodeIntrinsificationVerificationPhase.verify(snippetCopy); @@ -344,7 +346,7 @@ LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin); int mark = snippetCopy.getMark(); LoopTransformations.fullUnroll(loop, runtime, null); - new CanonicalizerPhase(runtime, assumptions, mark, null).apply(snippetCopy); + new CanonicalizerPhase(runtime, replacements.getAssumptions(), mark, null).apply(snippetCopy); } FixedNode explodeLoopNext = explodeLoop.next(); explodeLoop.clearSuccessors(); diff -r b6491ee579d3 -r 54a373881da6 make/build-graal.xml --- a/make/build-graal.xml Thu Apr 04 15:31:27 2013 +0200 +++ b/make/build-graal.xml Thu Apr 04 16:58:59 2013 +0200 @@ -39,6 +39,7 @@ + @@ -49,7 +50,6 @@ - diff -r b6491ee579d3 -r 54a373881da6 mx/projects --- a/mx/projects Thu Apr 04 15:31:27 2013 +0200 +++ b/mx/projects Thu Apr 04 16:58:59 2013 +0200 @@ -61,7 +61,7 @@ # graal.api.replacements project@com.oracle.graal.api.replacements@subDir=graal project@com.oracle.graal.api.replacements@sourceDirs=src -project@com.oracle.graal.api.replacements@dependencies=com.oracle.graal.api.meta +project@com.oracle.graal.api.replacements@dependencies=com.oracle.graal.nodes project@com.oracle.graal.api.replacements@checkstyle=com.oracle.graal.graph project@com.oracle.graal.api.replacements@javaCompliance=1.7 @@ -200,7 +200,7 @@ # graal.replacements project@com.oracle.graal.replacements@subDir=graal project@com.oracle.graal.replacements@sourceDirs=src -project@com.oracle.graal.replacements@dependencies=com.oracle.graal.compiler,com.oracle.graal.java,com.oracle.graal.word,com.oracle.graal.api.runtime +project@com.oracle.graal.replacements@dependencies=com.oracle.graal.compiler,com.oracle.graal.java,com.oracle.graal.word project@com.oracle.graal.replacements@checkstyle=com.oracle.graal.graph project@com.oracle.graal.replacements@javaCompliance=1.7 project@com.oracle.graal.replacements@annotationProcessors=com.oracle.graal.replacements.verifier,com.oracle.graal.service.processor @@ -243,7 +243,7 @@ # graal.phases.common project@com.oracle.graal.phases.common@subDir=graal project@com.oracle.graal.phases.common@sourceDirs=src -project@com.oracle.graal.phases.common@dependencies=com.oracle.graal.phases,com.oracle.graal.api.replacements +project@com.oracle.graal.phases.common@dependencies=com.oracle.graal.phases,com.oracle.graal.api.replacements,com.oracle.graal.api.runtime project@com.oracle.graal.phases.common@checkstyle=com.oracle.graal.graph project@com.oracle.graal.phases.common@javaCompliance=1.7 @@ -333,7 +333,7 @@ # graal.compiler.test project@com.oracle.graal.compiler.test@subDir=graal project@com.oracle.graal.compiler.test@sourceDirs=src -project@com.oracle.graal.compiler.test@dependencies=com.oracle.graal.api.runtime,com.oracle.graal.printer,com.oracle.graal.test +project@com.oracle.graal.compiler.test@dependencies=com.oracle.graal.printer,com.oracle.graal.test project@com.oracle.graal.compiler.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.compiler.test@javaCompliance=1.7 diff -r b6491ee579d3 -r 54a373881da6 mxtool/mx.py --- a/mxtool/mx.py Thu Apr 04 15:31:27 2013 +0200 +++ b/mxtool/mx.py Thu Apr 04 16:58:59 2013 +0200 @@ -663,12 +663,14 @@ def element(self, tag, attributes={}, data=None): return self.open(tag, attributes, data).close(tag) - def xml(self, indent='', newl='', escape=False): + def xml(self, indent='', newl='', escape=False, standalone=None): assert self.current == self result = self.toprettyxml(indent, newl, encoding="UTF-8") if escape: entities = { '"': """, "'": "'", '\n': ' ' } result = xml.sax.saxutils.escape(result, entities) + if standalone is not None: + result = result.replace('encoding="UTF-8"?>', 'encoding="UTF-8" standalone="' + str(standalone) + '"?>') return result def get_os(): @@ -1977,16 +1979,16 @@ slm.open('sourceContainers', {'duplicates' : 'false'}) # Every Java program depends on the JRE - memento = XMLDoc().element('classpathContainer', {'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER'}).xml() + memento = XMLDoc().element('classpathContainer', {'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER'}).xml(standalone='no') slm.element('classpathContainer', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.classpathContainer'}) for dep in deps: if dep.isLibrary(): if hasattr(dep, 'eclipse.container'): - memento = XMLDoc().element('classpathContainer', {'path' : getattr(dep, 'eclipse.container')}).xml() + memento = XMLDoc().element('classpathContainer', {'path' : getattr(dep, 'eclipse.container')}).xml(standalone='no') slm.element('classpathContainer', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.classpathContainer'}) else: - memento = XMLDoc().element('javaProject', {'name' : dep.name}).xml() + memento = XMLDoc().element('javaProject', {'name' : dep.name}).xml(standalone='no') slm.element('container', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.javaProject'}) slm.close('sourceContainers') @@ -2010,7 +2012,7 @@ launch.element('stringAttribute', {'key' : 'org.eclipse.jdt.launching.PROJECT_ATTR', 'value' : ''}) launch.element('stringAttribute', {'key' : 'org.eclipse.jdt.launching.VM_CONNECTOR_ID', 'value' : 'org.eclipse.jdt.launching.socketAttachConnector'}) launch.close('launchConfiguration') - launch = launch.xml(newl='\n') % slm.xml(escape=True) + launch = launch.xml(newl='\n', standalone='no') % slm.xml(escape=True, standalone='no') if name is None: name = 'attach-' + hostname + '-' + port @@ -2077,7 +2079,7 @@ launch.element('stringAttribute', {'key' : 'org.eclipse.jdt.launching.PROJECT_ATTR', 'value' : ''}) launch.element('stringAttribute', {'key' : 'org.eclipse.jdt.launching.VM_ARGUMENTS', 'value' : ' '.join(vmArgs)}) launch.close('launchConfiguration') - launch = launch.xml(newl='\n') % slm.xml(escape=True) + launch = launch.xml(newl='\n', standalone='no') % slm.xml(escape=True, standalone='no') eclipseLaunches = join('mx', 'eclipse-launches') if not exists(eclipseLaunches): @@ -2214,7 +2216,7 @@ out.close('buildCommand') if _isAnnotationProcessorDependency(p): - _genEclipseBuilder(out, p, 'Jar.launch', 'archive ' + p.name, refresh = False, async = False) + _genEclipseBuilder(out, p, 'Jar.launch', 'archive ' + p.name, refresh = False, async = False, xmlIndent='', xmlStandalone='no') _genEclipseBuilder(out, p, 'Refresh.launch', '', refresh = True, async = True) if projToDist.has_key(p.name): @@ -2296,10 +2298,11 @@ return False -def _genEclipseBuilder(dotProjectDoc, p, name, mxCommand, refresh=True, async=False, logToConsole=False): +def _genEclipseBuilder(dotProjectDoc, p, name, mxCommand, refresh=True, async=False, logToConsole=False, xmlIndent='\t', xmlStandalone=None): launchOut = XMLDoc(); consoleOn = 'true' if logToConsole else 'false' launchOut.open('launchConfiguration', {'type' : 'org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType'}) + launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.core.capture_output', 'value': consoleOn}) launchOut.open('mapAttribute', {'key' : 'org.eclipse.debug.core.environmentVariables'}) launchOut.element('mapEntry', {'key' : 'JAVA_HOME', 'value' : java().jdk}) launchOut.close('mapAttribute') @@ -2307,9 +2310,7 @@ if refresh: launchOut.element('stringAttribute', {'key' : 'org.eclipse.debug.core.ATTR_REFRESH_SCOPE', 'value': '${project}'}) launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON', 'value': consoleOn}) - launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.core.capture_output', 'value': consoleOn}) - if async: - launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND', 'value': 'true'}) + launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND', 'value': 'true' if async else 'false'}) baseDir = dirname(dirname(os.path.abspath(__file__))) @@ -2329,7 +2330,7 @@ if not exists(externalToolDir): os.makedirs(externalToolDir) - update_file(join(externalToolDir, name), launchOut.xml(indent='\t', newl='\n')) + update_file(join(externalToolDir, name), launchOut.xml(indent=xmlIndent, standalone=xmlStandalone, newl='\n')) dotProjectDoc.open('buildCommand') dotProjectDoc.element('name', data='org.eclipse.ui.externaltools.ExternalToolBuilder')