changeset 19938:ed3e144ced29

Merge
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Wed, 18 Mar 2015 16:39:06 +0100
parents c7caa3f463e3 (current diff) 4fe66c16e942 (diff)
children f73a6e260e0c
files graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARCScratchRegister.java
diffstat 14 files changed, 97 insertions(+), 171 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Wed Mar 18 15:58:55 2015 +0100
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Wed Mar 18 16:39:06 2015 +0100
@@ -39,6 +39,9 @@
      * patched.
      */
     private static final SPARCAddress Placeholder = new SPARCAddress(g0, 0);
+    private final ScratchRegister[] scratchRegister = new ScratchRegister[]{new ScratchRegister(g1), new ScratchRegister(g3)};
+    // Points to the next free scratch register
+    private int nextFreeScratchRegister = 0;
 
     public SPARCMacroAssembler(TargetDescription target, RegisterConfig registerConfig) {
         super(target, registerConfig);
@@ -389,4 +392,26 @@
     public void signx(Register rd) {
         sra(rd, g0, rd);
     }
+
+    public ScratchRegister getScratchRegister() {
+        return scratchRegister[nextFreeScratchRegister++];
+    }
+
+    public class ScratchRegister implements AutoCloseable {
+        private final Register register;
+
+        public ScratchRegister(Register register) {
+            super();
+            this.register = register;
+        }
+
+        public Register getRegister() {
+            return register;
+        }
+
+        public void close() {
+            assert nextFreeScratchRegister > 0 : "Close called too often";
+            nextFreeScratchRegister--;
+        }
+    }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java	Wed Mar 18 15:58:55 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java	Wed Mar 18 16:39:06 2015 +0100
@@ -40,6 +40,8 @@
 @ServiceProvider(HotSpotBackendFactory.class)
 public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory {
 
+    private static final int PLUGIN_COUNT_ESTIMATE = 160;
+
     protected Architecture createArchitecture(HotSpotVMConfig config) {
         return new AMD64(computeFeatures(config), computeFlags(config));
     }
@@ -171,7 +173,8 @@
                 wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind);
             }
             try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
-                plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch);
+                plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch,
+                                PLUGIN_COUNT_ESTIMATE);
                 replacements.setGraphBuilderPlugins(plugins);
             }
             try (InitTimer rt = timer("create Suites provider")) {
@@ -260,15 +263,15 @@
         } 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
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Wed Mar 18 15:58:55 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Wed Mar 18 16:39:06 2015 +0100
@@ -38,6 +38,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
 import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.hotspot.*;
