changeset 9617:c1ef2bf6848e

removed the requirement that a compiled stub is implemented by a snippet
author Doug Simon <doug.simon@oracle.com>
date Wed, 08 May 2013 20:12:12 +0200
parents ff62d13ad3e7
children bd4a7d657dcc
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/CRuntimeStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java
diffstat 6 files changed, 131 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java	Wed May 08 18:22:58 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java	Wed May 08 20:12:12 2013 +0200
@@ -74,7 +74,7 @@
 
     @Override
     public String toString() {
-        return (stub == null ? descriptor.toString() : MetaUtil.format("%h.%n", stub.getMethod())) + "@0x" + Long.toHexString(address) + ":" + cc;
+        return (stub == null ? descriptor.toString() : stub) + "@0x" + Long.toHexString(address) + ":" + cc;
     }
 
     public CallingConvention getCallingConvention() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/CRuntimeStub.java	Wed May 08 18:22:58 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/CRuntimeStub.java	Wed May 08 20:12:12 2013 +0200
@@ -32,7 +32,7 @@
 /**
  * Base class for a stub that saves registers around a C runtime call.
  */
-public abstract class CRuntimeStub extends Stub {
+public abstract class CRuntimeStub extends SnippetStub {
 
     public CRuntimeStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) {
         super(runtime, replacements, target, linkage);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Wed May 08 18:22:58 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Wed May 08 20:12:12 2013 +0200
@@ -50,7 +50,7 @@
  * code when TLAB allocation fails. If this stub fails to refill the TLAB or allocate the object, it
  * calls out to the HotSpot C++ runtime to complete the allocation.
  */
-public class NewArrayStub extends Stub {
+public class NewArrayStub extends SnippetStub {
 
     public NewArrayStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) {
         super(runtime, replacements, target, linkage);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Wed May 08 18:22:58 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Wed May 08 20:12:12 2013 +0200
@@ -52,7 +52,7 @@
  * code when TLAB allocation fails. If this stub fails to refill the TLAB or allocate the object, it
  * calls out to the HotSpot C++ runtime for to complete the allocation.
  */
-public class NewInstanceStub extends Stub {
+public class NewInstanceStub extends SnippetStub {
 
     public NewInstanceStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) {
         super(runtime, replacements, target, linkage);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Wed May 08 20:12:12 2013 +0200
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.stubs;
+
+import static com.oracle.graal.api.meta.MetaUtil.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.replacements.Snippet.ConstantParameter;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
+import com.oracle.graal.replacements.SnippetTemplate.Arguments;
+import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo;
+
+/**
+ * Base class for a stub defined by a snippet.
+ */
+public abstract class SnippetStub extends Stub implements Snippets {
+
+    static class Template extends AbstractTemplates {
+
+        Template(HotSpotRuntime runtime, Replacements replacements, TargetDescription target, Class<? extends Snippets> declaringClass) {
+            super(runtime, replacements, target);
+            this.info = snippet(declaringClass, null);
+        }
+
+        /**
+         * Info for the method implementing the stub.
+         */
+        protected final SnippetInfo info;
+
+        protected StructuredGraph getGraph(Arguments args) {
+            SnippetTemplate template = template(args);
+            return template.copySpecializedGraph();
+        }
+    }
+
+    protected final Template snippet;
+
+    /**
+     * Creates a new snippet stub.
+     * 
+     * @param linkage linkage details for a call to the stub
+     */
+    public SnippetStub(HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) {
+        super(runtime, replacements, linkage);
+        this.snippet = new Template(runtime, replacements, target, getClass());
+    }
+
+    @Override
+    protected StructuredGraph getGraph() {
+        return snippet.getGraph(makeArguments(snippet.info));
+    }
+
+    /**
+     * Adds the {@linkplain ConstantParameter constant} arguments of this stub.
+     */
+    protected abstract Arguments makeArguments(SnippetInfo stub);
+
+    @Override
+    public ResolvedJavaMethod getInstallationMethod() {
+        return snippet.info.getMethod();
+    }
+
+    @Override
+    public String toString() {
+        return format("%h.%n", getInstallationMethod());
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Wed May 08 18:22:58 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Wed May 08 20:12:12 2013 +0200
@@ -24,7 +24,6 @@
 
 import static com.oracle.graal.api.code.DeoptimizationAction.*;
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
-import static com.oracle.graal.api.meta.MetaUtil.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.nodes.CStringNode.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
@@ -55,29 +54,17 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.replacements.*;
-import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.Fold;
-import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
-import com.oracle.graal.replacements.SnippetTemplate.Arguments;
-import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo;
 import com.oracle.graal.word.*;
 
 //JaCoCo Exclude
 
 /**
- * Base class for implementing some low level code providing the out-of-line slow path for a
- * snippet. A stub may make a direct call to a HotSpot C/C++ runtime function. Stubs are installed
- * as an instance of the C++ RuntimeStub class (as opposed to nmethod).
- * <p>
- * 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 ReplacementsImpl}).
+ * Base class for implementing some low level code providing the out-of-line slow path for a snippet
+ * and/or a callee saved call to a HotSpot C/C++ runtime function or even a another compiled Java
+ * method.
  */
-public abstract class Stub extends AbstractTemplates implements Snippets {
-
-    /**
-     * The method implementing the stub.
-     */
-    protected final SnippetInfo stubInfo;
+public abstract class Stub {
 
     /**
      * The linkage information for the stub.
@@ -117,31 +104,19 @@
         return true;
     }
 
+    protected final HotSpotRuntime runtime;
+
+    protected final Replacements replacements;
+
     /**
-     * Creates a new stub container..
+     * Creates a new stub.
      * 
      * @param linkage linkage details for a call to the stub
      */
-    public Stub(HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) {
-        super(runtime, replacements, target);
-        this.stubInfo = snippet(getClass(), null);
+    public Stub(HotSpotRuntime runtime, Replacements replacements, HotSpotRuntimeCallTarget linkage) {
         this.linkage = linkage;
-    }
-
-    /**
-     * Adds the {@linkplain ConstantParameter constant} arguments of this stub.
-     */
-    protected abstract Arguments makeArguments(SnippetInfo stub);
-
-    protected HotSpotRuntime runtime() {
-        return (HotSpotRuntime) runtime;
-    }
-
-    /**
-     * Gets the method implementing this stub.
-     */
-    public ResolvedJavaMethod getMethod() {
-        return stubInfo.getMethod();
+        this.runtime = runtime;
+        this.replacements = replacements;
     }
 
     public HotSpotRuntimeCallTarget getLinkage() {
@@ -154,16 +129,15 @@
     private boolean checkStubInvariants(CompilationResult compResult) {
         for (DataPatch data : compResult.getDataReferences()) {
             Constant constant = data.constant;
-            assert constant.getKind() != Kind.Object : format("%h.%n(%p): ", getMethod()) + "cannot have embedded object constant: " + constant;
-            assert constant.getPrimitiveAnnotation() == null : format("%h.%n(%p): ", getMethod()) + "cannot have embedded metadata: " + constant;
+            assert constant.getKind() != Kind.Object : this + " cannot have embedded object constant: " + constant;
+            assert constant.getPrimitiveAnnotation() == null : this + " cannot have embedded metadata: " + constant;
         }
         for (Infopoint infopoint : compResult.getInfopoints()) {
-            assert infopoint instanceof Call : format("%h.%n(%p): ", getMethod()) + "cannot have non-call infopoint: " + infopoint;
+            assert infopoint instanceof Call : this + " cannot have non-call infopoint: " + infopoint;
             Call call = (Call) infopoint;
-            assert call.target instanceof HotSpotRuntimeCallTarget : format("%h.%n(%p): ", getMethod()) + "cannot have non runtime call: " + call.target;
+            assert call.target instanceof HotSpotRuntimeCallTarget : this + " cannot have non runtime call: " + call.target;
             HotSpotRuntimeCallTarget callTarget = (HotSpotRuntimeCallTarget) call.target;
-            assert callTarget.getAddress() == graalRuntime().getConfig().uncommonTrapStub || callTarget.isCRuntimeCall() : format("%h.%n(%p): ", getMethod()) +
-                            "must only call C runtime or deoptimization stub, not " + call.target;
+            assert callTarget.getAddress() == graalRuntime().getConfig().uncommonTrapStub || callTarget.isCRuntimeCall() : this + "must only call C runtime or deoptimization stub, not " + call.target;
         }
         return true;
     }
@@ -190,20 +164,28 @@
         return new Descriptor(name, hasSideEffect, found.getReturnType(), cCallTypes);
     }
 
+    protected abstract StructuredGraph getGraph();
+
+    @Override
+    public abstract String toString();
+
+    /**
+     * Gets the method under which the compiled code for this stub is
+     * {@linkplain CodeCacheProvider#addMethod(ResolvedJavaMethod, CompilationResult) installed}.
+     */
+    protected abstract ResolvedJavaMethod getInstallationMethod();
+
     /**
      * Gets the code for this stub, compiling it first if necessary.
      */
     public synchronized InstalledCode getCode(final Backend backend) {
         if (code == null) {
-            Debug.sandbox("CompilingStub", new Object[]{runtime(), getMethod()}, DebugScope.getConfig(), new Runnable() {
+            final StructuredGraph graph = getGraph();
+            Debug.sandbox("CompilingStub", new Object[]{runtime, graph}, DebugScope.getConfig(), new Runnable() {
 
                 @Override
                 public void run() {
 
-                    Arguments args = makeArguments(stubInfo);
-                    SnippetTemplate template = template(args);
-                    StructuredGraph graph = template.copySpecializedGraph();
-
                     StubStartNode newStart = graph.add(new StubStartNode(Stub.this));
                     newStart.setStateAfter(graph.start().stateAfter());
                     graph.replaceFixed(graph.start(), newStart);
@@ -213,7 +195,7 @@
                     GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
                     phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
                     CallingConvention cc = linkage.getCallingConvention();
-                    final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, runtime(), replacements, backend, runtime().getTarget(), null, phasePlan, OptimisticOptimizations.ALL,
+                    final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, runtime, replacements, backend, runtime.getTarget(), null, phasePlan, OptimisticOptimizations.ALL,
                                     new SpeculationLog());
 
                     assert checkStubInvariants(compResult);
@@ -223,8 +205,8 @@
 
                         @Override
                         public InstalledCode call() {
-                            InstalledCode installedCode = runtime().addMethod(getMethod(), compResult);
-                            assert installedCode != null : "error installing stub " + getMethod();
+                            InstalledCode installedCode = runtime.addMethod(getInstallationMethod(), compResult);
+                            assert installedCode != null : "error installing stub " + this;
                             if (Debug.isDumpEnabled()) {
                                 Debug.dump(new Object[]{compResult, installedCode}, "After code installation");
                             }
@@ -235,7 +217,7 @@
                     });
                 }
             });
-            assert code != null : "error installing stub " + getMethod();
+            assert code != null : "error installing stub " + this;
         }
         return code;
     }