Mercurial > hg > truffle
comparison src/gpu/ptx/vm/gpu_ptx.cpp @ 13832:ab370d74a8eb
implemented GC locking for duration of a PTX kernel call
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Thu, 30 Jan 2014 23:52:34 +0100 |
parents | 49db2c1e3bee |
children | fe99bfb55626 |
comparison
equal
deleted
inserted
replaced
13831:d6823d127f76 | 13832:ab370d74a8eb |
---|---|
27 #include "runtime/gpu.hpp" | 27 #include "runtime/gpu.hpp" |
28 #include "utilities/globalDefinitions.hpp" | 28 #include "utilities/globalDefinitions.hpp" |
29 #include "utilities/ostream.hpp" | 29 #include "utilities/ostream.hpp" |
30 #include "memory/allocation.hpp" | 30 #include "memory/allocation.hpp" |
31 #include "memory/allocation.inline.hpp" | 31 #include "memory/allocation.inline.hpp" |
32 #include "memory/gcLocker.inline.hpp" | |
32 #include "runtime/interfaceSupport.hpp" | 33 #include "runtime/interfaceSupport.hpp" |
33 #include "graal/graalEnv.hpp" | 34 #include "graal/graalEnv.hpp" |
34 #include "graal/graalCompiler.hpp" | 35 #include "graal/graalCompiler.hpp" |
35 #include "ptxKernelArguments.hpp" | 36 #include "ptxKernelArguments.hpp" |
36 | 37 |
402 oop* _pinned; // objects that have been pinned with cuMemHostRegister | 403 oop* _pinned; // objects that have been pinned with cuMemHostRegister |
403 int _pinned_length; // length of _pinned | 404 int _pinned_length; // length of _pinned |
404 gpu::Ptx::CUdeviceptr _ret_value; // pointer to slot in GPU memory holding the return value | 405 gpu::Ptx::CUdeviceptr _ret_value; // pointer to slot in GPU memory holding the return value |
405 int _ret_type_size; // size of the return type value | 406 int _ret_type_size; // size of the return type value |
406 bool _ret_is_object; // specifies if the return type is Object | 407 bool _ret_is_object; // specifies if the return type is Object |
408 bool _gc_locked; | |
407 | 409 |
408 bool check(int status, const char *action) { | 410 bool check(int status, const char *action) { |
409 if (status != GRAAL_CUDA_SUCCESS) { | 411 if (status != GRAAL_CUDA_SUCCESS) { |
410 Thread* THREAD = _thread; | 412 Thread* THREAD = _thread; |
411 char* message = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, O_BUFLEN + 1); | 413 char* message = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, O_BUFLEN + 1); |
423 } | 425 } |
424 return true; | 426 return true; |
425 } | 427 } |
426 | 428 |
427 public: | 429 public: |
428 PtxCall(JavaThread* thread, address buffer, int buffer_size, oop* pinned, int encodedReturnTypeSize) : _thread(thread), | 430 PtxCall(JavaThread* thread, address buffer, int buffer_size, oop* pinned, int encodedReturnTypeSize) : _thread(thread), _gc_locked(false), |
429 _buffer(buffer), _buffer_size(buffer_size), _pinned(pinned), _pinned_length(0), _ret_value(0), _ret_is_object(encodedReturnTypeSize < 0) { | 431 _buffer(buffer), _buffer_size(buffer_size), _pinned(pinned), _pinned_length(0), _ret_value(0), _ret_is_object(encodedReturnTypeSize < 0) { |
430 _ret_type_size = _ret_is_object ? -encodedReturnTypeSize : encodedReturnTypeSize; | 432 _ret_type_size = _ret_is_object ? -encodedReturnTypeSize : encodedReturnTypeSize; |
431 } | 433 } |
432 | 434 |
433 bool is_object_return() { return _ret_is_object; } | 435 bool is_object_return() { return _ret_is_object; } |
443 | 445 |
444 void pin_objects(int count, int* objectOffsets) { | 446 void pin_objects(int count, int* objectOffsets) { |
445 if (count == 0) { | 447 if (count == 0) { |
446 return; | 448 return; |
447 } | 449 } |
450 // Once we start pinning objects, no GC must occur | |
451 // until the kernel has completed. This is a big | |
452 // hammer for ensuring we can safely pass objects | |
453 // to the GPU. | |
454 GC_locker::lock_critical(_thread); | |
455 _gc_locked = true; | |
456 if (TraceGPUInteraction) { | |
457 tty->print_cr("[CUDA] Locked GC"); | |
458 } | |
459 | |
448 for (int i = 0; i < count; i++) { | 460 for (int i = 0; i < count; i++) { |
449 int offset = objectOffsets[i]; | 461 int offset = objectOffsets[i]; |
450 oop* argPtr = (oop*) (_buffer + offset); | 462 oop* argPtr = (oop*) (_buffer + offset); |
451 oop obj = *argPtr; | 463 oop obj = *argPtr; |
452 if (obj != NULL) { | 464 if (obj != NULL) { |
529 | 541 |
530 ~PtxCall() { | 542 ~PtxCall() { |
531 unpin_objects(); | 543 unpin_objects(); |
532 free_return_value(); | 544 free_return_value(); |
533 destroy_context(); | 545 destroy_context(); |
546 if (_gc_locked) { | |
547 GC_locker::unlock_critical(_thread); | |
548 if (TraceGPUInteraction) { | |
549 tty->print_cr("[CUDA] Unlocked GC"); | |
550 } | |
551 } | |
534 } | 552 } |
535 }; | 553 }; |
536 | 554 |
537 GPU_VMENTRY(jlong, gpu::Ptx::get_execute_kernel_from_vm_address, (JNIEnv *env, jclass)) | 555 GPU_VMENTRY(jlong, gpu::Ptx::get_execute_kernel_from_vm_address, (JNIEnv *env, jclass)) |
538 return (jlong) gpu::Ptx::execute_kernel_from_vm; | 556 return (jlong) gpu::Ptx::execute_kernel_from_vm; |
547 int encodedReturnTypeSize)) | 565 int encodedReturnTypeSize)) |
548 if (kernel == 0L) { | 566 if (kernel == 0L) { |
549 SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL); | 567 SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL); |
550 return 0L; | 568 return 0L; |
551 } | 569 } |
552 | |
553 #if 0 | |
554 Universe::heap()->collect(GCCause::_jvmti_force_gc); | |
555 #endif | |
556 | 570 |
557 PtxCall call(thread, (address) buffer, bufferSize, (oop*) (address) pinnedObjects, encodedReturnTypeSize); | 571 PtxCall call(thread, (address) buffer, bufferSize, (oop*) (address) pinnedObjects, encodedReturnTypeSize); |
558 | 572 |
559 #define TRY(action) do { \ | 573 #define TRY(action) do { \ |
560 action; \ | 574 action; \ |