@@ -52,7 +53,6 @@
 import com.oracle.graal.lir.sparc.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.sparc.*;
 
 /**
  * HotSpot SPARC specific backend.
@@ -113,7 +113,7 @@
                     if (SPARCAssembler.isSimm13(address.getDisplacement())) {
                         masm.stx(g0, address);
                     } else {
-                        try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+                        try (ScratchRegister sc = masm.getScratchRegister()) {
                             Register scratch = sc.getRegister();
                             new Setx(address.getDisplacement(), scratch).emit(masm);
                             masm.stx(g0, new SPARCAddress(sp, scratch));
@@ -148,7 +148,7 @@
             if (SPARCAssembler.isSimm13(stackpoinerChange)) {
                 masm.save(sp, stackpoinerChange, sp);
             } else {
-                try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+                try (ScratchRegister sc = masm.getScratchRegister()) {
                     Register scratch = sc.getRegister();
                     new Setx(stackpoinerChange, scratch).emit(masm);
                     masm.save(sp, scratch, sp);
@@ -227,7 +227,7 @@
                 CallingConvention cc = regConfig.getCallingConvention(JavaCall, null, new JavaType[]{getProviders().getMetaAccess().lookupJavaType(Object.class)}, getTarget(), false);
                 Register inlineCacheKlass = g5; // see MacroAssembler::ic_call
 
-                try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+                try (ScratchRegister sc = masm.getScratchRegister()) {
                     Register scratch = sc.getRegister();
                     Register receiver = asRegister(cc.getArgument(0));
                     SPARCAddress src = new SPARCAddress(receiver, config.hubOffset);
@@ -261,7 +261,7 @@
 
         if (unverifiedStub != null) {
             masm.bind(unverifiedStub);
-            try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+            try (ScratchRegister sc = masm.getScratchRegister()) {
                 Register scratch = sc.getRegister();
                 SPARCCall.indirectJmp(crb, masm, scratch, foreignCalls.lookupForeignCall(IC_MISS_HANDLER));
             }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Wed Mar 18 15:58:55 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Wed Mar 18 16:39:06 2015 +0100
@@ -39,6 +39,8 @@
 @ServiceProvider(HotSpotBackendFactory.class)
 public class SPARCHotSpotBackendFactory implements HotSpotBackendFactory {
 
+    private static final int PLUGIN_COUNT_ESTIMATE = 155;
+
     protected Architecture createArchitecture(HotSpotVMConfig config) {
         return new SPARC(computeFeatures(config));
     }
@@ -68,7 +70,8 @@
         HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), target);
         HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(runtime);
         HotSpotWordTypes wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind);
-        Plugins plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch);
+        Plugins plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch,
+                        PLUGIN_COUNT_ESTIMATE);
         replacements.setGraphBuilderPlugins(plugins);
         HotSpotSuitesProvider suites = createSuites(runtime, plugins);
         HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection,
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCounterOp.java	Wed Mar 18 15:58:55 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCounterOp.java	Wed Mar 18 16:39:06 2015 +0100
@@ -27,6 +27,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.*;
@@ -36,19 +37,12 @@
 public class SPARCHotSpotCounterOp extends HotSpotCounterOp {
     public static final LIRInstructionClass<SPARCHotSpotCounterOp> TYPE = LIRInstructionClass.create(SPARCHotSpotCounterOp.class);
 
-    @Temp({OperandFlag.REG}) private AllocatableValue scratch0;
-    @Temp({OperandFlag.REG}) private AllocatableValue scratch1;
-
-    public SPARCHotSpotCounterOp(String name, String group, Value increment, HotSpotRegistersProvider registers, HotSpotVMConfig config, AllocatableValue scratch0, AllocatableValue scratch1) {
+    public SPARCHotSpotCounterOp(String name, String group, Value increment, HotSpotRegistersProvider registers, HotSpotVMConfig config) {
         super(TYPE, name, group, increment, registers, config);
-        this.scratch0 = scratch0;
-        this.scratch1 = scratch1;
     }
 
-    public SPARCHotSpotCounterOp(String[] names, String[] groups, Value[] increments, HotSpotRegistersProvider registers, HotSpotVMConfig config, AllocatableValue scratch0, AllocatableValue scratch1) {
+    public SPARCHotSpotCounterOp(String[] names, String[] groups, Value[] increments, HotSpotRegistersProvider registers, HotSpotVMConfig config) {
         super(TYPE, names, groups, increments, registers, config);
-        this.scratch0 = scratch0;
-        this.scratch1 = scratch1;
     }
 
     @Override
@@ -58,27 +52,32 @@
 
         // address for counters array
         SPARCAddress countersArrayAddr = new SPARCAddress(thread, config.graalCountersThreadOffset);
-        Register countersArrayReg = asRegister(scratch0);
+        try (ScratchRegister scratch = masm.getScratchRegister()) {
+            Register countersArrayReg = scratch.getRegister();
 
-        // load counters array
-        masm.ldx(countersArrayAddr, countersArrayReg);
+            // load counters array
+            masm.ldx(countersArrayAddr, countersArrayReg);
 
-        forEachCounter((name, group, increment) -> emitIncrement(masm, target, countersArrayReg, name, group, increment));
+            forEachCounter((name, group, increment) -> emitIncrement(masm, target, countersArrayReg, name, group, increment));
+        }
     }
 
     private void emitIncrement(SPARCMacroAssembler masm, TargetDescription target, Register countersArrayReg, String name, String group, Value increment) {
         // address for counter
         SPARCAddress counterAddr = new SPARCAddress(countersArrayReg, getDisplacementForLongIndex(target, getIndex(name, group, increment)));
-        Register counterReg = asRegister(scratch1);
-        // load counter value
-        masm.ldx(counterAddr, counterReg);
-        // increment counter
-        if (isConstant(increment)) {
-            masm.add(counterReg, asInt(asConstant(increment)), counterReg);
-        } else {
-            masm.add(counterReg, asRegister(increment), counterReg);
+
+        try (ScratchRegister scratch = masm.getScratchRegister()) {
+            Register counterReg = scratch.getRegister();
+            // load counter value
+            masm.ldx(counterAddr, counterReg);
+            // increment counter
+            if (isConstant(increment)) {
+                masm.add(counterReg, asInt(asConstant(increment)), counterReg);
+            } else {
+                masm.add(counterReg, asRegister(increment), counterReg);
+            }
+            // store counter value
+            masm.stx(counterReg, counterAddr);
         }
-        // store counter value
-        masm.stx(counterReg, counterAddr);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java	Wed Mar 18 15:58:55 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java	Wed Mar 18 16:39:06 2015 +0100
@@ -26,10 +26,10 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
-import com.oracle.graal.sparc.*;
 
 /**
  * Removes the current frame and tail calls the uncommon trap routine.
@@ -52,7 +52,7 @@
         // HotSpotFrameContext frameContext = backend.new HotSpotFrameContext(isStub);
         // frameContext.enter(crb);
 
-        try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+        try (ScratchRegister sc = masm.getScratchRegister()) {
             Register scratch = sc.getRegister();
             SPARCCall.indirectJmp(crb, masm, scratch, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP_HANDLER));
         }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java	Wed Mar 18 15:58:55 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java	Wed Mar 18 16:39:06 2015 +0100
@@ -31,9 +31,9 @@
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.asm.sparc.SPARCAssembler.CC;
 import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.sparc.*;
 
 /**
  * Sets up the arguments for an exception handler in the callers frame, removes the current frame
@@ -69,7 +69,7 @@
 
         // Restore SP from L7 if the exception PC is a method handle call site.
         SPARCAddress dst = new SPARCAddress(thread, isMethodHandleReturnOffset);
-        try (SPARCScratchRegister scratch = SPARCScratchRegister.get()) {
+        try (ScratchRegister scratch = masm.getScratchRegister()) {
             Register scratchReg = scratch.getRegister();
             masm.lduw(dst, scratchReg);
             masm.cmp(scratchReg, scratchReg);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Mar 18 15:58:55 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Mar 18 16:39:06 2015 +0100
@@ -49,7 +49,6 @@
 import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp;
 import com.oracle.graal.lir.sparc.SPARCMove.StoreConstantOp;
 import com.oracle.graal.lir.sparc.SPARCMove.StoreOp;
-import com.oracle.graal.sparc.*;
 
 public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSpotLIRGenerator {
 
@@ -368,28 +367,18 @@
     @Override
     public LIRInstruction createBenchmarkCounter(String name, String group, Value increment) {
         if (BenchmarkCounters.enabled) {
-            try (SPARCScratchRegister sc0 = SPARCScratchRegister.get()) {
-                RegisterValue scratch0 = sc0.getRegister().asValue(getLIRKindTool().getWordKind());
-                try (SPARCScratchRegister sc1 = SPARCScratchRegister.get()) {
-                    RegisterValue scratch1 = sc1.getRegister().asValue(getLIRKindTool().getWordKind());
-                    return new SPARCHotSpotCounterOp(name, group, increment, getProviders().getRegisters(), config, scratch0, scratch1);
-                }
-            }
+            return new SPARCHotSpotCounterOp(name, group, increment, getProviders().getRegisters(), config);
+        } else {
+            return null;
         }
-        return null;
     }
 
     @Override
     public LIRInstruction createMultiBenchmarkCounter(String[] names, String[] groups, Value[] increments) {
         if (BenchmarkCounters.enabled) {
-            try (SPARCScratchRegister sc0 = SPARCScratchRegister.get()) {
-                RegisterValue scratch0 = sc0.getRegister().asValue(getLIRKindTool().getWordKind());
-                try (SPARCScratchRegister sc1 = SPARCScratchRegister.get()) {
-                    RegisterValue scratch1 = sc1.getRegister().asValue(getLIRKindTool().getWordKind());
-                    return new SPARCHotSpotCounterOp(names, groups, increments, getProviders().getRegisters(), config, scratch0, scratch1);
-                }
-            }
+            return new SPARCHotSpotCounterOp(names, groups, increments, getProviders().getRegisters(), config);
+        } else {
+            return null;
         }
-        return null;
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Wed Mar 18 15:58:55 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Wed Mar 18 16:39:06 2015 +0100
@@ -49,8 +49,6 @@
  */
 public class HotSpotGraphBuilderPlugins {
 
-    private static final int PLUGIN_COUNT_ESTIMATE = 160;
-
     /**
      * Creates a {@link Plugins} object that should be used when running on HotSpot.
      *
@@ -60,9 +58,9 @@
      * @param stampProvider
      */
     public static Plugins create(HotSpotVMConfig config, HotSpotWordTypes wordTypes, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection,
-                    SnippetReflectionProvider snippetReflection, ForeignCallsProvider foreignCalls, StampProvider stampProvider, ReplacementsImpl replacements, Architecture arch) {
-
-        InvocationPlugins invocationPlugins = new HotSpotInvocationPlugins(config, metaAccess, PLUGIN_COUNT_ESTIMATE);
+                    SnippetReflectionProvider snippetReflection, ForeignCallsProvider foreignCalls, StampProvider stampProvider, ReplacementsImpl replacements, Architecture arch,
+                    int pluginCountEstimate) {
+        InvocationPlugins invocationPlugins = new HotSpotInvocationPlugins(config, metaAccess, pluginCountEstimate);
 
         Plugins plugins = new Plugins(invocationPlugins);
         NodeIntrinsificationPhase nodeIntrinsification = new NodeIntrinsificationPhase(metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider);
@@ -81,8 +79,8 @@
         StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, arch, invocationPlugins, !config.useHeapProfiler);
 
         int size = invocationPlugins.size();
-        assert PLUGIN_COUNT_ESTIMATE >= size : String.format("adjust %s.PLUGIN_COUNT_ESTIMATE to be above or equal to %d", HotSpotGraphBuilderPlugins.class.getSimpleName(), size);
-        assert PLUGIN_COUNT_ESTIMATE - size < 20 : String.format("adjust %s.PLUGIN_COUNT_ESTIMATE to be closer to %d", HotSpotGraphBuilderPlugins.class.getSimpleName(), size);
+        assert pluginCountEstimate >= size : String.format("adjust %s.PLUGIN_COUNT_ESTIMATE to be above or equal to %d", HotSpotGraphBuilderPlugins.class.getSimpleName(), size);
+        assert pluginCountEstimate - size < 20 : String.format("adjust %s.PLUGIN_COUNT_ESTIMATE to be closer to %d", HotSpotGraphBuilderPlugins.class.getSimpleName(), size);
         return plugins;
     }
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Wed Mar 18 15:58:55 2015 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Wed Mar 18 16:39:06 2015 +0100
@@ -37,7 +37,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
@@ -371,7 +371,7 @@
                 masm.mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst));
                 break;
             case IMULCC:
-                try (SPARCScratchRegister tmpScratch = SPARCScratchRegister.get()) {
+                try (ScratchRegister tmpScratch = masm.getScratchRegister()) {
                     Register tmp = tmpScratch.getRegister();
                     masm.mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst));
                     Label noOverflow = new Label();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Wed Mar 18 15:58:55 2015 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Wed Mar 18 16:39:06 2015 +0100
@@ -39,6 +39,7 @@
 import com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict;
 import com.oracle.graal.asm.sparc.SPARCAssembler.CC;
 import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.calc.*;
@@ -47,7 +48,6 @@
 import com.oracle.graal.lir.SwitchStrategy.BaseSwitchClosure;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.sparc.SPARC.CPUFeature;
-import com.oracle.graal.sparc.*;
 
 public class SPARCControlFlow {
 
@@ -219,21 +219,14 @@
                 actualConditionFlag = actualConditionFlag.mirror();
             }
             boolean isValidConstant = isConstant(actualY) && isSimm5(asConstant(actualY));
-            SPARCScratchRegister scratch = null;
-            try {
+            try (ScratchRegister scratch = masm.getScratchRegister()) {
                 if (isConstant(actualY) && !isValidConstant) { // Make sure, the y value is loaded
-                    scratch = SPARCScratchRegister.get();
                     Value scratchValue = scratch.getRegister().asValue(actualY.getLIRKind());
                     SPARCMove.move(crb, masm, scratchValue, actualY, SPARCDelayedControlTransfer.DUMMY);
                     actualY = scratchValue;
                 }
                 emitCBCond(masm, actualX, actualY, actualTrueTarget, actualConditionFlag);
                 masm.nop();
-            } finally {
-                if (scratch != null) {
-                    // release the scratch if used
-                    scratch.close();
-                }
             }
             if (needJump) {
                 masm.jmp(actualFalseTarget);
@@ -481,14 +474,14 @@
             if (isSimm13(lowKey)) {
                 masm.sub(value, lowKey, scratchReg);
             } else {
-                try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+                try (ScratchRegister sc = masm.getScratchRegister()) {
                     Register scratch2 = sc.getRegister();
                     new Setx(lowKey, scratch2).emit(masm);
                     masm.sub(value, scratch2, scratchReg);
                 }
             }
             int upperLimit = highKey - lowKey;
-            try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+            try (ScratchRegister sc = masm.getScratchRegister()) {
                 Register scratch2 = sc.getRegister();
                 if (isSimm13(upperLimit)) {
                     masm.cmp(scratchReg, upperLimit);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Wed Mar 18 15:58:55 2015 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Wed Mar 18 16:39:06 2015 +0100
@@ -31,7 +31,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
@@ -133,7 +133,7 @@
             Kind inputKind = (Kind) input.getPlatformKind();
             Kind resultKind = (Kind) result.getPlatformKind();
             int resultKindSize = crb.target.getSizeInBytes(resultKind);
-            try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+            try (ScratchRegister sc = masm.getScratchRegister()) {
                 Register scratch = sc.getRegister();
                 SPARCAddress tempAddress = generateSimm13OffsetLoad((SPARCAddress) crb.asAddress(temp), masm, scratch);
                 switch (inputKind) {
@@ -295,7 +295,7 @@
 
         @Override
         public void emitMemAccess(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+            try (ScratchRegister sc = masm.getScratchRegister()) {
                 Register scratch = sc.getRegister();
                 final SPARCAddress addr = generateSimm13OffsetLoad(address.toAddress(), masm, scratch);
                 final Register dst = asRegister(result);
@@ -495,7 +495,7 @@
         @Override
         public void emitMemAccess(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             assert isRegister(input);
-            try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+            try (ScratchRegister sc = masm.getScratchRegister()) {
                 Register scratch = sc.getRegister();
                 SPARCAddress addr = generateSimm13OffsetLoad(address.toAddress(), masm, scratch);
                 delayedControlTransfer.emitControlTransfer(crb, masm);
@@ -548,7 +548,7 @@
 
         @Override
         public void emitMemAccess(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+            try (ScratchRegister sc = masm.getScratchRegister()) {
                 Register scratch = sc.getRegister();
                 SPARCAddress addr = generateSimm13OffsetLoad(address.toAddress(), masm, scratch);
                 delayedControlTransfer.emitControlTransfer(crb, masm);
@@ -604,7 +604,7 @@
                 if (constant.isDefaultForKind() || constant.isNull()) {
                     reg2stack(crb, masm, result, g0.asValue(LIRKind.derive(input)), delaySlotLir);
                 } else {
-                    try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+                    try (ScratchRegister sc = masm.getScratchRegister()) {
                         Register scratch = sc.getRegister();
                         long value = constant.asLong();
                         if (isSimm13(value)) {
@@ -681,7 +681,7 @@
 
     private static void reg2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) {
         SPARCAddress dst = (SPARCAddress) crb.asAddress(result);
-        try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+        try (ScratchRegister sc = masm.getScratchRegister()) {
             Register scratch = sc.getRegister();
             dst = generateSimm13OffsetLoad(dst, masm, scratch);
             Register src = asRegister(input);
@@ -716,7 +716,7 @@
 
     private static void stack2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) {
         SPARCAddress src = (SPARCAddress) crb.asAddress(input);
-        try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+        try (ScratchRegister sc = masm.getScratchRegister()) {
             Register scratch = sc.getRegister();
             src = generateSimm13OffsetLoad(src, masm, scratch);
             Register dst = asRegister(result);
@@ -752,7 +752,7 @@
     }
 
     private static void const2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, JavaConstant input, SPARCDelayedControlTransfer delaySlotLir) {
-        try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+        try (ScratchRegister sc = masm.getScratchRegister()) {
             Register scratch = sc.getRegister();
             boolean hasVIS3 = ((SPARC) masm.target.arch).getFeatures().contains(CPUFeature.VIS3);
             switch (input.getKind().getStackKind()) {
--- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARCScratchRegister.java	Wed Mar 18 15:58:55 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.sparc;
-
-import com.oracle.graal.api.code.*;
-
-public final class SPARCScratchRegister implements AutoCloseable {
-    private final ThreadLocal<Boolean> locked = new ThreadLocal<>();
-    private final ThreadLocal<Exception> where = new ThreadLocal<>();
-    private final Register register;
-    private static final SPARCScratchRegister scratch1 = new SPARCScratchRegister(SPARC.g3);
-    private static final SPARCScratchRegister scratch2 = new SPARCScratchRegister(SPARC.g1);
-    private static final boolean LOG_REQUEST_STACK = false;
-
-    private SPARCScratchRegister(Register register) {
-        super();
-        this.register = register;
-    }
-
-    public Register getRegister() {
-        if (locked.get() == null) {
-            locked.set(false);
-        }
-        boolean isLocked = locked.get();
-        if (isLocked) {
-            if (LOG_REQUEST_STACK) {
-                where.get().printStackTrace();
-            }
-            throw new RuntimeException("Temp Register is already taken!");
-        } else {
-            if (LOG_REQUEST_STACK) {
-                where.set(new Exception());
-            }
-            locked.set(true);
-            return register;
-        }
-    }
-
-    public void close() {
-        boolean isLocked = locked.get();
-        if (isLocked) {
-            locked.set(false);
-        } else {
-            throw new RuntimeException("Temp Register is not taken!");
-        }
-    }
-
-    public static SPARCScratchRegister get() {
-        if (scratch1.isLocked()) {
-            return scratch2;
-        } else {
-            return scratch1;
-        }
-    }
-
-    public boolean isLocked() {
-        Boolean isLocked = locked.get();
-        if (isLocked == null) {
-            return false;
-        } else {
-            return isLocked;
-        }
-    }
-}
--- a/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java	Wed Mar 18 15:58:55 2015 +0100
+++ b/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java	Wed Mar 18 16:39:06 2015 +0100
@@ -35,11 +35,11 @@
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.framemap.*;
-import com.oracle.graal.sparc.*;
 import com.oracle.graal.truffle.*;
 import com.oracle.graal.truffle.hotspot.*;
 
@@ -53,7 +53,7 @@
             protected void injectTailCallCode(HotSpotVMConfig config, HotSpotRegistersProvider registers) {
                 @SuppressWarnings("hiding")
                 SPARCMacroAssembler asm = (SPARCMacroAssembler) this.asm;
-                try (SPARCScratchRegister scratch = SPARCScratchRegister.get()) {
+                try (ScratchRegister scratch = asm.getScratchRegister()) {
                     Register thisRegister = codeCache.getRegisterConfig().getCallingConventionRegisters(JavaCall, Object)[0];
                     Register spillRegister = scratch.getRegister();
                     Label doProlog = new Label();