changeset 11760:ce0b00597980

made safepoint-on-return use specialized HotSpot runtime support for such safepoints (which have no debug info attached)
author Doug Simon <doug.simon@oracle.com>
date Tue, 24 Sep 2013 08:51:02 +0200
parents 8bcd76c3f23b
children 3b25f37d5561
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.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/AMD64HotSpotReturnOp.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.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/SPARCHotSpotReturnOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCSafepointOp.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoopSafepointInsertionPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/SafepointInsertionPhase.java src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp src/cpu/x86/vm/graalCodeInstaller_x86.hpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalCodeInstaller.hpp
diffstat 18 files changed, 336 insertions(+), 253 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java	Mon Sep 23 22:04:51 2013 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java	Tue Sep 24 08:51:02 2013 +0200
@@ -81,7 +81,7 @@
 
         appendPhase(new LoopSafepointEliminationPhase());
 
-        appendPhase(new SafepointInsertionPhase());
+        appendPhase(new LoopSafepointInsertionPhase());
 
         appendPhase(new GuardLoweringPhase());
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon Sep 23 22:04:51 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Tue Sep 24 08:51:02 2013 +0200
@@ -176,7 +176,7 @@
 
     @Override
     protected void emitReturn(Value input) {
-        append(new AMD64HotSpotReturnOp(input));
+        append(new AMD64HotSpotReturnOp(input, getStub() != null));
     }
 
     @Override
