Mercurial > hg > graal-jvmci-8
diff src/gpu/hsail/vm/gpu_hsail.cpp @ 13819:49db2c1e3bee
added support for co-existing GPU backends (JBS:GRAAL-1)
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Thu, 30 Jan 2014 00:52:33 +0100 |
parents | bfd61161d752 |
children | 35fc64972250 |
line wrap: on
line diff
--- a/src/gpu/hsail/vm/gpu_hsail.cpp Thu Jan 30 00:48:41 2014 +0100 +++ b/src/gpu/hsail/vm/gpu_hsail.cpp Thu Jan 30 00:52:33 2014 +0100 @@ -29,9 +29,39 @@ #include "utilities/ostream.hpp" #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" +#include "graal/graalEnv.hpp" +#include "graal/graalCompiler.hpp" +#include "graal/graalJavaAccess.hpp" #include "hsailKernelArguments.hpp" -void * gpu::Hsail::_device_context; +// Entry to GPU native method implementation that transitions current thread to '_thread_in_vm'. +#define GPU_VMENTRY(result_type, name, signature) \ + JNIEXPORT result_type JNICALL name signature { \ + GRAAL_VM_ENTRY_MARK; \ + +// Entry to GPU native method implementation that calls a JNI function +// and hence cannot transition current thread to '_thread_in_vm'. +#define GPU_ENTRY(result_type, name, signature) \ + JNIEXPORT result_type JNICALL name signature { \ + +#define GPU_END } + +#define CC (char*) /*cast a literal from (const char*)*/ +#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(f)) + +#define OBJECT "Ljava/lang/Object;" +#define STRING "Ljava/lang/String;" +#define HS_INSTALLED_CODE "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;" + +// public native void executeKernel(HotSpotNmethod kernel, int jobSize, int i, int j, Object[] args) throws InvalidInstalledCodeException; + +JNINativeMethod gpu::Hsail::HSAIL_methods[] = { + {CC"initialize", CC"()Z", FN_PTR(gpu::Hsail::initialize)}, + {CC"generateKernel", CC"([B" STRING ")J", FN_PTR(gpu::Hsail::generate_kernel)}, + {CC"executeKernel0", CC"("HS_INSTALLED_CODE"I["OBJECT")Z", FN_PTR(gpu::Hsail::execute_kernel_void_1d)}, +}; + +void * gpu::Hsail::_device_context = NULL; gpu::Hsail::okra_create_context_func_t gpu::Hsail::_okra_create_context; gpu::Hsail::okra_create_kernel_func_t gpu::Hsail::_okra_create_kernel; @@ -47,20 +77,6 @@ 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."); @@ -71,54 +87,67 @@ _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); +GPU_VMENTRY(jboolean, gpu::Hsail::execute_kernel_void_1d, (JNIEnv* env, jclass, jobject kernel_handle, jint dimX, jobject args_handle)) + + ResourceMark rm; + jlong nmethodValue = HotSpotInstalledCode::codeBlob(kernel_handle); + if (nmethodValue == 0) { + SharedRuntime::throw_and_post_jvmti_exception(JavaThread::current(), vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException(), NULL); + } + nmethod* nm = (nmethod*) (address) nmethodValue; + methodHandle mh = nm->method(); + Symbol* signature = mh->signature(); + + void* kernel = (void*) HotSpotInstalledCode::codeStart(kernel_handle); + if (kernel == NULL) { + SharedRuntime::throw_and_post_jvmti_exception(JavaThread::current(), vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException(), NULL); + } + + objArrayOop args = (objArrayOop) JNIHandles::resolve(args_handle); // Reset the kernel arguments _okra_clearargs(kernel); // This object sets up the kernel arguments - HSAILKernelArguments hka(kernel, mh->signature(), argsArray, mh->is_static()); + HSAILKernelArguments hka((address) kernel, mh->signature(), args, mh->is_static()); // Run the kernel - bool success = _okra_execute_with_range(kernel, dimX); - return success; -} + return _okra_execute_with_range(kernel, dimX); +GPU_END -void *gpu::Hsail::generate_kernel(unsigned char *code, int code_len, const char *name) { +GPU_ENTRY(jlong, gpu::Hsail::generate_kernel, (JNIEnv *env, jclass, jbyteArray code_handle, jstring name_handle)) + guarantee(_okra_create_kernel != NULL, "[HSAIL] Okra not linked"); + ResourceMark rm; + jsize name_len = env->GetStringLength(name_handle); + jsize code_len = env->GetArrayLength(code_handle); - if (_okra_create_kernel == NULL) { - // probe linkage and we really need it to work this time - bool success = probe_linkage_internal(true); - guarantee(success, "[HSAIL] loading okra library"); - } + char* name = NEW_RESOURCE_ARRAY(char, name_len + 1); + unsigned char *code = NEW_RESOURCE_ARRAY(unsigned char, code_len + 1); - gpu::Hsail::register_heap(); + code[code_len] = 0; + name[name_len] = 0; + + env->GetByteArrayRegion(code_handle, 0, code_len, (jbyte*) code); + env->GetStringUTFRegion(name_handle, 0, name_len, name); + + register_heap(); // The kernel entrypoint is always run for the time being const char* entryPointName = "&run"; _device_context = _okra_create_context(); - // 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_create_kernel(_device_context, nullTerminatedCodeBuffer, entryPointName); - free(nullTerminatedCodeBuffer); - return kernel; -} + return (jlong) _okra_create_kernel(_device_context, code, entryPointName); +GPU_END #if defined(LINUX) static const char okra_library_name[] = "libokra_x86_64.so"; -#elif defined (_WINDOWS) +#elif defined(_WINDOWS) static char const okra_library_name[] = "okra_x86_64.dll"; #else -static char const okra_library_name[] = ""; +static char const okra_library_name[] = NULL; #endif -#define STD_BUFFER_SIZE 1024 - #define STRINGIFY(x) #x #define LOOKUP_OKRA_FUNCTION(name, alias) \ @@ -126,15 +155,10 @@ CAST_TO_FN_PTR(alias##_func_t, os::dll_lookup(handle, STRINGIFY(name))); \ if (_##alias == NULL) { \ tty->print_cr("[HSAIL] ***** Error: Failed to lookup %s in %s, wrong version of OKRA?", STRINGIFY(name), okra_library_name); \ - return 0; \ + return false; \ } \ -bool gpu::Hsail::probe_linkage() { - return probe_linkage_internal(false); -} - - -bool gpu::Hsail::probe_linkage_internal(bool isRequired) { +GPU_ENTRY(jboolean, gpu::Hsail::initialize, (JNIEnv *env, jclass)) if (okra_library_name == NULL) { if (TraceGPUInteraction) { tty->print_cr("Unsupported HSAIL platform"); @@ -143,32 +167,21 @@ } // here we know we have a valid okra_library_name to try to load - // the isRequired boolean specifies whether it is an error if the - // probe does not find the okra library - char *buffer = (char*)malloc(STD_BUFFER_SIZE); + char ebuf[O_BUFLEN]; if (TraceGPUInteraction) { tty->print_cr("[HSAIL] library is %s", okra_library_name); } - void *handle = os::dll_load(okra_library_name, buffer, STD_BUFFER_SIZE); + void *handle = os::dll_load(okra_library_name, ebuf, O_BUFLEN); // try alternate location if env variable set char *okra_lib_name_from_env_var = getenv("_OKRA_SIM_LIB_PATH_"); if ((handle == NULL) && (okra_lib_name_from_env_var != NULL)) { - handle = os::dll_load(okra_lib_name_from_env_var, buffer, STD_BUFFER_SIZE); + handle = os::dll_load(okra_lib_name_from_env_var, ebuf, O_BUFLEN); if ((handle != NULL) && TraceGPUInteraction) { tty->print_cr("[HSAIL] using _OKRA_SIM_LIB_PATH_=%s", getenv("_OKRA_SIM_LIB_PATH_")); } } - free(buffer); - if ((handle == NULL) && !isRequired) { - // return true for now but we will probe again later - if (TraceGPUInteraction) { - tty->print_cr("[HSAIL] library load not in PATH, waiting for Java to put in tmpdir."); - } - return true; - } - - if ((handle == NULL) && isRequired) { + if (handle == NULL) { // Unable to dlopen okra if (TraceGPUInteraction) { tty->print_cr("[HSAIL] library load failed."); @@ -176,6 +189,8 @@ return false; } + guarantee(_okra_create_context == NULL, "cannot repeat GPU initialization"); + // at this point we know handle is valid and we can lookup the functions LOOKUP_OKRA_FUNCTION(okra_create_context, okra_create_context); LOOKUP_OKRA_FUNCTION(okra_create_kernel, okra_create_kernel); @@ -189,7 +204,27 @@ LOOKUP_OKRA_FUNCTION(okra_execute_with_range, okra_execute_with_range); LOOKUP_OKRA_FUNCTION(okra_clearargs, okra_clearargs); LOOKUP_OKRA_FUNCTION(okra_register_heap, okra_register_heap); - // if we made it this far, real success + + gpu::initialized_gpu("Okra"); + + return true; +GPU_END + +bool gpu::Hsail::register_natives(JNIEnv* env) { + jclass klass = env->FindClass("com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend"); + if (klass == NULL) { + if (TraceGPUInteraction) { + tty->print_cr("HSAILHotSpotBackend class not found"); + } + return false; + } + jint status = env->RegisterNatives(klass, HSAIL_methods, sizeof(HSAIL_methods) / sizeof(JNINativeMethod)); + if (status != JNI_OK) { + if (TraceGPUInteraction) { + tty->print_cr("Error registering natives for HSAILHotSpotBackend: %d", status); + } + return false; + } return true; }