changeset 12613:595f01abb887

clearer API and documentation for the capability of a SaveRegistersOp to have its registers pruned
author Doug Simon <doug.simon@oracle.com>
date Sun, 27 Oct 2013 19:59:00 +0100
parents 42a2c235652f
children 47ac1df40fc2 ba6593e52d22
files graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64SaveRegistersOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ZapRegistersOp.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java
diffstat 5 files changed, 37 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Sun Oct 27 19:51:44 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Sun Oct 27 19:59:00 2013 +0100
@@ -222,7 +222,7 @@
     }
 
     protected AMD64SaveRegistersOp emitSaveRegisters(Register[] savedRegisters, StackSlot[] savedRegisterLocations) {
-        AMD64SaveRegistersOp save = new AMD64SaveRegistersOp(savedRegisters, savedRegisterLocations, false);
+        AMD64SaveRegistersOp save = new AMD64SaveRegistersOp(savedRegisters, savedRegisterLocations, true);
         append(save);
         return save;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Sun Oct 27 19:51:44 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Sun Oct 27 19:59:00 2013 +0100
@@ -138,11 +138,15 @@
     protected void updateStub(Stub stub, Set<Register> destroyedRegisters, Map<LIRFrameState, SaveRegistersOp> calleeSaveInfo, FrameMap frameMap) {
         stub.initDestroyedRegisters(destroyedRegisters);
 
-        // Eliminate unnecessary register preservation and
-        // record where preserved registers are saved
         for (Map.Entry<LIRFrameState, SaveRegistersOp> e : calleeSaveInfo.entrySet()) {
             SaveRegistersOp save = e.getValue();
-            save.remove(destroyedRegisters);
+            if (save.supportsRemove()) {
+                // Since the registers destroyed by the stub are declared as temporaries in the
+                // linkage (see ForeignCallLinkage.getTemporaries()) for the stub, the caller
+                // will already save these registers and so there's no need for the stub to
+                // save them again.
+                save.remove(destroyedRegisters);
+            }
             DebugInfo info = e.getKey() == null ? null : e.getKey().debugInfo();
             if (info != null) {
                 info.setCalleeSaveInfo(save.getMap(frameMap));
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64SaveRegistersOp.java	Sun Oct 27 19:51:44 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64SaveRegistersOp.java	Sun Oct 27 19:59:00 2013 +0100
@@ -29,7 +29,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.*;
+import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
 import com.oracle.graal.lir.asm.*;
 
 /**
@@ -51,12 +51,19 @@
     /**
      * Specifies if {@link #remove(Set)} should have an effect.
      */
-    protected final boolean forceAll;
+    protected final boolean supportsRemove;
 
-    public AMD64SaveRegistersOp(Register[] savedRegisters, StackSlot[] slots, boolean forceAll) {
+    /**
+     * 
+     * @param savedRegisters the registers saved by this operation which may be subject to
+     *            {@linkplain #remove(Set) pruning}
+     * @param slots the slots to which the registers are saved
+     * @param supportsRemove determines if registers can be {@linkplain #remove(Set) pruned}
+     */
+    public AMD64SaveRegistersOp(Register[] savedRegisters, StackSlot[] slots, boolean supportsRemove) {
         this.savedRegisters = savedRegisters;
         this.slots = slots;
-        this.forceAll = forceAll;
+        this.supportsRemove = supportsRemove;
     }
 
     protected void saveRegister(TargetMethodAssembler tasm, AMD64MacroAssembler masm, StackSlot result, Register register) {
@@ -77,7 +84,14 @@
         return slots;
     }
 
+    public boolean supportsRemove() {
+        return supportsRemove;
+    }
+
     public int remove(Set<Register> doNotSave) {
+        if (!supportsRemove) {
+            throw new UnsupportedOperationException();
+        }
         return prune(doNotSave, savedRegisters);
     }
 
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ZapRegistersOp.java	Sun Oct 27 19:51:44 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ZapRegistersOp.java	Sun Oct 27 19:59:00 2013 +0100
@@ -65,6 +65,10 @@
         }
     }
 
+    public boolean supportsRemove() {
+        return true;
+    }
+
     public int remove(Set<Register> doNotSave) {
         return prune(doNotSave, zappedRegisters);
     }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Sun Oct 27 19:51:44 2013 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Sun Oct 27 19:59:00 2013 +0100
@@ -149,10 +149,17 @@
     public interface SaveRegistersOp {
 
         /**
+         * Determines if the {@link #remove(Set)} operation is supported for this object.
+         */
+        boolean supportsRemove();
+
+        /**
          * Prunes {@code doNotSave} from the registers saved by this operation.
          * 
          * @param doNotSave registers that should not be saved by this operation
          * @return the number of registers pruned
+         * @throws UnsupportedOperationException if removal is not {@linkplain #supportsRemove()
+         *             supported}
          */
         int remove(Set<Register> doNotSave);