changeset 12743:f1a55428a8d7

more HSAIL support in the C++ layer for executing HSAIL code on the simulator Contributed-by: Eric Caspole <eric.caspole@amd.com>
author Doug Simon <doug.simon@oracle.com>
date Sun, 10 Nov 2013 13:18:09 +0100
parents 40924dbc623b
children 41f0bd213b51
files graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILCompilationResult.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java hotspot/.project make/linux/makefiles/buildtree.make make/linux/makefiles/vm.make make/windows/makefiles/projectcreator.make make/windows/makefiles/vm.make src/gpu/hsail/vm/gpu_hsail.cpp src/gpu/hsail/vm/gpu_hsail.hpp src/gpu/hsail/vm/hsailKernelArguments.cpp src/gpu/hsail/vm/hsailKernelArguments.hpp src/os_gpu/linux_ptx/vm/gpu_linux.cpp src/os_gpu/windows_hsail/vm/gpu_windows.cpp src/os_gpu/windows_hsail/vm/gpu_windows.hpp src/share/vm/graal/graalCompilerToGPU.cpp src/share/vm/graal/graalEnv.cpp src/share/vm/runtime/globals.hpp src/share/vm/runtime/gpu.cpp src/share/vm/runtime/gpu.hpp
diffstat 22 files changed, 835 insertions(+), 82 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java	Sun Nov 10 11:42:31 2013 +0100
+++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java	Sun Nov 10 13:18:09 2013 +0100
@@ -32,8 +32,11 @@
 import java.io.*;
 import java.lang.reflect.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.hsail.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.options.*;
 
 public abstract class GraalKernelTester extends KernelTester {
@@ -43,9 +46,9 @@
     private boolean saveInFile = false;
 
     @Override
-    public String getCompiledHSAILSource(Method testMethod) {
+    public String getCompiledHSAILSource(Method method) {
         if (hsailCompResult == null) {
-            hsailCompResult = HSAILCompilationResult.getHSAILCompilationResult(testMethod);
+            hsailCompResult = HSAILCompilationResult.getHSAILCompilationResult(method);
         }
         String hsailSource = hsailCompResult.getHSAILCode();
         if (showHsailSource) {
@@ -78,6 +81,56 @@
         return (canGenerateCalls && canExecuteCalls);
     }
 
+    @Override
+    protected void dispatchLambdaMethodKernelOkra(int range, MyIntConsumer consumer) {
+        HSAILCompilationResult hcr = HSAILCompilationResult.getCompiledLambda(consumer.getClass());
+        HotSpotNmethod code = (HotSpotNmethod) hcr.getInstalledCode();
+
+        logger.info("To determine parameters to pass to hsail kernel, we will examine   " + consumer.getClass());
+        Field[] fields = consumer.getClass().getDeclaredFields();
+        Object[] args = new Object[fields.length];
+        int argIndex = 0;
+        for (Field f : fields) {
+            logger.info("... " + f);
+            args[argIndex++] = getFieldFromObject(f, consumer);
+        }
+
+        if (code != null) {
+            try {
+                // No return value from HSAIL kernels
+                code.executeParallel(range, 0, 0, args);
+            } catch (InvalidInstalledCodeException e) {
+                Debug.log("WARNING:Invalid installed code: " + e);
+                e.printStackTrace();
+            }
+        }
+    }
+
+    @Override
+    protected void dispatchMethodKernelOkra(int range, Object... args) {
+        Object[] fixedArgs = fixArgTypes(args);
+
+        HSAILCompilationResult hcr = HSAILCompilationResult.getHSAILCompilationResult(testMethod);
+        HotSpotNmethod code = (HotSpotNmethod) hcr.getInstalledCode();
+
+        if (code != null) {
+            try {
+                if (Modifier.isStatic(testMethod.getModifiers())) {
+                    code.executeParallel(range, 0, 0, fixedArgs);
+                } else {
+                    // If it is a non-static method we have to push "this" as the first argument.
+                    Object[] newFixedArgs = new Object[fixedArgs.length + 1];
+                    System.arraycopy(fixedArgs, 0, newFixedArgs, 1, fixedArgs.length);
+                    newFixedArgs[0] = this;
+                    code.executeParallel(range, 0, 0, newFixedArgs);
+                }
+            } catch (InvalidInstalledCodeException e) {
+                Debug.log("WARNING:Invalid installed code: " + e);
+                e.printStackTrace();
+            }
+        }
+    }
+
     public static OptionValue<?> getOptionFromField(Class declaringClass, String fieldName) {
         try {
             Field f = declaringClass.getDeclaredField(fieldName);
--- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java	Sun Nov 10 11:42:31 2013 +0100
+++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java	Sun Nov 10 13:18:09 2013 +0100
@@ -72,7 +72,7 @@
     public DispatchMode dispatchMode;
     // Where the hsail comes from.
     private HsailMode hsailMode;
-    private Method testMethod;
+    protected Method testMethod;
     // What type of okra dispatch to use when client calls.
     private boolean useLambdaMethod;
     private Class<?>[] testMethodParams = null;
@@ -581,7 +581,7 @@
         }
     }
 
-    private void dispatchMethodKernelOkra(int range, Object... args) {
+    protected void dispatchMethodKernelOkra(int range, Object... args) {
         Object[] fixedArgs = fixArgTypes(args);
         if (Modifier.isStatic(testMethod.getModifiers())) {
             dispatchKernelOkra(range, fixedArgs);
@@ -598,7 +598,7 @@
      * For primitive arg parameters, make sure arg types are cast to whatever the testMethod
      * signature says they should be.
      */
-    private Object[] fixArgTypes(Object[] args) {
+    protected Object[] fixArgTypes(Object[] args) {
         Object[] fixedArgs = new Object[args.length];
         for (int i = 0; i < args.length; i++) {
             Class<?> paramClass = testMethodParams[i];
@@ -644,7 +644,7 @@
      * the lambda method itself as opposed to the wrapper that calls the lambda method. From the
      * consumer object, we need to find the fields and pass them to the kernel.
      */
-    private void dispatchLambdaMethodKernelOkra(int range, MyIntConsumer consumer) {
+    protected void dispatchLambdaMethodKernelOkra(int range, MyIntConsumer consumer) {
         logger.info("To determine parameters to pass to hsail kernel, we will examine   " + consumer.getClass());
         Field[] fields = consumer.getClass().getDeclaredFields();
         Object[] args = new Object[fields.length];
@@ -747,7 +747,7 @@
         newInstance().compareOkraToSeq(HsailMode.INJECT_OCL);
     }
 
-    private static Object getFieldFromObject(Field f, Object fromObj) {
+    protected static Object getFieldFromObject(Field f, Object fromObj) {
         try {
             f.setAccessible(true);
             Type type = f.getType();
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java	Sun Nov 10 11:42:31 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java	Sun Nov 10 13:18:09 2013 +0100
@@ -23,20 +23,10 @@
 
 package com.oracle.graal.hotspot.hsail;
 
-import java.lang.reflect.*;
-
-import com.amd.okra.*;
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.hsail.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.java.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.phases.*;
 
 /**
  * Implements compile and dispatch of Java code containing lambda constructs. Currently only used by
@@ -44,78 +34,41 @@
  */
 public class ForEachToGraal implements CompileAndDispatch {
 
-    private static CompilationResult getCompiledLambda(Class consumerClass) {
-        /**
-         * Find the accept() method in the IntConsumer, then use Graal API to find the target lambda
-         * that accept will call.
-         */
-        Method[] icMethods = consumerClass.getMethods();
-        Method acceptMethod = null;
-        for (Method m : icMethods) {
-            if (m.getName().equals("accept") && acceptMethod == null) {
-                acceptMethod = m;
-            }
-        }
-        HotSpotProviders providers = HSAILCompilationResult.backend.getProviders();
-        MetaAccessProvider metaAccess = providers.getMetaAccess();
-        ResolvedJavaMethod method = metaAccess.lookupJavaMethod(acceptMethod);
-        StructuredGraph graph = new StructuredGraph(method);
-        ForeignCallsProvider foreignCalls = providers.getForeignCalls();
-        new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
-        NodeIterable<Node> nin = graph.getNodes();
-        ResolvedJavaMethod lambdaMethod = null;
-        for (Node n : nin) {
-            if (n instanceof MethodCallTargetNode) {
-                lambdaMethod = ((MethodCallTargetNode) n).targetMethod();
-                Debug.log("target ... " + lambdaMethod);
-                break;
-            }
-        }
-        if (lambdaMethod == null) {
-            // Did not find call in Consumer.accept.
-            Debug.log("Should not Reach here, did not find call in accept()");
-            return null;
-        }
-        // Now that we have the target lambda, compile it.
-        HSAILCompilationResult hsailCompResult = HSAILCompilationResult.getHSAILCompilationResult(lambdaMethod);
-        if (hsailCompResult != null) {
-            hsailCompResult.dumpCompilationResult();
-        }
-        return hsailCompResult;
+    private static HSAILCompilationResult getCompiledLambda(Class consumerClass) {
+        return HSAILCompilationResult.getCompiledLambda(consumerClass);
     }
 
     // Implementations of the CompileAndDispatch interface.
     @Override
     public Object createKernel(Class<?> consumerClass) {
         try {
-            CompilationResult result = getCompiledLambda(consumerClass);
-            if (result != null) {
-                String code = new String(new String(result.getTargetCode(), 0, result.getTargetCodeSize()));
-                OkraContext okraContext = new OkraContext();
-                OkraKernel okraKernel = new OkraKernel(okraContext, code, "&run");
-                if (okraKernel.isValid()) {
-                    return okraKernel;
-                }
-            }
+            return getCompiledLambda(consumerClass);
         } catch (Throwable e) {
             // Note: Graal throws Errors. We want to revert to regular Java in these cases.
             Debug.log("WARNING:Graal compilation failed.");
             e.printStackTrace();
             return null;
         }
-        // If we got this far, return null.
-        return null;
     }
 
     @Override
     public boolean dispatchKernel(Object kernel, int jobSize, Object[] args) {
-        if (!(kernel instanceof OkraKernel)) {
-            Debug.log("unknown kernel for dispatchKernel");
+        // kernel is an HSAILCompilationResult
+        HotSpotNmethod code = (HotSpotNmethod) ((HSAILCompilationResult) kernel).getInstalledCode();
+
+        if (code != null) {
+            try {
+                // No return value from HSAIL kernels
+                code.executeParallel(jobSize, 0, 0, args);
+                return true;
+            } catch (InvalidInstalledCodeException iice) {
+                Debug.log("WARNING:Invalid installed code at exec time." + iice);
+                iice.printStackTrace();
+                return false;
+            }
+        } else {
+            // Should throw something sensible here
             return false;
         }
-        OkraKernel okraKernel = (OkraKernel) kernel;
-        okraKernel.setLaunchAttributes(jobSize);
-        int status = okraKernel.dispatchWithArgs(args);
-        return (status == 0);
     }
 }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILCompilationResult.java	Sun Nov 10 11:42:31 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILCompilationResult.java	Sun Nov 10 13:18:09 2013 +0100
@@ -35,10 +35,14 @@
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.bridge.CompilerToGPU;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hsail.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
@@ -49,10 +53,24 @@
 /**
  * Class that represents a HSAIL compilation result. Includes the compiled HSAIL code.
  */
-public class HSAILCompilationResult extends CompilationResult {
+public class HSAILCompilationResult extends ExternalCompilationResult {
 
     private static final long serialVersionUID = -4178700465275724625L;
 
+    private static CompilerToGPU toGPU = HotSpotGraalRuntime.runtime().getCompilerToGPU();
+    private static boolean validDevice = toGPU.deviceInit();
+
+    // The installedCode is the executable representation of the kernel in the code cache
+    private InstalledCode installedCode;
+
+    public void setInstalledCode(InstalledCode newCode) {
+        installedCode = newCode;
+    }
+
+    public InstalledCode getInstalledCode() {
+        return installedCode;
+    }
+
     private static final String propPkgName = HSAILCompilationResult.class.getPackage().getName();
     private static Level logLevel;
     private static ConsoleHandler consoleHandler;
@@ -131,6 +149,48 @@
         return registerConfig.getCallingConvention(type, retType, argTypes, target, stackOnly);
     }
 
+    public static HSAILCompilationResult getCompiledLambda(Class consumerClass) {
+        /**
+         * Find the accept() method in the IntConsumer, then use Graal API to find the target lambda
+         * that accept will call.
+         */
+        Method[] icMethods = consumerClass.getMethods();
+        Method acceptMethod = null;
+        for (Method m : icMethods) {
+            if (m.getName().equals("accept") && acceptMethod == null) {
+                acceptMethod = m;
+                break;
+            }
+        }
+
+        Providers providers = backend.getProviders();
+        HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) providers.getMetaAccess();
+        ResolvedJavaMethod rm = metaAccess.lookupJavaMethod(acceptMethod);
+        StructuredGraph graph = new StructuredGraph(rm);
+        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(providers.getMetaAccess(), providers.getForeignCalls(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
+        graphBuilderPhase.apply(graph);
+        NodeIterable<Node> nin = graph.getNodes();
+        ResolvedJavaMethod lambdaMethod = null;
+        for (Node n : nin) {
+            if (n instanceof MethodCallTargetNode) {
+                lambdaMethod = ((MethodCallTargetNode) n).targetMethod();
+                Debug.log("target ... " + lambdaMethod);
+                break;
+            }
+        }
+        if (lambdaMethod == null) {
+            // Did not find call in Consumer.accept.
+            Debug.log("Should not Reach here, did not find call in accept()");
+            return null;
+        }
+        // Now that we have the target lambda, compile it.
+        HSAILCompilationResult hsailCompResult = HSAILCompilationResult.getHSAILCompilationResult(lambdaMethod);
+        if (hsailCompResult != null) {
+            hsailCompResult.dumpCompilationResult();
+        }
+        return hsailCompResult;
+    }
+
     public static HSAILCompilationResult getHSAILCompilationResult(StructuredGraph graph) {
         Debug.dump(graph, "Graph");
         Providers providers = backend.getProviders();
@@ -145,7 +205,22 @@
         try {
             HSAILCompilationResult compResult = GraalCompiler.compileGraph(graph, cc, graph.method(), providers, backend, target, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(),
                             suitesProvider.getDefaultSuites(), new HSAILCompilationResult());
+            if ((validDevice) && (compResult.getTargetCode() != null)) {
+                long kernel = toGPU.generateKernel(compResult.getTargetCode(), graph.method().getName());
+
+                if (kernel == 0) {
+                    throw new GraalInternalError("Failed to compile kernel.");
+                }
+
+                ((ExternalCompilationResult) compResult).setEntryPoint(kernel);
+                HotSpotResolvedJavaMethod compiledMethod = (HotSpotResolvedJavaMethod) graph.method();
+                InstalledCode installedCode = ((HotSpotCodeCacheProvider) providers.getCodeCache()).addExternalMethod(compiledMethod, compResult);
+                compResult.setInstalledCode(installedCode);
+            }
             return compResult;
+        } catch (InvalidInstalledCodeException e) {
+            e.printStackTrace();
+            return null;
         } catch (GraalInternalError e) {
             String partialCode = backend.getPartialCodeString();
             if (partialCode != null && !partialCode.equals("")) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Sun Nov 10 11:42:31 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Sun Nov 10 13:18:09 2013 +0100
@@ -116,7 +116,9 @@
     }
 
     public Object executeParallel(int dimX, int dimY, int dimZ, Object... args) throws InvalidInstalledCodeException {
-        assert checkArgs(args);
+
+        // For HSAIL, we do not pass the iteration variable, it comes from the workitemid
+        // assert checkArgs(args);
 
         assert isExternal(); // for now
 
--- a/hotspot/.project	Sun Nov 10 11:42:31 2013 +0100
+++ b/hotspot/.project	Sun Nov 10 13:18:09 2013 +0100
@@ -101,6 +101,11 @@
 			<locationURI>PARENT-1-PROJECT_LOC/src/gpu/ptx/vm</locationURI>
 		</link>
 		<link>
+			<name>hsail</name>
+			<type>2</type>
+			<locationURI>PARENT-1-PROJECT_LOC/src/gpu/hsail/vm</locationURI>
+		</link>
+		<link>
 			<name>sparc</name>
 			<type>2</type>
 			<locationURI>PARENT-1-PROJECT_LOC/src/cpu/sparc/vm</locationURI>
@@ -151,6 +156,11 @@
 			<locationURI>PARENT-1-PROJECT_LOC/src/os_cpu/linux_x86/vm</locationURI>
 		</link>
 		<link>
+			<name>windows_hsail</name>
+			<type>2</type>
+			<locationURI>PARENT-1-PROJECT_LOC/src/os_gpu/windows_hsail/vm</locationURI>
+		</link>
+		<link>
 			<name>linux_ptx</name>
 			<type>2</type>
 			<locationURI>PARENT-1-PROJECT_LOC/src/os_gpu/linux_ptx/vm</locationURI>
--- a/make/linux/makefiles/buildtree.make	Sun Nov 10 11:42:31 2013 +0100
+++ b/make/linux/makefiles/buildtree.make	Sun Nov 10 13:18:09 2013 +0100
@@ -242,7 +242,9 @@
 	echo "$(call gamma-path,altsrc,os/posix/vm) \\"; \
 	echo "$(call gamma-path,commonsrc,os/posix/vm) \\"; \
 	echo "$(call gamma-path,altsrc,gpu/ptx/vm) \\"; \
-	echo "$(call gamma-path,commonsrc,gpu/ptx/vm)"; \
+	echo "$(call gamma-path,commonsrc,gpu/ptx/vm)" \\; \
+	echo "$(call gamma-path,altsrc,gpu/hsail/vm) \\"; \
+	echo "$(call gamma-path,commonsrc,gpu/hsail/vm)"; \
 	echo; \
 	echo "Src_Dirs_I = \\"; \
 	echo "$(call gamma-path,altsrc,share/vm/prims) \\"; \
--- a/make/linux/makefiles/vm.make	Sun Nov 10 11:42:31 2013 +0100
+++ b/make/linux/makefiles/vm.make	Sun Nov 10 13:18:09 2013 +0100
@@ -157,6 +157,7 @@
 SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm
 SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
 SOURCE_PATHS+=$(HS_COMMON_SRC)/gpu/ptx/vm
+SOURCE_PATHS+=$(HS_COMMON_SRC)/gpu/hsail/vm
 SOURCE_PATHS+=$(HS_COMMON_SRC)/os_gpu/linux_ptx/vm
 
 CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
--- a/make/windows/makefiles/projectcreator.make	Sun Nov 10 11:42:31 2013 +0100
+++ b/make/windows/makefiles/projectcreator.make	Sun Nov 10 13:18:09 2013 +0100
@@ -56,6 +56,7 @@
         -relativeInclude src\os\windows\vm \
         -relativeInclude src\os_cpu\windows_$(Platform_arch)\vm \
         -relativeInclude src\cpu\$(Platform_arch)\vm \
+        -relativeInclude src\os_gpu\windows_hsail\vm \
         -relativeInclude src\gpu \
         -absoluteInclude $(HOTSPOTBUILDSPACE)/%f/generated \
         -relativeSrcInclude src \
--- a/make/windows/makefiles/vm.make	Sun Nov 10 11:42:31 2013 +0100
+++ b/make/windows/makefiles/vm.make	Sun Nov 10 13:18:09 2013 +0100
@@ -126,6 +126,7 @@
   /I "$(COMMONSRC)\share\vm\prims" \
   /I "$(COMMONSRC)\os\windows\vm" \
   /I "$(COMMONSRC)\os_cpu\windows_$(Platform_arch)\vm" \
+  /I "$(COMMONSRC)\os_gpu\windows_hsail\vm" \
   /I "$(COMMONSRC)\cpu\$(Platform_arch)\vm"
 
 CXX_DONT_USE_PCH=/D DONT_USE_PRECOMPILED_HEADER
@@ -170,6 +171,7 @@
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/libadt
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/os/windows/vm
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/os_cpu/windows_$(Platform_arch)/vm
+VM_PATH=$(VM_PATH);$(WorkSpace)/src/os_gpu/windows_hsail/vm
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/cpu/$(Platform_arch)/vm
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/opto
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gpu/hsail/vm/gpu_hsail.cpp	Sun Nov 10 13:18:09 2013 +0100
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "runtime/javaCalls.hpp"
+#include "runtime/gpu.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/ostream.hpp"
+#include "memory/allocation.hpp"
+#include "memory/allocation.inline.hpp"
+#include "hsailKernelArguments.hpp"
+
+void * gpu::Hsail::_device_context;
+
+gpu::Hsail::okra_ctx_create_func_t      gpu::Hsail::_okra_ctx_create;
+gpu::Hsail::okra_kernel_create_func_t   gpu::Hsail::_okra_kernel_create;
+gpu::Hsail::okra_push_object_func_t     gpu::Hsail::_okra_push_object;
+gpu::Hsail::okra_push_boolean_func_t    gpu::Hsail::_okra_push_boolean;
+gpu::Hsail::okra_push_byte_func_t       gpu::Hsail::_okra_push_byte;
+gpu::Hsail::okra_push_double_func_t     gpu::Hsail::_okra_push_double;
+gpu::Hsail::okra_push_float_func_t      gpu::Hsail::_okra_push_float;
+gpu::Hsail::okra_push_int_func_t        gpu::Hsail::_okra_push_int;
+gpu::Hsail::okra_push_long_func_t       gpu::Hsail::_okra_push_long;
+gpu::Hsail::okra_execute_with_range_func_t    gpu::Hsail::_okra_execute_with_range;
+gpu::Hsail::okra_clearargs_func_t       gpu::Hsail::_okra_clearargs;
+gpu::Hsail::okra_register_heap_func_t   gpu::Hsail::_okra_register_heap;
+
+
+bool gpu::Hsail::initialize_gpu() {
+  // All the initialization is done in the okra library so
+  // nothing to do here.
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] Simulator: initialize_gpu");
+  }
+  return true;
+}
+
+unsigned int gpu::Hsail::total_cores() {
+  // This is not important with simulator
+  return 1;
+}
+
+void gpu::Hsail::register_heap() {
+  // After the okra functions are set up and the heap is initialized, register the java heap with HSA
+  guarantee(Universe::heap() != NULL, "heap should be there by now.");
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] heap=" PTR_FORMAT, Universe::heap());
+    tty->print_cr("[HSAIL] base=0x%08x, capacity=%ld", Universe::heap()->base(), Universe::heap()->capacity());
+  }
+  _okra_register_heap(Universe::heap()->base(), Universe::heap()->capacity());
+}
+
+bool  gpu::Hsail::execute_kernel_void_1d(address kernel, int dimX, jobject args, methodHandle& mh) {
+  objArrayOop argsArray = (objArrayOop) JNIHandles::resolve(args);
+
+  // Reset the kernel arguments
+  _okra_clearargs(kernel);
+
+  // This object sets up the kernel arguments
+  HSAILKernelArguments hka(kernel, mh->signature(), argsArray, mh->is_static());
+
+  // Run the kernel
+  bool success = _okra_execute_with_range(kernel, dimX);
+  return success;
+}
+
+void *gpu::Hsail::generate_kernel(unsigned char *code, int code_len, const char *name) {
+
+  gpu::Hsail::register_heap();
+
+  // The kernel entrypoint is always run for the time being  
+  const char* entryPointName = "&run";
+
+  _device_context = _okra_ctx_create();
+
+  // code is not null terminated, must be a better way to do this
+  unsigned char* nullTerminatedCodeBuffer = (unsigned char*) malloc(code_len + 1);
+  memcpy(nullTerminatedCodeBuffer, code, code_len);
+  nullTerminatedCodeBuffer[code_len] = 0;
+  void* kernel = _okra_kernel_create(_device_context, nullTerminatedCodeBuffer, entryPointName);
+  free(nullTerminatedCodeBuffer);
+  return kernel;
+}
+
+#if defined(LINUX)
+static const char okra_library_name[] = "libokra_x86_64.so";
+#elif defined (_WINDOWS)
+static char const okra_library_name[] = "okra_x86_64.dll";
+#else
+static char const okra_library_name[] = "";
+#endif
+
+#define STD_BUFFER_SIZE 1024
+
+bool gpu::Hsail::probe_linkage() {
+  if (okra_library_name != NULL) {
+    char *buffer = (char*)malloc(STD_BUFFER_SIZE);
+    if (TraceGPUInteraction) {
+      tty->print_cr("[HSAIL] library is %s", okra_library_name);
+    }
+    void *handle = os::dll_load(okra_library_name, buffer, STD_BUFFER_SIZE);
+    free(buffer);
+    if (handle != NULL) {
+
+      _okra_ctx_create =
+        CAST_TO_FN_PTR(okra_ctx_create_func_t, os::dll_lookup(handle, "okra_create_context"));
+      _okra_kernel_create =
+        CAST_TO_FN_PTR(okra_kernel_create_func_t, os::dll_lookup(handle, "okra_create_kernel"));
+      _okra_push_object =
+        CAST_TO_FN_PTR(okra_push_object_func_t, os::dll_lookup(handle, "okra_push_object"));
+      _okra_push_boolean =
+        CAST_TO_FN_PTR(okra_push_boolean_func_t, os::dll_lookup(handle, "okra_push_boolean"));
+      _okra_push_byte =
+        CAST_TO_FN_PTR(okra_push_byte_func_t, os::dll_lookup(handle, "okra_push_byte"));
+      _okra_push_double =
+        CAST_TO_FN_PTR(okra_push_double_func_t, os::dll_lookup(handle, "okra_push_double"));
+      _okra_push_float =
+        CAST_TO_FN_PTR(okra_push_float_func_t, os::dll_lookup(handle, "okra_push_float"));
+      _okra_push_int =
+        CAST_TO_FN_PTR(okra_push_int_func_t, os::dll_lookup(handle, "okra_push_int"));
+      _okra_push_long =
+        CAST_TO_FN_PTR(okra_push_long_func_t, os::dll_lookup(handle, "okra_push_long"));
+      _okra_execute_with_range =
+        CAST_TO_FN_PTR(okra_execute_with_range_func_t, os::dll_lookup(handle, "okra_execute_with_range"));
+      _okra_clearargs =
+        CAST_TO_FN_PTR(okra_clearargs_func_t, os::dll_lookup(handle, "okra_clearargs"));
+      _okra_register_heap =
+        CAST_TO_FN_PTR(okra_register_heap_func_t, os::dll_lookup(handle, "okra_register_heap"));
+
+      if (TraceGPUInteraction) {
+        tty->print_cr("[HSAIL] Success: library linkage _okra_clearargs=0x%08x", _okra_clearargs);
+      }
+      return true;
+    } else {
+      // Unable to dlopen okra
+      tty->print_cr("[HSAIL] library load failed.");
+      return false;
+    }
+  } else {
+    tty->print_cr("Unsupported HSAIL platform");
+    return false;
+  }
+  tty->print_cr("Failed to find HSAIL linkage");
+  return false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gpu/hsail/vm/gpu_hsail.hpp	Sun Nov 10 13:18:09 2013 +0100
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef GPU_HSAIL_HPP
+#define GPU_HSAIL_HPP
+
+class Hsail {
+  friend class gpu;
+
+ protected:
+  static bool probe_linkage();
+  static bool initialize_gpu();
+  static unsigned int total_cores();
+  static void* generate_kernel(unsigned char *code, int code_len, const char *name);
+  static bool execute_kernel_void_1d(address kernel, int dimX, jobject args, methodHandle& mh);
+  static void register_heap();
+
+public:
+#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
+  typedef unsigned long long CUdeviceptr;
+#else
+  typedef unsigned int CUdeviceptr;
+#endif
+
+private:
+  typedef void* (*okra_ctx_create_func_t)();
+  typedef void* (*okra_kernel_create_func_t)(void*, unsigned char *, const char *);
+  typedef bool (*okra_push_object_func_t)(void*, void*);
+  typedef bool (*okra_push_boolean_func_t)(void*, jboolean);
+  typedef bool (*okra_push_byte_func_t)(void*, jbyte);
+  typedef bool (*okra_push_double_func_t)(void*, jdouble);
+  typedef bool (*okra_push_float_func_t)(void*, jfloat);
+  typedef bool (*okra_push_int_func_t)(void*, jint);
+  typedef bool (*okra_push_long_func_t)(void*, jlong);
+  typedef bool (*okra_execute_with_range_func_t)(void*, jint);
+  typedef bool (*okra_clearargs_func_t)(void*);
+  typedef bool (*okra_register_heap_func_t)(void*, size_t);
+  
+public:
+  static okra_ctx_create_func_t                 _okra_ctx_create;
+  static okra_kernel_create_func_t              _okra_kernel_create;
+  static okra_push_object_func_t                _okra_push_object;
+  static okra_push_boolean_func_t               _okra_push_boolean;
+  static okra_push_byte_func_t                  _okra_push_byte;
+  static okra_push_double_func_t                _okra_push_double;
+  static okra_push_float_func_t                 _okra_push_float;
+  static okra_push_int_func_t                   _okra_push_int;
+  static okra_push_long_func_t                  _okra_push_long;
+  static okra_execute_with_range_func_t         _okra_execute_with_range;
+  static okra_clearargs_func_t                  _okra_clearargs;
+  static okra_register_heap_func_t              _okra_register_heap;
+  
+protected:
+  static void* _device_context;
+};
+#endif // GPU_HSAIL_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gpu/hsail/vm/hsailKernelArguments.cpp	Sun Nov 10 13:18:09 2013 +0100
@@ -0,0 +1,184 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "hsailKernelArguments.hpp"
+#include "runtime/javaCalls.hpp"
+
+
+// Get next java argument
+oop HSAILKernelArguments::next_arg(BasicType expectedType) {
+  assert(_index < _args->length(), "out of bounds");
+
+  oop arg = ((objArrayOop) (_args))->obj_at(_index++);
+  assert(expectedType == T_OBJECT ||
+         java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch");
+
+  return arg;
+}
+
+void HSAILKernelArguments::do_bool() {
+  // Get the boxed value
+  oop arg = _args->obj_at(_index++);
+  assert(java_lang_boxing_object::is_instance(arg, T_BOOLEAN), "arg type mismatch");
+  
+  jvalue jValue;
+  java_lang_boxing_object::get_value(arg, &jValue);
+  
+  bool pushed = gpu::Hsail::_okra_push_boolean(_kernel, jValue.z);
+  assert(pushed == true, "arg push failed");
+}
+
+void HSAILKernelArguments::do_byte() {
+  // Get the boxed value
+  oop arg = _args->obj_at(_index++);
+  assert(java_lang_boxing_object::is_instance(arg, T_BYTE), "arg type mismatch");
+  
+  jvalue jValue;
+  java_lang_boxing_object::get_value(arg, &jValue);
+  
+  bool pushed = gpu::Hsail::_okra_push_byte(_kernel, jValue.b);
+  assert(pushed == true, "arg push failed");
+}
+
+void HSAILKernelArguments::do_double() {
+  // Get the boxed value
+  oop arg = _args->obj_at(_index++);
+  assert(java_lang_boxing_object::is_instance(arg, T_DOUBLE), "arg type mismatch");
+  
+  jvalue jValue;
+  java_lang_boxing_object::get_value(arg, &jValue);
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] HSAILKernelArguments::double value = %e", jValue.d);
+  }  
+  bool pushed = gpu::Hsail::_okra_push_double(_kernel, jValue.d);
+  assert(pushed == true, "arg push failed");
+}
+
+void HSAILKernelArguments::do_float() {
+  // Get the boxed value
+  oop arg = _args->obj_at(_index++);
+  assert(java_lang_boxing_object::is_instance(arg, T_FLOAT), "arg type mismatch");
+  
+  jvalue jValue;
+  java_lang_boxing_object::get_value(arg, &jValue);
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] HSAILKernelArguments::float value = %f", jValue.f);
+  }    
+  bool pushed = gpu::Hsail::_okra_push_float(_kernel, jValue.f);
+  assert(pushed == true, "float push failed");
+}
+
+void HSAILKernelArguments::do_int() {
+  // The last int is the iteration variable in an IntStream, but we don't pass it
+  // since we use the HSAIL workitemid in place of that int value
+  if (_index == _length) {
+    if (TraceGPUInteraction) {
+      tty->print_cr("[HSAIL] HSAILKernelArguments::not pushing trailing int");
+    }
+    return;
+  }
+
+  // Get the boxed int
+  oop arg = _args->obj_at(_index++);
+  assert(java_lang_boxing_object::is_instance(arg, T_INT), "arg type mismatch");
+  
+  jvalue jValue;
+  java_lang_boxing_object::get_value(arg, &jValue);
+  
+  bool pushed = gpu::Hsail::_okra_push_int(_kernel, jValue.i);
+  assert(pushed == true, "arg push failed");
+}
+
+void HSAILKernelArguments::do_long() {
+  // Get the boxed value
+  oop arg = _args->obj_at(_index++);
+  assert(java_lang_boxing_object::is_instance(arg, T_LONG), "arg type mismatch");
+  
+  jvalue jValue;
+  java_lang_boxing_object::get_value(arg, &jValue);
+  
+  bool pushed = gpu::Hsail::_okra_push_long(_kernel, jValue.j);
+  assert(pushed == true, "arg push failed");  
+}
+
+void HSAILKernelArguments::do_array(int begin, int end) {
+  oop arg = _args->obj_at(_index++);
+  assert(arg->is_array(), "arg type mismatch");
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] HSAILKernelArguments::do_array 0x%08x, is a %s", (address) arg, arg->klass()->external_name());
+  }
+    
+  bool pushed = gpu::Hsail::_okra_push_object(_kernel, arg);
+  assert(pushed == true, "arg push failed");  
+}
+
+void HSAILKernelArguments::do_object() {
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] HSAILKernelArguments::do_object.");
+  }
+  if (_index == _length) {  
+    // last arg in object stream lambda is  the object stream source array
+    if (TraceGPUInteraction) {
+      tty->print_cr("[HSAIL] HSAILKernelArguments::trailing object ref should be object source array ref");
+    }
+  }
+
+  oop arg = _args->obj_at(_index++);
+  assert(arg->is_array(), "arg type mismatch");
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] HSAILKernelArguments::do_object, 0x%08x is a %s", (address) arg, arg->klass()->external_name());
+  }
+    
+  bool pushed = gpu::Hsail::_okra_push_object(_kernel, arg);
+  assert(pushed == true, "arg push failed");  
+}
+
+void HSAILKernelArguments::do_object(int begin, int end) {
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] HSAILKernelArguments::do_object(int begin, int end).");
+  }
+
+  if ((!_is_static && (_index >=(_length-1))) || (_is_static && (_index >=(_length)))) {
+    // last arg in object stream lambda is  the object stream source array
+    if (TraceGPUInteraction) {
+      tty->print_cr("[HSAIL] HSAILKernelArguments::trailing object ref should be object source array ref");
+    }
+  }
+  
+  oop arg = _args->obj_at(_index++);
+  assert(arg->is_array(), "arg type mismatch");
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] HSAILKernelArguments::do_object(int, int), 0x%08x is a %s", (address) arg, arg->klass()->external_name());
+  }
+    
+  bool pushed = gpu::Hsail::_okra_push_object(_kernel, arg);
+  assert(pushed == true, "arg push failed");  
+}
+
+void HSAILKernelArguments::do_void() {
+    return;
+}
+
+// TODO implement other do_*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gpu/hsail/vm/hsailKernelArguments.hpp	Sun Nov 10 13:18:09 2013 +0100
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef KERNEL_ARGUMENTS_HSAIL_HPP
+#define KERNEL_ARGUMENTS_HSAIL_HPP
+
+#include "runtime/gpu.hpp"
+#include "runtime/signature.hpp"
+
+class HSAILKernelArguments : public SignatureIterator {
+  friend class gpu::Hsail;
+
+public:
+
+private:
+  // Array of java argument oops
+  objArrayOop _args;
+  // Length of args array
+  int   _length;
+  // Current index into _args
+  int _index;
+  // Kernel to push into
+  address _kernel;
+
+  bool _is_static;
+  
+  // Get next java argument
+  oop next_arg(BasicType expectedType);
+
+ public:
+  HSAILKernelArguments(address kernel, Symbol* signature, objArrayOop args, bool is_static) : SignatureIterator(signature) {
+    this->_return_type = T_ILLEGAL;
+    _index = 0;
+    _args = args;
+    _kernel = kernel;
+    _is_static = is_static;
+    
+    _length = args->length();
+    if (TraceGPUInteraction) {
+      tty->print_cr("[HSAIL] sig:%s  args length=%d", signature->as_C_string(), _length);
+    }    
+    if (!_is_static) {      
+      // First object in args should be 'this'
+      oop arg = args->obj_at(_index++);
+      assert(arg->is_instance() && (! arg->is_array()), "First arg should be 'this'");
+      if (TraceGPUInteraction) {
+        tty->print_cr("[HSAIL] instance method, this 0x%08x, is a %s", (address) arg, arg->klass()->external_name());
+      }
+      bool pushed = gpu::Hsail::_okra_push_object(kernel, arg);
+      assert(pushed == true, "'this' push failed");
+    } else {
+      if (TraceGPUInteraction) {
+        tty->print_cr("[HSAIL] static method");
+      }
+    }
+    // Iterate over the entire signature
+    iterate();
+  }
+
+  void do_bool();
+  void do_byte();
+  void do_double();
+  void do_float();
+  void do_int();
+  void do_long();
+  void do_array(int begin, int end);
+  void do_object();
+  void do_object(int begin, int end);
+
+  void do_void();
+
+  inline void do_char()   {
+    /* TODO : To be implemented */
+    guarantee(false, "do_char:NYI");
+  }
+  inline void do_short()  {
+    /* TODO : To be implemented */
+    guarantee(false, "do_short:NYI");
+  }
+};
+
+#endif  // KERNEL_ARGUMENTS_HPP
--- a/src/os_gpu/linux_ptx/vm/gpu_linux.cpp	Sun Nov 10 11:42:31 2013 +0100
+++ b/src/os_gpu/linux_ptx/vm/gpu_linux.cpp	Sun Nov 10 13:18:09 2013 +0100
@@ -42,6 +42,19 @@
 static unsigned int amd_vendor_id = 0x1002;
 
 bool gpu::Linux::probe_gpu() {
+
+  /*
+   * The simulator only depends on shared libraries.
+   * That linkage is checked in a later step.
+   */
+  if (UseHSAILSimulator) {
+      set_target_il_type(gpu::HSAIL);
+      if (TraceGPUInteraction) {
+        tty->print_cr("Setup HSAIL Simulator");
+      }
+      return true;
+  }
+
   /* 
    * Open /proc/bus/pci/devices to look for the first GPU device. For
    * now, we will just find the first GPU device. Will need to revisit
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_gpu/windows_hsail/vm/gpu_windows.cpp	Sun Nov 10 13:18:09 2013 +0100
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "runtime/gpu.hpp"
+#include "utilities/ostream.hpp"
+
+void gpu::probe_gpu() {
+  set_available(gpu::Windows::probe_gpu());
+  if (TraceGPUInteraction) {
+    tty->print_cr("probe_gpu(): %d", gpu::is_available());
+  }
+}
+
+bool gpu::Windows::probe_gpu() {
+    
+  /*
+   * We will check the HSA environment in the libraries,
+   * so nothing to do here.
+   * The HSA library linkage is checked in a later step.
+   */  
+  bool gpu_device_exists = true;
+  set_target_il_type(gpu::HSAIL);
+
+  return gpu_device_exists;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_gpu/windows_hsail/vm/gpu_windows.hpp	Sun Nov 10 13:18:09 2013 +0100
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef OS_WINDOWS_VM_GPU_WINDOWS_HPP
+#define OS_WINDOWS_VM_GPU_WINDOWS_HPP
+
+
+class Windows {
+  friend class gpu;
+
+ protected:
+  static bool probe_gpu();
+};
+
+#endif // OS_WINDOWS_VM_GPU_WINDOWS_HPP
--- a/src/share/vm/graal/graalCompilerToGPU.cpp	Sun Nov 10 11:42:31 2013 +0100
+++ b/src/share/vm/graal/graalCompilerToGPU.cpp	Sun Nov 10 13:18:09 2013 +0100
@@ -117,7 +117,6 @@
     }
     return JNIHandles::make_local(o);
   }
-
 C2V_END
 
 C2V_VMENTRY(jobject, executeParallelMethodVarargs, (JNIEnv *env,
@@ -139,9 +138,14 @@
   // start value is the kernel
   jlong startValue = HotSpotInstalledCode::codeStart(hotspotInstalledCode);
 
+  if (UseHSAILSimulator) {
+    gpu::execute_kernel_void_1d((address)startValue, dimX, args, mh);
+    return NULL;
+  }
+
   PTXKernelArguments ptxka(signature, (arrayOop) JNIHandles::resolve(args), mh->is_static());
   JavaValue result(ptxka.get_ret_type());
-if (!gpu::execute_warp(dimX, dimY, dimZ, (address)startValue, ptxka, result)) {
+  if (!gpu::execute_warp(dimX, dimY, dimZ, (address) startValue, ptxka, result)) {
     return NULL;
   }
 
@@ -169,7 +173,6 @@
     }
     return JNIHandles::make_local(o);
   }
-
 C2V_END
 
 C2V_VMENTRY(jboolean, deviceInit, (JNIEnv *env, jobject))
--- a/src/share/vm/graal/graalEnv.cpp	Sun Nov 10 11:42:31 2013 +0100
+++ b/src/share/vm/graal/graalEnv.cpp	Sun Nov 10 13:18:09 2013 +0100
@@ -566,7 +566,7 @@
         }
       }
       
-      if (HotSpotNmethod::isExternal(installed_code())) {
+      if (TraceGPUInteraction && HotSpotNmethod::isExternal(installed_code())) {
         tty->print_cr("External method:%s", method()->name_and_sig_as_C_string());
       }
     }
--- a/src/share/vm/runtime/globals.hpp	Sun Nov 10 11:42:31 2013 +0100
+++ b/src/share/vm/runtime/globals.hpp	Sun Nov 10 13:18:09 2013 +0100
@@ -3774,6 +3774,9 @@
   product(bool, TraceGPUInteraction, false,                                 \
           "Trace external GPU Interaction")                                 \
                                                                             \
+  product(bool, UseHSAILSimulator, false,                                   \
+          "Run code on HSAIL Simulator")                                    \
+                                                                            \
   diagnostic(ccstr, SharedArchiveFile, NULL,                                \
           "Override the default location of the CDS archive file")          \
                                                                             \
--- a/src/share/vm/runtime/gpu.cpp	Sun Nov 10 11:42:31 2013 +0100
+++ b/src/share/vm/runtime/gpu.cpp	Sun Nov 10 13:18:09 2013 +0100
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "runtime/gpu.hpp"
+#include "runtime/handles.hpp"
 
 bool gpu::_available = false;    // does the hardware exist?
 bool gpu::_gpu_linkage = false;  // is the driver library to access the GPU installed
@@ -31,10 +32,12 @@
 gpu::TargetGPUIL gpu::_targetIL = gpu::NONE; // No GPU detected yet.
 
 void gpu::init() {
-#if defined(TARGET_OS_FAMILY_bsd) || defined(TARGET_OS_FAMILY_linux)
+#if defined(TARGET_OS_FAMILY_bsd) || defined(TARGET_OS_FAMILY_linux) || defined(TARGET_OS_FAMILY_windows)
   gpu::probe_gpu();
   if (gpu::get_target_il_type() == gpu::PTX) {
     set_gpu_linkage(gpu::Ptx::probe_linkage());
+  } else if (gpu::get_target_il_type() == gpu::HSAIL) {
+    set_gpu_linkage(gpu::Hsail::probe_linkage());
   } else {
     set_gpu_linkage(false);
   }
@@ -45,8 +48,9 @@
   if (gpu::has_gpu_linkage()) {
     if (gpu::get_target_il_type() == gpu::PTX) {
       set_initialized(gpu::Ptx::initialize_gpu());
+    } else if (gpu::get_target_il_type() == gpu::HSAIL) {
+      set_initialized(gpu::Hsail::initialize_gpu());
     }
-    // Add initialization of other GPUs here
   }
 }
 
@@ -54,8 +58,9 @@
   if (gpu::has_gpu_linkage()) {
     if (gpu::get_target_il_type() == gpu::PTX) {
       return (gpu::Ptx::generate_kernel(code, code_len, name));
+    } else if (gpu::get_target_il_type() == gpu::HSAIL) {
+      return (gpu::Hsail::generate_kernel(code, code_len, name));
     }
-    // Add kernel generation functionality of other GPUs here
   }
   return NULL;
 }
