changeset 12793:af7fb87fc62e

pass thread register into all stubs instead of getting it from the host provider
author Doug Simon <doug.simon@oracle.com>
date Wed, 20 Nov 2013 14:45:43 +0100
parents be9c3426daad
children f8aef2693731
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java
diffstat 9 files changed, 75 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Wed Nov 20 13:58:38 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Wed Nov 20 14:45:43 2013 +0100
@@ -202,11 +202,6 @@
     }
 
     @Fold
-    public static Register threadRegister() {
-        return runtime().getHostProviders().getRegisters().getThreadRegister();
-    }
-
-    @Fold
     public static int wordSize() {
         return runtime().getTarget().wordSize;
     }
@@ -464,13 +459,6 @@
     @NodeIntrinsic(ForeignCallNode.class)
     private static native Object verifyOopStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object);
 
-    /**
-     * Gets the value of the thread register as a Word.
-     */
-    public static Word thread() {
-        return registerAsWord(threadRegister());
-    }
-
     public static Word loadWordFromObject(Object object, int offset) {
         assert offset != hubOffset() : "Use loadHubIntrinsic instead";
         return loadWordFromObjectIntrinsic(object, offset, getWordKind(), LocationIdentity.ANY_LOCATION);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Wed Nov 20 13:58:38 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Wed Nov 20 14:45:43 2013 +0100
@@ -35,7 +35,7 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.replacements.*;
-import com.oracle.graal.replacements.Snippet.Fold;
+import com.oracle.graal.replacements.Snippet.*;
 import com.oracle.graal.word.*;
 
 /**
@@ -62,12 +62,19 @@
         return false;
     }
 
+    @Override
+    protected Object getConstantParameterValue(int index, String name) {
+        assert index == 2;
+        return providers.getRegisters().getThreadRegister();
+    }
+
     @Snippet
-    private static void exceptionHandler(Object exception, Word exceptionPc) {
-        checkNoExceptionInThread(assertionsEnabled());
+    private static void exceptionHandler(Object exception, Word exceptionPc, @ConstantParameter Register threadRegister) {
+        Word thread = registerAsWord(threadRegister);
+        checkNoExceptionInThread(thread, assertionsEnabled());
         checkExceptionNotNull(assertionsEnabled(), exception);
-        writeExceptionOop(thread(), exception);
-        writeExceptionPc(thread(), exceptionPc);
+        writeExceptionOop(thread, exception);
+        writeExceptionPc(thread, exceptionPc);
         if (logging()) {
             printf("handling exception %p (", Word.fromObject(exception).rawValue());
             decipher(Word.fromObject(exception).rawValue());
@@ -79,7 +86,7 @@
         // patch throwing pc into return address so that deoptimization finds the right debug info
         patchReturnAddress(exceptionPc);
 
-        Word handlerPc = exceptionHandlerForPc(EXCEPTION_HANDLER_FOR_PC, thread());
+        Word handlerPc = exceptionHandlerForPc(EXCEPTION_HANDLER_FOR_PC, thread);
 
         if (logging()) {
             printf("handler for exception %p at %p is at %p (", Word.fromObject(exception).rawValue(), exceptionPc.rawValue(), handlerPc.rawValue());
@@ -91,16 +98,16 @@
         patchReturnAddress(handlerPc);
     }
 
-    static void checkNoExceptionInThread(boolean enabled) {
+    static void checkNoExceptionInThread(Word thread, boolean enabled) {
         if (enabled) {
-            Object currentException = readExceptionOop(thread());
+            Object currentException = readExceptionOop(thread);
             if (currentException != null) {
                 fatal("exception object in thread must be null, not %p", Word.fromObject(currentException).rawValue());
             }
             if (cAssertionsEnabled()) {
                 // This thread-local is only cleared in DEBUG builds of the VM
                 // (see OptoRuntime::generate_exception_blob)
-                Word currentExceptionPc = readExceptionPc(thread());
+                Word currentExceptionPc = readExceptionPc(thread);
                 if (currentExceptionPc.notEqual(Word.zero())) {
                     fatal("exception PC in thread must be zero, not %p", currentExceptionPc.rawValue());
                 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Wed Nov 20 13:58:38 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Wed Nov 20 14:45:43 2013 +0100
@@ -54,8 +54,8 @@
  * deoptimization while the call is in progress. And since these are foreign/runtime calls on slow
  * paths, we don't want to force the register allocator to spill around the call. As such, this stub
  * saves and restores all allocatable registers. It also
- * {@linkplain StubUtil#handlePendingException(boolean) handles} any exceptions raised during the
- * foreign call.
+ * {@linkplain StubUtil#handlePendingException(Word, boolean) handles} any exceptions raised during
+ * the foreign call.
  */
 public class ForeignCallStub extends Stub {
 
@@ -226,9 +226,9 @@
         LocalNode[] locals = createLocals(builder, args);
         List<InvokeNode> invokes = new ArrayList<>(3);
 
-        ReadRegisterNode thread = prependThread || isObjectResult ? builder.append(new ReadRegisterNode(providers.getRegisters().getThreadRegister(), true, false)) : null;
+        ReadRegisterNode thread = builder.append(new ReadRegisterNode(providers.getRegisters().getThreadRegister(), true, false));
         ValueNode result = createTargetCall(builder, locals, thread);
-        invokes.add(createInvoke(builder, StubUtil.class, "handlePendingException", ConstantNode.forBoolean(isObjectResult, builder.graph)));
+        invokes.add(createInvoke(builder, StubUtil.class, "handlePendingException", thread, ConstantNode.forBoolean(isObjectResult, builder.graph)));
         if (isObjectResult) {
             InvokeNode object = createInvoke(builder, HotSpotReplacementsUtil.class, "getAndClearObjectResult", thread);
             result = createInvoke(builder, StubUtil.class, "verifyObject", object);
@@ -276,7 +276,7 @@
         return locals;
     }
 
-    private InvokeNode createInvoke(GraphBuilder builder, Class<?> declaringClass, String name, ValueNode... hpeArgs) {
+    private InvokeNode createInvoke(GraphBuilder builder, Class<?> declaringClass, String name, ValueNode... args) {
         ResolvedJavaMethod method = null;
         for (Method m : declaringClass.getDeclaredMethods()) {
             if (Modifier.isStatic(m.getModifiers()) && m.getName().equals(name)) {
@@ -285,12 +285,25 @@
             }
         }
         assert method != null : "did not find method in " + declaringClass + " named " + name;
-        JavaType returnType = method.getSignature().getReturnType(null);
-        MethodCallTargetNode callTarget = builder.graph.add(new MethodCallTargetNode(InvokeKind.Static, method, hpeArgs, returnType));
+        Signature signature = method.getSignature();
+        JavaType returnType = signature.getReturnType(null);
+        assert checkArgs(method, args);
+        MethodCallTargetNode callTarget = builder.graph.add(new MethodCallTargetNode(InvokeKind.Static, method, args, returnType));
         InvokeNode invoke = builder.append(new InvokeNode(callTarget, FrameState.UNKNOWN_BCI));
         return invoke;
     }
 
+    private boolean checkArgs(ResolvedJavaMethod method, ValueNode... args) {
+        Signature signature = method.getSignature();
+        assert signature.getParameterCount(false) == args.length : target + ": wrong number of arguments to " + method;
+        for (int i = 0; i != args.length; i++) {
+            Kind expected = signature.getParameterKind(i).getStackKind();
+            Kind actual = args[i].stamp().kind();
+            assert expected == actual : target + ": wrong kind of value for argument " + i + " of calls to " + method + " [" + actual + " != " + expected + "]";
+        }
+        return true;
+    }
+
     private StubForeignCallNode createTargetCall(GraphBuilder builder, LocalNode[] locals, ReadRegisterNode thread) {
         if (prependThread) {
             ValueNode[] targetArguments = new ValueNode[1 + locals.length];
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Wed Nov 20 13:58:38 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Wed Nov 20 14:45:43 2013 +0100
@@ -102,8 +102,9 @@
         }
 
         // check that array length is small enough for fast path.
+        Word thread = registerAsWord(threadRegister);
         if (length <= MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH) {
-            Word memory = refillAllocate(threadRegister, intArrayHub, sizeInBytes, logging());
+            Word memory = refillAllocate(thread, intArrayHub, sizeInBytes, logging());
             if (memory.notEqual(0)) {
                 if (logging()) {
                     printf("newArray: allocated new array at %p\n", memory.rawValue());
@@ -115,9 +116,9 @@
             printf("newArray: calling new_array_c\n");
         }
 
-        newArrayC(NEW_ARRAY_C, registerAsWord(threadRegister), hub, length);
-        handlePendingException(true);
-        return verifyObject(getAndClearObjectResult(registerAsWord(threadRegister)));
+        newArrayC(NEW_ARRAY_C, thread, hub, length);
+        handlePendingException(thread, true);
+        return verifyObject(getAndClearObjectResult(thread));
     }
 
     public static final ForeignCallDescriptor NEW_ARRAY_C = descriptorFor(NewArrayStub.class, "newArrayC");
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Wed Nov 20 13:58:38 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Wed Nov 20 14:45:43 2013 +0100
@@ -104,9 +104,10 @@
     @Snippet
     private static Object newInstance(Word hub, @ConstantParameter Word intArrayHub, @ConstantParameter Register threadRegister) {
         int sizeInBytes = hub.readInt(klassInstanceSizeOffset(), LocationIdentity.FINAL_LOCATION);
+        Word thread = registerAsWord(threadRegister);
         if (!forceSlowPath() && inlineContiguousAllocationSupported()) {
             if (hub.readByte(klassStateOffset(), CLASS_STATE_LOCATION) == klassStateFullyInitialized()) {
-                Word memory = refillAllocate(threadRegister, intArrayHub, sizeInBytes, logging());
+                Word memory = refillAllocate(thread, intArrayHub, sizeInBytes, logging());
                 if (memory.notEqual(0)) {
                     Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
                     initializeObjectHeader(memory, prototypeMarkWord, hub);
@@ -122,9 +123,9 @@
             printf("newInstance: calling new_instance_c\n");
         }
 
-        newInstanceC(NEW_INSTANCE_C, registerAsWord(threadRegister), hub);
-        handlePendingException(true);
-        return verifyObject(getAndClearObjectResult(registerAsWord(threadRegister)));
+        newInstanceC(NEW_INSTANCE_C, thread, hub);
+        handlePendingException(thread, true);
+        return verifyObject(getAndClearObjectResult(thread));
     }
 
     /**
@@ -137,7 +138,7 @@
      * @return the newly allocated, uninitialized chunk of memory, or {@link Word#zero()} if the
      *         operation was unsuccessful
      */
-    static Word refillAllocate(Register threadRegister, Word intArrayHub, int sizeInBytes, boolean log) {
+    static Word refillAllocate(Word thread, Word intArrayHub, int sizeInBytes, boolean log) {
         // If G1 is enabled, the "eden" allocation space is not the same always
         // and therefore we have to go to slowpath to allocate a new TLAB.
         if (useG1GC()) {
@@ -149,7 +150,6 @@
         Word intArrayMarkWord = Word.unsigned(tlabIntArrayMarkWord());
         int alignmentReserveInBytes = tlabAlignmentReserveInHeapWords() * wordSize();
 
-        Word thread = registerAsWord(threadRegister);
         Word top = readTlabTop(thread);
         Word end = readTlabEnd(thread);
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Wed Nov 20 13:58:38 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Wed Nov 20 14:45:43 2013 +0100
@@ -26,6 +26,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.nodes.*;
@@ -82,11 +83,21 @@
     protected Arguments makeArguments(SnippetInfo stub) {
         Arguments args = new Arguments(stub, GuardsStage.FLOATING_GUARDS);
         for (int i = 0; i < stub.getParameterCount(); i++) {
-            args.add(stub.getParameterName(i), null);
+            String name = stub.getParameterName(i);
+            if (stub.isConstantParameter(i)) {
+                args.addConst(name, getConstantParameterValue(i, name));
+            } else {
+                assert !stub.isVarargsParameter(i);
+                args.add(name, null);
+            }
         }
         return args;
     }
 
+    protected Object getConstantParameterValue(int index, String name) {
+        throw new GraalInternalError("%s must override getConstantParameterValue() to provide a value for parameter %d%s", getClass().getName(), index, name == null ? "" : " (" + name + ")");
+    }
+
     @Override
     protected Object debugScopeContext() {
         return getInstalledCodeOwner();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Wed Nov 20 13:58:38 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Wed Nov 20 14:45:43 2013 +0100
@@ -73,10 +73,10 @@
         return new ForeignCallDescriptor(name, found.getReturnType(), cCallTypes);
     }
 
-    public static void handlePendingException(boolean isObjectResult) {
-        if (clearPendingException(thread())) {
+    public static void handlePendingException(Word thread, boolean isObjectResult) {
+        if (clearPendingException(thread)) {
             if (isObjectResult) {
-                getAndClearObjectResult(thread());
+                getAndClearObjectResult(thread);
             }
             DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint);
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Wed Nov 20 13:58:38 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Wed Nov 20 14:45:43 2013 +0100
@@ -36,7 +36,7 @@
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.replacements.*;
-import com.oracle.graal.replacements.Snippet.Fold;
+import com.oracle.graal.replacements.Snippet.*;
 import com.oracle.graal.word.*;
 
 /**
@@ -58,8 +58,14 @@
         return false;
     }
 
+    @Override
+    protected Object getConstantParameterValue(int index, String name) {
+        assert index == 2;
+        return providers.getRegisters().getThreadRegister();
+    }
+
     @Snippet
-    private static void unwindExceptionToCaller(Object exception, Word returnAddress) {
+    private static void unwindExceptionToCaller(Object exception, Word returnAddress, @ConstantParameter Register threadRegister) {
         Pointer exceptionOop = Word.fromObject(exception);
         if (logging()) {
             printf("unwinding exception %p (", exceptionOop.rawValue());
@@ -68,10 +74,11 @@
             decipher(returnAddress.rawValue());
             printf(")\n");
         }
-        checkNoExceptionInThread(assertionsEnabled());
+        Word thread = registerAsWord(threadRegister);
+        checkNoExceptionInThread(thread, assertionsEnabled());
         checkExceptionNotNull(assertionsEnabled(), exception);
 
-        Word handlerInCallerPc = exceptionHandlerForReturnAddress(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, thread(), returnAddress);
+        Word handlerInCallerPc = exceptionHandlerForReturnAddress(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, thread, returnAddress);
 
         if (logging()) {
             printf("handler for exception %p at return address %p is at %p (", exceptionOop.rawValue(), returnAddress.rawValue(), handlerInCallerPc.rawValue());
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java	Wed Nov 20 13:58:38 2013 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java	Wed Nov 20 14:45:43 2013 +0100
@@ -56,6 +56,7 @@
 
     public ReadRegisterNode(Register register, Kind kind, boolean directUse, boolean incoming) {
         super(StampFactory.forKind(kind));
+        assert register != null;
         this.register = register;
         this.directUse = directUse;
         this.incoming = incoming;
@@ -67,6 +68,7 @@
      */
     public ReadRegisterNode(Register register, boolean directUse, boolean incoming) {
         super(StampFactory.forNodeIntrinsic());
+        assert register != null;
         this.register = register;
         this.directUse = directUse;
         this.incoming = incoming;