changeset 10870:886c2df7a7e4

Stubs need both an outgoing and incoming calling convention.
author twisti
date Wed, 24 Jul 2013 16:19:17 -0700
parents 3ad7c15c2623
children c3b09d69dfde
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ForeignCallLinkage.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRuntime.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java
diffstat 12 files changed, 60 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ForeignCallLinkage.java	Wed Jul 24 15:07:17 2013 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ForeignCallLinkage.java	Wed Jul 24 16:19:17 2013 -0700
@@ -30,9 +30,16 @@
 public interface ForeignCallLinkage extends InvokeTarget {
 
     /**
-     * Gets the details of where parameters are passed and value(s) are returned.
+     * Gets the details of where parameters are passed and value(s) are returned from the caller's
+     * perspective.
      */
-    CallingConvention getCallingConvention();
+    CallingConvention getOutgoingCallingConvention();
+
+    /**
+     * Gets the details of where parameters are passed and value(s) are returned from the callee's
+     * perspective.
+     */
+    CallingConvention getIncomingCallingConvention();
 
     /**
      * Returns the maximum absolute offset of PC relative call to this stub from any position in the
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Jul 24 15:07:17 2013 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Jul 24 16:19:17 2013 -0700
@@ -603,7 +603,7 @@
         LIRFrameState state = !linkage.canDeoptimize() ? null : stateFor(info.getDeoptimizationState(), info.getDeoptimizationReason());
 
         // move the arguments into the correct location
-        CallingConvention linkageCc = linkage.getCallingConvention();
+        CallingConvention linkageCc = linkage.getOutgoingCallingConvention();
         frameMap.callsMethod(linkageCc);
         assert linkageCc.getArgumentCount() == args.length : "argument count mismatch";
         Value[] argLocations = new Value[args.length];
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed Jul 24 15:07:17 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed Jul 24 16:19:17 2013 -0700
@@ -355,7 +355,7 @@
     @Override
     public void emitUnwind(Value exception) {
         ForeignCallLinkage linkage = getRuntime().lookupForeignCall(HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER);
-        CallingConvention linkageCc = linkage.getCallingConvention();
+        CallingConvention linkageCc = linkage.getOutgoingCallingConvention();
         assert linkageCc.getArgumentCount() == 2;
         RegisterValue exceptionParameter = (RegisterValue) linkageCc.getArgument(0);
         emitMove(exceptionParameter, exception);
@@ -381,7 +381,7 @@
     public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc) {
         Variable handler = load(operand(handlerInCallerPc));
         ForeignCallLinkage linkage = getRuntime().lookupForeignCall(EXCEPTION_HANDLER_IN_CALLER);
-        CallingConvention linkageCc = linkage.getCallingConvention();
+        CallingConvention linkageCc = linkage.getOutgoingCallingConvention();
         assert linkageCc.getArgumentCount() == 2;
         RegisterValue exceptionFixed = (RegisterValue) linkageCc.getArgument(0);
         RegisterValue exceptionPcFixed = (RegisterValue) linkageCc.getArgument(1);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Wed Jul 24 15:07:17 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Wed Jul 24 16:19:17 2013 -0700
@@ -61,8 +61,8 @@
         RegisterValue exception = rax.asValue(Kind.Object);
         RegisterValue exceptionPc = rdx.asValue(word);
         CallingConvention exceptionCc = new CallingConvention(0, ILLEGAL, exception, exceptionPc);
-        register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
-        register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
+        register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, exceptionCc, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
+        register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, exceptionCc, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
 
         // The x86 crypto stubs do callee saving
         registerForeignCall(ENCRYPT_BLOCK, config.aescryptEncryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java	Wed Jul 24 15:07:17 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java	Wed Jul 24 16:19:17 2013 -0700
@@ -51,7 +51,7 @@
         leaveFrameAndRestoreRbp(tasm, masm);
 
         ForeignCallLinkage linkage = tasm.runtime.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER);
-        CallingConvention cc = linkage.getCallingConvention();
+        CallingConvention cc = linkage.getOutgoingCallingConvention();
         assert cc.getArgumentCount() == 2;
         assert exception.equals(cc.getArgument(0));
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Jul 24 15:07:17 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Jul 24 16:19:17 2013 -0700
@@ -154,7 +154,7 @@
     @Override
     public void emitUnwind(Value exception) {
         ForeignCallLinkage linkage = getRuntime().lookupForeignCall(HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER);
-        CallingConvention linkageCc = linkage.getCallingConvention();
+        CallingConvention linkageCc = linkage.getOutgoingCallingConvention();
         assert linkageCc.getArgumentCount() == 2;
         RegisterValue exceptionParameter = (RegisterValue) linkageCc.getArgument(0);
         emitMove(exceptionParameter, exception);
@@ -182,7 +182,7 @@
     public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc) {
         Variable handler = load(operand(handlerInCallerPc));
         ForeignCallLinkage linkage = getRuntime().lookupForeignCall(EXCEPTION_HANDLER_IN_CALLER);
-        CallingConvention linkageCc = linkage.getCallingConvention();
+        CallingConvention linkageCc = linkage.getOutgoingCallingConvention();
         assert linkageCc.getArgumentCount() == 2;
         RegisterValue exceptionFixed = (RegisterValue) linkageCc.getArgument(0);
         RegisterValue exceptionPcFixed = (RegisterValue) linkageCc.getArgument(1);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRuntime.java	Wed Jul 24 15:07:17 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRuntime.java	Wed Jul 24 16:19:17 2013 -0700
@@ -51,11 +51,14 @@
         // The calling convention for the exception handler stub is (only?) defined in
         // TemplateInterpreterGenerator::generate_throw_exception()
         // in templateInterpreter_sparc.cpp around line 1925
-        RegisterValue exception = o0.asValue(Kind.Object);  // XXX should this be i0?
-        RegisterValue exceptionPc = o1.asValue(word);  // XXX should this be i1?
-        CallingConvention exceptionCc = new CallingConvention(0, ILLEGAL, exception, exceptionPc);
-        register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
-        register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
+        RegisterValue outgoingException = o0.asValue(Kind.Object);
+        RegisterValue outgoingExceptionPc = o1.asValue(word);
+        RegisterValue incomingException = i0.asValue(Kind.Object);
+        RegisterValue incomingExceptionPc = i1.asValue(word);
+        CallingConvention outgoingExceptionCc = new CallingConvention(0, ILLEGAL, outgoingException, outgoingExceptionPc);
+        CallingConvention incomingExceptionCc = new CallingConvention(0, ILLEGAL, incomingException, incomingExceptionPc);
+        register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, outgoingExceptionCc, incomingExceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
+        register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, outgoingExceptionCc, incomingExceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
 
         super.registerReplacements(replacements);
     }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java	Wed Jul 24 15:07:17 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java	Wed Jul 24 16:19:17 2013 -0700
@@ -52,7 +52,7 @@
         leaveFrame(tasm);
 
         ForeignCallLinkage linkage = tasm.runtime.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER);
-        CallingConvention cc = linkage.getCallingConvention();
+        CallingConvention cc = linkage.getOutgoingCallingConvention();
         assert cc.getArgumentCount() == 2;
         assert exception.equals(cc.getArgument(0));
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Wed Jul 24 15:07:17 2013 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Wed Jul 24 16:19:17 2013 -0700
@@ -42,7 +42,7 @@
 
     /**
      * Constants for specifying whether a foreign call destroys or preserves registers. A foreign
-     * call will always destroy {@link HotSpotForeignCallLinkage#getCallingConvention() its}
+     * call will always destroy {@link HotSpotForeignCallLinkage#getOutgoingCallingConvention() its}
      * {@linkplain ForeignCallLinkage#getTemporaries() temporary} registers.
      */
     public enum RegisterEffect {
@@ -81,7 +81,13 @@
     /**
      * The calling convention for this call.
      */
-    private final CallingConvention cc;
+    private final CallingConvention outgoingCallingConvention;
+
+    /**
+     * The calling convention for incoming arguments to the stub, iff this call uses a compiled
+     * {@linkplain Stub stub}.
+     */
+    private final CallingConvention incomingCallingConvention;
 
     private final RegisterEffect effect;
 
@@ -106,17 +112,19 @@
      * @param address the address of the code to call
      * @param effect specifies if the call destroys or preserves all registers (apart from
      *            temporaries which are always destroyed)
-     * @param ccType calling convention type
+     * @param outgoingCcType outgoing (caller) calling convention type
+     * @param incomingCcType incoming (callee) calling convention type
      * @param transition specifies if this is a {@linkplain #canDeoptimize() leaf} call
      * @param reexecutable specifies if the call can be re-executed without (meaningful) side
      *            effects. Deoptimization will not return to a point before a call that cannot be
      *            re-executed.
      * @param killedLocations the memory locations killed by the call
      */
-    public static HotSpotForeignCallLinkage create(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Type ccType, Transition transition, boolean reexecutable,
-                    LocationIdentity... killedLocations) {
-        CallingConvention targetCc = createCallingConvention(descriptor, ccType);
-        return new HotSpotForeignCallLinkage(descriptor, address, effect, transition, targetCc, reexecutable, killedLocations);
+    public static HotSpotForeignCallLinkage create(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Type outgoingCcType, Type incomingCcType, Transition transition,
+                    boolean reexecutable, LocationIdentity... killedLocations) {
+        CallingConvention outgoingCc = createCallingConvention(descriptor, outgoingCcType);
+        CallingConvention incomingCc = createCallingConvention(descriptor, incomingCcType);
+        return new HotSpotForeignCallLinkage(descriptor, address, effect, transition, outgoingCc, incomingCc, reexecutable, killedLocations);
     }
 
     /**
@@ -142,13 +150,14 @@
         }
     }
 
-    public HotSpotForeignCallLinkage(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Transition transition, CallingConvention cc, boolean reexecutable,
-                    LocationIdentity... killedLocations) {
+    public HotSpotForeignCallLinkage(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Transition transition, CallingConvention outgoingCallingConvention,
+                    CallingConvention incomingCallingConvention, boolean reexecutable, LocationIdentity... killedLocations) {
         this.address = address;
         this.effect = effect;
         this.transition = transition;
         this.descriptor = descriptor;
-        this.cc = cc;
+        this.outgoingCallingConvention = outgoingCallingConvention;
+        this.incomingCallingConvention = incomingCallingConvention;
         this.reexecutable = reexecutable;
         this.killedLocations = killedLocations;
     }
@@ -156,7 +165,7 @@
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder(stub == null ? descriptor.toString() : stub.toString());
-        sb.append("@0x").append(Long.toHexString(address)).append(':').append(cc);
+        sb.append("@0x").append(Long.toHexString(address)).append(':').append(outgoingCallingConvention).append(":").append(incomingCallingConvention);
         if (temporaries != null && temporaries.length != 0) {
             sb.append("; temps=");
             String sep = "";
@@ -176,8 +185,12 @@
         return killedLocations;
     }
 
-    public CallingConvention getCallingConvention() {
-        return cc;
+    public CallingConvention getOutgoingCallingConvention() {
+        return outgoingCallingConvention;
+    }
+
+    public CallingConvention getIncomingCallingConvention() {
+        return incomingCallingConvention;
     }
 
     public Value[] getTemporaries() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Jul 24 15:07:17 2013 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Jul 24 16:19:17 2013 -0700
@@ -207,7 +207,7 @@
      * @param killedLocations the memory locations killed by the stub call
      */
     protected HotSpotForeignCallLinkage registerStubCall(ForeignCallDescriptor descriptor, boolean reexecutable, Transition transition, LocationIdentity... killedLocations) {
-        return register(HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCallee, transition, reexecutable, killedLocations));
+        return register(HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations));
     }
 
     /**
@@ -222,7 +222,7 @@
                     boolean reexecutable, LocationIdentity... killedLocations) {
         Class<?> resultType = descriptor.getResultType();
         assert transition == LEAF || resultType.isPrimitive() || Word.class.isAssignableFrom(resultType) : "non-leaf foreign calls must return objects in thread local storage: " + descriptor;
-        return register(HotSpotForeignCallLinkage.create(descriptor, address, effect, ccType, transition, reexecutable, killedLocations));
+        return register(HotSpotForeignCallLinkage.create(descriptor, address, effect, ccType, ccType, transition, reexecutable, killedLocations));
     }
 
     private static void link(Stub stub) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Wed Jul 24 15:07:17 2013 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Wed Jul 24 16:19:17 2013 -0700
@@ -86,11 +86,11 @@
      */
     public ForeignCallStub(HotSpotRuntime runtime, Replacements replacements, long address, ForeignCallDescriptor descriptor, boolean prependThread, Transition transition, boolean reexecutable,
                     LocationIdentity... killedLocations) {
-        super(runtime, replacements, HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCallee, transition, reexecutable, killedLocations));
+        super(runtime, replacements, HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations));
         this.prependThread = prependThread;
         Class[] targetParameterTypes = createTargetParameters(descriptor);
         ForeignCallDescriptor targetSig = new ForeignCallDescriptor(descriptor.getName() + ":C", descriptor.getResultType(), targetParameterTypes);
-        target = HotSpotForeignCallLinkage.create(targetSig, address, DESTROYS_REGISTERS, NativeCall, transition, reexecutable, killedLocations);
+        target = HotSpotForeignCallLinkage.create(targetSig, address, DESTROYS_REGISTERS, NativeCall, NativeCall, transition, reexecutable, killedLocations);
     }
 
     /**
@@ -220,7 +220,7 @@
     @Override
     protected StructuredGraph getGraph() {
         Class<?>[] args = linkage.getDescriptor().getArgumentTypes();
-        boolean isObjectResult = linkage.getCallingConvention().getReturn().getKind() == Kind.Object;
+        boolean isObjectResult = linkage.getOutgoingCallingConvention().getReturn().getKind() == Kind.Object;
         GraphBuilder builder = new GraphBuilder(this);
         LocalNode[] locals = createLocals(builder, args);
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Wed Jul 24 15:07:17 2013 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Wed Jul 24 16:19:17 2013 -0700
@@ -154,8 +154,9 @@
                     PhasePlan phasePlan = new PhasePlan();
                     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, getInstalledCodeOwner(), runtime, replacements, backend, runtime.getTarget(), null, phasePlan,
+                    // The stub itself needs the incoming calling convention.
+                    CallingConvention incomingCc = linkage.getIncomingCallingConvention();
+                    final CompilationResult compResult = GraalCompiler.compileGraph(graph, incomingCc, getInstalledCodeOwner(), runtime, replacements, backend, runtime.getTarget(), null, phasePlan,
                                     OptimisticOptimizations.ALL, new SpeculationLog(), runtime.getDefaultSuites(), new CompilationResult());
 
                     assert destroyedRegisters != null;