changeset 9452:c1ba734c1ea0

more extensive checking of compiled stub invariants
author Doug Simon <doug.simon@oracle.com>
date Tue, 30 Apr 2013 19:11:46 +0200
parents 3ccda80d466b
children cdc839f22a23
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java
diffstat 2 files changed, 26 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java	Tue Apr 30 19:11:14 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java	Tue Apr 30 19:11:46 2013 +0200
@@ -111,6 +111,11 @@
         }
     }
 
+    public long getAddress() {
+        assert address != 0L : "address not yet finalized: " + this;
+        return address;
+    }
+
     @Override
     public boolean preservesRegisters() {
         assert address != 0;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Tue Apr 30 19:11:14 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Tue Apr 30 19:11:46 2013 +0200
@@ -24,6 +24,8 @@
 
 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.HotSpotSnippetUtils.*;
 
@@ -32,7 +34,9 @@
 import java.util.concurrent.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CompilationResult.Call;
 import com.oracle.graal.api.code.CompilationResult.DataPatch;
+import com.oracle.graal.api.code.CompilationResult.Infopoint;
 import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
@@ -61,7 +65,8 @@
 
 /**
  * Base class for implementing some low level code providing the out-of-line slow path for a
- * snippet. A concrete stub is defined a subclass of this class.
+ * 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}).
@@ -130,11 +135,22 @@
         return linkage;
     }
 
-    private boolean checkCompilationResult(CompilationResult compResult) {
+    /**
+     * Checks the conditions a compilation must satisfy to be installed as a RuntimeStub.
+     */
+    private boolean checkStubInvariants(CompilationResult compResult) {
         for (DataPatch data : compResult.getDataReferences()) {
             Constant constant = data.constant;
-            assert constant.getKind() != Kind.Object : MetaUtil.format("%h.%n(%p): ", getMethod()) + "cannot have embedded oop: " + constant;
-            assert constant.getPrimitiveAnnotation() == null : MetaUtil.format("%h.%n(%p): ", getMethod()) + "cannot have embedded metadata: " + constant;
+            assert constant.getKind() != Kind.Object : format("%h.%n(%p): ", getMethod()) + "cannot have embedded oop: " + constant;
+            assert constant.getPrimitiveAnnotation() == null : format("%h.%n(%p): ", getMethod()) + "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;
+            Call call = (Call) infopoint;
+            assert call.target instanceof HotSpotRuntimeCallTarget : format("%h.%n(%p): ", getMethod()) + "cannot have non runtime call: " + call.target;
+            HotSpotRuntimeCallTarget callTarget = (HotSpotRuntimeCallTarget) call.target;
+            assert callTarget.getAddress() == graalRuntime().getConfig().deoptimizeStub || callTarget.isCRuntimeCall() : format("%h.%n(%p): ", getMethod()) +
+                            "must only call C runtime or deoptimization stub, not " + call.target;
         }
         return true;
     }
@@ -181,7 +197,7 @@
                     final CompilationResult compResult = GraalCompiler.compileMethod(runtime(), replacements, backend, runtime().getTarget(), getMethod(), graph, null, phasePlan,
                                     OptimisticOptimizations.ALL, new SpeculationLog());
 
-                    assert checkCompilationResult(compResult);
+                    assert checkStubInvariants(compResult);
 
                     assert definedRegisters != null;
                     code = Debug.scope("CodeInstall", new Callable<InstalledCode>() {