# HG changeset patch # User Doug Simon # Date 1382900340 -3600 # Node ID 595f01abb887ab0e4ff5ee5df51ffb141eeb0a2c # Parent 42a2c235652f6002132f2eb4e386a60acc1633e7 clearer API and documentation for the capability of a SaveRegistersOp to have its registers pruned diff -r 42a2c235652f -r 595f01abb887 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- 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; } diff -r 42a2c235652f -r 595f01abb887 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java --- 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 destroyedRegisters, Map calleeSaveInfo, FrameMap frameMap) { stub.initDestroyedRegisters(destroyedRegisters); - // Eliminate unnecessary register preservation and - // record where preserved registers are saved for (Map.Entry 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)); diff -r 42a2c235652f -r 595f01abb887 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64SaveRegistersOp.java --- 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 doNotSave) { + if (!supportsRemove) { + throw new UnsupportedOperationException(); + } return prune(doNotSave, savedRegisters); } diff -r 42a2c235652f -r 595f01abb887 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ZapRegistersOp.java --- 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 doNotSave) { return prune(doNotSave, zappedRegisters); } diff -r 42a2c235652f -r 595f01abb887 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java --- 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 doNotSave);