changeset 26683 | a02753d5a0b2 |
parent 26295 | 6a9d9192f215 |
child 26684 | d1221849ea3d |
26331:8f17e084029b | 26683:a02753d5a0b2 |
---|---|
124 |
124 |
125 HINSTANCE vm_lib_handle; |
125 HINSTANCE vm_lib_handle; |
126 |
126 |
127 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) { |
127 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) { |
128 switch (reason) { |
128 switch (reason) { |
129 case DLL_PROCESS_ATTACH: |
129 case DLL_PROCESS_ATTACH: |
130 vm_lib_handle = hinst; |
130 vm_lib_handle = hinst; |
131 if (ForceTimeHighResolution) |
131 if (ForceTimeHighResolution) |
132 timeBeginPeriod(1L); |
132 timeBeginPeriod(1L); |
133 break; |
133 break; |
134 case DLL_PROCESS_DETACH: |
134 case DLL_PROCESS_DETACH: |
135 if (ForceTimeHighResolution) |
135 if (ForceTimeHighResolution) |
136 timeEndPeriod(1L); |
136 timeEndPeriod(1L); |
137 |
137 |
138 break; |
138 break; |
139 default: |
139 default: |
140 break; |
140 break; |
141 } |
141 } |
142 return true; |
142 return true; |
143 } |
143 } |
144 |
144 |
145 static inline double fileTimeAsDouble(FILETIME* time) { |
145 static inline double fileTimeAsDouble(FILETIME* time) { |
151 } |
151 } |
152 |
152 |
153 // Implementation of os |
153 // Implementation of os |
154 |
154 |
155 bool os::getenv(const char* name, char* buffer, int len) { |
155 bool os::getenv(const char* name, char* buffer, int len) { |
156 int result = GetEnvironmentVariable(name, buffer, len); |
156 int result = GetEnvironmentVariable(name, buffer, len); |
157 return result > 0 && result < len; |
157 return result > 0 && result < len; |
158 } |
158 } |
159 |
159 |
160 bool os::unsetenv(const char* name) { |
160 bool os::unsetenv(const char* name) { |
161 assert(name != NULL, "Null pointer"); |
161 assert(name != NULL, "Null pointer"); |
162 return (SetEnvironmentVariable(name, NULL) == TRUE); |
162 return (SetEnvironmentVariable(name, NULL) == TRUE); |
180 |
180 |
181 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo); |
181 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo); |
182 void os::init_system_properties_values() { |
182 void os::init_system_properties_values() { |
183 /* sysclasspath, java_home, dll_dir */ |
183 /* sysclasspath, java_home, dll_dir */ |
184 { |
184 { |
185 char *home_path; |
185 char *home_path; |
186 char *dll_path; |
186 char *dll_path; |
187 char *pslash; |
187 char *pslash; |
188 char *bin = "\\bin"; |
188 char *bin = "\\bin"; |
189 char home_dir[MAX_PATH]; |
189 char home_dir[MAX_PATH]; |
190 |
190 |
191 if (!getenv("_ALT_JAVA_HOME_DIR", home_dir, MAX_PATH)) { |
191 if (!getenv("_ALT_JAVA_HOME_DIR", home_dir, MAX_PATH)) { |
192 os::jvm_path(home_dir, sizeof(home_dir)); |
192 os::jvm_path(home_dir, sizeof(home_dir)); |
193 // Found the full path to jvm.dll. |
193 // Found the full path to jvm.dll. |
194 // Now cut the path to <java_home>/jre if we can. |
194 // Now cut the path to <java_home>/jre if we can. |
195 *(strrchr(home_dir, '\\')) = '\0'; /* get rid of \jvm.dll */ |
195 *(strrchr(home_dir, '\\')) = '\0'; /* get rid of \jvm.dll */ |
196 pslash = strrchr(home_dir, '\\'); |
196 pslash = strrchr(home_dir, '\\'); |
197 if (pslash != NULL) { |
197 if (pslash != NULL) { |
198 *pslash = '\0'; /* get rid of \{client|server} */ |
198 *pslash = '\0'; /* get rid of \{client|server} */ |
199 pslash = strrchr(home_dir, '\\'); |
199 pslash = strrchr(home_dir, '\\'); |
200 if (pslash != NULL) |
200 if (pslash != NULL) |
201 *pslash = '\0'; /* get rid of \bin */ |
201 *pslash = '\0'; /* get rid of \bin */ |
202 } |
|
203 } |
202 } |
204 |
203 } |
205 home_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + 1, mtInternal); |
204 |
206 if (home_path == NULL) |
205 home_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + 1, mtInternal); |
207 return; |
206 if (home_path == NULL) |
208 strcpy(home_path, home_dir); |
207 return; |
209 Arguments::set_java_home(home_path); |
208 strcpy(home_path, home_dir); |
210 |
209 Arguments::set_java_home(home_path); |
211 dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1, mtInternal); |
210 |
212 if (dll_path == NULL) |
211 dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1, mtInternal); |
213 return; |
212 if (dll_path == NULL) |
214 strcpy(dll_path, home_dir); |
213 return; |
215 strcat(dll_path, bin); |
214 strcpy(dll_path, home_dir); |
216 Arguments::set_dll_dir(dll_path); |
215 strcat(dll_path, bin); |
217 |
216 Arguments::set_dll_dir(dll_path); |
218 if (!set_boot_path('\\', ';')) |
217 |
219 return; |
218 if (!set_boot_path('\\', ';')) |
219 return; |
|
220 } |
220 } |
221 |
221 |
222 /* library_path */ |
222 /* library_path */ |
223 #define EXT_DIR "\\lib\\ext" |
223 #define EXT_DIR "\\lib\\ext" |
224 #define BIN_DIR "\\bin" |
224 #define BIN_DIR "\\bin" |
237 char *library_path; |
237 char *library_path; |
238 char tmp[MAX_PATH]; |
238 char tmp[MAX_PATH]; |
239 char *path_str = ::getenv("PATH"); |
239 char *path_str = ::getenv("PATH"); |
240 |
240 |
241 library_path = NEW_C_HEAP_ARRAY(char, MAX_PATH * 5 + sizeof(PACKAGE_DIR) + |
241 library_path = NEW_C_HEAP_ARRAY(char, MAX_PATH * 5 + sizeof(PACKAGE_DIR) + |
242 sizeof(BIN_DIR) + (path_str ? strlen(path_str) : 0) + 10, mtInternal); |
242 sizeof(BIN_DIR) + (path_str ? strlen(path_str) : 0) + 10, mtInternal); |
243 |
243 |
244 library_path[0] = '\0'; |
244 library_path[0] = '\0'; |
245 |
245 |
246 GetModuleFileName(NULL, tmp, sizeof(tmp)); |
246 GetModuleFileName(NULL, tmp, sizeof(tmp)); |
247 *(strrchr(tmp, '\\')) = '\0'; |
247 *(strrchr(tmp, '\\')) = '\0'; |
259 GetWindowsDirectory(tmp, sizeof(tmp)); |
259 GetWindowsDirectory(tmp, sizeof(tmp)); |
260 strcat(library_path, ";"); |
260 strcat(library_path, ";"); |
261 strcat(library_path, tmp); |
261 strcat(library_path, tmp); |
262 |
262 |
263 if (path_str) { |
263 if (path_str) { |
264 strcat(library_path, ";"); |
264 strcat(library_path, ";"); |
265 strcat(library_path, path_str); |
265 strcat(library_path, path_str); |
266 } |
266 } |
267 |
267 |
268 strcat(library_path, ";."); |
268 strcat(library_path, ";."); |
269 |
269 |
270 Arguments::set_library_path(library_path); |
270 Arguments::set_library_path(library_path); |
275 { |
275 { |
276 char path[MAX_PATH]; |
276 char path[MAX_PATH]; |
277 char buf[2 * MAX_PATH + 2 * sizeof(EXT_DIR) + sizeof(PACKAGE_DIR) + 1]; |
277 char buf[2 * MAX_PATH + 2 * sizeof(EXT_DIR) + sizeof(PACKAGE_DIR) + 1]; |
278 GetWindowsDirectory(path, MAX_PATH); |
278 GetWindowsDirectory(path, MAX_PATH); |
279 sprintf(buf, "%s%s;%s%s%s", Arguments::get_java_home(), EXT_DIR, |
279 sprintf(buf, "%s%s;%s%s%s", Arguments::get_java_home(), EXT_DIR, |
280 path, PACKAGE_DIR, EXT_DIR); |
280 path, PACKAGE_DIR, EXT_DIR); |
281 Arguments::set_ext_dirs(buf); |
281 Arguments::set_ext_dirs(buf); |
282 } |
282 } |
283 #undef EXT_DIR |
283 #undef EXT_DIR |
284 #undef BIN_DIR |
284 #undef BIN_DIR |
285 #undef PACKAGE_DIR |
285 #undef PACKAGE_DIR |
320 int os::get_native_stack(address* stack, int frames, int toSkip) { |
320 int os::get_native_stack(address* stack, int frames, int toSkip) { |
321 #ifdef _NMT_NOINLINE_ |
321 #ifdef _NMT_NOINLINE_ |
322 toSkip ++; |
322 toSkip ++; |
323 #endif |
323 #endif |
324 int captured = Kernel32Dll::RtlCaptureStackBackTrace(toSkip + 1, frames, |
324 int captured = Kernel32Dll::RtlCaptureStackBackTrace(toSkip + 1, frames, |
325 (PVOID*)stack, NULL); |
325 (PVOID*)stack, NULL); |
326 for (int index = captured; index < frames; index ++) { |
326 for (int index = captured; index < frames; index ++) { |
327 stack[index] = NULL; |
327 stack[index] = NULL; |
328 } |
328 } |
329 return captured; |
329 return captured; |
330 } |
330 } |
443 |
443 |
444 // Install a win32 structured exception handler around every thread created |
444 // Install a win32 structured exception handler around every thread created |
445 // by VM, so VM can generate error dump when an exception occurred in non- |
445 // by VM, so VM can generate error dump when an exception occurred in non- |
446 // Java thread (e.g. VM thread). |
446 // Java thread (e.g. VM thread). |
447 __try { |
447 __try { |
448 thread->run(); |
448 thread->run(); |
449 } __except(topLevelExceptionFilter( |
449 } __except(topLevelExceptionFilter( |
450 (_EXCEPTION_POINTERS*)_exception_info())) { |
450 (_EXCEPTION_POINTERS*)_exception_info())) { |
451 // Nothing to do. |
451 // Nothing to do. |
452 } |
452 } |
453 |
453 |
454 // One less thread is executing |
454 // One less thread is executing |
455 // When the VMThread gets here, the main thread may have already exited |
455 // When the VMThread gets here, the main thread may have already exited |
456 // which frees the CodeHeap containing the Atomic::add code |
456 // which frees the CodeHeap containing the Atomic::add code |
507 fatal("DuplicateHandle failed\n"); |
507 fatal("DuplicateHandle failed\n"); |
508 } |
508 } |
509 OSThread* osthread = create_os_thread(thread, thread_h, |
509 OSThread* osthread = create_os_thread(thread, thread_h, |
510 (int)current_thread_id()); |
510 (int)current_thread_id()); |
511 if (osthread == NULL) { |
511 if (osthread == NULL) { |
512 return false; |
512 return false; |
513 } |
513 } |
514 |
514 |
515 // Initial thread state is RUNNABLE |
515 // Initial thread state is RUNNABLE |
516 osthread->set_state(RUNNABLE); |
516 osthread->set_state(RUNNABLE); |
517 |
517 |
523 #ifdef ASSERT |
523 #ifdef ASSERT |
524 thread->verify_not_published(); |
524 thread->verify_not_published(); |
525 #endif |
525 #endif |
526 if (_starting_thread == NULL) { |
526 if (_starting_thread == NULL) { |
527 _starting_thread = create_os_thread(thread, main_thread, main_thread_id); |
527 _starting_thread = create_os_thread(thread, main_thread, main_thread_id); |
528 if (_starting_thread == NULL) { |
528 if (_starting_thread == NULL) { |
529 return false; |
529 return false; |
530 } |
530 } |
531 } |
531 } |
532 |
532 |
533 // The primordial thread is runnable from the start) |
533 // The primordial thread is runnable from the start) |
534 _starting_thread->set_state(RUNNABLE); |
534 _starting_thread->set_state(RUNNABLE); |
535 |
535 |
614 &thread_id); |
614 &thread_id); |
615 if (thread_handle == NULL) { |
615 if (thread_handle == NULL) { |
616 // perhaps STACK_SIZE_PARAM_IS_A_RESERVATION is not supported, try again |
616 // perhaps STACK_SIZE_PARAM_IS_A_RESERVATION is not supported, try again |
617 // without the flag. |
617 // without the flag. |
618 thread_handle = |
618 thread_handle = |
619 (HANDLE)_beginthreadex(NULL, |
619 (HANDLE)_beginthreadex(NULL, |
620 (unsigned)stack_size, |
620 (unsigned)stack_size, |
621 (unsigned (__stdcall *)(void*)) java_start, |
621 (unsigned (__stdcall *)(void*)) java_start, |
622 thread, |
622 thread, |
623 CREATE_SUSPENDED, |
623 CREATE_SUSPENDED, |
624 &thread_id); |
624 &thread_id); |
625 } |
625 } |
626 if (thread_handle == NULL) { |
626 if (thread_handle == NULL) { |
627 // Need to clean up stuff we've allocated so far |
627 // Need to clean up stuff we've allocated so far |
628 CloseHandle(osthread->interrupt_event()); |
628 CloseHandle(osthread->interrupt_event()); |
629 thread->set_osthread(NULL); |
629 thread->set_osthread(NULL); |
681 |
681 |
682 jlong os::elapsed_frequency() { |
682 jlong os::elapsed_frequency() { |
683 if (win32::_has_performance_count) { |
683 if (win32::_has_performance_count) { |
684 return performance_frequency; |
684 return performance_frequency; |
685 } else { |
685 } else { |
686 // the FILETIME time is the number of 100-nanosecond intervals since January 1,1601. |
686 // the FILETIME time is the number of 100-nanosecond intervals since January 1,1601. |
687 return 10000000; |
687 return 10000000; |
688 } |
688 } |
689 } |
689 } |
690 |
690 |
691 |
691 |
692 julong os::available_memory() { |
692 julong os::available_memory() { |
914 st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); |
914 st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); |
915 return buf; |
915 return buf; |
916 } |
916 } |
917 |
917 |
918 bool os::getTimesSecs(double* process_real_time, |
918 bool os::getTimesSecs(double* process_real_time, |
919 double* process_user_time, |
919 double* process_user_time, |
920 double* process_system_time) { |
920 double* process_system_time) { |
921 HANDLE h_process = GetCurrentProcess(); |
921 HANDLE h_process = GetCurrentProcess(); |
922 FILETIME create_time, exit_time, kernel_time, user_time; |
922 FILETIME create_time, exit_time, kernel_time, user_time; |
923 BOOL result = GetProcessTimes(h_process, |
923 BOOL result = GetProcessTimes(h_process, |
924 &create_time, |
924 &create_time, |
925 &exit_time, |
925 &exit_time, |
926 &kernel_time, |
926 &kernel_time, |
927 &user_time); |
927 &user_time); |
928 if (result != 0) { |
928 if (result != 0) { |
929 FILETIME wt; |
929 FILETIME wt; |
930 GetSystemTimeAsFileTime(&wt); |
930 GetSystemTimeAsFileTime(&wt); |
931 jlong rtc_millis = windows_to_java_time(wt); |
931 jlong rtc_millis = windows_to_java_time(wt); |
932 jlong user_millis = windows_to_java_time(user_time); |
932 jlong user_millis = windows_to_java_time(user_time); |
995 VMError::report_coredump_status("Failed to load dbghelp.dll", false); |
995 VMError::report_coredump_status("Failed to load dbghelp.dll", false); |
996 return; |
996 return; |
997 } |
997 } |
998 |
998 |
999 _MiniDumpWriteDump = CAST_TO_FN_PTR( |
999 _MiniDumpWriteDump = CAST_TO_FN_PTR( |
1000 BOOL(WINAPI *)( HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION, |
1000 BOOL(WINAPI *)( HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION, |
1001 PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION), |
1001 PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION), |
1002 GetProcAddress(dbghelp, "MiniDumpWriteDump")); |
1002 GetProcAddress(dbghelp, "MiniDumpWriteDump")); |
1003 |
1003 |
1004 if (_MiniDumpWriteDump == NULL) { |
1004 if (_MiniDumpWriteDump == NULL) { |
1005 VMError::report_coredump_status("Failed to find MiniDumpWriteDump() in module dbghelp.dll", false); |
1005 VMError::report_coredump_status("Failed to find MiniDumpWriteDump() in module dbghelp.dll", false); |
1006 return; |
1006 return; |
1007 } |
1007 } |
1010 |
1010 |
1011 // Older versions of dbghelp.h doesn't contain all the dumptypes we want, dbghelp.h with |
1011 // Older versions of dbghelp.h doesn't contain all the dumptypes we want, dbghelp.h with |
1012 // API_VERSION_NUMBER 11 or higher contains the ones we want though |
1012 // API_VERSION_NUMBER 11 or higher contains the ones we want though |
1013 #if API_VERSION_NUMBER >= 11 |
1013 #if API_VERSION_NUMBER >= 11 |
1014 dumpType = (MINIDUMP_TYPE)(dumpType | MiniDumpWithFullMemoryInfo | MiniDumpWithThreadInfo | |
1014 dumpType = (MINIDUMP_TYPE)(dumpType | MiniDumpWithFullMemoryInfo | MiniDumpWithThreadInfo | |
1015 MiniDumpWithUnloadedModules); |
1015 MiniDumpWithUnloadedModules); |
1016 #endif |
1016 #endif |
1017 |
1017 |
1018 cwd = get_current_directory(NULL, 0); |
1018 cwd = get_current_directory(NULL, 0); |
1019 jio_snprintf(buffer, bufferSize, "%s\\hs_err_pid%u.mdmp", cwd, current_process_id()); |
1019 jio_snprintf(buffer, bufferSize, "%s\\hs_err_pid%u.mdmp", cwd, current_process_id()); |
1020 dumpFile = CreateFile(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
1020 dumpFile = CreateFile(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
1037 |
1037 |
1038 // Older versions of dbghelp.dll (the one shipped with Win2003 for example) may not support all |
1038 // Older versions of dbghelp.dll (the one shipped with Win2003 for example) may not support all |
1039 // the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then. |
1039 // the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then. |
1040 if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == false && |
1040 if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == false && |
1041 _MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == false) { |
1041 _MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == false) { |
1042 DWORD error = GetLastError(); |
1042 DWORD error = GetLastError(); |
1043 LPTSTR msgbuf = NULL; |
1043 LPTSTR msgbuf = NULL; |
1044 |
1044 |
1045 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | |
1045 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | |
1046 FORMAT_MESSAGE_FROM_SYSTEM | |
1046 FORMAT_MESSAGE_FROM_SYSTEM | |
1047 FORMAT_MESSAGE_IGNORE_INSERTS, |
1047 FORMAT_MESSAGE_IGNORE_INSERTS, |
1048 NULL, error, 0, (LPTSTR)&msgbuf, 0, NULL) != 0) { |
1048 NULL, error, 0, (LPTSTR)&msgbuf, 0, NULL) != 0) { |
1049 |
1049 |
1050 jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x: %s)", error, msgbuf); |
1050 jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x: %s)", error, msgbuf); |
1051 LocalFree(msgbuf); |
1051 LocalFree(msgbuf); |
1052 } else { |
1052 } else { |
1053 // Call to FormatMessage failed, just include the result from GetLastError |
1053 // Call to FormatMessage failed, just include the result from GetLastError |
1054 jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x)", error); |
1054 jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x)", error); |
1055 } |
1055 } |
1056 VMError::report_coredump_status(buffer, false); |
1056 VMError::report_coredump_status(buffer, false); |
1057 } else { |
1057 } else { |
1058 VMError::report_coredump_status(buffer, true); |
1058 VMError::report_coredump_status(buffer, true); |
1059 } |
1059 } |
1060 |
1060 |
1061 CloseHandle(dumpFile); |
1061 CloseHandle(dumpFile); |
1084 duplicate slashes and converts all instances of '/' into '\\'. */ |
1084 duplicate slashes and converts all instances of '/' into '\\'. */ |
1085 |
1085 |
1086 DIR * |
1086 DIR * |
1087 os::opendir(const char *dirname) |
1087 os::opendir(const char *dirname) |
1088 { |
1088 { |
1089 assert(dirname != NULL, "just checking"); // hotspot change |
1089 assert(dirname != NULL, "just checking"); // hotspot change |
1090 DIR *dirp = (DIR *)malloc(sizeof(DIR), mtInternal); |
1090 DIR *dirp = (DIR *)malloc(sizeof(DIR), mtInternal); |
1091 DWORD fattr; // hotspot change |
1091 DWORD fattr; // hotspot change |
1092 char alt_dirname[4] = { 0, 0, 0, 0 }; |
1092 char alt_dirname[4] = { 0, 0, 0, 0 }; |
1093 |
1093 |
1094 if (dirp == 0) { |
1094 if (dirp == 0) { |
1095 errno = ENOMEM; |
1095 errno = ENOMEM; |
1096 return 0; |
1096 return 0; |
1097 } |
1097 } |
1098 |
1098 |
1099 /* |
1099 /* |
1100 * Win32 accepts "\" in its POSIX stat(), but refuses to treat it |
1100 * Win32 accepts "\" in its POSIX stat(), but refuses to treat it |
1101 * as a directory in FindFirstFile(). We detect this case here and |
1101 * as a directory in FindFirstFile(). We detect this case here and |
1102 * prepend the current drive name. |
1102 * prepend the current drive name. |
1103 */ |
1103 */ |
1104 if (dirname[1] == '\0' && dirname[0] == '\\') { |
1104 if (dirname[1] == '\0' && dirname[0] == '\\') { |
1105 alt_dirname[0] = _getdrive() + 'A' - 1; |
1105 alt_dirname[0] = _getdrive() + 'A' - 1; |
1106 alt_dirname[1] = ':'; |
1106 alt_dirname[1] = ':'; |
1107 alt_dirname[2] = '\\'; |
1107 alt_dirname[2] = '\\'; |
1108 alt_dirname[3] = '\0'; |
1108 alt_dirname[3] = '\0'; |
1109 dirname = alt_dirname; |
1109 dirname = alt_dirname; |
1110 } |
1110 } |
1111 |
1111 |
1112 dirp->path = (char *)malloc(strlen(dirname) + 5, mtInternal); |
1112 dirp->path = (char *)malloc(strlen(dirname) + 5, mtInternal); |
1113 if (dirp->path == 0) { |
1113 if (dirp->path == 0) { |
1114 free(dirp, mtInternal); |
1114 free(dirp, mtInternal); |
1115 errno = ENOMEM; |
1115 errno = ENOMEM; |
1116 return 0; |
1116 return 0; |
1117 } |
1117 } |
1118 strcpy(dirp->path, dirname); |
1118 strcpy(dirp->path, dirname); |
1119 |
1119 |
1120 fattr = GetFileAttributes(dirp->path); |
1120 fattr = GetFileAttributes(dirp->path); |
1121 if (fattr == 0xffffffff) { |
1121 if (fattr == 0xffffffff) { |
1122 free(dirp->path, mtInternal); |
1122 free(dirp->path, mtInternal); |
1123 free(dirp, mtInternal); |
1123 free(dirp, mtInternal); |
1124 errno = ENOENT; |
1124 errno = ENOENT; |
1125 return 0; |
1125 return 0; |
1126 } else if ((fattr & FILE_ATTRIBUTE_DIRECTORY) == 0) { |
1126 } else if ((fattr & FILE_ATTRIBUTE_DIRECTORY) == 0) { |
1127 free(dirp->path, mtInternal); |
1127 free(dirp->path, mtInternal); |
1128 free(dirp, mtInternal); |
1128 free(dirp, mtInternal); |
1129 errno = ENOTDIR; |
1129 errno = ENOTDIR; |
1130 return 0; |
1130 return 0; |
1131 } |
1131 } |
1132 |
1132 |
1133 /* Append "*.*", or possibly "\\*.*", to path */ |
1133 /* Append "*.*", or possibly "\\*.*", to path */ |
1134 if (dirp->path[1] == ':' |
1134 if (dirp->path[1] == ':' |
1135 && (dirp->path[2] == '\0' |
1135 && (dirp->path[2] == '\0' |
1136 || (dirp->path[2] == '\\' && dirp->path[3] == '\0'))) { |
1136 || (dirp->path[2] == '\\' && dirp->path[3] == '\0'))) { |
1137 /* No '\\' needed for cases like "Z:" or "Z:\" */ |
1137 /* No '\\' needed for cases like "Z:" or "Z:\" */ |
1138 strcat(dirp->path, "*.*"); |
1138 strcat(dirp->path, "*.*"); |
1139 } else { |
1139 } else { |
1140 strcat(dirp->path, "\\*.*"); |
1140 strcat(dirp->path, "\\*.*"); |
1141 } |
1141 } |
1142 |
1142 |
1143 dirp->handle = FindFirstFile(dirp->path, &dirp->find_data); |
1143 dirp->handle = FindFirstFile(dirp->path, &dirp->find_data); |
1144 if (dirp->handle == INVALID_HANDLE_VALUE) { |
1144 if (dirp->handle == INVALID_HANDLE_VALUE) { |
1145 if (GetLastError() != ERROR_FILE_NOT_FOUND) { |
1145 if (GetLastError() != ERROR_FILE_NOT_FOUND) { |
1146 free(dirp->path, mtInternal); |
1146 free(dirp->path, mtInternal); |
1147 free(dirp, mtInternal); |
1147 free(dirp, mtInternal); |
1148 errno = EACCES; |
1148 errno = EACCES; |
1149 return 0; |
1149 return 0; |
1150 } |
1150 } |
1151 } |
1151 } |
1152 return dirp; |
1152 return dirp; |
1153 } |
1153 } |
1154 |
1154 |
1155 /* parameter dbuf unused on Windows */ |
1155 /* parameter dbuf unused on Windows */ |
1156 |
1156 |
1157 struct dirent * |
1157 struct dirent * |
1158 os::readdir(DIR *dirp, dirent *dbuf) |
1158 os::readdir(DIR *dirp, dirent *dbuf) |
1159 { |
1159 { |
1160 assert(dirp != NULL, "just checking"); // hotspot change |
1160 assert(dirp != NULL, "just checking"); // hotspot change |
1161 if (dirp->handle == INVALID_HANDLE_VALUE) { |
1161 if (dirp->handle == INVALID_HANDLE_VALUE) { |
1162 return 0; |
1162 return 0; |
1163 } |
1163 } |
1164 |
1164 |
1165 strcpy(dirp->dirent.d_name, dirp->find_data.cFileName); |
1165 strcpy(dirp->dirent.d_name, dirp->find_data.cFileName); |
1166 |
1166 |
1167 if (!FindNextFile(dirp->handle, &dirp->find_data)) { |
1167 if (!FindNextFile(dirp->handle, &dirp->find_data)) { |
1168 if (GetLastError() == ERROR_INVALID_HANDLE) { |
1168 if (GetLastError() == ERROR_INVALID_HANDLE) { |
1169 errno = EBADF; |
1169 errno = EBADF; |
1170 return 0; |
1170 return 0; |
1171 } |
1171 } |
1172 FindClose(dirp->handle); |
1172 FindClose(dirp->handle); |
1173 dirp->handle = INVALID_HANDLE_VALUE; |
1173 dirp->handle = INVALID_HANDLE_VALUE; |
1174 } |
1174 } |
1175 |
1175 |
1176 return &dirp->dirent; |
1176 return &dirp->dirent; |
1177 } |
1177 } |
1178 |
1178 |
1179 int |
1179 int |
1180 os::closedir(DIR *dirp) |
1180 os::closedir(DIR *dirp) |
1181 { |
1181 { |
1182 assert(dirp != NULL, "just checking"); // hotspot change |
1182 assert(dirp != NULL, "just checking"); // hotspot change |
1183 if (dirp->handle != INVALID_HANDLE_VALUE) { |
1183 if (dirp->handle != INVALID_HANDLE_VALUE) { |
1184 if (!FindClose(dirp->handle)) { |
1184 if (!FindClose(dirp->handle)) { |
1185 errno = EBADF; |
1185 errno = EBADF; |
1186 return -1; |
1186 return -1; |
1187 } |
1187 } |
1188 dirp->handle = INVALID_HANDLE_VALUE; |
1188 dirp->handle = INVALID_HANDLE_VALUE; |
1189 } |
1189 } |
1190 free(dirp->path, mtInternal); |
1190 free(dirp->path, mtInternal); |
1191 free(dirp, mtInternal); |
1191 free(dirp, mtInternal); |
1192 return 0; |
1192 return 0; |
1193 } |
1193 } |
1194 |
1194 |
1195 // This must be hard coded because it's the system's temporary |
1195 // This must be hard coded because it's the system's temporary |
1196 // directory not the java application's temp directory, ala java.io.tmpdir. |
1196 // directory not the java application's temp directory, ala java.io.tmpdir. |
1197 const char* os::get_temp_directory() { |
1197 const char* os::get_temp_directory() { |
1288 MODULEINFO minfo; |
1288 MODULEINFO minfo; |
1289 |
1289 |
1290 hmod = GetModuleHandle("NTDLL.DLL"); |
1290 hmod = GetModuleHandle("NTDLL.DLL"); |
1291 if (hmod == NULL) return false; |
1291 if (hmod == NULL) return false; |
1292 if (!os::PSApiDll::GetModuleInformation( GetCurrentProcess(), hmod, |
1292 if (!os::PSApiDll::GetModuleInformation( GetCurrentProcess(), hmod, |
1293 &minfo, sizeof(MODULEINFO)) ) |
1293 &minfo, sizeof(MODULEINFO)) ) |
1294 return false; |
1294 return false; |
1295 |
1295 |
1296 if ((addr >= minfo.lpBaseOfDll) && |
1296 if ((addr >= minfo.lpBaseOfDll) && |
1297 (addr < (address)((uintptr_t)minfo.lpBaseOfDll + (uintptr_t)minfo.SizeOfImage))) |
1297 (addr < (address)((uintptr_t)minfo.lpBaseOfDll + (uintptr_t)minfo.SizeOfImage))) |
1298 return true; |
1298 return true; |
1299 else |
1299 else |
1300 return false; |
1300 return false; |
1301 } |
1301 } |
1302 #endif |
1302 #endif |
1336 FALSE, pid); |
1336 FALSE, pid); |
1337 if (hProcess == NULL) return 0; |
1337 if (hProcess == NULL) return 0; |
1338 |
1338 |
1339 DWORD size_needed; |
1339 DWORD size_needed; |
1340 if (!os::PSApiDll::EnumProcessModules(hProcess, modules, |
1340 if (!os::PSApiDll::EnumProcessModules(hProcess, modules, |
1341 sizeof(modules), &size_needed)) { |
1341 sizeof(modules), &size_needed)) { |
1342 CloseHandle(hProcess); |
1342 CloseHandle(hProcess); |
1343 return 0; |
1343 return 0; |
1344 } |
1344 } |
1345 |
1345 |
1346 // number of modules that are currently loaded |
1346 // number of modules that are currently loaded |
1347 int num_modules = size_needed / sizeof(HMODULE); |
1347 int num_modules = size_needed / sizeof(HMODULE); |
1348 |
1348 |
1349 for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) { |
1349 for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) { |
1350 // Get Full pathname: |
1350 // Get Full pathname: |
1351 if (!os::PSApiDll::GetModuleFileNameEx(hProcess, modules[i], |
1351 if (!os::PSApiDll::GetModuleFileNameEx(hProcess, modules[i], |
1352 filename, sizeof(filename))) { |
1352 filename, sizeof(filename))) { |
1353 filename[0] = '\0'; |
1353 filename[0] = '\0'; |
1354 } |
1354 } |
1355 |
1355 |
1356 MODULEINFO modinfo; |
1356 MODULEINFO modinfo; |
1357 if (!os::PSApiDll::GetModuleInformation(hProcess, modules[i], |
1357 if (!os::PSApiDll::GetModuleInformation(hProcess, modules[i], |
1358 &modinfo, sizeof(modinfo))) { |
1358 &modinfo, sizeof(modinfo))) { |
1359 modinfo.lpBaseOfDll = NULL; |
1359 modinfo.lpBaseOfDll = NULL; |
1360 modinfo.SizeOfImage = 0; |
1360 modinfo.SizeOfImage = 0; |
1361 } |
1361 } |
1362 |
1362 |
1363 // Invoke callback function |
1363 // Invoke callback function |
1364 result = func(pid, filename, (address)modinfo.lpBaseOfDll, |
1364 result = func(pid, filename, (address)modinfo.lpBaseOfDll, |
1365 modinfo.SizeOfImage, param); |
1365 modinfo.SizeOfImage, param); |
1383 } |
1383 } |
1384 |
1384 |
1385 // Get a handle to a Toolhelp snapshot of the system |
1385 // Get a handle to a Toolhelp snapshot of the system |
1386 hSnapShot = os::Kernel32Dll::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); |
1386 hSnapShot = os::Kernel32Dll::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); |
1387 if (hSnapShot == INVALID_HANDLE_VALUE) { |
1387 if (hSnapShot == INVALID_HANDLE_VALUE) { |
1388 return FALSE; |
1388 return FALSE; |
1389 } |
1389 } |
1390 |
1390 |
1391 // iterate through all modules |
1391 // iterate through all modules |
1392 modentry.dwSize = sizeof(MODULEENTRY32); |
1392 modentry.dwSize = sizeof(MODULEENTRY32); |
1393 bool not_done = os::Kernel32Dll::Module32First( hSnapShot, &modentry ) != 0; |
1393 bool not_done = os::Kernel32Dll::Module32First( hSnapShot, &modentry ) != 0; |
1414 if (os::win32::is_nt()) return _enumerate_modules_winnt (pid, func, param); |
1414 if (os::win32::is_nt()) return _enumerate_modules_winnt (pid, func, param); |
1415 else return _enumerate_modules_windows(pid, func, param); |
1415 else return _enumerate_modules_windows(pid, func, param); |
1416 } |
1416 } |
1417 |
1417 |
1418 struct _modinfo { |
1418 struct _modinfo { |
1419 address addr; |
1419 address addr; |
1420 char* full_path; // point to a char buffer |
1420 char* full_path; // point to a char buffer |
1421 int buflen; // size of the buffer |
1421 int buflen; // size of the buffer |
1422 address base_addr; |
1422 address base_addr; |
1423 }; |
1423 }; |
1424 |
1424 |
1425 static int _locate_module_by_addr(int pid, char * mod_fname, address base_addr, |
1425 static int _locate_module_by_addr(int pid, char * mod_fname, address base_addr, |
1426 unsigned size, void * param) { |
1426 unsigned size, void * param) { |
1427 struct _modinfo *pmod = (struct _modinfo *)param; |
1427 struct _modinfo *pmod = (struct _modinfo *)param; |
1428 if (!pmod) return -1; |
1428 if (!pmod) return -1; |
1429 |
1429 |
1430 if (base_addr <= pmod->addr && |
1430 if (base_addr <= pmod->addr && |
1431 base_addr+size > pmod->addr) { |
1431 base_addr+size > pmod->addr) { |
1432 // if a buffer is provided, copy path name to the buffer |
1432 // if a buffer is provided, copy path name to the buffer |
1433 if (pmod->full_path) { |
1433 if (pmod->full_path) { |
1434 jio_snprintf(pmod->full_path, pmod->buflen, "%s", mod_fname); |
1434 jio_snprintf(pmod->full_path, pmod->buflen, "%s", mod_fname); |
1435 } |
1435 } |
1436 pmod->base_addr = base_addr; |
1436 pmod->base_addr = base_addr; |
1437 return 1; |
1437 return 1; |
1438 } |
1438 } |
1439 return 0; |
1439 return 0; |
1440 } |
1440 } |
1441 |
1441 |
1442 bool os::dll_address_to_library_name(address addr, char* buf, |
1442 bool os::dll_address_to_library_name(address addr, char* buf, |
1443 int buflen, int* offset) { |
1443 int buflen, int* offset) { |
1444 // buf is not optional, but offset is optional |
1444 // buf is not optional, but offset is optional |
1478 return false; |
1478 return false; |
1479 } |
1479 } |
1480 |
1480 |
1481 // save the start and end address of jvm.dll into param[0] and param[1] |
1481 // save the start and end address of jvm.dll into param[0] and param[1] |
1482 static int _locate_jvm_dll(int pid, char* mod_fname, address base_addr, |
1482 static int _locate_jvm_dll(int pid, char* mod_fname, address base_addr, |
1483 unsigned size, void * param) { |
1483 unsigned size, void * param) { |
1484 if (!param) return -1; |
1484 if (!param) return -1; |
1485 |
1485 |
1486 if (base_addr <= (address)_locate_jvm_dll && |
1486 if (base_addr <= (address)_locate_jvm_dll && |
1487 base_addr+size > (address)_locate_jvm_dll) { |
1487 base_addr+size > (address)_locate_jvm_dll) { |
1488 ((address*)param)[0] = base_addr; |
1488 ((address*)param)[0] = base_addr; |
1489 ((address*)param)[1] = base_addr + size; |
1489 ((address*)param)[1] = base_addr + size; |
1490 return 1; |
1490 return 1; |
1491 } |
1491 } |
1492 return 0; |
1492 return 0; |
1493 } |
1493 } |
1494 |
1494 |
1495 address vm_lib_location[2]; // start and end address of jvm.dll |
1495 address vm_lib_location[2]; // start and end address of jvm.dll |
1496 |
1496 |
1497 // check if addr is inside jvm.dll |
1497 // check if addr is inside jvm.dll |
1508 } |
1508 } |
1509 |
1509 |
1510 // print module info; param is outputStream* |
1510 // print module info; param is outputStream* |
1511 static int _print_module(int pid, char* fname, address base, |
1511 static int _print_module(int pid, char* fname, address base, |
1512 unsigned size, void* param) { |
1512 unsigned size, void* param) { |
1513 if (!param) return -1; |
1513 if (!param) return -1; |
1514 |
1514 |
1515 outputStream* st = (outputStream*)param; |
1515 outputStream* st = (outputStream*)param; |
1516 |
1516 |
1517 address end_addr = base + size; |
1517 address end_addr = base + size; |
1518 st->print(PTR_FORMAT " - " PTR_FORMAT " \t%s\n", base, end_addr, fname); |
1518 st->print(PTR_FORMAT " - " PTR_FORMAT " \t%s\n", base, end_addr, fname); |
1519 return 0; |
1519 return 0; |
1520 } |
1520 } |
1521 |
1521 |
1522 // Loads .dll/.so and |
1522 // Loads .dll/.so and |
1523 // in case of error it checks if .dll/.so was built for the |
1523 // in case of error it checks if .dll/.so was built for the |
1524 // same architecture as Hotspot is running on |
1524 // same architecture as Hotspot is running on |
1554 } |
1554 } |
1555 |
1555 |
1556 uint32_t signature_offset; |
1556 uint32_t signature_offset; |
1557 uint16_t lib_arch=0; |
1557 uint16_t lib_arch=0; |
1558 bool failed_to_get_lib_arch= |
1558 bool failed_to_get_lib_arch= |
1559 ( |
1559 ( |
1560 //Go to position 3c in the dll |
1560 //Go to position 3c in the dll |
1561 (os::seek_to_file_offset(file_descriptor,IMAGE_FILE_PTR_TO_SIGNATURE)<0) |
1561 (os::seek_to_file_offset(file_descriptor,IMAGE_FILE_PTR_TO_SIGNATURE)<0) |
1562 || |
1562 || |
1563 // Read loacation of signature |
1563 // Read loacation of signature |
1564 (sizeof(signature_offset)!= |
1564 (sizeof(signature_offset)!= |
1565 (os::read(file_descriptor, (void*)&signature_offset,sizeof(signature_offset)))) |
1565 (os::read(file_descriptor, (void*)&signature_offset,sizeof(signature_offset)))) |
1566 || |
1566 || |
1567 //Go to COFF File Header in dll |
1567 //Go to COFF File Header in dll |
1568 //that is located after"signature" (4 bytes long) |
1568 //that is located after"signature" (4 bytes long) |
1569 (os::seek_to_file_offset(file_descriptor, |
1569 (os::seek_to_file_offset(file_descriptor, |
1570 signature_offset+IMAGE_FILE_SIGNATURE_LENGTH)<0) |
1570 signature_offset+IMAGE_FILE_SIGNATURE_LENGTH)<0) |
1571 || |
1571 || |
1572 //Read field that contains code of architecture |
1572 //Read field that contains code of architecture |
1573 // that dll was build for |
1573 // that dll was build for |
1574 (sizeof(lib_arch)!= |
1574 (sizeof(lib_arch)!= |
1575 (os::read(file_descriptor, (void*)&lib_arch,sizeof(lib_arch)))) |
1575 (os::read(file_descriptor, (void*)&lib_arch,sizeof(lib_arch)))) |
1576 ); |
1576 ); |
1577 |
1577 |
1578 ::close(file_descriptor); |
1578 ::close(file_descriptor); |
1579 if (failed_to_get_lib_arch) |
1579 if (failed_to_get_lib_arch) |
1580 { |
1580 { |
1581 // file i/o error - report os::lasterror(...) msg |
1581 // file i/o error - report os::lasterror(...) msg |
1592 {IMAGE_FILE_MACHINE_I386, (char*)"IA 32"}, |
1592 {IMAGE_FILE_MACHINE_I386, (char*)"IA 32"}, |
1593 {IMAGE_FILE_MACHINE_AMD64, (char*)"AMD 64"}, |
1593 {IMAGE_FILE_MACHINE_AMD64, (char*)"AMD 64"}, |
1594 {IMAGE_FILE_MACHINE_IA64, (char*)"IA 64"} |
1594 {IMAGE_FILE_MACHINE_IA64, (char*)"IA 64"} |
1595 }; |
1595 }; |
1596 #if (defined _M_IA64) |
1596 #if (defined _M_IA64) |
1597 static const uint16_t running_arch=IMAGE_FILE_MACHINE_IA64; |
1597 static const uint16_t running_arch=IMAGE_FILE_MACHINE_IA64; |
1598 #elif (defined _M_AMD64) |
1598 #elif (defined _M_AMD64) |
1599 static const uint16_t running_arch=IMAGE_FILE_MACHINE_AMD64; |
1599 static const uint16_t running_arch=IMAGE_FILE_MACHINE_AMD64; |
1600 #elif (defined _M_IX86) |
1600 #elif (defined _M_IX86) |
1601 static const uint16_t running_arch=IMAGE_FILE_MACHINE_I386; |
1601 static const uint16_t running_arch=IMAGE_FILE_MACHINE_I386; |
1602 #else |
1602 #else |
1603 #error Method os::dll_load requires that one of following \ |
1603 #error Method os::dll_load requires that one of following \ |
1604 is defined :_M_IA64,_M_AMD64 or _M_IX86 |
1604 is defined :_M_IA64,_M_AMD64 or _M_IX86 |
1605 #endif |
1605 #endif |
1606 |
1606 |
1616 if (running_arch==arch_array[i].arch_code) |
1616 if (running_arch==arch_array[i].arch_code) |
1617 running_arch_str=arch_array[i].arch_name; |
1617 running_arch_str=arch_array[i].arch_name; |
1618 } |
1618 } |
1619 |
1619 |
1620 assert(running_arch_str, |
1620 assert(running_arch_str, |
1621 "Didn't find runing architecture code in arch_array"); |
1621 "Didn't find runing architecture code in arch_array"); |
1622 |
1622 |
1623 // If the architure is right |
1623 // If the architure is right |
1624 // but some other error took place - report os::lasterror(...) msg |
1624 // but some other error took place - report os::lasterror(...) msg |
1625 if (lib_arch == running_arch) |
1625 if (lib_arch == running_arch) |
1626 { |
1626 { |
1628 } |
1628 } |
1629 |
1629 |
1630 if (lib_arch_str!=NULL) |
1630 if (lib_arch_str!=NULL) |
1631 { |
1631 { |
1632 ::_snprintf(ebuf, ebuflen-1, |
1632 ::_snprintf(ebuf, ebuflen-1, |
1633 "Can't load %s-bit .dll on a %s-bit platform", |
1633 "Can't load %s-bit .dll on a %s-bit platform", |
1634 lib_arch_str,running_arch_str); |
1634 lib_arch_str,running_arch_str); |
1635 } |
1635 } |
1636 else |
1636 else |
1637 { |
1637 { |
1638 // don't know what architecture this dll was build for |
1638 // don't know what architecture this dll was build for |
1639 ::_snprintf(ebuf, ebuflen-1, |
1639 ::_snprintf(ebuf, ebuflen-1, |
1640 "Can't load this .dll (machine code=0x%x) on a %s-bit platform", |
1640 "Can't load this .dll (machine code=0x%x) on a %s-bit platform", |
1641 lib_arch,running_arch_str); |
1641 lib_arch,running_arch_str); |
1642 } |
1642 } |
1643 |
1643 |
1644 return NULL; |
1644 return NULL; |
1645 } |
1645 } |
1646 |
1646 |
1647 |
1647 |
1648 void os::print_dll_info(outputStream *st) { |
1648 void os::print_dll_info(outputStream *st) { |
1649 int pid = os::current_process_id(); |
1649 int pid = os::current_process_id(); |
1650 st->print_cr("Dynamic libraries:"); |
1650 st->print_cr("Dynamic libraries:"); |
1651 enumerate_modules(pid, _print_module, (void *)st); |
1651 enumerate_modules(pid, _print_module, (void *)st); |
1652 } |
1652 } |
1653 |
1653 |
1654 void os::print_os_info_brief(outputStream* st) { |
1654 void os::print_os_info_brief(outputStream* st) { |
1655 os::print_os_info(st); |
1655 os::print_os_info(st); |
1656 } |
1656 } |
1783 st->print("siginfo:"); |
1783 st->print("siginfo:"); |
1784 st->print(" ExceptionCode=0x%x", er->ExceptionCode); |
1784 st->print(" ExceptionCode=0x%x", er->ExceptionCode); |
1785 |
1785 |
1786 if (er->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && |
1786 if (er->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && |
1787 er->NumberParameters >= 2) { |
1787 er->NumberParameters >= 2) { |
1788 switch (er->ExceptionInformation[0]) { |
1788 switch (er->ExceptionInformation[0]) { |
1789 case 0: st->print(", reading address"); break; |
1789 case 0: st->print(", reading address"); break; |
1790 case 1: st->print(", writing address"); break; |
1790 case 1: st->print(", writing address"); break; |
1791 default: st->print(", ExceptionInformation=" INTPTR_FORMAT, |
1791 default: st->print(", ExceptionInformation=" INTPTR_FORMAT, |
1792 er->ExceptionInformation[0]); |
1792 er->ExceptionInformation[0]); |
1793 } |
1793 } |
1794 st->print(" " INTPTR_FORMAT, er->ExceptionInformation[1]); |
1794 st->print(" " INTPTR_FORMAT, er->ExceptionInformation[1]); |
1795 } else if (er->ExceptionCode == EXCEPTION_IN_PAGE_ERROR && |
1795 } else if (er->ExceptionCode == EXCEPTION_IN_PAGE_ERROR && |
1796 er->NumberParameters >= 2 && UseSharedSpaces) { |
1796 er->NumberParameters >= 2 && UseSharedSpaces) { |
1797 FileMapInfo* mapinfo = FileMapInfo::current_info(); |
1797 FileMapInfo* mapinfo = FileMapInfo::current_info(); |
1798 if (mapinfo->is_in_shared_space((void*)er->ExceptionInformation[1])) { |
1798 if (mapinfo->is_in_shared_space((void*)er->ExceptionInformation[1])) { |
1799 st->print("\n\nError accessing class data sharing archive." \ |
1799 st->print("\n\nError accessing class data sharing archive." \ |
1884 DWORD errval; |
1884 DWORD errval; |
1885 |
1885 |
1886 if ((errval = GetLastError()) != 0) { |
1886 if ((errval = GetLastError()) != 0) { |
1887 // DOS error |
1887 // DOS error |
1888 size_t n = (size_t)FormatMessage( |
1888 size_t n = (size_t)FormatMessage( |
1889 FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, |
1889 FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, |
1890 NULL, |
1890 NULL, |
1891 errval, |
1891 errval, |
1892 0, |
1892 0, |
1893 buf, |
1893 buf, |
1894 (DWORD)len, |
1894 (DWORD)len, |
1895 NULL); |
1895 NULL); |
1896 if (n > 3) { |
1896 if (n > 3) { |
1897 // Drop final '.', CR, LF |
1897 // Drop final '.', CR, LF |
1898 if (buf[n - 1] == '\n') n--; |
1898 if (buf[n - 1] == '\n') n--; |
1899 if (buf[n - 1] == '\r') n--; |
1899 if (buf[n - 1] == '\r') n--; |
1900 if (buf[n - 1] == '.') n--; |
1900 if (buf[n - 1] == '.') n--; |
1959 // logoff, and shutdown events. We therefore install our own console handler |
1959 // logoff, and shutdown events. We therefore install our own console handler |
1960 // that raises SIGTERM for the latter cases. |
1960 // that raises SIGTERM for the latter cases. |
1961 // |
1961 // |
1962 static BOOL WINAPI consoleHandler(DWORD event) { |
1962 static BOOL WINAPI consoleHandler(DWORD event) { |
1963 switch (event) { |
1963 switch (event) { |
1964 case CTRL_C_EVENT: |
1964 case CTRL_C_EVENT: |
1965 if (is_error_reported()) { |
1965 if (is_error_reported()) { |
1966 // Ctrl-C is pressed during error reporting, likely because the error |
1966 // Ctrl-C is pressed during error reporting, likely because the error |
1967 // handler fails to abort. Let VM die immediately. |
1967 // handler fails to abort. Let VM die immediately. |
1968 os::die(); |
1968 os::die(); |
1969 } |
|
1970 |
|
1971 os::signal_raise(SIGINT); |
|
1972 return TRUE; |
|
1973 break; |
|
1974 case CTRL_BREAK_EVENT: |
|
1975 if (sigbreakHandler != NULL) { |
|
1976 (*sigbreakHandler)(SIGBREAK); |
|
1977 } |
|
1978 return TRUE; |
|
1979 break; |
|
1980 case CTRL_LOGOFF_EVENT: { |
|
1981 // Don't terminate JVM if it is running in a non-interactive session, |
|
1982 // such as a service process. |
|
1983 USEROBJECTFLAGS flags; |
|
1984 HANDLE handle = GetProcessWindowStation(); |
|
1985 if (handle != NULL && |
|
1986 GetUserObjectInformation(handle, UOI_FLAGS, &flags, |
|
1987 sizeof(USEROBJECTFLAGS), NULL)) { |
|
1988 // If it is a non-interactive session, let next handler to deal |
|
1989 // with it. |
|
1990 if ((flags.dwFlags & WSF_VISIBLE) == 0) { |
|
1991 return FALSE; |
|
1969 } |
1992 } |
1970 |
1993 } |
1971 os::signal_raise(SIGINT); |
1994 } |
1972 return TRUE; |
1995 case CTRL_CLOSE_EVENT: |
1973 break; |
1996 case CTRL_SHUTDOWN_EVENT: |
1974 case CTRL_BREAK_EVENT: |
1997 os::signal_raise(SIGTERM); |
1975 if (sigbreakHandler != NULL) { |
1998 return TRUE; |
1976 (*sigbreakHandler)(SIGBREAK); |
1999 break; |
1977 } |
2000 default: |
1978 return TRUE; |
2001 break; |
1979 break; |
|
1980 case CTRL_LOGOFF_EVENT: { |
|
1981 // Don't terminate JVM if it is running in a non-interactive session, |
|
1982 // such as a service process. |
|
1983 USEROBJECTFLAGS flags; |
|
1984 HANDLE handle = GetProcessWindowStation(); |
|
1985 if (handle != NULL && |
|
1986 GetUserObjectInformation(handle, UOI_FLAGS, &flags, |
|
1987 sizeof(USEROBJECTFLAGS), NULL)) { |
|
1988 // If it is a non-interactive session, let next handler to deal |
|
1989 // with it. |
|
1990 if ((flags.dwFlags & WSF_VISIBLE) == 0) { |
|
1991 return FALSE; |
|
1992 } |
|
1993 } |
|
1994 } |
|
1995 case CTRL_CLOSE_EVENT: |
|
1996 case CTRL_SHUTDOWN_EVENT: |
|
1997 os::signal_raise(SIGTERM); |
|
1998 return TRUE; |
|
1999 break; |
|
2000 default: |
|
2001 break; |
|
2002 } |
2002 } |
2003 return FALSE; |
2003 return FALSE; |
2004 } |
2004 } |
2005 |
2005 |
2006 /* |
2006 /* |
2219 }; |
2219 }; |
2220 |
2220 |
2221 const char* os::exception_name(int exception_code, char *buf, size_t size) { |
2221 const char* os::exception_name(int exception_code, char *buf, size_t size) { |
2222 for (int i = 0; exceptlabels[i].name != NULL; i++) { |
2222 for (int i = 0; exceptlabels[i].name != NULL; i++) { |
2223 if (exceptlabels[i].number == exception_code) { |
2223 if (exceptlabels[i].number == exception_code) { |
2224 jio_snprintf(buf, size, "%s", exceptlabels[i].name); |
2224 jio_snprintf(buf, size, "%s", exceptlabels[i].name); |
2225 return buf; |
2225 return buf; |
2226 } |
2226 } |
2227 } |
2227 } |
2228 |
2228 |
2229 return NULL; |
2229 return NULL; |
2230 } |
2230 } |
2267 #ifndef _WIN64 |
2267 #ifndef _WIN64 |
2268 // handle exception caused by native method modifying control word |
2268 // handle exception caused by native method modifying control word |
2269 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; |
2269 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; |
2270 |
2270 |
2271 switch (exception_code) { |
2271 switch (exception_code) { |
2272 case EXCEPTION_FLT_DENORMAL_OPERAND: |
2272 case EXCEPTION_FLT_DENORMAL_OPERAND: |
2273 case EXCEPTION_FLT_DIVIDE_BY_ZERO: |
2273 case EXCEPTION_FLT_DIVIDE_BY_ZERO: |
2274 case EXCEPTION_FLT_INEXACT_RESULT: |
2274 case EXCEPTION_FLT_INEXACT_RESULT: |
2275 case EXCEPTION_FLT_INVALID_OPERATION: |
2275 case EXCEPTION_FLT_INVALID_OPERATION: |
2276 case EXCEPTION_FLT_OVERFLOW: |
2276 case EXCEPTION_FLT_OVERFLOW: |
2277 case EXCEPTION_FLT_STACK_CHECK: |
2277 case EXCEPTION_FLT_STACK_CHECK: |
2278 case EXCEPTION_FLT_UNDERFLOW: |
2278 case EXCEPTION_FLT_UNDERFLOW: |
2279 jint fp_control_word = (* (jint*) StubRoutines::addr_fpu_cntrl_wrd_std()); |
2279 jint fp_control_word = (* (jint*) StubRoutines::addr_fpu_cntrl_wrd_std()); |
2280 if (fp_control_word != ctx->FloatSave.ControlWord) { |
2280 if (fp_control_word != ctx->FloatSave.ControlWord) { |
2281 // Restore FPCW and mask out FLT exceptions |
2281 // Restore FPCW and mask out FLT exceptions |
2282 ctx->FloatSave.ControlWord = fp_control_word | 0xffffffc0; |
2282 ctx->FloatSave.ControlWord = fp_control_word | 0xffffffc0; |
2283 // Mask out pending FLT exceptions |
2283 // Mask out pending FLT exceptions |
2284 ctx->FloatSave.StatusWord &= 0xffffff00; |
2284 ctx->FloatSave.StatusWord &= 0xffffff00; |
2285 return EXCEPTION_CONTINUE_EXECUTION; |
2285 return EXCEPTION_CONTINUE_EXECUTION; |
2286 } |
2286 } |
2287 } |
2287 } |
2288 |
2288 |
2289 if (prev_uef_handler != NULL) { |
2289 if (prev_uef_handler != NULL) { |
2290 // We didn't handle this exception so pass it to the previous |
2290 // We didn't handle this exception so pass it to the previous |
2291 // UnhandledExceptionFilter. |
2291 // UnhandledExceptionFilter. |
2294 #else // !_WIN64 |
2294 #else // !_WIN64 |
2295 /* |
2295 /* |
2296 On Windows, the mxcsr control bits are non-volatile across calls |
2296 On Windows, the mxcsr control bits are non-volatile across calls |
2297 See also CR 6192333 |
2297 See also CR 6192333 |
2298 */ |
2298 */ |
2299 jint MxCsr = INITIAL_MXCSR; |
2299 jint MxCsr = INITIAL_MXCSR; |
2300 // we can't use StubRoutines::addr_mxcsr_std() |
2300 // we can't use StubRoutines::addr_mxcsr_std() |
2301 // because in Win64 mxcsr is not saved there |
2301 // because in Win64 mxcsr is not saved there |
2302 if (MxCsr != ctx->MxCsr) { |
2302 if (MxCsr != ctx->MxCsr) { |
2303 ctx->MxCsr = MxCsr; |
2303 ctx->MxCsr = MxCsr; |
2304 return EXCEPTION_CONTINUE_EXECUTION; |
2304 return EXCEPTION_CONTINUE_EXECUTION; |
2305 } |
2305 } |
2306 #endif // !_WIN64 |
2306 #endif // !_WIN64 |
2307 |
2307 |
2308 return EXCEPTION_CONTINUE_SEARCH; |
2308 return EXCEPTION_CONTINUE_SEARCH; |
2309 } |
2309 } |
2310 |
2310 |
2486 // Reguard the permanent register stack red zone just to be sure. |
2486 // Reguard the permanent register stack red zone just to be sure. |
2487 // We saw Windows silently disabling this without telling us. |
2487 // We saw Windows silently disabling this without telling us. |
2488 thread->enable_register_stack_red_zone(); |
2488 thread->enable_register_stack_red_zone(); |
2489 |
2489 |
2490 return Handle_Exception(exceptionInfo, |
2490 return Handle_Exception(exceptionInfo, |
2491 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)); |
2491 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)); |
2492 } |
2492 } |
2493 #endif |
2493 #endif |
2494 if (thread->stack_yellow_zone_enabled()) { |
2494 if (thread->stack_yellow_zone_enabled()) { |
2495 // Yellow zone violation. The o/s has unprotected the first yellow |
2495 // Yellow zone violation. The o/s has unprotected the first yellow |
2496 // zone page for us. Note: must call disable_stack_yellow_zone to |
2496 // zone page for us. Note: must call disable_stack_yellow_zone to |
2497 // update the enabled status, even if the zone contains only one page. |
2497 // update the enabled status, even if the zone contains only one page. |
2498 thread->disable_stack_yellow_zone(); |
2498 thread->disable_stack_yellow_zone(); |
2499 // If not in java code, return and hope for the best. |
2499 // If not in java code, return and hope for the best. |
2500 return in_java ? Handle_Exception(exceptionInfo, |
2500 return in_java ? Handle_Exception(exceptionInfo, |
2501 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)) |
2501 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)) |
2502 : EXCEPTION_CONTINUE_EXECUTION; |
2502 : EXCEPTION_CONTINUE_EXECUTION; |
2503 } else { |
2503 } else { |
2504 // Fatal red zone violation. |
2504 // Fatal red zone violation. |
2505 thread->disable_stack_red_zone(); |
2505 thread->disable_stack_red_zone(); |
2506 tty->print_raw_cr("An unrecoverable stack overflow has occurred."); |
2506 tty->print_raw_cr("An unrecoverable stack overflow has occurred."); |
2507 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, |
2507 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, |
2511 } else if (in_java) { |
2511 } else if (in_java) { |
2512 // JVM-managed guard pages cannot be used on win95/98. The o/s provides |
2512 // JVM-managed guard pages cannot be used on win95/98. The o/s provides |
2513 // a one-time-only guard page, which it has released to us. The next |
2513 // a one-time-only guard page, which it has released to us. The next |
2514 // stack overflow on this thread will result in an ACCESS_VIOLATION. |
2514 // stack overflow on this thread will result in an ACCESS_VIOLATION. |
2515 return Handle_Exception(exceptionInfo, |
2515 return Handle_Exception(exceptionInfo, |
2516 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)); |
2516 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)); |
2517 } else { |
2517 } else { |
2518 // Can only return and hope for the best. Further stack growth will |
2518 // Can only return and hope for the best. Further stack growth will |
2519 // result in an ACCESS_VIOLATION. |
2519 // result in an ACCESS_VIOLATION. |
2520 return EXCEPTION_CONTINUE_EXECUTION; |
2520 return EXCEPTION_CONTINUE_EXECUTION; |
2521 } |
2521 } |
2526 address addr = (address) exceptionRecord->ExceptionInformation[1]; |
2526 address addr = (address) exceptionRecord->ExceptionInformation[1]; |
2527 address stack_end = thread->stack_base() - thread->stack_size(); |
2527 address stack_end = thread->stack_base() - thread->stack_size(); |
2528 if (addr < stack_end && addr >= stack_end - os::vm_page_size()) { |
2528 if (addr < stack_end && addr >= stack_end - os::vm_page_size()) { |
2529 // Stack overflow. |
2529 // Stack overflow. |
2530 assert(!os::uses_stack_guard_pages(), |
2530 assert(!os::uses_stack_guard_pages(), |
2531 "should be caught by red zone code above."); |
2531 "should be caught by red zone code above."); |
2532 return Handle_Exception(exceptionInfo, |
2532 return Handle_Exception(exceptionInfo, |
2533 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)); |
2533 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)); |
2534 } |
2534 } |
2535 // |
2535 // |
2536 // Check for safepoint polling and implicit null |
2536 // Check for safepoint polling and implicit null |
2537 // We only expect null pointers in the stubs (vtable) |
2537 // We only expect null pointers in the stubs (vtable) |
2538 // the rest are checked explicitly now. |
2538 // the rest are checked explicitly now. |
2550 // If it's a legal stack address map the entire region in |
2550 // If it's a legal stack address map the entire region in |
2551 // |
2551 // |
2552 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; |
2552 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; |
2553 address addr = (address) exceptionRecord->ExceptionInformation[1]; |
2553 address addr = (address) exceptionRecord->ExceptionInformation[1]; |
2554 if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base()) { |
2554 if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base()) { |
2555 addr = (address)((uintptr_t)addr & |
2555 addr = (address)((uintptr_t)addr & |
2556 (~((uintptr_t)os::vm_page_size() - (uintptr_t)1))); |
2556 (~((uintptr_t)os::vm_page_size() - (uintptr_t)1))); |
2557 os::commit_memory((char *)addr, thread->stack_base() - addr, |
2557 os::commit_memory((char *)addr, thread->stack_base() - addr, |
2558 !ExecMem); |
2558 !ExecMem); |
2559 return EXCEPTION_CONTINUE_EXECUTION; |
2559 return EXCEPTION_CONTINUE_EXECUTION; |
2560 } |
2560 } |
2561 else |
2561 else |
2562 #endif |
2562 #endif |
2563 { |
2563 { |
2564 // Null pointer exception. |
2564 // Null pointer exception. |
2576 tty->print_cr(" to addr " INTPTR_FORMAT, addr); |
2576 tty->print_cr(" to addr " INTPTR_FORMAT, addr); |
2577 tty->print_cr(" bundle is " INTPTR_FORMAT " (high), " INTPTR_FORMAT " (low)", |
2577 tty->print_cr(" bundle is " INTPTR_FORMAT " (high), " INTPTR_FORMAT " (low)", |
2578 *(bundle_start + 1), *bundle_start); |
2578 *(bundle_start + 1), *bundle_start); |
2579 } |
2579 } |
2580 return Handle_Exception(exceptionInfo, |
2580 return Handle_Exception(exceptionInfo, |
2581 SharedRuntime::continuation_for_implicit_exception(thread, pc_unix_format, SharedRuntime::IMPLICIT_NULL)); |
2581 SharedRuntime::continuation_for_implicit_exception(thread, pc_unix_format, SharedRuntime::IMPLICIT_NULL)); |
2582 } |
2582 } |
2583 } |
2583 } |
2584 |
2584 |
2585 // Implicit null checks were processed above. Hence, we should not reach |
2585 // Implicit null checks were processed above. Hence, we should not reach |
2586 // here in the usual case => die! |
2586 // here in the usual case => die! |
2630 |
2630 |
2631 // Compiled method patched to be non entrant? Following conditions must apply: |
2631 // Compiled method patched to be non entrant? Following conditions must apply: |
2632 // 1. must be first instruction in bundle |
2632 // 1. must be first instruction in bundle |
2633 // 2. must be a break instruction with appropriate code |
2633 // 2. must be a break instruction with appropriate code |
2634 if ((((uint64_t) pc & 0x0F) == 0) && |
2634 if ((((uint64_t) pc & 0x0F) == 0) && |
2635 (((IPF_Bundle*) pc)->get_slot0() == handle_wrong_method_break.bits())) { |
2635 (((IPF_Bundle*) pc)->get_slot0() == handle_wrong_method_break.bits())) { |
2636 return Handle_Exception(exceptionInfo, |
2636 return Handle_Exception(exceptionInfo, |
2637 (address)SharedRuntime::get_handle_wrong_method_stub()); |
2637 (address)SharedRuntime::get_handle_wrong_method_stub()); |
2638 } |
2638 } |
2639 } // /EXCEPTION_ILLEGAL_INSTRUCTION |
2639 } // /EXCEPTION_ILLEGAL_INSTRUCTION |
2640 #endif |
2640 #endif |
2649 return Handle_IDiv_Exception(exceptionInfo); |
2649 return Handle_IDiv_Exception(exceptionInfo); |
2650 |
2650 |
2651 } // switch |
2651 } // switch |
2652 } |
2652 } |
2653 if (((thread->thread_state() == _thread_in_Java) || |
2653 if (((thread->thread_state() == _thread_in_Java) || |
2654 (thread->thread_state() == _thread_in_native)) && |
2654 (thread->thread_state() == _thread_in_native)) && |
2655 exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION) |
2655 exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION) |
2656 { |
2656 { |
2657 LONG result=Handle_FLT_Exception(exceptionInfo); |
2657 LONG result=Handle_FLT_Exception(exceptionInfo); |
2658 if (result==EXCEPTION_CONTINUE_EXECUTION) return result; |
2658 if (result==EXCEPTION_CONTINUE_EXECUTION) return result; |
2659 } |
2659 } |
2660 } |
2660 } |
2702 DEFINE_FAST_GETFIELD(jfloat, float, Float) |
2702 DEFINE_FAST_GETFIELD(jfloat, float, Float) |
2703 DEFINE_FAST_GETFIELD(jdouble, double, Double) |
2703 DEFINE_FAST_GETFIELD(jdouble, double, Double) |
2704 |
2704 |
2705 address os::win32::fast_jni_accessor_wrapper(BasicType type) { |
2705 address os::win32::fast_jni_accessor_wrapper(BasicType type) { |
2706 switch (type) { |
2706 switch (type) { |
2707 case T_BOOLEAN: return (address)jni_fast_GetBooleanField_wrapper; |
2707 case T_BOOLEAN: return (address)jni_fast_GetBooleanField_wrapper; |
2708 case T_BYTE: return (address)jni_fast_GetByteField_wrapper; |
2708 case T_BYTE: return (address)jni_fast_GetByteField_wrapper; |
2709 case T_CHAR: return (address)jni_fast_GetCharField_wrapper; |
2709 case T_CHAR: return (address)jni_fast_GetCharField_wrapper; |
2710 case T_SHORT: return (address)jni_fast_GetShortField_wrapper; |
2710 case T_SHORT: return (address)jni_fast_GetShortField_wrapper; |
2711 case T_INT: return (address)jni_fast_GetIntField_wrapper; |
2711 case T_INT: return (address)jni_fast_GetIntField_wrapper; |
2712 case T_LONG: return (address)jni_fast_GetLongField_wrapper; |
2712 case T_LONG: return (address)jni_fast_GetLongField_wrapper; |
2713 case T_FLOAT: return (address)jni_fast_GetFloatField_wrapper; |
2713 case T_FLOAT: return (address)jni_fast_GetFloatField_wrapper; |
2714 case T_DOUBLE: return (address)jni_fast_GetDoubleField_wrapper; |
2714 case T_DOUBLE: return (address)jni_fast_GetDoubleField_wrapper; |
2715 default: ShouldNotReachHere(); |
2715 default: ShouldNotReachHere(); |
2716 } |
2716 } |
2717 return (address)-1; |
2717 return (address)-1; |
2718 } |
2718 } |
2719 #endif |
2719 #endif |
2720 |
2720 |
2722 // Install a win32 structured exception handler around the test |
2722 // Install a win32 structured exception handler around the test |
2723 // function call so the VM can generate an error dump if needed. |
2723 // function call so the VM can generate an error dump if needed. |
2724 __try { |
2724 __try { |
2725 (*funcPtr)(); |
2725 (*funcPtr)(); |
2726 } __except(topLevelExceptionFilter( |
2726 } __except(topLevelExceptionFilter( |
2727 (_EXCEPTION_POINTERS*)_exception_info())) { |
2727 (_EXCEPTION_POINTERS*)_exception_info())) { |
2728 // Nothing to do. |
2728 // Nothing to do. |
2729 } |
2729 } |
2730 } |
2730 } |
2731 |
2731 |
2732 // Virtual Memory |
2732 // Virtual Memory |
2761 static HANDLE _hProcess; |
2761 static HANDLE _hProcess; |
2762 static HANDLE _hToken; |
2762 static HANDLE _hToken; |
2763 |
2763 |
2764 // Container for NUMA node list info |
2764 // Container for NUMA node list info |
2765 class NUMANodeListHolder { |
2765 class NUMANodeListHolder { |
2766 private: |
2766 private: |
2767 int *_numa_used_node_list; // allocated below |
2767 int *_numa_used_node_list; // allocated below |
2768 int _numa_used_node_count; |
2768 int _numa_used_node_count; |
2769 |
2769 |
2770 void free_node_list() { |
2770 void free_node_list() { |
2771 if (_numa_used_node_list != NULL) { |
2771 if (_numa_used_node_list != NULL) { |
2772 FREE_C_HEAP_ARRAY(int, _numa_used_node_list, mtInternal); |
2772 FREE_C_HEAP_ARRAY(int, _numa_used_node_list, mtInternal); |
2773 } |
2773 } |
2774 } |
2774 } |
2775 |
2775 |
2776 public: |
2776 public: |
2777 NUMANodeListHolder() { |
2777 NUMANodeListHolder() { |
2778 _numa_used_node_count = 0; |
2778 _numa_used_node_count = 0; |
2779 _numa_used_node_list = NULL; |
2779 _numa_used_node_list = NULL; |
2780 // do rest of initialization in build routine (after function pointers are set up) |
2780 // do rest of initialization in build routine (after function pointers are set up) |
2781 } |
2781 } |
2819 os::Advapi32Dll::AdvapiAvailable(); |
2819 os::Advapi32Dll::AdvapiAvailable(); |
2820 } |
2820 } |
2821 |
2821 |
2822 static bool request_lock_memory_privilege() { |
2822 static bool request_lock_memory_privilege() { |
2823 _hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, |
2823 _hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, |
2824 os::current_process_id()); |
2824 os::current_process_id()); |
2825 |
2825 |
2826 LUID luid; |
2826 LUID luid; |
2827 if (_hProcess != NULL && |
2827 if (_hProcess != NULL && |
2828 os::Advapi32Dll::OpenProcessToken(_hProcess, TOKEN_ADJUST_PRIVILEGES, &_hToken) && |
2828 os::Advapi32Dll::OpenProcessToken(_hProcess, TOKEN_ADJUST_PRIVILEGES, &_hToken) && |
2829 os::Advapi32Dll::LookupPrivilegeValue(NULL, "SeLockMemoryPrivilege", &luid)) { |
2829 os::Advapi32Dll::LookupPrivilegeValue(NULL, "SeLockMemoryPrivilege", &luid)) { |
2979 size_t bytes_to_release = bytes - bytes_remaining; |
2979 size_t bytes_to_release = bytes - bytes_remaining; |
2980 // NMT has yet to record any individual blocks, so it |
2980 // NMT has yet to record any individual blocks, so it |
2981 // need to create a dummy 'reserve' record to match |
2981 // need to create a dummy 'reserve' record to match |
2982 // the release. |
2982 // the release. |
2983 MemTracker::record_virtual_memory_reserve((address)p_buf, |
2983 MemTracker::record_virtual_memory_reserve((address)p_buf, |
2984 bytes_to_release, CALLER_PC); |
2984 bytes_to_release, CALLER_PC); |
2985 os::release_memory(p_buf, bytes_to_release); |
2985 os::release_memory(p_buf, bytes_to_release); |
2986 } |
2986 } |
2987 #ifdef ASSERT |
2987 #ifdef ASSERT |
2988 if (should_inject_error) { |
2988 if (should_inject_error) { |
2989 if (TracePageSizes && Verbose) { |
2989 if (TracePageSizes && Verbose) { |
3063 |
3063 |
3064 // On win32, one cannot release just a part of reserved memory, it's an |
3064 // On win32, one cannot release just a part of reserved memory, it's an |
3065 // all or nothing deal. When we split a reservation, we must break the |
3065 // all or nothing deal. When we split a reservation, we must break the |
3066 // reservation into two reservations. |
3066 // reservation into two reservations. |
3067 void os::pd_split_reserved_memory(char *base, size_t size, size_t split, |
3067 void os::pd_split_reserved_memory(char *base, size_t size, size_t split, |
3068 bool realloc) { |
3068 bool realloc) { |
3069 if (size > 0) { |
3069 if (size > 0) { |
3070 release_memory(base, size); |
3070 release_memory(base, size); |
3071 if (realloc) { |
3071 if (realloc) { |
3072 reserve_memory(split, base); |
3072 reserve_memory(split, base); |
3073 } |
3073 } |
3080 // Multiple threads can race in this code but it's not possible to unmap small sections of |
3080 // Multiple threads can race in this code but it's not possible to unmap small sections of |
3081 // virtual space to get requested alignment, like posix-like os's. |
3081 // virtual space to get requested alignment, like posix-like os's. |
3082 // Windows prevents multiple thread from remapping over each other so this loop is thread-safe. |
3082 // Windows prevents multiple thread from remapping over each other so this loop is thread-safe. |
3083 char* os::reserve_memory_aligned(size_t size, size_t alignment) { |
3083 char* os::reserve_memory_aligned(size_t size, size_t alignment) { |
3084 assert((alignment & (os::vm_allocation_granularity() - 1)) == 0, |
3084 assert((alignment & (os::vm_allocation_granularity() - 1)) == 0, |
3085 "Alignment must be a multiple of allocation granularity (page size)"); |
3085 "Alignment must be a multiple of allocation granularity (page size)"); |
3086 assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned"); |
3086 assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned"); |
3087 |
3087 |
3088 size_t extra_size = size + alignment; |
3088 size_t extra_size = size + alignment; |
3089 assert(extra_size >= size, "overflow, size is too large to allow alignment"); |
3089 assert(extra_size >= size, "overflow, size is too large to allow alignment"); |
3090 |
3090 |
3174 // with large pages, there are two cases where we need to use Individual Allocation |
3174 // with large pages, there are two cases where we need to use Individual Allocation |
3175 // 1) the UseLargePagesIndividualAllocation flag is set (set by default on WS2003) |
3175 // 1) the UseLargePagesIndividualAllocation flag is set (set by default on WS2003) |
3176 // 2) NUMA Interleaving is enabled, in which case we use a different node for each page |
3176 // 2) NUMA Interleaving is enabled, in which case we use a different node for each page |
3177 if (UseLargePagesIndividualAllocation || UseNUMAInterleaving) { |
3177 if (UseLargePagesIndividualAllocation || UseNUMAInterleaving) { |
3178 if (TracePageSizes && Verbose) { |
3178 if (TracePageSizes && Verbose) { |
3179 tty->print_cr("Reserving large pages individually."); |
3179 tty->print_cr("Reserving large pages individually."); |
3180 } |
3180 } |
3181 char * p_buf = allocate_pages_individually(bytes, addr, flags, prot, LargePagesIndividualAllocationInjectError); |
3181 char * p_buf = allocate_pages_individually(bytes, addr, flags, prot, LargePagesIndividualAllocationInjectError); |
3182 if (p_buf == NULL) { |
3182 if (p_buf == NULL) { |
3183 // give an appropriate warning message |
3183 // give an appropriate warning message |
3184 if (UseNUMAInterleaving) { |
3184 if (UseNUMAInterleaving) { |
3193 |
3193 |
3194 return p_buf; |
3194 return p_buf; |
3195 |
3195 |
3196 } else { |
3196 } else { |
3197 if (TracePageSizes && Verbose) { |
3197 if (TracePageSizes && Verbose) { |
3198 tty->print_cr("Reserving large pages in a single large chunk."); |
3198 tty->print_cr("Reserving large pages in a single large chunk."); |
3199 } |
3199 } |
3200 // normal policy just allocate it all at once |
3200 // normal policy just allocate it all at once |
3201 DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES; |
3201 DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES; |
3202 char * res = (char *)VirtualAlloc(addr, bytes, flag, prot); |
3202 char * res = (char *)VirtualAlloc(addr, bytes, flag, prot); |
3203 if (res != NULL) { |
3203 if (res != NULL) { |
3286 // if we made it this far, return true |
3286 // if we made it this far, return true |
3287 return true; |
3287 return true; |
3288 } |
3288 } |
3289 |
3289 |
3290 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, |
3290 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, |
3291 bool exec) { |
3291 bool exec) { |
3292 // alignment_hint is ignored on this OS |
3292 // alignment_hint is ignored on this OS |
3293 return pd_commit_memory(addr, size, exec); |
3293 return pd_commit_memory(addr, size, exec); |
3294 } |
3294 } |
3295 |
3295 |
3296 void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec, |
3296 void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec, |
3434 // timeBeginPeriod() if the relative error exceeded some threshold. |
3434 // timeBeginPeriod() if the relative error exceeded some threshold. |
3435 // timeBeginPeriod() has been linked to problems with clock drift on win32 systems and |
3435 // timeBeginPeriod() has been linked to problems with clock drift on win32 systems and |
3436 // to decreased efficiency related to increased timer "tick" rates. We want to minimize |
3436 // to decreased efficiency related to increased timer "tick" rates. We want to minimize |
3437 // (a) calls to timeBeginPeriod() and timeEndPeriod() and (b) time spent with high |
3437 // (a) calls to timeBeginPeriod() and timeEndPeriod() and (b) time spent with high |
3438 // resolution timers running. |
3438 // resolution timers running. |
3439 private: |
3439 private: |
3440 jlong resolution; |
3440 jlong resolution; |
3441 public: |
3441 public: |
3442 HighResolutionInterval(jlong ms) { |
3442 HighResolutionInterval(jlong ms) { |
3443 resolution = ms % 10L; |
3443 resolution = ms % 10L; |
3444 if (resolution != 0) { |
3444 if (resolution != 0) { |
3445 MMRESULT result = timeBeginPeriod(1L); |
3445 MMRESULT result = timeBeginPeriod(1L); |
3446 } |
3446 } |
3682 // Processor level is not available on non-NT systems, use vm_version instead |
3682 // Processor level is not available on non-NT systems, use vm_version instead |
3683 int os::win32::_processor_level = 0; |
3683 int os::win32::_processor_level = 0; |
3684 julong os::win32::_physical_memory = 0; |
3684 julong os::win32::_physical_memory = 0; |
3685 size_t os::win32::_default_stack_size = 0; |
3685 size_t os::win32::_default_stack_size = 0; |
3686 |
3686 |
3687 intx os::win32::_os_thread_limit = 0; |
3687 intx os::win32::_os_thread_limit = 0; |
3688 volatile intx os::win32::_os_thread_count = 0; |
3688 volatile intx os::win32::_os_thread_count = 0; |
3689 |
3689 |
3690 bool os::win32::_is_nt = false; |
3690 bool os::win32::_is_nt = false; |
3691 bool os::win32::_is_windows_2003 = false; |
3691 bool os::win32::_is_windows_2003 = false; |
3692 bool os::win32::_is_windows_server = false; |
3692 bool os::win32::_is_windows_server = false; |
3712 |
3712 |
3713 OSVERSIONINFOEX oi; |
3713 OSVERSIONINFOEX oi; |
3714 oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); |
3714 oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); |
3715 GetVersionEx((OSVERSIONINFO*)&oi); |
3715 GetVersionEx((OSVERSIONINFO*)&oi); |
3716 switch (oi.dwPlatformId) { |
3716 switch (oi.dwPlatformId) { |
3717 case VER_PLATFORM_WIN32_WINDOWS: _is_nt = false; break; |
3717 case VER_PLATFORM_WIN32_WINDOWS: _is_nt = false; break; |
3718 case VER_PLATFORM_WIN32_NT: |
3718 case VER_PLATFORM_WIN32_NT: |
3719 _is_nt = true; |
3719 _is_nt = true; |
3720 { |
3720 { |
3721 int os_vers = oi.dwMajorVersion * 1000 + oi.dwMinorVersion; |
3721 int os_vers = oi.dwMajorVersion * 1000 + oi.dwMinorVersion; |
3722 if (os_vers == 5002) { |
3722 if (os_vers == 5002) { |
3723 _is_windows_2003 = true; |
3723 _is_windows_2003 = true; |
3724 } |
3724 } |
3725 if (oi.wProductType == VER_NT_DOMAIN_CONTROLLER || |
3725 if (oi.wProductType == VER_NT_DOMAIN_CONTROLLER || |
3726 oi.wProductType == VER_NT_SERVER) { |
3726 oi.wProductType == VER_NT_SERVER) { |
3727 _is_windows_server = true; |
3727 _is_windows_server = true; |
3728 } |
|
3729 } |
3728 } |
3730 break; |
3729 } |
3731 default: fatal("Unknown platform"); |
3730 break; |
3731 default: fatal("Unknown platform"); |
|
3732 } |
3732 } |
3733 |
3733 |
3734 _default_stack_size = os::current_stack_size(); |
3734 _default_stack_size = os::current_stack_size(); |
3735 assert(_default_stack_size > (size_t) _vm_page_size, "invalid stack size"); |
3735 assert(_default_stack_size > (size_t) _vm_page_size, "invalid stack size"); |
3736 assert((_default_stack_size & (_vm_page_size - 1)) == 0, |
3736 assert((_default_stack_size & (_vm_page_size - 1)) == 0, |
3737 "stack size not a multiple of page size"); |
3737 "stack size not a multiple of page size"); |
3738 |
3738 |
3739 initialize_performance_counter(); |
3739 initialize_performance_counter(); |
3740 |
3740 |
3741 // Win95/Win98 scheduler bug work-around. The Win95/98 scheduler is |
3741 // Win95/Win98 scheduler bug work-around. The Win95/98 scheduler is |
3742 // known to deadlock the system, if the VM issues to thread operations with |
3742 // known to deadlock the system, if the VM issues to thread operations with |
3758 // only allow library name without path component |
3758 // only allow library name without path component |
3759 assert(strchr(name, '\\') == NULL, "path not allowed"); |
3759 assert(strchr(name, '\\') == NULL, "path not allowed"); |
3760 assert(strchr(name, ':') == NULL, "path not allowed"); |
3760 assert(strchr(name, ':') == NULL, "path not allowed"); |
3761 if (strchr(name, '\\') != NULL || strchr(name, ':') != NULL) { |
3761 if (strchr(name, '\\') != NULL || strchr(name, ':') != NULL) { |
3762 jio_snprintf(ebuf, ebuflen, |
3762 jio_snprintf(ebuf, ebuflen, |
3763 "Invalid parameter while calling os::win32::load_windows_dll(): cannot take path: %s", name); |
3763 "Invalid parameter while calling os::win32::load_windows_dll(): cannot take path: %s", name); |
3764 return NULL; |
3764 return NULL; |
3765 } |
3765 } |
3766 |
3766 |
3767 // search system directory |
3767 // search system directory |
3768 if ((size = GetSystemDirectory(path, pathLen)) > 0) { |
3768 if ((size = GetSystemDirectory(path, pathLen)) > 0) { |
3781 return result; |
3781 return result; |
3782 } |
3782 } |
3783 } |
3783 } |
3784 |
3784 |
3785 jio_snprintf(ebuf, ebuflen, |
3785 jio_snprintf(ebuf, ebuflen, |
3786 "os::win32::load_windows_dll() cannot load %s from system directories.", name); |
3786 "os::win32::load_windows_dll() cannot load %s from system directories.", name); |
3787 return NULL; |
3787 return NULL; |
3788 } |
3788 } |
3789 |
3789 |
3790 void os::win32::setmode_streams() { |
3790 void os::win32::setmode_streams() { |
3791 _setmode(_fileno(stdin), _O_BINARY); |
3791 _setmode(_fileno(stdin), _O_BINARY); |
3870 win32::setmode_streams(); |
3870 win32::setmode_streams(); |
3871 init_page_sizes((size_t) win32::vm_page_size()); |
3871 init_page_sizes((size_t) win32::vm_page_size()); |
3872 |
3872 |
3873 // This may be overridden later when argument processing is done. |
3873 // This may be overridden later when argument processing is done. |
3874 FLAG_SET_ERGO(bool, UseLargePagesIndividualAllocation, |
3874 FLAG_SET_ERGO(bool, UseLargePagesIndividualAllocation, |
3875 os::win32::is_windows_2003()); |
3875 os::win32::is_windows_2003()); |
3876 |
3876 |
3877 // Initialize main_process and main_thread |
3877 // Initialize main_process and main_thread |
3878 main_process = GetCurrentProcess(); // Remember main_process is a pseudo handle |
3878 main_process = GetCurrentProcess(); // Remember main_process is a pseudo handle |
3879 if (!DuplicateHandle(main_process, GetCurrentThread(), main_process, |
3879 if (!DuplicateHandle(main_process, GetCurrentThread(), main_process, |
3880 &main_thread, THREAD_ALL_ACCESS, false, 0)) { |
3880 &main_thread, THREAD_ALL_ACCESS, false, 0)) { |
3881 fatal("DuplicateHandle failed\n"); |
3881 fatal("DuplicateHandle failed\n"); |
3882 } |
3882 } |
3883 main_thread_id = (int) GetCurrentThreadId(); |
3883 main_thread_id = (int) GetCurrentThreadId(); |
3884 } |
3884 } |
3957 // size. Add a page for compiler2 recursion in main thread. |
3957 // size. Add a page for compiler2 recursion in main thread. |
3958 // Add in 2*BytesPerWord times page size to account for VM stack during |
3958 // Add in 2*BytesPerWord times page size to account for VM stack during |
3959 // class initialization depending on 32 or 64 bit VM. |
3959 // class initialization depending on 32 or 64 bit VM. |
3960 size_t min_stack_allowed = |
3960 size_t min_stack_allowed = |
3961 (size_t)(StackYellowPages+StackRedPages+StackShadowPages+ |
3961 (size_t)(StackYellowPages+StackRedPages+StackShadowPages+ |
3962 2*BytesPerWord COMPILER2_PRESENT(+1)) * os::vm_page_size(); |
3962 2*BytesPerWord COMPILER2_PRESENT(+1)) * os::vm_page_size(); |
3963 if (actual_reserve_size < min_stack_allowed) { |
3963 if (actual_reserve_size < min_stack_allowed) { |
3964 tty->print_cr("\nThe stack size specified is too small, " |
3964 tty->print_cr("\nThe stack size specified is too small, " |
3965 "Specify at least %dk", |
3965 "Specify at least %dk", |
3966 min_stack_allowed / K); |
3966 min_stack_allowed / K); |
3967 return JNI_ERR; |
3967 return JNI_ERR; |
4118 FILETIME ExitTime; |
4118 FILETIME ExitTime; |
4119 FILETIME KernelTime; |
4119 FILETIME KernelTime; |
4120 FILETIME UserTime; |
4120 FILETIME UserTime; |
4121 |
4121 |
4122 if (GetThreadTimes(thread->osthread()->thread_handle(), |
4122 if (GetThreadTimes(thread->osthread()->thread_handle(), |
4123 &CreationTime, &ExitTime, &KernelTime, &UserTime) == 0) |
4123 &CreationTime, &ExitTime, &KernelTime, &UserTime) == 0) |
4124 return -1; |
4124 return -1; |
4125 else |
4125 else |
4126 if (user_sys_cpu_time) { |
4126 if (user_sys_cpu_time) { |
4127 return (FT2INT64(UserTime) + FT2INT64(KernelTime)) * 100; |
4127 return (FT2INT64(UserTime) + FT2INT64(KernelTime)) * 100; |
4128 } else { |
4128 } else { |
4129 return FT2INT64(UserTime) * 100; |
4129 return FT2INT64(UserTime) * 100; |
4130 } |
4130 } |
4131 } else { |
4131 } else { |
4132 return (jlong) timeGetTime() * 1000000; |
4132 return (jlong) timeGetTime() * 1000000; |
4133 } |
4133 } |
4134 } |
4134 } |
4135 |
4135 |
4154 FILETIME ExitTime; |
4154 FILETIME ExitTime; |
4155 FILETIME KernelTime; |
4155 FILETIME KernelTime; |
4156 FILETIME UserTime; |
4156 FILETIME UserTime; |
4157 |
4157 |
4158 if (GetThreadTimes(GetCurrentThread(), |
4158 if (GetThreadTimes(GetCurrentThread(), |
4159 &CreationTime, &ExitTime, &KernelTime, &UserTime) == 0) |
4159 &CreationTime, &ExitTime, &KernelTime, &UserTime) == 0) |
4160 return false; |
4160 return false; |
4161 else |
4161 else |
4162 return true; |
4162 return true; |
4163 } else { |
4163 } else { |
4164 return false; |
4164 return false; |
4202 int os::open(const char *path, int oflag, int mode) { |
4202 int os::open(const char *path, int oflag, int mode) { |
4203 char pathbuf[MAX_PATH]; |
4203 char pathbuf[MAX_PATH]; |
4204 |
4204 |
4205 if (strlen(path) > MAX_PATH - 1) { |
4205 if (strlen(path) > MAX_PATH - 1) { |
4206 errno = ENAMETOOLONG; |
4206 errno = ENAMETOOLONG; |
4207 return -1; |
4207 return -1; |
4208 } |
4208 } |
4209 os::native_path(strcpy(pathbuf, path)); |
4209 os::native_path(strcpy(pathbuf, path)); |
4210 return ::open(pathbuf, oflag | O_BINARY | O_NOINHERIT, mode); |
4210 return ::open(pathbuf, oflag | O_BINARY | O_NOINHERIT, mode); |
4211 } |
4211 } |
4212 |
4212 |
4268 point to the colon following the drive |
4268 point to the colon following the drive |
4269 letter */ |
4269 letter */ |
4270 |
4270 |
4271 /* Assumption: '/', '\\', ':', and drive letters are never lead bytes */ |
4271 /* Assumption: '/', '\\', ':', and drive letters are never lead bytes */ |
4272 assert(((!::IsDBCSLeadByte('/')) |
4272 assert(((!::IsDBCSLeadByte('/')) |
4273 && (!::IsDBCSLeadByte('\\')) |
4273 && (!::IsDBCSLeadByte('\\')) |
4274 && (!::IsDBCSLeadByte(':'))), |
4274 && (!::IsDBCSLeadByte(':'))), |
4275 "Illegal lead byte"); |
4275 "Illegal lead byte"); |
4276 |
4276 |
4277 /* Check for leading separators */ |
4277 /* Check for leading separators */ |
4278 #define isfilesep(c) ((c) == '/' || (c) == '\\') |
4278 #define isfilesep(c) ((c) == '/' || (c) == '\\') |
4279 while (isfilesep(*src)) { |
4279 while (isfilesep(*src)) { |
4280 src++; |
4280 src++; |
4348 |
4348 |
4349 *end = '\0'; |
4349 *end = '\0'; |
4350 |
4350 |
4351 /* For "z:", add "." to work around a bug in the C runtime library */ |
4351 /* For "z:", add "." to work around a bug in the C runtime library */ |
4352 if (colon == dst - 1) { |
4352 if (colon == dst - 1) { |
4353 path[2] = '.'; |
4353 path[2] = '.'; |
4354 path[3] = '\0'; |
4354 path[3] = '\0'; |
4355 } |
4355 } |
4356 |
4356 |
4357 return path; |
4357 return path; |
4358 } |
4358 } |
4359 |
4359 |
4369 return -1; |
4369 return -1; |
4370 } |
4370 } |
4371 |
4371 |
4372 ret = ::SetFilePointer(h, (long)(length), &high, FILE_BEGIN); |
4372 ret = ::SetFilePointer(h, (long)(length), &high, FILE_BEGIN); |
4373 if ((ret == 0xFFFFFFFF) && (::GetLastError() != NO_ERROR)) { |
4373 if ((ret == 0xFFFFFFFF) && (::GetLastError() != NO_ERROR)) { |
4374 return -1; |
4374 return -1; |
4375 } |
4375 } |
4376 |
4376 |
4377 if (::SetEndOfFile(h) == FALSE) { |
4377 if (::SetEndOfFile(h) == FALSE) { |
4378 return -1; |
4378 return -1; |
4379 } |
4379 } |
4388 |
4388 |
4389 int os::fsync(int fd) { |
4389 int os::fsync(int fd) { |
4390 HANDLE handle = (HANDLE)::_get_osfhandle(fd); |
4390 HANDLE handle = (HANDLE)::_get_osfhandle(fd); |
4391 |
4391 |
4392 if ((!::FlushFileBuffers(handle)) && |
4392 if ((!::FlushFileBuffers(handle)) && |
4393 (GetLastError() != ERROR_ACCESS_DENIED) ) { |
4393 (GetLastError() != ERROR_ACCESS_DENIED) ) { |
4394 /* from winerror.h */ |
4394 /* from winerror.h */ |
4395 return -1; |
4395 return -1; |
4396 } |
4396 } |
4397 return 0; |
4397 return 0; |
4398 } |
4398 } |
4482 DWORD actualLength = 0; /* Number of bytes readable */ |
4482 DWORD actualLength = 0; /* Number of bytes readable */ |
4483 BOOL error = FALSE; /* Error holder */ |
4483 BOOL error = FALSE; /* Error holder */ |
4484 INPUT_RECORD *lpBuffer; /* Pointer to records of input events */ |
4484 INPUT_RECORD *lpBuffer; /* Pointer to records of input events */ |
4485 |
4485 |
4486 if ((han = ::GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) { |
4486 if ((han = ::GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) { |
4487 return FALSE; |
4487 return FALSE; |
4488 } |
4488 } |
4489 |
4489 |
4490 /* Construct an array of input records in the console buffer */ |
4490 /* Construct an array of input records in the console buffer */ |
4491 error = ::GetNumberOfConsoleInputEvents(han, &numEvents); |
4491 error = ::GetNumberOfConsoleInputEvents(han, &numEvents); |
4492 if (error == 0) { |
4492 if (error == 0) { |
4533 return TRUE; |
4533 return TRUE; |
4534 } |
4534 } |
4535 |
4535 |
4536 // Map a block of memory. |
4536 // Map a block of memory. |
4537 char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, |
4537 char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, |
4538 char *addr, size_t bytes, bool read_only, |
4538 char *addr, size_t bytes, bool read_only, |
4539 bool allow_exec) { |
4539 bool allow_exec) { |
4540 HANDLE hFile; |
4540 HANDLE hFile; |
4541 char* base; |
4541 char* base; |
4542 |
4542 |
4543 hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, |
4543 hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, |
4544 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); |
4544 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); |
4653 } |
4653 } |
4654 |
4654 |
4655 |
4655 |
4656 // Remap a block of memory. |
4656 // Remap a block of memory. |
4657 char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset, |
4657 char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset, |
4658 char *addr, size_t bytes, bool read_only, |
4658 char *addr, size_t bytes, bool read_only, |
4659 bool allow_exec) { |
4659 bool allow_exec) { |
4660 // This OS does not allow existing memory maps to be remapped so we |
4660 // This OS does not allow existing memory maps to be remapped so we |
4661 // have to unmap the memory before we remap it. |
4661 // have to unmap the memory before we remap it. |
4662 if (!os::unmap_memory(addr, bytes)) { |
4662 if (!os::unmap_memory(addr, bytes)) { |
4663 return NULL; |
4663 return NULL; |
4664 } |
4664 } |
4666 // There is a very small theoretical window between the unmap_memory() |
4666 // There is a very small theoretical window between the unmap_memory() |
4667 // call above and the map_memory() call below where a thread in native |
4667 // call above and the map_memory() call below where a thread in native |
4668 // code may be able to access an address that is no longer mapped. |
4668 // code may be able to access an address that is no longer mapped. |
4669 |
4669 |
4670 return os::map_memory(fd, file_name, file_offset, addr, bytes, |
4670 return os::map_memory(fd, file_name, file_offset, addr, bytes, |
4671 read_only, allow_exec); |
4671 read_only, allow_exec); |
4672 } |
4672 } |
4673 |
4673 |
4674 |
4674 |
4675 // Unmap a block of memory. |
4675 // Unmap a block of memory. |
4676 // Returns true=success, otherwise false. |
4676 // Returns true=success, otherwise false. |
4702 while (::stat(filename, &buf) == 0) { |
4702 while (::stat(filename, &buf) == 0) { |
4703 Sleep(100); |
4703 Sleep(100); |
4704 } |
4704 } |
4705 } else { |
4705 } else { |
4706 jio_fprintf(stderr, |
4706 jio_fprintf(stderr, |
4707 "Could not open pause file '%s', continuing immediately.\n", filename); |
4707 "Could not open pause file '%s', continuing immediately.\n", filename); |
4708 } |
4708 } |
4709 } |
4709 } |
4710 |
4710 |
4711 os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { |
4711 os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { |
4712 assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); |
4712 assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); |
4720 * The callback is supposed to provide the method that should be protected. |
4720 * The callback is supposed to provide the method that should be protected. |
4721 */ |
4721 */ |
4722 bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) { |
4722 bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) { |
4723 assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread"); |
4723 assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread"); |
4724 assert(!WatcherThread::watcher_thread()->has_crash_protection(), |
4724 assert(!WatcherThread::watcher_thread()->has_crash_protection(), |
4725 "crash_protection already set?"); |
4725 "crash_protection already set?"); |
4726 |
4726 |
4727 bool success = true; |
4727 bool success = true; |
4728 __try { |
4728 __try { |
4729 WatcherThread::watcher_thread()->set_crash_protection(this); |
4729 WatcherThread::watcher_thread()->set_crash_protection(this); |
4730 cb.call(); |
4730 cb.call(); |
4786 // |
4786 // |
4787 // Another possible encoding of _Event would be |
4787 // Another possible encoding of _Event would be |
4788 // with explicit "PARKED" and "SIGNALED" bits. |
4788 // with explicit "PARKED" and "SIGNALED" bits. |
4789 |
4789 |
4790 int os::PlatformEvent::park (jlong Millis) { |
4790 int os::PlatformEvent::park (jlong Millis) { |
4791 guarantee(_ParkHandle != NULL , "Invariant"); |
4791 guarantee(_ParkHandle != NULL , "Invariant"); |
4792 guarantee(Millis > 0 , "Invariant"); |
4792 guarantee(Millis > 0 , "Invariant"); |
4793 int v; |
4793 int v; |
4794 |
4794 |
4795 // CONSIDER: defer assigning a CreateEvent() handle to the Event until |
4795 // CONSIDER: defer assigning a CreateEvent() handle to the Event until |
4796 // the initial park() operation. |
4796 // the initial park() operation. |
4797 |
4797 |
4798 for (;;) { |
4798 for (;;) { |
4799 v = _Event; |
|
4800 if (Atomic::cmpxchg(v-1, &_Event, v) == v) break; |
|
4801 } |
|
4802 guarantee((v == 0) || (v == 1), "invariant"); |
|
4803 if (v != 0) return OS_OK; |
|
4804 |
|
4805 // Do this the hard way by blocking ... |
|
4806 // TODO: consider a brief spin here, gated on the success of recent |
|
4807 // spin attempts by this thread. |
|
4808 // |
|
4809 // We decompose long timeouts into series of shorter timed waits. |
|
4810 // Evidently large timo values passed in WaitForSingleObject() are problematic on some |
|
4811 // versions of Windows. See EventWait() for details. This may be superstition. Or not. |
|
4812 // We trust the WAIT_TIMEOUT indication and don't track the elapsed wait time |
|
4813 // with os::javaTimeNanos(). Furthermore, we assume that spurious returns from |
|
4814 // ::WaitForSingleObject() caused by latent ::setEvent() operations will tend |
|
4815 // to happen early in the wait interval. Specifically, after a spurious wakeup (rv == |
|
4816 // WAIT_OBJECT_0 but _Event is still < 0) we don't bother to recompute Millis to compensate |
|
4817 // for the already waited time. This policy does not admit any new outcomes. |
|
4818 // In the future, however, we might want to track the accumulated wait time and |
|
4819 // adjust Millis accordingly if we encounter a spurious wakeup. |
|
4820 |
|
4821 const int MAXTIMEOUT = 0x10000000; |
|
4822 DWORD rv = WAIT_TIMEOUT; |
|
4823 while (_Event < 0 && Millis > 0) { |
|
4824 DWORD prd = Millis; // set prd = MAX (Millis, MAXTIMEOUT) |
|
4825 if (Millis > MAXTIMEOUT) { |
|
4826 prd = MAXTIMEOUT; |
|
4827 } |
|
4828 rv = ::WaitForSingleObject(_ParkHandle, prd); |
|
4829 assert(rv == WAIT_OBJECT_0 || rv == WAIT_TIMEOUT, "WaitForSingleObject failed"); |
|
4830 if (rv == WAIT_TIMEOUT) { |
|
4831 Millis -= prd; |
|
4832 } |
|
4833 } |
|
4834 v = _Event; |
4799 v = _Event; |
4835 _Event = 0; |
4800 if (Atomic::cmpxchg(v-1, &_Event, v) == v) break; |
4836 // see comment at end of os::PlatformEvent::park() below: |
4801 } |
4837 OrderAccess::fence(); |
4802 guarantee((v == 0) || (v == 1), "invariant"); |
4838 // If we encounter a nearly simultanous timeout expiry and unpark() |
4803 if (v != 0) return OS_OK; |
4839 // we return OS_OK indicating we awoke via unpark(). |
4804 |
4840 // Implementor's license -- returning OS_TIMEOUT would be equally valid, however. |
4805 // Do this the hard way by blocking ... |
4841 return (v >= 0) ? OS_OK : OS_TIMEOUT; |
4806 // TODO: consider a brief spin here, gated on the success of recent |
4807 // spin attempts by this thread. |
|
4808 // |
|
4809 // We decompose long timeouts into series of shorter timed waits. |
|
4810 // Evidently large timo values passed in WaitForSingleObject() are problematic on some |
|
4811 // versions of Windows. See EventWait() for details. This may be superstition. Or not. |
|
4812 // We trust the WAIT_TIMEOUT indication and don't track the elapsed wait time |
|
4813 // with os::javaTimeNanos(). Furthermore, we assume that spurious returns from |
|
4814 // ::WaitForSingleObject() caused by latent ::setEvent() operations will tend |
|
4815 // to happen early in the wait interval. Specifically, after a spurious wakeup (rv == |
|
4816 // WAIT_OBJECT_0 but _Event is still < 0) we don't bother to recompute Millis to compensate |
|
4817 // for the already waited time. This policy does not admit any new outcomes. |
|
4818 // In the future, however, we might want to track the accumulated wait time and |
|
4819 // adjust Millis accordingly if we encounter a spurious wakeup. |
|
4820 |
|
4821 const int MAXTIMEOUT = 0x10000000; |
|
4822 DWORD rv = WAIT_TIMEOUT; |
|
4823 while (_Event < 0 && Millis > 0) { |
|
4824 DWORD prd = Millis; // set prd = MAX (Millis, MAXTIMEOUT) |
|
4825 if (Millis > MAXTIMEOUT) { |
|
4826 prd = MAXTIMEOUT; |
|
4827 } |
|
4828 rv = ::WaitForSingleObject(_ParkHandle, prd); |
|
4829 assert(rv == WAIT_OBJECT_0 || rv == WAIT_TIMEOUT, "WaitForSingleObject failed"); |
|
4830 if (rv == WAIT_TIMEOUT) { |
|
4831 Millis -= prd; |
|
4832 } |
|
4833 } |
|
4834 v = _Event; |
|
4835 _Event = 0; |
|
4836 // see comment at end of os::PlatformEvent::park() below: |
|
4837 OrderAccess::fence(); |
|
4838 // If we encounter a nearly simultanous timeout expiry and unpark() |
|
4839 // we return OS_OK indicating we awoke via unpark(). |
|
4840 // Implementor's license -- returning OS_TIMEOUT would be equally valid, however. |
|
4841 return (v >= 0) ? OS_OK : OS_TIMEOUT; |
|
4842 } |
4842 } |
4843 |
4843 |
4844 void os::PlatformEvent::park() { |
4844 void os::PlatformEvent::park() { |
4845 guarantee(_ParkHandle != NULL, "Invariant"); |
4845 guarantee(_ParkHandle != NULL, "Invariant"); |
4846 // Invariant: Only the thread associated with the Event/PlatformEvent |
4846 // Invariant: Only the thread associated with the Event/PlatformEvent |
4847 // may call park(). |
4847 // may call park(). |
4848 int v; |
4848 int v; |
4849 for (;;) { |
4849 for (;;) { |
4850 v = _Event; |
4850 v = _Event; |
4851 if (Atomic::cmpxchg(v-1, &_Event, v) == v) break; |
4851 if (Atomic::cmpxchg(v-1, &_Event, v) == v) break; |
4852 } |
4852 } |
4853 guarantee((v == 0) || (v == 1), "invariant"); |
4853 guarantee((v == 0) || (v == 1), "invariant"); |
4854 if (v != 0) return; |
4854 if (v != 0) return; |
4855 |
4855 |
4856 // Do this the hard way by blocking ... |
4856 // Do this the hard way by blocking ... |
4857 // TODO: consider a brief spin here, gated on the success of recent |
4857 // TODO: consider a brief spin here, gated on the success of recent |
4858 // spin attempts by this thread. |
4858 // spin attempts by this thread. |
4859 while (_Event < 0) { |
4859 while (_Event < 0) { |
4860 DWORD rv = ::WaitForSingleObject(_ParkHandle, INFINITE); |
4860 DWORD rv = ::WaitForSingleObject(_ParkHandle, INFINITE); |
4861 assert(rv == WAIT_OBJECT_0, "WaitForSingleObject failed"); |
4861 assert(rv == WAIT_OBJECT_0, "WaitForSingleObject failed"); |
4862 } |
4862 } |
4863 |
4863 |
4864 // Usually we'll find _Event == 0 at this point, but as |
4864 // Usually we'll find _Event == 0 at this point, but as |
4865 // an optional optimization we clear it, just in case can |
4865 // an optional optimization we clear it, just in case can |
4866 // multiple unpark() operations drove _Event up to 1. |
4866 // multiple unpark() operations drove _Event up to 1. |
4867 _Event = 0; |
4867 _Event = 0; |
4868 OrderAccess::fence(); |
4868 OrderAccess::fence(); |
4869 guarantee(_Event >= 0, "invariant"); |
4869 guarantee(_Event >= 0, "invariant"); |
4870 } |
4870 } |
4871 |
4871 |
4872 void os::PlatformEvent::unpark() { |
4872 void os::PlatformEvent::unpark() { |
4873 guarantee(_ParkHandle != NULL, "Invariant"); |
4873 guarantee(_ParkHandle != NULL, "Invariant"); |
4874 |
4874 |
4927 assert(thread->is_Java_thread(), "Must be JavaThread"); |
4927 assert(thread->is_Java_thread(), "Must be JavaThread"); |
4928 JavaThread *jt = (JavaThread *)thread; |
4928 JavaThread *jt = (JavaThread *)thread; |
4929 |
4929 |
4930 // Don't wait if interrupted or already triggered |
4930 // Don't wait if interrupted or already triggered |
4931 if (Thread::is_interrupted(thread, false) || |
4931 if (Thread::is_interrupted(thread, false) || |
4932 WaitForSingleObject(_ParkEvent, 0) == WAIT_OBJECT_0) { |
4932 WaitForSingleObject(_ParkEvent, 0) == WAIT_OBJECT_0) { |
4933 ResetEvent(_ParkEvent); |
4933 ResetEvent(_ParkEvent); |
4934 return; |
4934 return; |
4935 } |
4935 } |
4936 else { |
4936 else { |
4937 ThreadBlockInVM tbivm(jt); |
4937 ThreadBlockInVM tbivm(jt); |
5055 static jint initSock() { |
5055 static jint initSock() { |
5056 WSADATA wsadata; |
5056 WSADATA wsadata; |
5057 |
5057 |
5058 if (!os::WinSock2Dll::WinSock2Available()) { |
5058 if (!os::WinSock2Dll::WinSock2Available()) { |
5059 jio_fprintf(stderr, "Could not load Winsock (error: %d)\n", |
5059 jio_fprintf(stderr, "Could not load Winsock (error: %d)\n", |
5060 ::GetLastError()); |
5060 ::GetLastError()); |
5061 return JNI_ERR; |
5061 return JNI_ERR; |
5062 } |
5062 } |
5063 |
5063 |
5064 if (os::WinSock2Dll::WSAStartup(MAKEWORD(2,2), &wsadata) != 0) { |
5064 if (os::WinSock2Dll::WSAStartup(MAKEWORD(2,2), &wsadata) != 0) { |
5065 jio_fprintf(stderr, "Could not initialize Winsock (error: %d)\n", |
5065 jio_fprintf(stderr, "Could not initialize Winsock (error: %d)\n", |
5066 ::GetLastError()); |
5066 ::GetLastError()); |
5067 return JNI_ERR; |
5067 return JNI_ERR; |
5068 } |
5068 } |
5069 return JNI_OK; |
5069 return JNI_OK; |
5070 } |
5070 } |
5071 |
5071 |
5242 |
5242 |
5243 |
5243 |
5244 BOOL os::Kernel32Dll::initialized = FALSE; |
5244 BOOL os::Kernel32Dll::initialized = FALSE; |
5245 SIZE_T os::Kernel32Dll::GetLargePageMinimum() { |
5245 SIZE_T os::Kernel32Dll::GetLargePageMinimum() { |
5246 assert(initialized && _GetLargePageMinimum != NULL, |
5246 assert(initialized && _GetLargePageMinimum != NULL, |
5247 "GetLargePageMinimumAvailable() not yet called"); |
5247 "GetLargePageMinimumAvailable() not yet called"); |
5248 return _GetLargePageMinimum(); |
5248 return _GetLargePageMinimum(); |
5249 } |
5249 } |
5250 |
5250 |
5251 BOOL os::Kernel32Dll::GetLargePageMinimumAvailable() { |
5251 BOOL os::Kernel32Dll::GetLargePageMinimumAvailable() { |
5252 if (!initialized) { |
5252 if (!initialized) { |
5262 return _VirtualAllocExNuma != NULL; |
5262 return _VirtualAllocExNuma != NULL; |
5263 } |
5263 } |
5264 |
5264 |
5265 LPVOID os::Kernel32Dll::VirtualAllocExNuma(HANDLE hProc, LPVOID addr, SIZE_T bytes, DWORD flags, DWORD prot, DWORD node) { |
5265 LPVOID os::Kernel32Dll::VirtualAllocExNuma(HANDLE hProc, LPVOID addr, SIZE_T bytes, DWORD flags, DWORD prot, DWORD node) { |
5266 assert(initialized && _VirtualAllocExNuma != NULL, |
5266 assert(initialized && _VirtualAllocExNuma != NULL, |
5267 "NUMACallsAvailable() not yet called"); |
5267 "NUMACallsAvailable() not yet called"); |
5268 |
5268 |
5269 return _VirtualAllocExNuma(hProc, addr, bytes, flags, prot, node); |
5269 return _VirtualAllocExNuma(hProc, addr, bytes, flags, prot, node); |
5270 } |
5270 } |
5271 |
5271 |
5272 BOOL os::Kernel32Dll::GetNumaHighestNodeNumber(PULONG ptr_highest_node_number) { |
5272 BOOL os::Kernel32Dll::GetNumaHighestNodeNumber(PULONG ptr_highest_node_number) { |
5273 assert(initialized && _GetNumaHighestNodeNumber != NULL, |
5273 assert(initialized && _GetNumaHighestNodeNumber != NULL, |
5274 "NUMACallsAvailable() not yet called"); |
5274 "NUMACallsAvailable() not yet called"); |
5275 |
5275 |
5276 return _GetNumaHighestNodeNumber(ptr_highest_node_number); |
5276 return _GetNumaHighestNodeNumber(ptr_highest_node_number); |
5277 } |
5277 } |
5278 |
5278 |
5279 BOOL os::Kernel32Dll::GetNumaNodeProcessorMask(UCHAR node, PULONGLONG proc_mask) { |
5279 BOOL os::Kernel32Dll::GetNumaNodeProcessorMask(UCHAR node, PULONGLONG proc_mask) { |
5280 assert(initialized && _GetNumaNodeProcessorMask != NULL, |
5280 assert(initialized && _GetNumaNodeProcessorMask != NULL, |
5281 "NUMACallsAvailable() not yet called"); |
5281 "NUMACallsAvailable() not yet called"); |
5282 |
5282 |
5283 return _GetNumaNodeProcessorMask(node, proc_mask); |
5283 return _GetNumaNodeProcessorMask(node, proc_mask); |
5284 } |
5284 } |
5285 |
5285 |
5286 USHORT os::Kernel32Dll::RtlCaptureStackBackTrace(ULONG FrameToSkip, |
5286 USHORT os::Kernel32Dll::RtlCaptureStackBackTrace(ULONG FrameToSkip, |
5287 ULONG FrameToCapture, PVOID* BackTrace, PULONG BackTraceHash) { |
5287 ULONG FrameToCapture, PVOID* BackTrace, PULONG BackTraceHash) { |
5288 if (!initialized) { |
5288 if (!initialized) { |
5289 initialize(); |
5289 initialize(); |
5290 } |
5290 } |
5291 |
5291 |
5292 if (_RtlCaptureStackBackTrace != NULL) { |
5292 if (_RtlCaptureStackBackTrace != NULL) { |
5293 return _RtlCaptureStackBackTrace(FrameToSkip, FrameToCapture, |
5293 return _RtlCaptureStackBackTrace(FrameToSkip, FrameToCapture, |
5294 BackTrace, BackTraceHash); |
5294 BackTrace, BackTraceHash); |
5295 } else { |
5295 } else { |
5296 return 0; |
5296 return 0; |
5297 } |
5297 } |
5298 } |
5298 } |
5299 |
5299 |
5300 void os::Kernel32Dll::initializeCommon() { |
5300 void os::Kernel32Dll::initializeCommon() { |
5301 if (!initialized) { |
5301 if (!initialized) { |
5302 HMODULE handle = ::GetModuleHandle("Kernel32.dll"); |
5302 HMODULE handle = ::GetModuleHandle("Kernel32.dll"); |
5326 |
5326 |
5327 inline BOOL os::Kernel32Dll::SwitchToThreadAvailable() { |
5327 inline BOOL os::Kernel32Dll::SwitchToThreadAvailable() { |
5328 return true; |
5328 return true; |
5329 } |
5329 } |
5330 |
5330 |
5331 // Help tools |
5331 // Help tools |
5332 inline BOOL os::Kernel32Dll::HelpToolsAvailable() { |
5332 inline BOOL os::Kernel32Dll::HelpToolsAvailable() { |
5333 return true; |
5333 return true; |
5334 } |
5334 } |
5335 |
5335 |
5336 inline HANDLE os::Kernel32Dll::CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessId) { |
5336 inline HANDLE os::Kernel32Dll::CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessId) { |
5385 return true; |
5385 return true; |
5386 } |
5386 } |
5387 |
5387 |
5388 // Advapi API |
5388 // Advapi API |
5389 inline BOOL os::Advapi32Dll::AdjustTokenPrivileges(HANDLE TokenHandle, |
5389 inline BOOL os::Advapi32Dll::AdjustTokenPrivileges(HANDLE TokenHandle, |
5390 BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, |
5390 BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, |
5391 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength) { |
5391 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength) { |
5392 return ::AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges, NewState, |
5392 return ::AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges, NewState, |
5393 BufferLength, PreviousState, ReturnLength); |
5393 BufferLength, PreviousState, ReturnLength); |
5394 } |
5394 } |
5395 |
5395 |
5396 inline BOOL os::Advapi32Dll::OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, |
5396 inline BOOL os::Advapi32Dll::OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, |
5397 PHANDLE TokenHandle) { |
5397 PHANDLE TokenHandle) { |
5398 return ::OpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle); |
5398 return ::OpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle); |
5399 } |
5399 } |
5400 |
5400 |
5401 inline BOOL os::Advapi32Dll::LookupPrivilegeValue(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid) { |
5401 inline BOOL os::Advapi32Dll::LookupPrivilegeValue(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid) { |
5402 return ::LookupPrivilegeValue(lpSystemName, lpName, lpLuid); |
5402 return ::LookupPrivilegeValue(lpSystemName, lpName, lpLuid); |
5403 } |
5403 } |
5506 } |
5506 } |
5507 } |
5507 } |
5508 |
5508 |
5509 BOOL os::Kernel32Dll::SwitchToThread() { |
5509 BOOL os::Kernel32Dll::SwitchToThread() { |
5510 assert(initialized && _SwitchToThread != NULL, |
5510 assert(initialized && _SwitchToThread != NULL, |
5511 "SwitchToThreadAvailable() not yet called"); |
5511 "SwitchToThreadAvailable() not yet called"); |
5512 return _SwitchToThread(); |
5512 return _SwitchToThread(); |
5513 } |
5513 } |
5514 |
5514 |
5515 |
5515 |
5516 BOOL os::Kernel32Dll::SwitchToThreadAvailable() { |
5516 BOOL os::Kernel32Dll::SwitchToThreadAvailable() { |
5530 _Module32Next != NULL; |
5530 _Module32Next != NULL; |
5531 } |
5531 } |
5532 |
5532 |
5533 HANDLE os::Kernel32Dll::CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessId) { |
5533 HANDLE os::Kernel32Dll::CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessId) { |
5534 assert(initialized && _CreateToolhelp32Snapshot != NULL, |
5534 assert(initialized && _CreateToolhelp32Snapshot != NULL, |
5535 "HelpToolsAvailable() not yet called"); |
5535 "HelpToolsAvailable() not yet called"); |
5536 |
5536 |
5537 return _CreateToolhelp32Snapshot(dwFlags, th32ProcessId); |
5537 return _CreateToolhelp32Snapshot(dwFlags, th32ProcessId); |
5538 } |
5538 } |
5539 |
5539 |
5540 BOOL os::Kernel32Dll::Module32First(HANDLE hSnapshot,LPMODULEENTRY32 lpme) { |
5540 BOOL os::Kernel32Dll::Module32First(HANDLE hSnapshot,LPMODULEENTRY32 lpme) { |
5541 assert(initialized && _Module32First != NULL, |
5541 assert(initialized && _Module32First != NULL, |
5542 "HelpToolsAvailable() not yet called"); |
5542 "HelpToolsAvailable() not yet called"); |
5543 |
5543 |
5544 return _Module32First(hSnapshot, lpme); |
5544 return _Module32First(hSnapshot, lpme); |
5545 } |
5545 } |
5546 |
5546 |
5547 inline BOOL os::Kernel32Dll::Module32Next(HANDLE hSnapshot,LPMODULEENTRY32 lpme) { |
5547 inline BOOL os::Kernel32Dll::Module32Next(HANDLE hSnapshot,LPMODULEENTRY32 lpme) { |
5548 assert(initialized && _Module32Next != NULL, |
5548 assert(initialized && _Module32Next != NULL, |
5549 "HelpToolsAvailable() not yet called"); |
5549 "HelpToolsAvailable() not yet called"); |
5550 |
5550 |
5551 return _Module32Next(hSnapshot, lpme); |
5551 return _Module32Next(hSnapshot, lpme); |
5552 } |
5552 } |
5553 |
5553 |
5554 |
5554 |
5559 return _GetNativeSystemInfo != NULL; |
5559 return _GetNativeSystemInfo != NULL; |
5560 } |
5560 } |
5561 |
5561 |
5562 void os::Kernel32Dll::GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) { |
5562 void os::Kernel32Dll::GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) { |
5563 assert(initialized && _GetNativeSystemInfo != NULL, |
5563 assert(initialized && _GetNativeSystemInfo != NULL, |
5564 "GetNativeSystemInfoAvailable() not yet called"); |
5564 "GetNativeSystemInfoAvailable() not yet called"); |
5565 |
5565 |
5566 _GetNativeSystemInfo(lpSystemInfo); |
5566 _GetNativeSystemInfo(lpSystemInfo); |
5567 } |
5567 } |
5568 |
5568 |
5569 // PSAPI API |
5569 // PSAPI API |
5581 void os::PSApiDll::initialize() { |
5581 void os::PSApiDll::initialize() { |
5582 if (!initialized) { |
5582 if (!initialized) { |
5583 HMODULE handle = os::win32::load_Windows_dll("PSAPI.DLL", NULL, 0); |
5583 HMODULE handle = os::win32::load_Windows_dll("PSAPI.DLL", NULL, 0); |
5584 if (handle != NULL) { |
5584 if (handle != NULL) { |
5585 _EnumProcessModules = (EnumProcessModules_Fn)::GetProcAddress(handle, |
5585 _EnumProcessModules = (EnumProcessModules_Fn)::GetProcAddress(handle, |
5586 "EnumProcessModules"); |
5586 "EnumProcessModules"); |
5587 _GetModuleFileNameEx = (GetModuleFileNameEx_Fn)::GetProcAddress(handle, |
5587 _GetModuleFileNameEx = (GetModuleFileNameEx_Fn)::GetProcAddress(handle, |
5588 "GetModuleFileNameExA"); |
5588 "GetModuleFileNameExA"); |
5589 _GetModuleInformation = (GetModuleInformation_Fn)::GetProcAddress(handle, |
5589 _GetModuleInformation = (GetModuleInformation_Fn)::GetProcAddress(handle, |
5590 "GetModuleInformation"); |
5590 "GetModuleInformation"); |
5591 } |
5591 } |
5592 initialized = TRUE; |
5592 initialized = TRUE; |
5593 } |
5593 } |
5594 } |
5594 } |
5595 |
5595 |
5596 |
5596 |
5597 |
5597 |
5598 BOOL os::PSApiDll::EnumProcessModules(HANDLE hProcess, HMODULE *lpModule, DWORD cb, LPDWORD lpcbNeeded) { |
5598 BOOL os::PSApiDll::EnumProcessModules(HANDLE hProcess, HMODULE *lpModule, DWORD cb, LPDWORD lpcbNeeded) { |
5599 assert(initialized && _EnumProcessModules != NULL, |
5599 assert(initialized && _EnumProcessModules != NULL, |
5600 "PSApiAvailable() not yet called"); |
5600 "PSApiAvailable() not yet called"); |
5601 return _EnumProcessModules(hProcess, lpModule, cb, lpcbNeeded); |
5601 return _EnumProcessModules(hProcess, lpModule, cb, lpcbNeeded); |
5602 } |
5602 } |
5603 |
5603 |
5604 DWORD os::PSApiDll::GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize) { |
5604 DWORD os::PSApiDll::GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize) { |
5605 assert(initialized && _GetModuleFileNameEx != NULL, |
5605 assert(initialized && _GetModuleFileNameEx != NULL, |
5606 "PSApiAvailable() not yet called"); |
5606 "PSApiAvailable() not yet called"); |
5607 return _GetModuleFileNameEx(hProcess, hModule, lpFilename, nSize); |
5607 return _GetModuleFileNameEx(hProcess, hModule, lpFilename, nSize); |
5608 } |
5608 } |
5609 |
5609 |
5610 BOOL os::PSApiDll::GetModuleInformation(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb) { |
5610 BOOL os::PSApiDll::GetModuleInformation(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb) { |
5611 assert(initialized && _GetModuleInformation != NULL, |
5611 assert(initialized && _GetModuleInformation != NULL, |
5612 "PSApiAvailable() not yet called"); |
5612 "PSApiAvailable() not yet called"); |
5613 return _GetModuleInformation(hProcess, hModule, lpmodinfo, cb); |
5613 return _GetModuleInformation(hProcess, hModule, lpmodinfo, cb); |
5614 } |
5614 } |
5615 |
5615 |
5616 BOOL os::PSApiDll::PSApiAvailable() { |
5616 BOOL os::PSApiDll::PSApiAvailable() { |
5617 if (!initialized) { |
5617 if (!initialized) { |
5643 } |
5643 } |
5644 |
5644 |
5645 |
5645 |
5646 BOOL os::WinSock2Dll::WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) { |
5646 BOOL os::WinSock2Dll::WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) { |
5647 assert(initialized && _WSAStartup != NULL, |
5647 assert(initialized && _WSAStartup != NULL, |
5648 "WinSock2Available() not yet called"); |
5648 "WinSock2Available() not yet called"); |
5649 return _WSAStartup(wVersionRequested, lpWSAData); |
5649 return _WSAStartup(wVersionRequested, lpWSAData); |
5650 } |
5650 } |
5651 |
5651 |
5652 struct hostent* os::WinSock2Dll::gethostbyname(const char *name) { |
5652 struct hostent* os::WinSock2Dll::gethostbyname(const char *name) { |
5653 assert(initialized && _gethostbyname != NULL, |
5653 assert(initialized && _gethostbyname != NULL, |
5654 "WinSock2Available() not yet called"); |
5654 "WinSock2Available() not yet called"); |
5655 return _gethostbyname(name); |
5655 return _gethostbyname(name); |
5656 } |
5656 } |
5657 |
5657 |
5658 BOOL os::WinSock2Dll::WinSock2Available() { |
5658 BOOL os::WinSock2Dll::WinSock2Available() { |
5659 if (!initialized) { |
5659 if (!initialized) { |
5675 void os::Advapi32Dll::initialize() { |
5675 void os::Advapi32Dll::initialize() { |
5676 if (!initialized) { |
5676 if (!initialized) { |
5677 HMODULE handle = os::win32::load_Windows_dll("advapi32.dll", NULL, 0); |
5677 HMODULE handle = os::win32::load_Windows_dll("advapi32.dll", NULL, 0); |
5678 if (handle != NULL) { |
5678 if (handle != NULL) { |
5679 _AdjustTokenPrivileges = (AdjustTokenPrivileges_Fn)::GetProcAddress(handle, |
5679 _AdjustTokenPrivileges = (AdjustTokenPrivileges_Fn)::GetProcAddress(handle, |
5680 "AdjustTokenPrivileges"); |
5680 "AdjustTokenPrivileges"); |
5681 _OpenProcessToken = (OpenProcessToken_Fn)::GetProcAddress(handle, |
5681 _OpenProcessToken = (OpenProcessToken_Fn)::GetProcAddress(handle, |
5682 "OpenProcessToken"); |
5682 "OpenProcessToken"); |
5683 _LookupPrivilegeValue = (LookupPrivilegeValue_Fn)::GetProcAddress(handle, |
5683 _LookupPrivilegeValue = (LookupPrivilegeValue_Fn)::GetProcAddress(handle, |
5684 "LookupPrivilegeValueA"); |
5684 "LookupPrivilegeValueA"); |
5685 } |
5685 } |
5686 initialized = TRUE; |
5686 initialized = TRUE; |
5687 } |
5687 } |
5688 } |
5688 } |
5689 |
5689 |
5690 BOOL os::Advapi32Dll::AdjustTokenPrivileges(HANDLE TokenHandle, |
5690 BOOL os::Advapi32Dll::AdjustTokenPrivileges(HANDLE TokenHandle, |
5691 BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, |
5691 BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, |
5692 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength) { |
5692 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength) { |
5693 assert(initialized && _AdjustTokenPrivileges != NULL, |
5693 assert(initialized && _AdjustTokenPrivileges != NULL, |
5694 "AdvapiAvailable() not yet called"); |
5694 "AdvapiAvailable() not yet called"); |
5695 return _AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges, NewState, |
5695 return _AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges, NewState, |
5696 BufferLength, PreviousState, ReturnLength); |
5696 BufferLength, PreviousState, ReturnLength); |
5697 } |
5697 } |
5698 |
5698 |
5699 BOOL os::Advapi32Dll::OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, |
5699 BOOL os::Advapi32Dll::OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, |
5700 PHANDLE TokenHandle) { |
5700 PHANDLE TokenHandle) { |
5701 assert(initialized && _OpenProcessToken != NULL, |
5701 assert(initialized && _OpenProcessToken != NULL, |
5702 "AdvapiAvailable() not yet called"); |
5702 "AdvapiAvailable() not yet called"); |
5703 return _OpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle); |
5703 return _OpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle); |
5704 } |
5704 } |
5705 |
5705 |
5706 BOOL os::Advapi32Dll::LookupPrivilegeValue(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid) { |
5706 BOOL os::Advapi32Dll::LookupPrivilegeValue(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid) { |
5707 assert(initialized && _LookupPrivilegeValue != NULL, |
5707 assert(initialized && _LookupPrivilegeValue != NULL, |
5708 "AdvapiAvailable() not yet called"); |
5708 "AdvapiAvailable() not yet called"); |
5709 return _LookupPrivilegeValue(lpSystemName, lpName, lpLuid); |
5709 return _LookupPrivilegeValue(lpSystemName, lpName, lpLuid); |
5710 } |
5710 } |
5711 |
5711 |
5712 BOOL os::Advapi32Dll::AdvapiAvailable() { |
5712 BOOL os::Advapi32Dll::AdvapiAvailable() { |
5713 if (!initialized) { |
5713 if (!initialized) { |
5751 const size_t large_allocation_size = os::large_page_size() * 4; |
5751 const size_t large_allocation_size = os::large_page_size() * 4; |
5752 char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), NULL, false); |
5752 char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), NULL, false); |
5753 if (result == NULL) { |
5753 if (result == NULL) { |
5754 if (VerboseInternalVMTests) { |
5754 if (VerboseInternalVMTests) { |
5755 gclog_or_tty->print("Failed to allocate control block with size "SIZE_FORMAT". Skipping remainder of test.", |
5755 gclog_or_tty->print("Failed to allocate control block with size "SIZE_FORMAT". Skipping remainder of test.", |
5756 large_allocation_size); |
5756 large_allocation_size); |
5757 } |
5757 } |
5758 } else { |
5758 } else { |
5759 os::release_memory_special(result, large_allocation_size); |
5759 os::release_memory_special(result, large_allocation_size); |
5760 |
5760 |
5761 // allocate another page within the recently allocated memory area which seems to be a good location. At least |
5761 // allocate another page within the recently allocated memory area which seems to be a good location. At least |
5764 char* expected_location = result + os::large_page_size(); |
5764 char* expected_location = result + os::large_page_size(); |
5765 char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false); |
5765 char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false); |
5766 if (actual_location == NULL) { |
5766 if (actual_location == NULL) { |
5767 if (VerboseInternalVMTests) { |
5767 if (VerboseInternalVMTests) { |
5768 gclog_or_tty->print("Failed to allocate any memory at "PTR_FORMAT" size "SIZE_FORMAT". Skipping remainder of test.", |
5768 gclog_or_tty->print("Failed to allocate any memory at "PTR_FORMAT" size "SIZE_FORMAT". Skipping remainder of test.", |
5769 expected_location, large_allocation_size); |
5769 expected_location, large_allocation_size); |
5770 } |
5770 } |
5771 } else { |
5771 } else { |
5772 // release memory |
5772 // release memory |
5773 os::release_memory_special(actual_location, expected_allocation_size); |
5773 os::release_memory_special(actual_location, expected_allocation_size); |
5774 // only now check, after releasing any memory to avoid any leaks. |
5774 // only now check, after releasing any memory to avoid any leaks. |
5775 assert(actual_location == expected_location, |
5775 assert(actual_location == expected_location, |
5776 err_msg("Failed to allocate memory at requested location "PTR_FORMAT" of size "SIZE_FORMAT", is "PTR_FORMAT" instead", |
5776 err_msg("Failed to allocate memory at requested location "PTR_FORMAT" of size "SIZE_FORMAT", is "PTR_FORMAT" instead", |
5777 expected_location, expected_allocation_size, actual_location)); |
5777 expected_location, expected_allocation_size, actual_location)); |
5778 } |
5778 } |
5779 } |
5779 } |
5780 |
5780 |
5781 // restore globals |
5781 // restore globals |
5782 UseLargePagesIndividualAllocation = old_use_large_pages_individual_allocation; |
5782 UseLargePagesIndividualAllocation = old_use_large_pages_individual_allocation; |