24 |
24 |
25 // Must be at least Windows Vista or Server 2008 to use InitOnceExecuteOnce |
25 // Must be at least Windows Vista or Server 2008 to use InitOnceExecuteOnce |
26 #define _WIN32_WINNT 0x0600 |
26 #define _WIN32_WINNT 0x0600 |
27 |
27 |
28 // no precompiled headers |
28 // no precompiled headers |
|
29 #include "jvm.h" |
29 #include "classfile/classLoader.hpp" |
30 #include "classfile/classLoader.hpp" |
30 #include "classfile/systemDictionary.hpp" |
31 #include "classfile/systemDictionary.hpp" |
31 #include "classfile/vmSymbols.hpp" |
32 #include "classfile/vmSymbols.hpp" |
32 #include "code/icBuffer.hpp" |
33 #include "code/icBuffer.hpp" |
33 #include "code/vtableStubs.hpp" |
34 #include "code/vtableStubs.hpp" |
34 #include "compiler/compileBroker.hpp" |
35 #include "compiler/compileBroker.hpp" |
35 #include "compiler/disassembler.hpp" |
36 #include "compiler/disassembler.hpp" |
36 #include "interpreter/interpreter.hpp" |
37 #include "interpreter/interpreter.hpp" |
37 #include "jvm_windows.h" |
|
38 #include "logging/log.hpp" |
38 #include "logging/log.hpp" |
39 #include "memory/allocation.inline.hpp" |
39 #include "memory/allocation.inline.hpp" |
40 #include "memory/filemap.hpp" |
40 #include "memory/filemap.hpp" |
41 #include "oops/oop.inline.hpp" |
41 #include "oops/oop.inline.hpp" |
42 #include "os_share_windows.hpp" |
42 #include "os_share_windows.hpp" |
43 #include "os_windows.inline.hpp" |
43 #include "os_windows.inline.hpp" |
44 #include "prims/jniFastGetField.hpp" |
44 #include "prims/jniFastGetField.hpp" |
45 #include "prims/jvm.h" |
|
46 #include "prims/jvm_misc.hpp" |
45 #include "prims/jvm_misc.hpp" |
47 #include "runtime/arguments.hpp" |
46 #include "runtime/arguments.hpp" |
48 #include "runtime/atomic.hpp" |
47 #include "runtime/atomic.hpp" |
49 #include "runtime/extendedPC.hpp" |
48 #include "runtime/extendedPC.hpp" |
50 #include "runtime/globals.hpp" |
49 #include "runtime/globals.hpp" |
98 #include <io.h> |
97 #include <io.h> |
99 #include <process.h> // For _beginthreadex(), _endthreadex() |
98 #include <process.h> // For _beginthreadex(), _endthreadex() |
100 #include <imagehlp.h> // For os::dll_address_to_function_name |
99 #include <imagehlp.h> // For os::dll_address_to_function_name |
101 // for enumerating dll libraries |
100 // for enumerating dll libraries |
102 #include <vdmdbg.h> |
101 #include <vdmdbg.h> |
|
102 #include <psapi.h> |
103 |
103 |
104 // for timer info max values which include all bits |
104 // for timer info max values which include all bits |
105 #define ALL_64_BITS CONST64(-1) |
105 #define ALL_64_BITS CONST64(-1) |
106 |
106 |
107 // For DLL loading/load error detection |
107 // For DLL loading/load error detection |
3654 static HANDLE handles[MAXIMUM_THREADS_TO_KEEP]; |
3654 static HANDLE handles[MAXIMUM_THREADS_TO_KEEP]; |
3655 static int handle_count = 0; |
3655 static int handle_count = 0; |
3656 |
3656 |
3657 static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT; |
3657 static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT; |
3658 static CRITICAL_SECTION crit_sect; |
3658 static CRITICAL_SECTION crit_sect; |
3659 static volatile jint process_exiting = 0; |
3659 static volatile DWORD process_exiting = 0; |
3660 int i, j; |
3660 int i, j; |
3661 DWORD res; |
3661 DWORD res; |
3662 HANDLE hproc, hthr; |
3662 HANDLE hproc, hthr; |
3663 |
3663 |
3664 // We only attempt to register threads until a process exiting |
3664 // We only attempt to register threads until a process exiting |
3673 warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__); |
3673 warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__); |
3674 } else if (OrderAccess::load_acquire(&process_exiting) == 0) { |
3674 } else if (OrderAccess::load_acquire(&process_exiting) == 0) { |
3675 if (what != EPT_THREAD) { |
3675 if (what != EPT_THREAD) { |
3676 // Atomically set process_exiting before the critical section |
3676 // Atomically set process_exiting before the critical section |
3677 // to increase the visibility between racing threads. |
3677 // to increase the visibility between racing threads. |
3678 Atomic::cmpxchg((jint)GetCurrentThreadId(), &process_exiting, 0); |
3678 Atomic::cmpxchg(GetCurrentThreadId(), &process_exiting, (DWORD)0); |
3679 } |
3679 } |
3680 EnterCriticalSection(&crit_sect); |
3680 EnterCriticalSection(&crit_sect); |
3681 |
3681 |
3682 if (what == EPT_THREAD && OrderAccess::load_acquire(&process_exiting) == 0) { |
3682 if (what == EPT_THREAD && OrderAccess::load_acquire(&process_exiting) == 0) { |
3683 // Remove from the array those handles of the threads that have completed exiting. |
3683 // Remove from the array those handles of the threads that have completed exiting. |
3791 LeaveCriticalSection(&crit_sect); |
3791 LeaveCriticalSection(&crit_sect); |
3792 } |
3792 } |
3793 |
3793 |
3794 if (!registered && |
3794 if (!registered && |
3795 OrderAccess::load_acquire(&process_exiting) != 0 && |
3795 OrderAccess::load_acquire(&process_exiting) != 0 && |
3796 process_exiting != (jint)GetCurrentThreadId()) { |
3796 process_exiting != GetCurrentThreadId()) { |
3797 // Some other thread is about to call exit(), so we don't let |
3797 // Some other thread is about to call exit(), so we don't let |
3798 // the current unregistered thread proceed to exit() or _endthreadex() |
3798 // the current unregistered thread proceed to exit() or _endthreadex() |
3799 while (true) { |
3799 while (true) { |
3800 SuspendThread(GetCurrentThread()); |
3800 SuspendThread(GetCurrentThread()); |
3801 // Avoid busy-wait loop, if SuspendThread() failed. |
3801 // Avoid busy-wait loop, if SuspendThread() failed. |