changeset 13699:2eee4d12e00c

PTX wrapper maintains a reference to the HotSpotNmethod object for the installed GPU code so that code invalidation can be tested for in the wrapper
author Doug Simon <doug.simon@oracle.com>
date Mon, 20 Jan 2014 16:29:10 +0100
parents c3370b2e1cbc
children 3c047737189a
files graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXMethodInvalidation1Test.java graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXMethodInvalidation2Test.java graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTest.java graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java
diffstat 4 files changed, 145 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXMethodInvalidation1Test.java	Mon Jan 20 16:29:10 2014 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 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.compiler.ptx.test;
+
+import org.junit.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.ptx.*;
+
+/**
+ * Tests that a {@linkplain PTXWrapperBuilder PTX kernel wrapper} deoptimizes if the kernel is
+ * invalid.
+ */
+public class PTXMethodInvalidation1Test extends PTXTest {
+
+    @Test
+    public void test() {
+        test("testSnippet", 100);
+    }
+
+    @Override
+    protected HotSpotNmethod installKernel(ResolvedJavaMethod method, ExternalCompilationResult ptxCode) {
+        HotSpotNmethod ptxKernel = super.installKernel(method, ptxCode);
+        ptxKernel.invalidate();
+        return ptxKernel;
+    }
+
+    int f = 42;
+
+    public int testSnippet(int delta) {
+        return f + delta;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXMethodInvalidation2Test.java	Mon Jan 20 16:29:10 2014 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 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.compiler.ptx.test;
+
+import org.junit.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.ptx.*;
+import com.oracle.graal.nodes.*;
+
+/**
+ * A full GC on HotSpot will unload an nmethod that has an embedded oop that is only referenced from
+ * the nmethod. The nmethod created for a {@linkplain PTXWrapperBuilder PTX kernel wrapper} has an
+ * embedded oop referring to the {@link HotSpotNmethod} linked with the nmethod for the installed
+ * PTX kernel. This embedded oop is a weak as described above sp there must be another strong
+ * reference from the wrapper to the {@link HotSpotNmethod} object.
+ */
+public class PTXMethodInvalidation2Test extends PTXTest {
+
+    @Test
+    public void test() {
+        test("testSnippet", 100);
+    }
+
+    @Override
+    @Ignore("still need to make a strong reference from a PTX wrapper to a PTX kernel")
+    protected InstalledCode getCode(ResolvedJavaMethod method, StructuredGraph graph) {
+        InstalledCode code = super.getCode(method, graph);
+
+        // This seems to result in a full GC on HotSpot but there's no guarantee of that
+        System.gc();
+
+        Assert.assertFalse(code.getStart() == 0L);
+        return code;
+    }
+
+    int f = 42;
+
+    public int testSnippet(int delta) {
+        return f + delta;
+    }
+}
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTest.java	Mon Jan 20 16:27:24 2014 +0100
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTest.java	Mon Jan 20 16:29:10 2014 +0100
@@ -57,13 +57,18 @@
         return compileKernel(getMetaAccess().lookupJavaMethod(getMethod(test)));
     }
 
+    protected HotSpotNmethod installKernel(ResolvedJavaMethod method, ExternalCompilationResult ptxCode) {
+        PTXHotSpotBackend ptxBackend = getPTXBackend();
+        return ptxBackend.installKernel(method, ptxCode);
+    }
+
     @Override
     protected InstalledCode getCode(ResolvedJavaMethod method, StructuredGraph graph) {
         PTXHotSpotBackend ptxBackend = getPTXBackend();
         ExternalCompilationResult ptxCode = compileKernel(method);
         Assume.assumeTrue(ptxBackend.isDeviceInitialized());
-        InstalledCode installedPTXCode = ptxBackend.installKernel(method, ptxCode);
-        StructuredGraph wrapper = new PTXWrapperBuilder(method, installedPTXCode.getStart(), (HotSpotProviders) getProviders()).getGraph();
+        HotSpotNmethod installedPTXCode = installKernel(method, ptxCode);
+        StructuredGraph wrapper = new PTXWrapperBuilder(method, installedPTXCode, (HotSpotProviders) getProviders()).getGraph();
         return super.getCode(method, wrapper);
     }
 
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java	Mon Jan 20 16:27:24 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java	Mon Jan 20 16:29:10 2014 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.hotspot.ptx;
 
+import static com.oracle.graal.api.meta.DeoptimizationAction.*;
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.api.meta.LocationIdentity.*;
 import static com.oracle.graal.api.meta.MetaUtil.*;
@@ -97,9 +98,9 @@
      * Creates the graph implementing the CPU to GPU transition.
      * 
      * @param method a method that has been compiled to GPU binary code
-     * @param kernelAddress the entry point of the GPU binary for {@code kernelMethod}
+     * @param ptxInstalledCode the installed GPU binary for {@code method}
      */
-    public PTXWrapperBuilder(ResolvedJavaMethod method, long kernelAddress, HotSpotProviders providers) {
+    public PTXWrapperBuilder(ResolvedJavaMethod method, HotSpotNmethod ptxInstalledCode, HotSpotProviders providers) {
         super(new StructuredGraph(method), providers);
         int wordSize = providers.getCodeCache().getTarget().wordSize;
         Kind wordKind = providers.getCodeCache().getTarget().wordKind;
@@ -132,11 +133,13 @@
             }
         }
 
+        InvokeNode kernel = createInvoke(getClass(), "getKernelStart", ConstantNode.forObject(ptxInstalledCode, providers.getMetaAccess(), getGraph()));
+
         AllocaNode buf = append(new AllocaNode(bufSize / wordSize, objects));
 
         Map<LaunchArg, ValueNode> args = new EnumMap<>(LaunchArg.class);
         args.put(Thread, append(new ReadRegisterNode(providers.getRegisters().getThreadRegister(), true, false)));
-        args.put(Kernel, ConstantNode.forLong(kernelAddress, getGraph()));
+        args.put(Kernel, kernel);
         args.put(DimX, forInt(1, getGraph()));
         args.put(DimY, forInt(1, getGraph()));
         args.put(DimZ, forInt(1, getGraph()));
@@ -252,6 +255,19 @@
     }
 
     /**
+     * Snippet invoked to get the {@linkplain HotSpotNmethod#getStart() entry point} of the kernel,
+     * deoptimizing if the kernel is invalid.
+     */
+    @Snippet
+    private static long getKernelStart(HotSpotNmethod ptxKernel) {
+        long start = ptxKernel.getStart();
+        if (start == 0L) {
+            DeoptimizeNode.deopt(InvalidateRecompile, RuntimeConstraint);
+        }
+        return start;
+    }
+
+    /**
      * Snippet invoked upon return from the kernel to handle any pending exceptions.
      */
     @Snippet