# HG changeset patch # User Doug Simon # Date 1390231750 -3600 # Node ID 2eee4d12e00c712b1f351444e180d2e4b5aa450a # Parent c3370b2e1cbcf206190443ec138ae01269966834 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 diff -r c3370b2e1cbc -r 2eee4d12e00c graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXMethodInvalidation1Test.java --- /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; + } +} diff -r c3370b2e1cbc -r 2eee4d12e00c graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXMethodInvalidation2Test.java --- /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; + } +} diff -r c3370b2e1cbc -r 2eee4d12e00c graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTest.java --- 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); } diff -r c3370b2e1cbc -r 2eee4d12e00c graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java --- 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 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