changeset 11275:a5105213af33

Graal now complies with native ABI callee/caller save conventions for foreign calls (GRAAL-413)
author Doug Simon <doug.simon@oracle.com>
date Fri, 09 Aug 2013 16:04:01 +0200
parents 3209552fdb4e
children abba25b953a2
files graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java
diffstat 4 files changed, 66 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java	Fri Aug 09 13:48:08 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java	Fri Aug 09 16:04:01 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot.amd64;
 
-import static com.oracle.graal.amd64.AMD64.*;
+import java.util.*;
 
 import com.oracle.graal.amd64.*;
 import com.oracle.graal.api.code.*;
@@ -35,6 +35,8 @@
  */
 public class AMD64HotSpotGraalRuntime extends HotSpotGraalRuntime {
 
+    private Value[] nativeABICallerSaveRegisters;
+
     protected AMD64HotSpotGraalRuntime() {
     }
 
@@ -76,7 +78,62 @@
     }
 
     @Override
-    protected Value[] getRuntimeCallVolatileRegisters() {
-        return new Value[]{r10.asValue(), r11.asValue()};
+    protected Value[] getNativeABICallerSaveRegisters() {
+        if (nativeABICallerSaveRegisters == null) {
+            List<Register> callerSave = new ArrayList<>(Arrays.asList(getRuntime().lookupRegisterConfig().getAllocatableRegisters()));
+            if (getConfig().windowsOs) {
+                // http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx
+                callerSave.remove(AMD64.rdi);
+                callerSave.remove(AMD64.rsi);
+                callerSave.remove(AMD64.rbx);
+                callerSave.remove(AMD64.rbp);
+                callerSave.remove(AMD64.rsp);
+                callerSave.remove(AMD64.r12);
+                callerSave.remove(AMD64.r13);
+                callerSave.remove(AMD64.r14);
+                callerSave.remove(AMD64.r15);
+                callerSave.remove(AMD64.xmm6);
+                callerSave.remove(AMD64.xmm7);
+                callerSave.remove(AMD64.xmm8);
+                callerSave.remove(AMD64.xmm9);
+                callerSave.remove(AMD64.xmm10);
+                callerSave.remove(AMD64.xmm11);
+                callerSave.remove(AMD64.xmm12);
+                callerSave.remove(AMD64.xmm13);
+                callerSave.remove(AMD64.xmm14);
+                callerSave.remove(AMD64.xmm15);
+            } else {
+                /*
+                 * System V Application Binary Interface, AMD64 Architecture Processor Supplement
+                 * 
+                 * Draft Version 0.96
+                 * 
+                 * http://www.uclibc.org/docs/psABI-x86_64.pdf
+                 * 
+                 * 3.2.1
+                 * 
+                 * ...
+                 * 
+                 * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12
+                 * through %r15 "belong" to the calling function and the called function is required
+                 * to preserve their values. In other words, a called function must preserve these
+                 * registers' values for its caller. Remaining registers "belong" to the called
+                 * function. If a calling function wants to preserve such a register value across a
+                 * function call, it must save the value in its local stack frame.
+                 */
+                callerSave.remove(AMD64.rbp);
+                callerSave.remove(AMD64.rbx);
+                callerSave.remove(AMD64.r12);
+                callerSave.remove(AMD64.r13);
+                callerSave.remove(AMD64.r14);
+                callerSave.remove(AMD64.r15);
+            }
+            nativeABICallerSaveRegisters = new Value[callerSave.size()];
+            for (int i = 0; i < callerSave.size(); i++) {
+                nativeABICallerSaveRegisters[i] = callerSave.get(i).asValue();
+            }
+        }
+
+        return nativeABICallerSaveRegisters;
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java	Fri Aug 09 13:48:08 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java	Fri Aug 09 16:04:01 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.sparc.*;
@@ -69,8 +70,7 @@
     }
 
     @Override
-    protected Value[] getRuntimeCallVolatileRegisters() {
-        // TODO: is this correct?
-        return new Value[0];
+    protected Value[] getNativeABICallerSaveRegisters() {
+        throw GraalInternalError.unimplemented();
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Fri Aug 09 13:48:08 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Fri Aug 09 16:04:01 2013 +0200
@@ -126,7 +126,7 @@
         CallingConvention incomingCc = incomingCcType == null ? null : createCallingConvention(descriptor, incomingCcType);
         HotSpotForeignCallLinkage linkage = new HotSpotForeignCallLinkage(descriptor, address, effect, transition, outgoingCc, incomingCc, reexecutable, killedLocations);
         if (outgoingCcType == Type.NativeCall) {
-            linkage.temporaries = graalRuntime().getRuntimeCallVolatileRegisters();
+            linkage.temporaries = graalRuntime().getNativeABICallerSaveRegisters();
         }
         return linkage;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Fri Aug 09 13:48:08 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Fri Aug 09 16:04:01 2013 +0200
@@ -32,7 +32,6 @@
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.logging.*;
 import com.oracle.graal.hotspot.meta.*;
@@ -255,11 +254,9 @@
     protected abstract HotSpotRuntime createRuntime();
 
     /**
-     * Gets the registers that are treated volatile by foreign calls into the runtime. These
-     * registers must be spilled across all native foreign runtime calls, even for calls that are
-     * declared as {@link RegisterEffect#PRESERVES_REGISTERS register preserving}.
+     * Gets the registers that must be saved across a foreign call into the runtime.
      */
-    protected abstract Value[] getRuntimeCallVolatileRegisters();
+    protected abstract Value[] getNativeABICallerSaveRegisters();
 
     public HotSpotVMConfig getConfig() {
         return config;