Mercurial > hg > graal-compiler
comparison src/os/windows/vm/os_windows.cpp @ 10408:836a62f43af9
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 19 Jun 2013 10:45:56 +0200 |
parents | 19b998ad9264 f2110083203d |
children | 6b0fd0964b87 |
comparison
equal
deleted
inserted
replaced
10086:e0fb8a213650 | 10408:836a62f43af9 |
---|---|
811 result.dwHighDateTime = high(a); | 811 result.dwHighDateTime = high(a); |
812 result.dwLowDateTime = low(a); | 812 result.dwLowDateTime = low(a); |
813 return result; | 813 return result; |
814 } | 814 } |
815 | 815 |
816 // For now, we say that Windows does not support vtime. I have no idea | 816 bool os::supports_vtime() { return true; } |
817 // whether it can actually be made to (DLD, 9/13/05). | |
818 | |
819 bool os::supports_vtime() { return false; } | |
820 bool os::enable_vtime() { return false; } | 817 bool os::enable_vtime() { return false; } |
821 bool os::vtime_enabled() { return false; } | 818 bool os::vtime_enabled() { return false; } |
819 | |
822 double os::elapsedVTime() { | 820 double os::elapsedVTime() { |
823 // better than nothing, but not much | 821 FILETIME created; |
824 return elapsedTime(); | 822 FILETIME exited; |
823 FILETIME kernel; | |
824 FILETIME user; | |
825 if (GetThreadTimes(GetCurrentThread(), &created, &exited, &kernel, &user) != 0) { | |
826 // the resolution of windows_to_java_time() should be sufficient (ms) | |
827 return (double) (windows_to_java_time(kernel) + windows_to_java_time(user)) / MILLIUNITS; | |
828 } else { | |
829 return elapsedTime(); | |
830 } | |
825 } | 831 } |
826 | 832 |
827 jlong os::javaTimeMillis() { | 833 jlong os::javaTimeMillis() { |
828 if (UseFakeTimers) { | 834 if (UseFakeTimers) { |
829 return fake_time++; | 835 return fake_time++; |
942 DWORD processId = GetCurrentProcessId(); | 948 DWORD processId = GetCurrentProcessId(); |
943 HANDLE dumpFile; | 949 HANDLE dumpFile; |
944 MINIDUMP_TYPE dumpType; | 950 MINIDUMP_TYPE dumpType; |
945 static const char* cwd; | 951 static const char* cwd; |
946 | 952 |
953 // Default is to always create dump for debug builds, on product builds only dump on server versions of Windows. | |
954 #ifndef ASSERT | |
947 // If running on a client version of Windows and user has not explicitly enabled dumping | 955 // If running on a client version of Windows and user has not explicitly enabled dumping |
948 if (!os::win32::is_windows_server() && !CreateMinidumpOnCrash) { | 956 if (!os::win32::is_windows_server() && !CreateMinidumpOnCrash) { |
949 VMError::report_coredump_status("Minidumps are not enabled by default on client versions of Windows", false); | 957 VMError::report_coredump_status("Minidumps are not enabled by default on client versions of Windows", false); |
950 return; | 958 return; |
951 // If running on a server version of Windows and user has explictly disabled dumping | 959 // If running on a server version of Windows and user has explictly disabled dumping |
952 } else if (os::win32::is_windows_server() && !FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) { | 960 } else if (os::win32::is_windows_server() && !FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) { |
953 VMError::report_coredump_status("Minidump has been disabled from the command line", false); | 961 VMError::report_coredump_status("Minidump has been disabled from the command line", false); |
954 return; | 962 return; |
955 } | 963 } |
964 #else | |
965 if (!FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) { | |
966 VMError::report_coredump_status("Minidump has been disabled from the command line", false); | |
967 return; | |
968 } | |
969 #endif | |
956 | 970 |
957 dbghelp = os::win32::load_Windows_dll("DBGHELP.DLL", NULL, 0); | 971 dbghelp = os::win32::load_Windows_dll("DBGHELP.DLL", NULL, 0); |
958 | 972 |
959 if (dbghelp == NULL) { | 973 if (dbghelp == NULL) { |
960 VMError::report_coredump_status("Failed to load dbghelp.dll", false); | 974 VMError::report_coredump_status("Failed to load dbghelp.dll", false); |
1002 | 1016 |
1003 // Older versions of dbghelp.dll (the one shipped with Win2003 for example) may not support all | 1017 // Older versions of dbghelp.dll (the one shipped with Win2003 for example) may not support all |
1004 // the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then. | 1018 // the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then. |
1005 if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == false && | 1019 if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == false && |
1006 _MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == false) { | 1020 _MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == false) { |
1007 VMError::report_coredump_status("Call to MiniDumpWriteDump() failed", false); | 1021 DWORD error = GetLastError(); |
1022 LPTSTR msgbuf = NULL; | |
1023 | |
1024 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
1025 FORMAT_MESSAGE_FROM_SYSTEM | | |
1026 FORMAT_MESSAGE_IGNORE_INSERTS, | |
1027 NULL, error, 0, (LPTSTR)&msgbuf, 0, NULL) != 0) { | |
1028 | |
1029 jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x: %s)", error, msgbuf); | |
1030 LocalFree(msgbuf); | |
1031 } else { | |
1032 // Call to FormatMessage failed, just include the result from GetLastError | |
1033 jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x)", error); | |
1034 } | |
1035 VMError::report_coredump_status(buffer, false); | |
1008 } else { | 1036 } else { |
1009 VMError::report_coredump_status(buffer, true); | 1037 VMError::report_coredump_status(buffer, true); |
1010 } | 1038 } |
1011 | 1039 |
1012 CloseHandle(dumpFile); | 1040 CloseHandle(dumpFile); |
1219 return retval; | 1247 return retval; |
1220 } | 1248 } |
1221 | 1249 |
1222 // Needs to be in os specific directory because windows requires another | 1250 // Needs to be in os specific directory because windows requires another |
1223 // header file <direct.h> | 1251 // header file <direct.h> |
1224 const char* os::get_current_directory(char *buf, int buflen) { | 1252 const char* os::get_current_directory(char *buf, size_t buflen) { |
1225 return _getcwd(buf, buflen); | 1253 int n = static_cast<int>(buflen); |
1254 if (buflen > INT_MAX) n = INT_MAX; | |
1255 return _getcwd(buf, n); | |
1226 } | 1256 } |
1227 | 1257 |
1228 //----------------------------------------------------------- | 1258 //----------------------------------------------------------- |
1229 // Helper functions for fatal error handler | 1259 // Helper functions for fatal error handler |
1230 #ifdef _WIN64 | 1260 #ifdef _WIN64 |
3320 // 1: Thread is running now | 3350 // 1: Thread is running now |
3321 // >1: Thread is still suspended. | 3351 // >1: Thread is still suspended. |
3322 assert(ret != SYS_THREAD_ERROR, "StartThread failed"); // should propagate back | 3352 assert(ret != SYS_THREAD_ERROR, "StartThread failed"); // should propagate back |
3323 } | 3353 } |
3324 | 3354 |
3325 class HighResolutionInterval { | 3355 class HighResolutionInterval : public CHeapObj<mtThread> { |
3326 // The default timer resolution seems to be 10 milliseconds. | 3356 // The default timer resolution seems to be 10 milliseconds. |
3327 // (Where is this written down?) | 3357 // (Where is this written down?) |
3328 // If someone wants to sleep for only a fraction of the default, | 3358 // If someone wants to sleep for only a fraction of the default, |
3329 // then we set the timer resolution down to 1 millisecond for | 3359 // then we set the timer resolution down to 1 millisecond for |
3330 // the duration of their interval. | 3360 // the duration of their interval. |
4111 errno = ENAMETOOLONG; | 4141 errno = ENAMETOOLONG; |
4112 return -1; | 4142 return -1; |
4113 } | 4143 } |
4114 os::native_path(strcpy(pathbuf, path)); | 4144 os::native_path(strcpy(pathbuf, path)); |
4115 return ::open(pathbuf, oflag | O_BINARY | O_NOINHERIT, mode); | 4145 return ::open(pathbuf, oflag | O_BINARY | O_NOINHERIT, mode); |
4146 } | |
4147 | |
4148 FILE* os::open(int fd, const char* mode) { | |
4149 return ::_fdopen(fd, mode); | |
4116 } | 4150 } |
4117 | 4151 |
4118 // Is a (classpath) directory empty? | 4152 // Is a (classpath) directory empty? |
4119 bool os::dir_is_empty(const char* path) { | 4153 bool os::dir_is_empty(const char* path) { |
4120 WIN32_FIND_DATA fd; | 4154 WIN32_FIND_DATA fd; |
5029 int os::set_sock_opt(int fd, int level, int optname, | 5063 int os::set_sock_opt(int fd, int level, int optname, |
5030 const char* optval, socklen_t optlen) { | 5064 const char* optval, socklen_t optlen) { |
5031 return ::setsockopt(fd, level, optname, optval, optlen); | 5065 return ::setsockopt(fd, level, optname, optval, optlen); |
5032 } | 5066 } |
5033 | 5067 |
5068 // WINDOWS CONTEXT Flags for THREAD_SAMPLING | |
5069 #if defined(IA32) | |
5070 # define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS) | |
5071 #elif defined (AMD64) | |
5072 # define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT) | |
5073 #endif | |
5074 | |
5075 // returns true if thread could be suspended, | |
5076 // false otherwise | |
5077 static bool do_suspend(HANDLE* h) { | |
5078 if (h != NULL) { | |
5079 if (SuspendThread(*h) != ~0) { | |
5080 return true; | |
5081 } | |
5082 } | |
5083 return false; | |
5084 } | |
5085 | |
5086 // resume the thread | |
5087 // calling resume on an active thread is a no-op | |
5088 static void do_resume(HANDLE* h) { | |
5089 if (h != NULL) { | |
5090 ResumeThread(*h); | |
5091 } | |
5092 } | |
5093 | |
5094 // retrieve a suspend/resume context capable handle | |
5095 // from the tid. Caller validates handle return value. | |
5096 void get_thread_handle_for_extended_context(HANDLE* h, OSThread::thread_id_t tid) { | |
5097 if (h != NULL) { | |
5098 *h = OpenThread(THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, tid); | |
5099 } | |
5100 } | |
5101 | |
5102 // | |
5103 // Thread sampling implementation | |
5104 // | |
5105 void os::SuspendedThreadTask::internal_do_task() { | |
5106 CONTEXT ctxt; | |
5107 HANDLE h = NULL; | |
5108 | |
5109 // get context capable handle for thread | |
5110 get_thread_handle_for_extended_context(&h, _thread->osthread()->thread_id()); | |
5111 | |
5112 // sanity | |
5113 if (h == NULL || h == INVALID_HANDLE_VALUE) { | |
5114 return; | |
5115 } | |
5116 | |
5117 // suspend the thread | |
5118 if (do_suspend(&h)) { | |
5119 ctxt.ContextFlags = sampling_context_flags; | |
5120 // get thread context | |
5121 GetThreadContext(h, &ctxt); | |
5122 SuspendedThreadTaskContext context(_thread, &ctxt); | |
5123 // pass context to Thread Sampling impl | |
5124 do_task(context); | |
5125 // resume thread | |
5126 do_resume(&h); | |
5127 } | |
5128 | |
5129 // close handle | |
5130 CloseHandle(h); | |
5131 } | |
5132 | |
5034 | 5133 |
5035 // Kernel32 API | 5134 // Kernel32 API |
5036 typedef SIZE_T (WINAPI* GetLargePageMinimum_Fn)(void); | 5135 typedef SIZE_T (WINAPI* GetLargePageMinimum_Fn)(void); |
5037 typedef LPVOID (WINAPI *VirtualAllocExNuma_Fn) (HANDLE, LPVOID, SIZE_T, DWORD, DWORD, DWORD); | 5136 typedef LPVOID (WINAPI *VirtualAllocExNuma_Fn) (HANDLE, LPVOID, SIZE_T, DWORD, DWORD, DWORD); |
5038 typedef BOOL (WINAPI *GetNumaHighestNodeNumber_Fn) (PULONG); | 5137 typedef BOOL (WINAPI *GetNumaHighestNodeNumber_Fn) (PULONG); |