@@ -70,6 +75,18 @@
     return false;
 }
 
+// This is HSAIL specific to work with Sumatra JDK
+bool gpu::execute_kernel_void_1d(address kernel, int dimX, jobject args, methodHandle& mh) {
+    if (gpu::has_gpu_linkage()) {
+        if (gpu::get_target_il_type() == gpu::HSAIL) {
+            return (gpu::Hsail::execute_kernel_void_1d(kernel, dimX, args, mh));
+        }
+    }
+    return false;
+    
+}
+
+
 bool gpu::execute_warp(int dimX, int dimY, int dimZ,
                        address kernel, PTXKernelArguments & ptxka, JavaValue& ret) {
     if (gpu::has_gpu_linkage()) {
--- a/src/share/vm/runtime/gpu.hpp	Sun Nov 10 11:42:31 2013 +0100
+++ b/src/share/vm/runtime/gpu.hpp	Sun Nov 10 13:18:09 2013 +0100
@@ -53,6 +53,9 @@
 
   static bool execute_kernel(address kernel, PTXKernelArguments & ptxka, JavaValue & ret);
 
+  // No return value from HSAIL kernels
+  static bool execute_kernel_void_1d(address kernel, int dimX, jobject args, methodHandle& mh);
+
   static void set_available(bool value) {
     _available = value;
   }
@@ -92,6 +95,7 @@
 #ifdef TARGET_OS_FAMILY_solaris
 #endif
 #ifdef TARGET_OS_FAMILY_windows
+# include "gpu_windows.hpp"
 #endif
 #ifdef TARGET_OS_FAMILY_bsd
 # include "gpu_bsd.hpp"
@@ -99,6 +103,7 @@
 
 public:
 # include "ptx/vm/gpu_ptx.hpp"
+# include "hsail/vm/gpu_hsail.hpp"
 
 };