@@ -287,7 +287,7 @@
     @Override
     public void visitSafepointNode(SafepointNode i) {
         LIRFrameState info = state(i);
-        append(new AMD64SafepointOp(info, runtime().config, this));
+        append(new AMD64HotSpotSafepointOp(info, runtime().config, this));
     }
 
     @SuppressWarnings("hiding")
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Mon Sep 23 22:04:51 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Tue Sep 24 08:51:02 2013 +0200
@@ -22,10 +22,16 @@
  */
 package com.oracle.graal.hotspot.amd64;
 
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
+import com.oracle.graal.amd64.*;
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
@@ -36,14 +42,31 @@
 final class AMD64HotSpotReturnOp extends AMD64HotSpotEpilogueOp {
 
     @Use({REG, ILLEGAL}) protected Value value;
+    private final boolean isStub;
 
-    AMD64HotSpotReturnOp(Value value) {
+    AMD64HotSpotReturnOp(Value value, boolean isStub) {
         this.value = value;
+        this.isStub = isStub;
     }
 
+    private static Register findPollOnReturnScratchRegister() {
+        RegisterConfig config = HotSpotGraalRuntime.graalRuntime().getRuntime().lookupRegisterConfig();
+        for (Register r : config.getAllocatableRegisters(Kind.Long)) {
+            if (r != config.getReturnRegister(Kind.Long) && r != AMD64.rbp) {
+                return r;
+            }
+        }
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    private static final Register scratchForSafepointOnReturn = findPollOnReturnScratchRegister();
+
     @Override
     public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
         leaveFrameAndRestoreRbp(tasm, masm);
+        if (!isStub && tasm.frameContext != null || !OptEliminateSafepoints.getValue()) {
+            AMD64HotSpotSafepointOp.emitCode(tasm, masm, graalRuntime().getConfig(), true, null, scratchForSafepointOnReturn);
+        }
         masm.ret(0);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java	Tue Sep 24 08:51:02 2013 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2011, 2012, 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.hotspot.amd64;
+
+import static com.oracle.graal.amd64.AMD64.*;
+import static com.oracle.graal.hotspot.bridge.Marks.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.spi.*;
+
+/**
+ * Emits a safepoint poll.
+ */
+@Opcode("SAFEPOINT")
+public class AMD64HotSpotSafepointOp extends AMD64LIRInstruction {
+
+    @State protected LIRFrameState state;
+    @Temp({OperandFlag.REG}) private AllocatableValue temp;
+
+    private final HotSpotVMConfig config;
+
+    public AMD64HotSpotSafepointOp(LIRFrameState state, HotSpotVMConfig config, LIRGeneratorTool tool) {
+        this.state = state;
+        this.config = config;
+        temp = tool.newVariable(tool.target().wordKind);
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler asm) {
+        RegisterValue scratch = (RegisterValue) temp;
+        emitCode(tasm, asm, config, false, state, scratch.getRegister());
+    }
+
+    public static void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler asm, HotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register scratch) {
+        final int pos = asm.codeBuffer.position();
+        if (config.isPollingPageFar) {
+            asm.movq(scratch, config.safepointPollingAddress);
+            tasm.recordMark(atReturn ? MARK_POLL_RETURN_FAR : MARK_POLL_FAR);
+            if (state != null) {
+                tasm.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
+            }
+            asm.movq(scratch, new AMD64Address(scratch));
+        } else {
+            tasm.recordMark(atReturn ? MARK_POLL_RETURN_NEAR : MARK_POLL_NEAR);
+            if (state != null) {
+                tasm.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
+            }
+            // The C++ code transforms the polling page offset into an RIP displacement
+            // to the real address at that offset in the polling page.
+            asm.movq(scratch, new AMD64Address(rip, 0));
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java	Mon Sep 23 22:04:51 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.hotspot.amd64;
-
-import static com.oracle.graal.amd64.AMD64.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.bridge.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.nodes.spi.*;
-
-/**
- * Emits a safepoint poll.
- */
-@Opcode("SAFEPOINT")
-public class AMD64SafepointOp extends AMD64LIRInstruction {
-
-    @State protected LIRFrameState state;
-    @Temp({OperandFlag.REG}) private AllocatableValue temp;
-
-    private final HotSpotVMConfig config;
-
-    public AMD64SafepointOp(LIRFrameState state, HotSpotVMConfig config, LIRGeneratorTool tool) {
-        this.state = state;
-        this.config = config;
-        temp = tool.newVariable(tool.target().wordKind);
-    }
-
-    @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler asm) {
-        final int pos = asm.codeBuffer.position();
-        RegisterValue scratch = (RegisterValue) temp;
-        if (config.isPollingPageFar) {
-            asm.movq(scratch.getRegister(), config.safepointPollingAddress);
-            tasm.recordMark(Marks.MARK_POLL_FAR);
-            tasm.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
-            asm.movq(scratch.getRegister(), new AMD64Address(scratch.getRegister()));
-        } else {
-            tasm.recordMark(Marks.MARK_POLL_NEAR);
-            tasm.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
-            // The C++ code transforms the polling page offset into an RIP displacement
-            // to the real address at that offset in the polling page.
-            asm.movq(scratch.getRegister(), new AMD64Address(rip, 0));
-        }
-    }
-}
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Mon Sep 23 22:04:51 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Tue Sep 24 08:51:02 2013 +0200
@@ -39,7 +39,10 @@
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.sparc.*;
-import com.oracle.graal.lir.sparc.SPARCMove.*;
+import com.oracle.graal.lir.sparc.SPARCMove.CompareAndSwapOp;
+import com.oracle.graal.lir.sparc.SPARCMove.LoadOp;
+import com.oracle.graal.lir.sparc.SPARCMove.StoreConstantOp;
+import com.oracle.graal.lir.sparc.SPARCMove.StoreOp;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 
@@ -103,9 +106,14 @@
     }
 
     @Override
+    protected void emitReturn(Value input) {
+        append(new SPARCHotSpotReturnOp(input, getStub() != null));
+    }
+
+    @Override
     public void visitSafepointNode(SafepointNode i) {
         LIRFrameState info = state(i);
-        append(new SPARCSafepointOp(info, runtime().config, this));
+        append(new SPARCHotSpotSafepointOp(info, runtime().config, this));
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotReturnOp.java	Tue Sep 24 08:51:02 2013 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012, 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.hotspot.sparc;
+
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+import static com.oracle.graal.phases.GraalOptions.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.sparc.SPARCControlFlow.ReturnOp;
+
+/**
+ * Returns from a function.
+ */
+@Opcode("RETURN")
+final class SPARCHotSpotReturnOp extends SPARCHotSpotEpilogueOp {
+
+    @Use({REG, ILLEGAL}) protected Value value;
+    private final boolean isStub;
+
+    SPARCHotSpotReturnOp(Value value, boolean isStub) {
+        this.value = value;
+        this.isStub = isStub;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+        leaveFrame(tasm);
+        if (!isStub && tasm.frameContext != null || !OptEliminateSafepoints.getValue()) {
+            Register scratchForSafepointOnReturn = null;
+            GraalInternalError.unimplemented("need to find a scratch register for the safepoint instruction sequence");
+            SPARCHotSpotSafepointOp.emitCode(tasm, masm, graalRuntime().getConfig(), true, null, scratchForSafepointOnReturn);
+        }
+        ReturnOp.emitCodeHelper(tasm, masm);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java	Tue Sep 24 08:51:02 2013 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2011, 2013, 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.hotspot.sparc;
+
+import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
+import static com.oracle.graal.hotspot.bridge.Marks.*;
+import static com.oracle.graal.sparc.SPARC.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.sparc.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.spi.*;
+
+/**
+ * Emits a safepoint poll.
+ */
+@Opcode("SAFEPOINT")
+public class SPARCHotSpotSafepointOp extends SPARCLIRInstruction {
+
+    @State protected LIRFrameState state;
+    @Temp({OperandFlag.REG}) private AllocatableValue temp;
+
+    private final HotSpotVMConfig config;
+
+    public SPARCHotSpotSafepointOp(LIRFrameState state, HotSpotVMConfig config, LIRGeneratorTool tool) {
+        this.state = state;
+        this.config = config;
+        temp = tool.newVariable(tool.target().wordKind);
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+        Register scratch = ((RegisterValue) temp).getRegister();
+        emitCode(tasm, masm, config, false, state, scratch);
+    }
+
+    public static void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm, HotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register scratch) {
+        final int pos = masm.codeBuffer.position();
+        new Setx(config.safepointPollingAddress, scratch).emit(masm);
+        assert !config.isPollingPageFar;
+        tasm.recordMark(atReturn ? MARK_POLL_RETURN_NEAR : MARK_POLL_NEAR);
+        if (state != null) {
+            tasm.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
+        }
+        new Ldx(new SPARCAddress(scratch, 0), g0).emit(masm);
+    }
+}
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCSafepointOp.java	Mon Sep 23 22:04:51 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, 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.hotspot.sparc;
-
-import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
-import static com.oracle.graal.sparc.SPARC.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.sparc.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.nodes.spi.*;
-
-/**
- * Emits a safepoint poll.
- */
-@Opcode("SAFEPOINT")
-public class SPARCSafepointOp extends SPARCLIRInstruction {
-
-    @State protected LIRFrameState state;
-    @Temp({OperandFlag.REG}) private AllocatableValue temp;
-
-    private final HotSpotVMConfig config;
-
-    public SPARCSafepointOp(LIRFrameState state, HotSpotVMConfig config, LIRGeneratorTool tool) {
-        this.state = state;
-        this.config = config;
-        temp = tool.newVariable(tool.target().wordKind);
-    }
-
-    @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-        final int pos = masm.codeBuffer.position();
-        Register scratch = ((RegisterValue) temp).getRegister();
-        new Setx(config.safepointPollingAddress, scratch).emit(masm);
-        tasm.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
-        new Ldx(new SPARCAddress(scratch, 0), g0).emit(masm);
-    }
-}
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Mon Sep 23 22:04:51 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Tue Sep 24 08:51:02 2013 +0200
@@ -638,7 +638,7 @@
 
                 new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext);
                 new GuardLoweringPhase().apply(graph, midTierContext);
-                new SafepointInsertionPhase().apply(graph);
+                new LoopSafepointInsertionPhase().apply(graph);
                 new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext);
 
                 new WriteBarrierAdditionPhase().apply(graph);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Mon Sep 23 22:04:51 2013 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Tue Sep 24 08:51:02 2013 +0200
@@ -247,8 +247,12 @@
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+            emitCodeHelper(tasm, masm);
+        }
+
+        public static void emitCodeHelper(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             new Ret().emit(masm);
-            // On SPARC we always leave the frame.
+            // On SPARC we always leave the frame (in the delay slot).
             tasm.frameContext.leave(tasm);
         }
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java	Mon Sep 23 22:04:51 2013 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java	Tue Sep 24 08:51:02 2013 +0200
@@ -32,11 +32,7 @@
 public class SafepointNode extends DeoptimizingFixedWithNextNode implements LIRLowerable {
 
     public SafepointNode() {
-        this(StampFactory.forVoid());
-    }
-
-    public SafepointNode(Stamp stamp) {
-        super(stamp);
+        super(StampFactory.forVoid());
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoopSafepointInsertionPhase.java	Tue Sep 24 08:51:02 2013 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011, 2013, 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.phases.common;
+
+import static com.oracle.graal.phases.GraalOptions.*;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.phases.*;
+
+/**
+ * Adds safepoints to loops.
+ */
+public class LoopSafepointInsertionPhase extends Phase {
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        if (GenLoopSafepoints.getValue()) {
+            for (LoopEndNode loopEndNode : graph.getNodes(LoopEndNode.class)) {
+                if (loopEndNode.canSafepoint()) {
+                    SafepointNode safepointNode = graph.add(new SafepointNode());
+                    graph.addBeforeFixed(loopEndNode, safepointNode);
+                }
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/SafepointInsertionPhase.java	Mon Sep 23 22:04:51 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, 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.phases.common;
-
-import static com.oracle.graal.phases.GraalOptions.*;
-
-import java.util.*;
-
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.phases.*;
-
-/**
- * Adds safepoints to loops and return points.
- */
-public class SafepointInsertionPhase extends Phase {
-
-    @Override
-    protected void run(StructuredGraph graph) {
-        final boolean addLoopSafepoints = GenLoopSafepoints.getValue();
-        if (addLoopSafepoints && !GenSafepoints.getValue()) {
-            // Use (faster) typed node iteration if we are not adding return safepoints
-            for (LoopEndNode loopEndNode : graph.getNodes(LoopEndNode.class)) {
-                addLoopSafepoint(graph, loopEndNode);
-            }
-        }
-
-        if (GenSafepoints.getValue()) {
-            List<ReturnNode> returnNodes = new ArrayList<>();
-            boolean addReturnSafepoints = !OptEliminateSafepoints.getValue();
-            for (Node n : graph.getNodes()) {
-                if (addLoopSafepoints && n instanceof LoopEndNode) {
-                    addLoopSafepoint(graph, (LoopEndNode) n);
-                } else if (n instanceof ReturnNode) {
-                    returnNodes.add((ReturnNode) n);
-                } else {
-                    if (!addReturnSafepoints && n instanceof LoweredCallTargetNode) {
-                        addReturnSafepoints = true;
-                    }
-                }
-            }
-            if (addReturnSafepoints) {
-                for (ReturnNode returnNode : returnNodes) {
-                    SafepointNode safepoint = graph.add(new SafepointNode());
-                    graph.addBeforeFixed(returnNode, safepoint);
-                }
-            }
-        }
-    }
-
-    private static void addLoopSafepoint(StructuredGraph graph, LoopEndNode loopEndNode) {
-        if (loopEndNode.canSafepoint()) {
-            SafepointNode safepointNode = graph.add(new SafepointNode());
-            graph.addBeforeFixed(loopEndNode, safepointNode);
-        }
-    }
-}
--- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp	Mon Sep 23 22:04:51 2013 -0700
+++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp	Tue Sep 24 08:51:02 2013 +0200
@@ -182,9 +182,4 @@
   }
 }
 
-inline int32_t* CodeInstaller::pd_locate_operand(address instruction) {
-  fatal("CodeInstaller::pd_locate_operand - sparc unimp");
-  return (int32_t*)0;
-}
-
 #endif // CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP
--- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Mon Sep 23 22:04:51 2013 -0700
+++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Tue Sep 24 08:51:02 2013 +0200
@@ -20,8 +20,8 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-#ifndef CPU_SPARC_VM_CODEINSTALLER_X86_HPP
-#define CPU_SPARC_VM_CODEINSTALLER_X86_HPP
+#ifndef CPU_X86_VM_CODEINSTALLER_X86_HPP
+#define CPU_X86_VM_CODEINSTALLER_X86_HPP
 
 #include "compiler/disassembler.hpp"
 #include "runtime/javaCalls.hpp"
@@ -207,9 +207,35 @@
   }
 }
 
-inline int32_t* CodeInstaller::pd_locate_operand(address instruction) {
-  return (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
+inline void CodeInstaller::pd_relocate_poll(address pc, jint mark) {
+  switch (mark) {
+    case MARK_POLL_NEAR: {
+      NativeInstruction* ni = nativeInstruction_at(pc);
+      int32_t* disp = (int32_t*) Assembler::locate_operand(pc, Assembler::disp32_operand);
+      // int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
+      int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand
+      intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni;
+      *disp = (int32_t)new_disp;
+    }
+    case MARK_POLL_FAR:
+      _instructions->relocate(pc, relocInfo::poll_type);
+      break;
+    case MARK_POLL_RETURN_NEAR: {
+      NativeInstruction* ni = nativeInstruction_at(pc);
+      int32_t* disp = (int32_t*) Assembler::locate_operand(pc, Assembler::disp32_operand);
+      // int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
+      int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand
+      intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni;
+      *disp = (int32_t)new_disp;
+    }
+    case MARK_POLL_RETURN_FAR:
+      _instructions->relocate(pc, relocInfo::poll_return_type);
+      break;
+    default:
+      ShouldNotReachHere();
+      break;
+  }
 }
 
-#endif // CPU_SPARC_VM_CODEINSTALLER_X86_HPP
+#endif // CPU_X86_VM_CODEINSTALLER_X86_HPP
 
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Mon Sep 23 22:04:51 2013 -0700
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Tue Sep 24 08:51:02 2013 +0200
@@ -810,27 +810,11 @@
         _next_call_type = (MarkId) id;
         _invoke_mark_pc = pc;
         break;
-      case MARK_POLL_NEAR: {
-        NativeInstruction* ni = nativeInstruction_at(pc);
-        int32_t* disp = (int32_t*) pd_locate_operand(pc);
-        // int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
-        int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand
-        intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni;
-        *disp = (int32_t)new_disp;
-      }
+      case MARK_POLL_NEAR:
       case MARK_POLL_FAR:
-        _instructions->relocate(pc, relocInfo::poll_type);
-        break;
-      case MARK_POLL_RETURN_NEAR: {
-        NativeInstruction* ni = nativeInstruction_at(pc);
-        int32_t* disp = (int32_t*) pd_locate_operand(pc);
-        // int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
-        int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand
-        intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni;
-        *disp = (int32_t)new_disp;
-      }
+      case MARK_POLL_RETURN_NEAR:
       case MARK_POLL_RETURN_FAR:
-        _instructions->relocate(pc, relocInfo::poll_return_type);
+        pd_relocate_poll(pc, id);
         break;
       default:
         ShouldNotReachHere();
--- a/src/share/vm/graal/graalCodeInstaller.hpp	Mon Sep 23 22:04:51 2013 -0700
+++ b/src/share/vm/graal/graalCodeInstaller.hpp	Tue Sep 24 08:51:02 2013 +0200
@@ -80,7 +80,7 @@
   void pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst);
   void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination);
   void pd_relocate_JavaMethod(oop method, jint pc_offset);
-  int32_t* pd_locate_operand(address instruction);
+  void pd_relocate_poll(address pc, jint mark);
 
 public: