changeset 13834:4ca607fc94e0

Merge.
author Doug Simon <doug.simon@oracle.com>
date Fri, 31 Jan 2014 00:32:03 +0100
parents fe99bfb55626 (diff) 5c8a3c09397b (current diff)
children 67e4e7f56911
files src/gpu/ptx/vm/gpu_ptx.cpp
diffstat 7 files changed, 35 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ObjectPTXTest.java	Thu Jan 30 17:49:56 2014 -0500
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ObjectPTXTest.java	Fri Jan 31 00:32:03 2014 +0100
@@ -40,7 +40,6 @@
         double d;
     }
 
-    @Ignore("Object parameters not yet GC safe")
     @Test
     public void test0() {
         for (long l : new long[]{Long.MIN_VALUE, -10, 0, 1, 2, 10, Long.MAX_VALUE}) {
@@ -54,7 +53,6 @@
         return a.l + l;
     }
 
-    @Ignore("Object parameters not yet GC safe")
     @Test
     public void test1() {
         for (int i : new int[]{Integer.MIN_VALUE, -10, 0, 1, 2, 10, Integer.MAX_VALUE}) {
@@ -68,7 +66,6 @@
         return a.i + i;
     }
 
-    @Ignore("Object parameters not yet GC safe")
     @Test
     public void test2() {
         A a = new A();
@@ -82,7 +79,6 @@
         return a.z;
     }
 
-    @Ignore("Object parameters not yet GC safe")
     @Test
     public void test3() {
         for (byte b : new byte[]{Byte.MIN_VALUE, -10, 0, 1, 2, 10, Byte.MAX_VALUE}) {
@@ -96,7 +92,6 @@
         return a.b + b;
     }
 
-    @Ignore("Object parameters not yet GC safe")
     @Test
     public void test4() {
         for (short s : new short[]{Short.MIN_VALUE, -10, 0, 1, 2, 10, Short.MAX_VALUE}) {
@@ -110,7 +105,7 @@
         return a.s + s;
     }
 
-    @Ignore("Object parameters not yet GC safe")
+    @Ignore("java.lang.AssertionError: expected:<65531> but was:<809107451>")
     @Test
     public void test5() {
         for (char c : new char[]{Character.MIN_VALUE, 1, 2, 10, Character.MAX_VALUE}) {
@@ -124,7 +119,6 @@
         return a.c + c;
     }
 
-    @Ignore("Object parameters not yet GC safe")
     @Test
     public void test6() {
         for (float f : new float[]{Float.MIN_VALUE, Float.MIN_NORMAL, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, Float.NaN, -11.45F, -0.0F, 0.0F, 2, 10, Float.MAX_VALUE}) {
@@ -138,7 +132,6 @@
         return a.f + f;
     }
 
-    @Ignore("Object parameters not yet GC safe")
     @Test
     public void test7() {
         for (double d : new double[]{Double.MIN_VALUE, Double.MIN_NORMAL, Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY - 11.45D, -0.0D, 0.0D, 2, 10, Double.MAX_VALUE}) {
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Thu Jan 30 17:49:56 2014 -0500
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Fri Jan 31 00:32:03 2014 +0100
@@ -299,7 +299,11 @@
         } else {
             // No need to emit the stubs for entries back into the method since
             // it has no calls that can cause such "return" entries
-            assert !frameMap.accessesCallerFrame() : lirGen.getGraph();
+
+            if (frameContext.omitFrame) {
+                // Cannot access slots in caller's frame if my frame is omitted
+                assert !frameMap.accessesCallerFrame() : lirGen.getGraph();
+            }
         }
     }
 }
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Thu Jan 30 17:49:56 2014 -0500
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Fri Jan 31 00:32:03 2014 +0100
@@ -22,11 +22,9 @@
  */
 package com.oracle.graal.hotspot.ptx;
 
-import static com.oracle.graal.api.code.CallingConvention.Type.*;
 import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.api.meta.LocationIdentity.*;
 import static com.oracle.graal.compiler.GraalCompiler.*;
-import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*;
 import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*;
 import static com.oracle.graal.hotspot.meta.HotSpotForeignCallsProviderImpl.*;
 import static com.oracle.graal.lir.LIRValueUtil.*;
@@ -133,10 +131,11 @@
 
     @Override
     public void completeInitialization() {
-        HotSpotHostForeignCallsProvider hostForeignCalls = (HotSpotHostForeignCallsProvider) getRuntime().getHostProviders().getForeignCalls();
+        HotSpotProviders hostProviders = getRuntime().getHostProviders();
+        HotSpotHostForeignCallsProvider hostForeignCalls = (HotSpotHostForeignCallsProvider) hostProviders.getForeignCalls();
         if (deviceInitialized) {
             long launchKernel = getLaunchKernelAddress();
-            hostForeignCalls.registerForeignCall(CALL_KERNEL, launchKernel, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
+            hostForeignCalls.linkForeignCall(hostProviders, CALL_KERNEL, launchKernel, false, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
         }
         super.completeInitialization();
     }
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java	Thu Jan 30 17:49:56 2014 -0500
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java	Fri Jan 31 00:32:03 2014 +0100
@@ -105,12 +105,12 @@
  * <p>
  * The generated graph includes a reference to the {@link HotSpotNmethod} for the kernel. There must
  * be another reference to the same {@link HotSpotNmethod} object to ensure that the nmethod is not
- * unloaded by the next full GC.
+ * unloaded by the next full GC. Currently, these extra "keep-alive" references are maintained by
+ * {@link PTXHotSpotBackend}.
  * <p>
- * TODO: Only the memory for objects passed as parameters is pinned. Surely the memory for other
- * objects accessed in the kernel reachable from the parameter objects needs to be pinned as well?
- * <p>
- * TODO: Objects references within kernels are currently completely hidden from GC.
+ * The PTX runtime code called by the wrapper blocks GC while the kernel is executing (cf
+ * GetPrimitiveArrayCritical/ReleasePrimitiveArrayCritical JNI functions). This ensures objects can
+ * be safely passed to kernels but should be replaced with a lighter weight mechanism at some point.
  */
 public class PTXWrapperBuilder extends GraphKit {
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Thu Jan 30 17:49:56 2014 -0500
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Fri Jan 31 00:32:03 2014 +0100
@@ -219,7 +219,6 @@
         } else {
             // No need to emit the stubs for entries back into the method since
             // it has no calls that can cause such "return" entries
-            assert !frameMap.accessesCallerFrame() : lirGen.getGraph();
         }
 
         if (unverifiedStub != null) {
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java	Thu Jan 30 17:49:56 2014 -0500
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java	Fri Jan 31 00:32:03 2014 +0100
@@ -54,6 +54,7 @@
         public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
             PTXAddress addr = address.toAddress();
             switch (kind) {
+                case Boolean:
                 case Byte:
                 case Short:
                 case Char:
--- a/src/gpu/ptx/vm/gpu_ptx.cpp	Thu Jan 30 17:49:56 2014 -0500
+++ b/src/gpu/ptx/vm/gpu_ptx.cpp	Fri Jan 31 00:32:03 2014 +0100
@@ -29,6 +29,7 @@
 #include "utilities/ostream.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/gcLocker.inline.hpp"
 #include "runtime/interfaceSupport.hpp"
 #include "graal/graalEnv.hpp"
 #include "graal/graalCompiler.hpp"
@@ -431,13 +432,14 @@
   gpu::Ptx::CUdeviceptr  _ret_value;     // pointer to slot in GPU memory holding the return value
   int          _ret_type_size; // size of the return type value
   bool         _ret_is_object; // specifies if the return type is Object
+  bool         _gc_locked;
 
   bool check(int status, const char *action) {
     if (status != GRAAL_CUDA_SUCCESS) {
       Thread* THREAD = _thread;
       char* message = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, O_BUFLEN + 1);
       jio_snprintf(message, O_BUFLEN, "[CUDA] *** Error (status=%d): %s", status, action);
-      if (TraceGPUInteraction || HAS_PENDING_EXCEPTION) {
+      if (TraceGPUInteraction) {
         tty->print_cr(message);
       }
       if (!HAS_PENDING_EXCEPTION) {
@@ -452,7 +454,7 @@
   }
 
  public:
-  PtxCall(JavaThread* thread, address buffer, int buffer_size, oop* pinned, int encodedReturnTypeSize) : _thread(thread),
+  PtxCall(JavaThread* thread, address buffer, int buffer_size, oop* pinned, int encodedReturnTypeSize) : _thread(thread), _gc_locked(false),
       _buffer(buffer), _buffer_size(buffer_size), _pinned(pinned), _pinned_length(0), _ret_value(0), _ret_is_object(encodedReturnTypeSize < 0) {
     _ret_type_size = _ret_is_object ? -encodedReturnTypeSize : encodedReturnTypeSize;
   }
@@ -472,6 +474,16 @@
     if (count == 0) {
       return;
     }
+    // Once we start pinning objects, no GC must occur
+    // until the kernel has completed. This is a big
+    // hammer for ensuring we can safely pass objects
+    // to the GPU.
+    GC_locker::lock_critical(_thread);
+    _gc_locked = true;
+    if (TraceGPUInteraction) {
+      tty->print_cr("[CUDA] Locked GC");
+    }
+
     for (int i = 0; i < count; i++) {
       int offset = objectOffsets[i];
       oop* argPtr = (oop*) (_buffer + offset);
@@ -558,6 +570,12 @@
     unpin_objects();
     free_return_value();
     destroy_context();
+    if (_gc_locked) {
+      GC_locker::unlock_critical(_thread);
+      if (TraceGPUInteraction) {
+        tty->print_cr("[CUDA] Unlocked GC");
+      }
+    }
   }
 };
 
@@ -577,10 +595,6 @@
     return 0L;
   }
 
-#if 0
-  Universe::heap()->collect(GCCause::_jvmti_force_gc);
-#endif
-
   PtxCall call(thread, (address) buffer, bufferSize, (oop*) (address) pinnedObjects, encodedReturnTypeSize);
 
 #define TRY(action) do { \