changeset 26684 | d1221849ea3d |
parent 26683 | a02753d5a0b2 |
child 26685 | aa239a0dfbea |
26683:a02753d5a0b2 | 26684:d1221849ea3d |
---|---|
90 #include <errno.h> |
90 #include <errno.h> |
91 #include <fcntl.h> |
91 #include <fcntl.h> |
92 #include <io.h> |
92 #include <io.h> |
93 #include <process.h> // For _beginthreadex(), _endthreadex() |
93 #include <process.h> // For _beginthreadex(), _endthreadex() |
94 #include <imagehlp.h> // For os::dll_address_to_function_name |
94 #include <imagehlp.h> // For os::dll_address_to_function_name |
95 /* for enumerating dll libraries */ |
95 // for enumerating dll libraries |
96 #include <vdmdbg.h> |
96 #include <vdmdbg.h> |
97 |
97 |
98 // for timer info max values which include all bits |
98 // for timer info max values which include all bits |
99 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) |
99 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) |
100 |
100 |
111 static FILETIME process_exit_time; |
111 static FILETIME process_exit_time; |
112 static FILETIME process_user_time; |
112 static FILETIME process_user_time; |
113 static FILETIME process_kernel_time; |
113 static FILETIME process_kernel_time; |
114 |
114 |
115 #ifdef _M_IA64 |
115 #ifdef _M_IA64 |
116 #define __CPU__ ia64 |
116 #define __CPU__ ia64 |
117 #elif _M_AMD64 |
117 #elif _M_AMD64 |
118 #define __CPU__ amd64 |
118 #define __CPU__ amd64 |
119 #else |
119 #else |
120 #define __CPU__ i486 |
120 #define __CPU__ i486 |
121 #endif |
121 #endif |
122 |
122 |
123 // save DLL module handle, used by GetModuleFileName |
123 // save DLL module handle, used by GetModuleFileName |
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 } |
|
133 break; |
134 break; |
134 case DLL_PROCESS_DETACH: |
135 case DLL_PROCESS_DETACH: |
135 if (ForceTimeHighResolution) |
136 if (ForceTimeHighResolution) { |
136 timeEndPeriod(1L); |
137 timeEndPeriod(1L); |
137 |
138 } |
138 break; |
139 break; |
139 default: |
140 default: |
140 break; |
141 break; |
141 } |
142 } |
142 return true; |
143 return true; |
177 |
178 |
178 // previous UnhandledExceptionFilter, if there is one |
179 // previous UnhandledExceptionFilter, if there is one |
179 static LPTOP_LEVEL_EXCEPTION_FILTER prev_uef_handler = NULL; |
180 static LPTOP_LEVEL_EXCEPTION_FILTER prev_uef_handler = NULL; |
180 |
181 |
181 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo); |
182 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo); |
183 |
|
182 void os::init_system_properties_values() { |
184 void os::init_system_properties_values() { |
183 /* sysclasspath, java_home, dll_dir */ |
185 // sysclasspath, java_home, dll_dir |
184 { |
186 { |
185 char *home_path; |
187 char *home_path; |
186 char *dll_path; |
188 char *dll_path; |
187 char *pslash; |
189 char *pslash; |
188 char *bin = "\\bin"; |
190 char *bin = "\\bin"; |
190 |
192 |
191 if (!getenv("_ALT_JAVA_HOME_DIR", home_dir, MAX_PATH)) { |
193 if (!getenv("_ALT_JAVA_HOME_DIR", home_dir, MAX_PATH)) { |
192 os::jvm_path(home_dir, sizeof(home_dir)); |
194 os::jvm_path(home_dir, sizeof(home_dir)); |
193 // Found the full path to jvm.dll. |
195 // Found the full path to jvm.dll. |
194 // Now cut the path to <java_home>/jre if we can. |
196 // Now cut the path to <java_home>/jre if we can. |
195 *(strrchr(home_dir, '\\')) = '\0'; /* get rid of \jvm.dll */ |
197 *(strrchr(home_dir, '\\')) = '\0'; // get rid of \jvm.dll |
196 pslash = strrchr(home_dir, '\\'); |
198 pslash = strrchr(home_dir, '\\'); |
197 if (pslash != NULL) { |
199 if (pslash != NULL) { |
198 *pslash = '\0'; /* get rid of \{client|server} */ |
200 *pslash = '\0'; // get rid of \{client|server} |
199 pslash = strrchr(home_dir, '\\'); |
201 pslash = strrchr(home_dir, '\\'); |
200 if (pslash != NULL) |
202 if (pslash != NULL) { |
201 *pslash = '\0'; /* get rid of \bin */ |
203 *pslash = '\0'; // get rid of \bin |
204 } |
|
202 } |
205 } |
203 } |
206 } |
204 |
207 |
205 home_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + 1, mtInternal); |
208 home_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + 1, mtInternal); |
206 if (home_path == NULL) |
209 if (home_path == NULL) { |
207 return; |
210 return; |
211 } |
|
208 strcpy(home_path, home_dir); |
212 strcpy(home_path, home_dir); |
209 Arguments::set_java_home(home_path); |
213 Arguments::set_java_home(home_path); |
210 |
214 |
211 dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1, mtInternal); |
215 dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1, |
212 if (dll_path == NULL) |
216 mtInternal); |
217 if (dll_path == NULL) { |
|
213 return; |
218 return; |
219 } |
|
214 strcpy(dll_path, home_dir); |
220 strcpy(dll_path, home_dir); |
215 strcat(dll_path, bin); |
221 strcat(dll_path, bin); |
216 Arguments::set_dll_dir(dll_path); |
222 Arguments::set_dll_dir(dll_path); |
217 |
223 |
218 if (!set_boot_path('\\', ';')) |
224 if (!set_boot_path('\\', ';')) { |
219 return; |
225 return; |
220 } |
226 } |
221 |
227 } |
222 /* library_path */ |
228 |
223 #define EXT_DIR "\\lib\\ext" |
229 // library_path |
224 #define BIN_DIR "\\bin" |
230 #define EXT_DIR "\\lib\\ext" |
225 #define PACKAGE_DIR "\\Sun\\Java" |
231 #define BIN_DIR "\\bin" |
232 #define PACKAGE_DIR "\\Sun\\Java" |
|
226 { |
233 { |
227 /* Win32 library search order (See the documentation for LoadLibrary): |
234 // Win32 library search order (See the documentation for LoadLibrary): |
228 * |
235 // |
229 * 1. The directory from which application is loaded. |
236 // 1. The directory from which application is loaded. |
230 * 2. The system wide Java Extensions directory (Java only) |
237 // 2. The system wide Java Extensions directory (Java only) |
231 * 3. System directory (GetSystemDirectory) |
238 // 3. System directory (GetSystemDirectory) |
232 * 4. Windows directory (GetWindowsDirectory) |
239 // 4. Windows directory (GetWindowsDirectory) |
233 * 5. The PATH environment variable |
240 // 5. The PATH environment variable |
234 * 6. The current directory |
241 // 6. The current directory |
235 */ |
|
236 |
242 |
237 char *library_path; |
243 char *library_path; |
238 char tmp[MAX_PATH]; |
244 char tmp[MAX_PATH]; |
239 char *path_str = ::getenv("PATH"); |
245 char *path_str = ::getenv("PATH"); |
240 |
246 |
269 |
275 |
270 Arguments::set_library_path(library_path); |
276 Arguments::set_library_path(library_path); |
271 FREE_C_HEAP_ARRAY(char, library_path, mtInternal); |
277 FREE_C_HEAP_ARRAY(char, library_path, mtInternal); |
272 } |
278 } |
273 |
279 |
274 /* Default extensions directory */ |
280 // Default extensions directory |
275 { |
281 { |
276 char path[MAX_PATH]; |
282 char path[MAX_PATH]; |
277 char buf[2 * MAX_PATH + 2 * sizeof(EXT_DIR) + sizeof(PACKAGE_DIR) + 1]; |
283 char buf[2 * MAX_PATH + 2 * sizeof(EXT_DIR) + sizeof(PACKAGE_DIR) + 1]; |
278 GetWindowsDirectory(path, MAX_PATH); |
284 GetWindowsDirectory(path, MAX_PATH); |
279 sprintf(buf, "%s%s;%s%s%s", Arguments::get_java_home(), EXT_DIR, |
285 sprintf(buf, "%s%s;%s%s%s", Arguments::get_java_home(), EXT_DIR, |
282 } |
288 } |
283 #undef EXT_DIR |
289 #undef EXT_DIR |
284 #undef BIN_DIR |
290 #undef BIN_DIR |
285 #undef PACKAGE_DIR |
291 #undef PACKAGE_DIR |
286 |
292 |
287 /* Default endorsed standards directory. */ |
293 // Default endorsed standards directory. |
288 { |
294 { |
289 #define ENDORSED_DIR "\\lib\\endorsed" |
295 #define ENDORSED_DIR "\\lib\\endorsed" |
290 size_t len = strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR); |
296 size_t len = strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR); |
291 char * buf = NEW_C_HEAP_ARRAY(char, len, mtInternal); |
297 char * buf = NEW_C_HEAP_ARRAY(char, len, mtInternal); |
292 sprintf(buf, "%s%s", Arguments::get_java_home(), ENDORSED_DIR); |
298 sprintf(buf, "%s%s", Arguments::get_java_home(), ENDORSED_DIR); |
293 Arguments::set_endorsed_dirs(buf); |
299 Arguments::set_endorsed_dirs(buf); |
294 #undef ENDORSED_DIR |
300 #undef ENDORSED_DIR |
295 } |
301 } |
296 |
302 |
297 #ifndef _WIN64 |
303 #ifndef _WIN64 |
298 // set our UnhandledExceptionFilter and save any previous one |
304 // set our UnhandledExceptionFilter and save any previous one |
299 prev_uef_handler = SetUnhandledExceptionFilter(Handle_FLT_Exception); |
305 prev_uef_handler = SetUnhandledExceptionFilter(Handle_FLT_Exception); |
310 // Invoked from the BREAKPOINT Macro |
316 // Invoked from the BREAKPOINT Macro |
311 extern "C" void breakpoint() { |
317 extern "C" void breakpoint() { |
312 os::breakpoint(); |
318 os::breakpoint(); |
313 } |
319 } |
314 |
320 |
315 /* |
321 // RtlCaptureStackBackTrace Windows API may not exist prior to Windows XP. |
316 * RtlCaptureStackBackTrace Windows API may not exist prior to Windows XP. |
322 // So far, this method is only used by Native Memory Tracking, which is |
317 * So far, this method is only used by Native Memory Tracking, which is |
323 // only supported on Windows XP or later. |
318 * only supported on Windows XP or later. |
324 // |
319 */ |
|
320 int os::get_native_stack(address* stack, int frames, int toSkip) { |
325 int os::get_native_stack(address* stack, int frames, int toSkip) { |
321 #ifdef _NMT_NOINLINE_ |
326 #ifdef _NMT_NOINLINE_ |
322 toSkip ++; |
327 toSkip++; |
323 #endif |
328 #endif |
324 int captured = Kernel32Dll::RtlCaptureStackBackTrace(toSkip + 1, frames, |
329 int captured = Kernel32Dll::RtlCaptureStackBackTrace(toSkip + 1, frames, |
325 (PVOID*)stack, NULL); |
330 (PVOID*)stack, NULL); |
326 for (int index = captured; index < frames; index ++) { |
331 for (int index = captured; index < frames; index ++) { |
327 stack[index] = NULL; |
332 stack[index] = NULL; |
345 stack_bottom = (address)minfo.AllocationBase; |
350 stack_bottom = (address)minfo.AllocationBase; |
346 stack_size = minfo.RegionSize; |
351 stack_size = minfo.RegionSize; |
347 |
352 |
348 // Add up the sizes of all the regions with the same |
353 // Add up the sizes of all the regions with the same |
349 // AllocationBase. |
354 // AllocationBase. |
350 while (1) |
355 while (1) { |
351 { |
|
352 VirtualQuery(stack_bottom+stack_size, &minfo, sizeof(minfo)); |
356 VirtualQuery(stack_bottom+stack_size, &minfo, sizeof(minfo)); |
353 if (stack_bottom == (address)minfo.AllocationBase) |
357 if (stack_bottom == (address)minfo.AllocationBase) { |
354 stack_size += minfo.RegionSize; |
358 stack_size += minfo.RegionSize; |
355 else |
359 } else { |
356 break; |
360 break; |
361 } |
|
357 } |
362 } |
358 |
363 |
359 #ifdef _M_IA64 |
364 #ifdef _M_IA64 |
360 // IA64 has memory and register stacks |
365 // IA64 has memory and register stacks |
361 // |
366 // |
464 } |
469 } |
465 |
470 |
466 return 0; |
471 return 0; |
467 } |
472 } |
468 |
473 |
469 static OSThread* create_os_thread(Thread* thread, HANDLE thread_handle, int thread_id) { |
474 static OSThread* create_os_thread(Thread* thread, HANDLE thread_handle, |
475 int thread_id) { |
|
470 // Allocate the OSThread object |
476 // Allocate the OSThread object |
471 OSThread* osthread = new OSThread(NULL, NULL); |
477 OSThread* osthread = new OSThread(NULL, NULL); |
472 if (osthread == NULL) return NULL; |
478 if (osthread == NULL) return NULL; |
473 |
479 |
474 // Initialize support for Java interrupts |
480 // Initialize support for Java interrupts |
536 thread->set_osthread(_starting_thread); |
542 thread->set_osthread(_starting_thread); |
537 return true; |
543 return true; |
538 } |
544 } |
539 |
545 |
540 // Allocate and initialize a new OSThread |
546 // Allocate and initialize a new OSThread |
541 bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { |
547 bool os::create_thread(Thread* thread, ThreadType thr_type, |
548 size_t stack_size) { |
|
542 unsigned thread_id; |
549 unsigned thread_id; |
543 |
550 |
544 // Allocate the OSThread object |
551 // Allocate the OSThread object |
545 OSThread* osthread = new OSThread(NULL, NULL); |
552 OSThread* osthread = new OSThread(NULL, NULL); |
546 if (osthread == NULL) { |
553 if (osthread == NULL) { |
560 |
567 |
561 if (stack_size == 0) { |
568 if (stack_size == 0) { |
562 switch (thr_type) { |
569 switch (thr_type) { |
563 case os::java_thread: |
570 case os::java_thread: |
564 // Java threads use ThreadStackSize which default value can be changed with the flag -Xss |
571 // Java threads use ThreadStackSize which default value can be changed with the flag -Xss |
565 if (JavaThread::stack_size_at_create() > 0) |
572 if (JavaThread::stack_size_at_create() > 0) { |
566 stack_size = JavaThread::stack_size_at_create(); |
573 stack_size = JavaThread::stack_size_at_create(); |
574 } |
|
567 break; |
575 break; |
568 case os::compiler_thread: |
576 case os::compiler_thread: |
569 if (CompilerThreadStackSize > 0) { |
577 if (CompilerThreadStackSize > 0) { |
570 stack_size = (size_t)(CompilerThreadStackSize * K); |
578 stack_size = (size_t)(CompilerThreadStackSize * K); |
571 break; |
579 break; |
600 // are not supposed to call CreateThread() directly according to MSDN |
608 // are not supposed to call CreateThread() directly according to MSDN |
601 // document because JVM uses C runtime library. The good news is that the |
609 // document because JVM uses C runtime library. The good news is that the |
602 // flag appears to work with _beginthredex() as well. |
610 // flag appears to work with _beginthredex() as well. |
603 |
611 |
604 #ifndef STACK_SIZE_PARAM_IS_A_RESERVATION |
612 #ifndef STACK_SIZE_PARAM_IS_A_RESERVATION |
605 #define STACK_SIZE_PARAM_IS_A_RESERVATION (0x10000) |
613 #define STACK_SIZE_PARAM_IS_A_RESERVATION (0x10000) |
606 #endif |
614 #endif |
607 |
615 |
608 HANDLE thread_handle = |
616 HANDLE thread_handle = |
609 (HANDLE)_beginthreadex(NULL, |
617 (HANDLE)_beginthreadex(NULL, |
610 (unsigned)stack_size, |
618 (unsigned)stack_size, |
939 return false; |
947 return false; |
940 } |
948 } |
941 } |
949 } |
942 |
950 |
943 void os::shutdown() { |
951 void os::shutdown() { |
944 |
|
945 // allow PerfMemory to attempt cleanup of any persistent resources |
952 // allow PerfMemory to attempt cleanup of any persistent resources |
946 perfMemory_exit(); |
953 perfMemory_exit(); |
947 |
954 |
948 // flush buffered output, finish log files |
955 // flush buffered output, finish log files |
949 ostream_abort(); |
956 ostream_abort(); |
954 abort_hook(); |
961 abort_hook(); |
955 } |
962 } |
956 } |
963 } |
957 |
964 |
958 |
965 |
959 static BOOL (WINAPI *_MiniDumpWriteDump) ( HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION, |
966 static BOOL (WINAPI *_MiniDumpWriteDump)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, |
960 PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION); |
967 PMINIDUMP_EXCEPTION_INFORMATION, |
968 PMINIDUMP_USER_STREAM_INFORMATION, |
|
969 PMINIDUMP_CALLBACK_INFORMATION); |
|
961 |
970 |
962 void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) { |
971 void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) { |
963 HINSTANCE dbghelp; |
972 HINSTANCE dbghelp; |
964 EXCEPTION_POINTERS ep; |
973 EXCEPTION_POINTERS ep; |
965 MINIDUMP_EXCEPTION_INFORMATION mei; |
974 MINIDUMP_EXCEPTION_INFORMATION mei; |
994 if (dbghelp == NULL) { |
1003 if (dbghelp == NULL) { |
995 VMError::report_coredump_status("Failed to load dbghelp.dll", false); |
1004 VMError::report_coredump_status("Failed to load dbghelp.dll", false); |
996 return; |
1005 return; |
997 } |
1006 } |
998 |
1007 |
999 _MiniDumpWriteDump = CAST_TO_FN_PTR( |
1008 _MiniDumpWriteDump = |
1000 BOOL(WINAPI *)( HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION, |
1009 CAST_TO_FN_PTR(BOOL(WINAPI *)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, |
1001 PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION), |
1010 PMINIDUMP_EXCEPTION_INFORMATION, |
1002 GetProcAddress(dbghelp, "MiniDumpWriteDump")); |
1011 PMINIDUMP_USER_STREAM_INFORMATION, |
1012 PMINIDUMP_CALLBACK_INFORMATION), |
|
1013 GetProcAddress(dbghelp, |
|
1014 "MiniDumpWriteDump")); |
|
1003 |
1015 |
1004 if (_MiniDumpWriteDump == NULL) { |
1016 if (_MiniDumpWriteDump == NULL) { |
1005 VMError::report_coredump_status("Failed to find MiniDumpWriteDump() in module dbghelp.dll", false); |
1017 VMError::report_coredump_status("Failed to find MiniDumpWriteDump() in module dbghelp.dll", false); |
1006 return; |
1018 return; |
1007 } |
1019 } |
1061 CloseHandle(dumpFile); |
1073 CloseHandle(dumpFile); |
1062 } |
1074 } |
1063 |
1075 |
1064 |
1076 |
1065 |
1077 |
1066 void os::abort(bool dump_core) |
1078 void os::abort(bool dump_core) { |
1067 { |
|
1068 os::shutdown(); |
1079 os::shutdown(); |
1069 // no core dump on Windows |
1080 // no core dump on Windows |
1070 ::exit(1); |
1081 ::exit(1); |
1071 } |
1082 } |
1072 |
1083 |
1078 // Directory routines copied from src/win32/native/java/io/dirent_md.c |
1089 // Directory routines copied from src/win32/native/java/io/dirent_md.c |
1079 // * dirent_md.c 1.15 00/02/02 |
1090 // * dirent_md.c 1.15 00/02/02 |
1080 // |
1091 // |
1081 // The declarations for DIR and struct dirent are in jvm_win32.h. |
1092 // The declarations for DIR and struct dirent are in jvm_win32.h. |
1082 |
1093 |
1083 /* Caller must have already run dirname through JVM_NativePath, which removes |
1094 // Caller must have already run dirname through JVM_NativePath, which removes |
1084 duplicate slashes and converts all instances of '/' into '\\'. */ |
1095 // duplicate slashes and converts all instances of '/' into '\\'. |
1085 |
1096 |
1086 DIR * |
1097 DIR * os::opendir(const char *dirname) { |
1087 os::opendir(const char *dirname) |
|
1088 { |
|
1089 assert(dirname != NULL, "just checking"); // hotspot change |
1098 assert(dirname != NULL, "just checking"); // hotspot change |
1090 DIR *dirp = (DIR *)malloc(sizeof(DIR), mtInternal); |
1099 DIR *dirp = (DIR *)malloc(sizeof(DIR), mtInternal); |
1091 DWORD fattr; // hotspot change |
1100 DWORD fattr; // hotspot change |
1092 char alt_dirname[4] = { 0, 0, 0, 0 }; |
1101 char alt_dirname[4] = { 0, 0, 0, 0 }; |
1093 |
1102 |
1094 if (dirp == 0) { |
1103 if (dirp == 0) { |
1095 errno = ENOMEM; |
1104 errno = ENOMEM; |
1096 return 0; |
1105 return 0; |
1097 } |
1106 } |
1098 |
1107 |
1099 /* |
1108 // Win32 accepts "\" in its POSIX stat(), but refuses to treat it |
1100 * Win32 accepts "\" in its POSIX stat(), but refuses to treat it |
1109 // as a directory in FindFirstFile(). We detect this case here and |
1101 * as a directory in FindFirstFile(). We detect this case here and |
1110 // prepend the current drive name. |
1102 * prepend the current drive name. |
1111 // |
1103 */ |
|
1104 if (dirname[1] == '\0' && dirname[0] == '\\') { |
1112 if (dirname[1] == '\0' && dirname[0] == '\\') { |
1105 alt_dirname[0] = _getdrive() + 'A' - 1; |
1113 alt_dirname[0] = _getdrive() + 'A' - 1; |
1106 alt_dirname[1] = ':'; |
1114 alt_dirname[1] = ':'; |
1107 alt_dirname[2] = '\\'; |
1115 alt_dirname[2] = '\\'; |
1108 alt_dirname[3] = '\0'; |
1116 alt_dirname[3] = '\0'; |
1128 free(dirp, mtInternal); |
1136 free(dirp, mtInternal); |
1129 errno = ENOTDIR; |
1137 errno = ENOTDIR; |
1130 return 0; |
1138 return 0; |
1131 } |
1139 } |
1132 |
1140 |
1133 /* Append "*.*", or possibly "\\*.*", to path */ |
1141 // Append "*.*", or possibly "\\*.*", to path |
1134 if (dirp->path[1] == ':' |
1142 if (dirp->path[1] == ':' && |
1135 && (dirp->path[2] == '\0' |
1143 (dirp->path[2] == '\0' || |
1136 || (dirp->path[2] == '\\' && dirp->path[3] == '\0'))) { |
1144 (dirp->path[2] == '\\' && dirp->path[3] == '\0'))) { |
1137 /* No '\\' needed for cases like "Z:" or "Z:\" */ |
1145 // No '\\' needed for cases like "Z:" or "Z:\" |
1138 strcat(dirp->path, "*.*"); |
1146 strcat(dirp->path, "*.*"); |
1139 } else { |
1147 } else { |
1140 strcat(dirp->path, "\\*.*"); |
1148 strcat(dirp->path, "\\*.*"); |
1141 } |
1149 } |
1142 |
1150 |
1150 } |
1158 } |
1151 } |
1159 } |
1152 return dirp; |
1160 return dirp; |
1153 } |
1161 } |
1154 |
1162 |
1155 /* parameter dbuf unused on Windows */ |
1163 // parameter dbuf unused on Windows |
1156 |
1164 struct dirent * os::readdir(DIR *dirp, dirent *dbuf) { |
1157 struct dirent * |
|
1158 os::readdir(DIR *dirp, dirent *dbuf) |
|
1159 { |
|
1160 assert(dirp != NULL, "just checking"); // hotspot change |
1165 assert(dirp != NULL, "just checking"); // hotspot change |
1161 if (dirp->handle == INVALID_HANDLE_VALUE) { |
1166 if (dirp->handle == INVALID_HANDLE_VALUE) { |
1162 return 0; |
1167 return 0; |
1163 } |
1168 } |
1164 |
1169 |
1174 } |
1179 } |
1175 |
1180 |
1176 return &dirp->dirent; |
1181 return &dirp->dirent; |
1177 } |
1182 } |
1178 |
1183 |
1179 int |
1184 int os::closedir(DIR *dirp) { |
1180 os::closedir(DIR *dirp) |
|
1181 { |
|
1182 assert(dirp != NULL, "just checking"); // hotspot change |
1185 assert(dirp != NULL, "just checking"); // hotspot change |
1183 if (dirp->handle != INVALID_HANDLE_VALUE) { |
1186 if (dirp->handle != INVALID_HANDLE_VALUE) { |
1184 if (!FindClose(dirp->handle)) { |
1187 if (!FindClose(dirp->handle)) { |
1185 errno = EBADF; |
1188 errno = EBADF; |
1186 return -1; |
1189 return -1; |
1194 |
1197 |
1195 // This must be hard coded because it's the system's temporary |
1198 // 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. |
1199 // directory not the java application's temp directory, ala java.io.tmpdir. |
1197 const char* os::get_temp_directory() { |
1200 const char* os::get_temp_directory() { |
1198 static char path_buf[MAX_PATH]; |
1201 static char path_buf[MAX_PATH]; |
1199 if (GetTempPath(MAX_PATH, path_buf)>0) |
1202 if (GetTempPath(MAX_PATH, path_buf) > 0) { |
1200 return path_buf; |
1203 return path_buf; |
1201 else{ |
1204 } else { |
1202 path_buf[0]='\0'; |
1205 path_buf[0] = '\0'; |
1203 return path_buf; |
1206 return path_buf; |
1204 } |
1207 } |
1205 } |
1208 } |
1206 |
1209 |
1207 static bool file_exists(const char* filename) { |
1210 static bool file_exists(const char* filename) { |
1280 // Helper functions for fatal error handler |
1283 // Helper functions for fatal error handler |
1281 #ifdef _WIN64 |
1284 #ifdef _WIN64 |
1282 // Helper routine which returns true if address in |
1285 // Helper routine which returns true if address in |
1283 // within the NTDLL address space. |
1286 // within the NTDLL address space. |
1284 // |
1287 // |
1285 static bool _addr_in_ntdll( address addr ) |
1288 static bool _addr_in_ntdll(address addr) { |
1286 { |
|
1287 HMODULE hmod; |
1289 HMODULE hmod; |
1288 MODULEINFO minfo; |
1290 MODULEINFO minfo; |
1289 |
1291 |
1290 hmod = GetModuleHandle("NTDLL.DLL"); |
1292 hmod = GetModuleHandle("NTDLL.DLL"); |
1291 if (hmod == NULL) return false; |
1293 if (hmod == NULL) return false; |
1292 if (!os::PSApiDll::GetModuleInformation( GetCurrentProcess(), hmod, |
1294 if (!os::PSApiDll::GetModuleInformation(GetCurrentProcess(), hmod, |
1293 &minfo, sizeof(MODULEINFO)) ) |
1295 &minfo, sizeof(MODULEINFO))) { |
1294 return false; |
1296 return false; |
1297 } |
|
1295 |
1298 |
1296 if ((addr >= minfo.lpBaseOfDll) && |
1299 if ((addr >= minfo.lpBaseOfDll) && |
1297 (addr < (address)((uintptr_t)minfo.lpBaseOfDll + (uintptr_t)minfo.SizeOfImage))) |
1300 (addr < (address)((uintptr_t)minfo.lpBaseOfDll + (uintptr_t)minfo.SizeOfImage))) { |
1298 return true; |
1301 return true; |
1299 else |
1302 } else { |
1300 return false; |
1303 return false; |
1304 } |
|
1301 } |
1305 } |
1302 #endif |
1306 #endif |
1303 |
1307 |
1304 |
1308 |
1305 // Enumerate all modules for a given process ID |
1309 // Enumerate all modules for a given process ID |
1317 // unsigned module_size, |
1321 // unsigned module_size, |
1318 // void* param |
1322 // void* param |
1319 typedef int (*EnumModulesCallbackFunc)(int, char *, address, unsigned, void *); |
1323 typedef int (*EnumModulesCallbackFunc)(int, char *, address, unsigned, void *); |
1320 |
1324 |
1321 // enumerate_modules for Windows NT, using PSAPI |
1325 // enumerate_modules for Windows NT, using PSAPI |
1322 static int _enumerate_modules_winnt( int pid, EnumModulesCallbackFunc func, void * param) |
1326 static int _enumerate_modules_winnt(int pid, EnumModulesCallbackFunc func, |
1323 { |
1327 void * param) { |
1324 HANDLE hProcess; |
1328 HANDLE hProcess; |
1325 |
1329 |
1326 # define MAX_NUM_MODULES 128 |
1330 #define MAX_NUM_MODULES 128 |
1327 HMODULE modules[MAX_NUM_MODULES]; |
1331 HMODULE modules[MAX_NUM_MODULES]; |
1328 static char filename[MAX_PATH]; |
1332 static char filename[MAX_PATH]; |
1329 int result = 0; |
1333 int result = 0; |
1330 |
1334 |
1331 if (!os::PSApiDll::PSApiAvailable()) { |
1335 if (!os::PSApiDll::PSApiAvailable()) { |
1370 return result; |
1374 return result; |
1371 } |
1375 } |
1372 |
1376 |
1373 |
1377 |
1374 // enumerate_modules for Windows 95/98/ME, using TOOLHELP |
1378 // enumerate_modules for Windows 95/98/ME, using TOOLHELP |
1375 static int _enumerate_modules_windows( int pid, EnumModulesCallbackFunc func, void *param) |
1379 static int _enumerate_modules_windows(int pid, EnumModulesCallbackFunc func, |
1376 { |
1380 void *param) { |
1377 HANDLE hSnapShot; |
1381 HANDLE hSnapShot; |
1378 static MODULEENTRY32 modentry; |
1382 static MODULEENTRY32 modentry; |
1379 int result = 0; |
1383 int result = 0; |
1380 |
1384 |
1381 if (!os::Kernel32Dll::HelpToolsAvailable()) { |
1385 if (!os::Kernel32Dll::HelpToolsAvailable()) { |
1388 return FALSE; |
1392 return FALSE; |
1389 } |
1393 } |
1390 |
1394 |
1391 // iterate through all modules |
1395 // iterate through all modules |
1392 modentry.dwSize = sizeof(MODULEENTRY32); |
1396 modentry.dwSize = sizeof(MODULEENTRY32); |
1393 bool not_done = os::Kernel32Dll::Module32First( hSnapShot, &modentry ) != 0; |
1397 bool not_done = os::Kernel32Dll::Module32First(hSnapShot, &modentry) != 0; |
1394 |
1398 |
1395 while (not_done) { |
1399 while (not_done) { |
1396 // invoke the callback |
1400 // invoke the callback |
1397 result=func(pid, modentry.szExePath, (address)modentry.modBaseAddr, |
1401 result=func(pid, modentry.szExePath, (address)modentry.modBaseAddr, |
1398 modentry.modBaseSize, param); |
1402 modentry.modBaseSize, param); |
1399 if (result) break; |
1403 if (result) break; |
1400 |
1404 |
1401 modentry.dwSize = sizeof(MODULEENTRY32); |
1405 modentry.dwSize = sizeof(MODULEENTRY32); |
1402 not_done = os::Kernel32Dll::Module32Next( hSnapShot, &modentry ) != 0; |
1406 not_done = os::Kernel32Dll::Module32Next(hSnapShot, &modentry) != 0; |
1403 } |
1407 } |
1404 |
1408 |
1405 CloseHandle(hSnapShot); |
1409 CloseHandle(hSnapShot); |
1406 return result; |
1410 return result; |
1407 } |
1411 } |
1408 |
1412 |
1409 int enumerate_modules( int pid, EnumModulesCallbackFunc func, void * param ) |
1413 int enumerate_modules(int pid, EnumModulesCallbackFunc func, void * param) { |
1410 { |
|
1411 // Get current process ID if caller doesn't provide it. |
1414 // Get current process ID if caller doesn't provide it. |
1412 if (!pid) pid = os::current_process_id(); |
1415 if (!pid) pid = os::current_process_id(); |
1413 |
1416 |
1414 if (os::win32::is_nt()) return _enumerate_modules_winnt (pid, func, param); |
1417 if (os::win32::is_nt()) { |
1415 else return _enumerate_modules_windows(pid, func, param); |
1418 return _enumerate_modules_winnt (pid, func, param); |
1419 } else { |
|
1420 return _enumerate_modules_windows(pid, func, param); |
|
1421 } |
|
1416 } |
1422 } |
1417 |
1423 |
1418 struct _modinfo { |
1424 struct _modinfo { |
1419 address addr; |
1425 address addr; |
1420 char* full_path; // point to a char buffer |
1426 char* full_path; // point to a char buffer |
1520 } |
1526 } |
1521 |
1527 |
1522 // Loads .dll/.so and |
1528 // Loads .dll/.so and |
1523 // in case of error it checks if .dll/.so was built for the |
1529 // in case of error it checks if .dll/.so was built for the |
1524 // same architecture as Hotspot is running on |
1530 // same architecture as Hotspot is running on |
1525 void * os::dll_load(const char *name, char *ebuf, int ebuflen) |
1531 void * os::dll_load(const char *name, char *ebuf, int ebuflen) { |
1526 { |
|
1527 void * result = LoadLibrary(name); |
1532 void * result = LoadLibrary(name); |
1528 if (result != NULL) |
1533 if (result != NULL) { |
1529 { |
|
1530 return result; |
1534 return result; |
1531 } |
1535 } |
1532 |
1536 |
1533 DWORD errcode = GetLastError(); |
1537 DWORD errcode = GetLastError(); |
1534 if (errcode == ERROR_MOD_NOT_FOUND) { |
1538 if (errcode == ERROR_MOD_NOT_FOUND) { |
1535 strncpy(ebuf, "Can't find dependent libraries", ebuflen-1); |
1539 strncpy(ebuf, "Can't find dependent libraries", ebuflen - 1); |
1536 ebuf[ebuflen-1]='\0'; |
1540 ebuf[ebuflen - 1] = '\0'; |
1537 return NULL; |
1541 return NULL; |
1538 } |
1542 } |
1539 |
1543 |
1540 // Parsing dll below |
1544 // Parsing dll below |
1541 // If we can read dll-info and find that dll was built |
1545 // If we can read dll-info and find that dll was built |
1544 // else call os::lasterror to obtain system error message |
1548 // else call os::lasterror to obtain system error message |
1545 |
1549 |
1546 // Read system error message into ebuf |
1550 // Read system error message into ebuf |
1547 // It may or may not be overwritten below (in the for loop and just above) |
1551 // It may or may not be overwritten below (in the for loop and just above) |
1548 lasterror(ebuf, (size_t) ebuflen); |
1552 lasterror(ebuf, (size_t) ebuflen); |
1549 ebuf[ebuflen-1]='\0'; |
1553 ebuf[ebuflen - 1] = '\0'; |
1550 int file_descriptor=::open(name, O_RDONLY | O_BINARY, 0); |
1554 int fd = ::open(name, O_RDONLY | O_BINARY, 0); |
1551 if (file_descriptor<0) |
1555 if (fd < 0) { |
1552 { |
|
1553 return NULL; |
1556 return NULL; |
1554 } |
1557 } |
1555 |
1558 |
1556 uint32_t signature_offset; |
1559 uint32_t signature_offset; |
1557 uint16_t lib_arch=0; |
1560 uint16_t lib_arch = 0; |
1558 bool failed_to_get_lib_arch= |
1561 bool failed_to_get_lib_arch = |
1559 ( |
1562 ( // Go to position 3c in the dll |
1560 //Go to position 3c in the dll |
1563 (os::seek_to_file_offset(fd, IMAGE_FILE_PTR_TO_SIGNATURE) < 0) |
1561 (os::seek_to_file_offset(file_descriptor,IMAGE_FILE_PTR_TO_SIGNATURE)<0) |
|
1562 || |
1564 || |
1563 // Read loacation of signature |
1565 // Read location of signature |
1564 (sizeof(signature_offset)!= |
1566 (sizeof(signature_offset) != |
1565 (os::read(file_descriptor, (void*)&signature_offset,sizeof(signature_offset)))) |
1567 (os::read(fd, (void*)&signature_offset, sizeof(signature_offset)))) |
1566 || |
1568 || |
1567 //Go to COFF File Header in dll |
1569 // Go to COFF File Header in dll |
1568 //that is located after"signature" (4 bytes long) |
1570 // that is located after "signature" (4 bytes long) |
1569 (os::seek_to_file_offset(file_descriptor, |
1571 (os::seek_to_file_offset(fd, |
1570 signature_offset+IMAGE_FILE_SIGNATURE_LENGTH)<0) |
1572 signature_offset + IMAGE_FILE_SIGNATURE_LENGTH) < 0) |
1571 || |
1573 || |
1572 //Read field that contains code of architecture |
1574 // Read field that contains code of architecture |
1573 // that dll was build for |
1575 // that dll was built for |
1574 (sizeof(lib_arch)!= |
1576 (sizeof(lib_arch) != (os::read(fd, (void*)&lib_arch, sizeof(lib_arch)))) |
1575 (os::read(file_descriptor, (void*)&lib_arch,sizeof(lib_arch)))) |
|
1576 ); |
1577 ); |
1577 |
1578 |
1578 ::close(file_descriptor); |
1579 ::close(fd); |
1579 if (failed_to_get_lib_arch) |
1580 if (failed_to_get_lib_arch) { |
1580 { |
|
1581 // file i/o error - report os::lasterror(...) msg |
1581 // file i/o error - report os::lasterror(...) msg |
1582 return NULL; |
1582 return NULL; |
1583 } |
1583 } |
1584 |
1584 |
1585 typedef struct |
1585 typedef struct { |
1586 { |
|
1587 uint16_t arch_code; |
1586 uint16_t arch_code; |
1588 char* arch_name; |
1587 char* arch_name; |
1589 } arch_t; |
1588 } arch_t; |
1590 |
1589 |
1591 static const arch_t arch_array[]={ |
1590 static const arch_t arch_array[] = { |
1592 {IMAGE_FILE_MACHINE_I386, (char*)"IA 32"}, |
1591 {IMAGE_FILE_MACHINE_I386, (char*)"IA 32"}, |
1593 {IMAGE_FILE_MACHINE_AMD64, (char*)"AMD 64"}, |
1592 {IMAGE_FILE_MACHINE_AMD64, (char*)"AMD 64"}, |
1594 {IMAGE_FILE_MACHINE_IA64, (char*)"IA 64"} |
1593 {IMAGE_FILE_MACHINE_IA64, (char*)"IA 64"} |
1595 }; |
1594 }; |
1596 #if (defined _M_IA64) |
1595 #if (defined _M_IA64) |
1597 static const uint16_t running_arch=IMAGE_FILE_MACHINE_IA64; |
1596 static const uint16_t running_arch = IMAGE_FILE_MACHINE_IA64; |
1598 #elif (defined _M_AMD64) |
1597 #elif (defined _M_AMD64) |
1599 static const uint16_t running_arch=IMAGE_FILE_MACHINE_AMD64; |
1598 static const uint16_t running_arch = IMAGE_FILE_MACHINE_AMD64; |
1600 #elif (defined _M_IX86) |
1599 #elif (defined _M_IX86) |
1601 static const uint16_t running_arch=IMAGE_FILE_MACHINE_I386; |
1600 static const uint16_t running_arch = IMAGE_FILE_MACHINE_I386; |
1602 #else |
1601 #else |
1603 #error Method os::dll_load requires that one of following \ |
1602 #error Method os::dll_load requires that one of following \ |
1604 is defined :_M_IA64,_M_AMD64 or _M_IX86 |
1603 is defined :_M_IA64,_M_AMD64 or _M_IX86 |
1605 #endif |
1604 #endif |
1606 |
1605 |
1607 |
1606 |
1608 // Obtain a string for printf operation |
1607 // Obtain a string for printf operation |
1609 // lib_arch_str shall contain string what platform this .dll was built for |
1608 // lib_arch_str shall contain string what platform this .dll was built for |
1610 // running_arch_str shall string contain what platform Hotspot was built for |
1609 // running_arch_str shall string contain what platform Hotspot was built for |
1611 char *running_arch_str=NULL,*lib_arch_str=NULL; |
1610 char *running_arch_str = NULL, *lib_arch_str = NULL; |
1612 for (unsigned int i=0;i<ARRAY_SIZE(arch_array);i++) |
1611 for (unsigned int i = 0; i < ARRAY_SIZE(arch_array); i++) { |
1613 { |
1612 if (lib_arch == arch_array[i].arch_code) { |
1614 if (lib_arch==arch_array[i].arch_code) |
1613 lib_arch_str = arch_array[i].arch_name; |
1615 lib_arch_str=arch_array[i].arch_name; |
1614 } |
1616 if (running_arch==arch_array[i].arch_code) |
1615 if (running_arch == arch_array[i].arch_code) { |
1617 running_arch_str=arch_array[i].arch_name; |
1616 running_arch_str = arch_array[i].arch_name; |
1617 } |
|
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 running architecture code in arch_array"); |
1622 |
1622 |
1623 // If the architure is right |
1623 // If the architecture 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 { |
|
1627 return NULL; |
1626 return NULL; |
1628 } |
1627 } |
1629 |
1628 |
1630 if (lib_arch_str!=NULL) |
1629 if (lib_arch_str != NULL) { |
1631 { |
1630 ::_snprintf(ebuf, ebuflen - 1, |
1632 ::_snprintf(ebuf, ebuflen-1, |
|
1633 "Can't load %s-bit .dll on a %s-bit platform", |
1631 "Can't load %s-bit .dll on a %s-bit platform", |
1634 lib_arch_str,running_arch_str); |
1632 lib_arch_str, running_arch_str); |
1635 } |
1633 } else { |
1636 else |
|
1637 { |
|
1638 // don't know what architecture this dll was build for |
1634 // don't know what architecture this dll was build for |
1639 ::_snprintf(ebuf, ebuflen-1, |
1635 ::_snprintf(ebuf, ebuflen - 1, |
1640 "Can't load this .dll (machine code=0x%x) on a %s-bit platform", |
1636 "Can't load this .dll (machine code=0x%x) on a %s-bit platform", |
1641 lib_arch,running_arch_str); |
1637 lib_arch, running_arch_str); |
1642 } |
1638 } |
1643 |
1639 |
1644 return NULL; |
1640 return NULL; |
1645 } |
1641 } |
1646 |
1642 |
1839 // looks like jvm.dll is installed there (append a fake suffix |
1835 // looks like jvm.dll is installed there (append a fake suffix |
1840 // hotspot/jvm.dll). |
1836 // hotspot/jvm.dll). |
1841 char* java_home_var = ::getenv("JAVA_HOME"); |
1837 char* java_home_var = ::getenv("JAVA_HOME"); |
1842 if (java_home_var != NULL && java_home_var[0] != 0 && |
1838 if (java_home_var != NULL && java_home_var[0] != 0 && |
1843 strlen(java_home_var) < (size_t)buflen) { |
1839 strlen(java_home_var) < (size_t)buflen) { |
1844 |
|
1845 strncpy(buf, java_home_var, buflen); |
1840 strncpy(buf, java_home_var, buflen); |
1846 |
1841 |
1847 // determine if this is a legacy image or modules image |
1842 // determine if this is a legacy image or modules image |
1848 // modules image doesn't have "jre" subdirectory |
1843 // modules image doesn't have "jre" subdirectory |
1849 size_t len = strlen(buf); |
1844 size_t len = strlen(buf); |
1916 return 0; |
1911 return 0; |
1917 } |
1912 } |
1918 |
1913 |
1919 int os::get_last_error() { |
1914 int os::get_last_error() { |
1920 DWORD error = GetLastError(); |
1915 DWORD error = GetLastError(); |
1921 if (error == 0) |
1916 if (error == 0) { |
1922 error = errno; |
1917 error = errno; |
1918 } |
|
1923 return (int)error; |
1919 return (int)error; |
1924 } |
1920 } |
1925 |
1921 |
1926 // sun.misc.Signal |
1922 // sun.misc.Signal |
1927 // NOTE that this is a workaround for an apparent kernel bug where if |
1923 // NOTE that this is a workaround for an apparent kernel bug where if |
2001 break; |
1997 break; |
2002 } |
1998 } |
2003 return FALSE; |
1999 return FALSE; |
2004 } |
2000 } |
2005 |
2001 |
2006 /* |
2002 // The following code is moved from os.cpp for making this |
2007 * The following code is moved from os.cpp for making this |
2003 // code platform specific, which it is by its very nature. |
2008 * code platform specific, which it is by its very nature. |
|
2009 */ |
|
2010 |
2004 |
2011 // Return maximum OS signal used + 1 for internal use only |
2005 // Return maximum OS signal used + 1 for internal use only |
2012 // Used as exit signal for signal_thread |
2006 // Used as exit signal for signal_thread |
2013 int os::sigexitnum_pd() { |
2007 int os::sigexitnum_pd() { |
2014 return NSIG; |
2008 return NSIG; |
2078 assert(ret == WAIT_OBJECT_0, "WaitForSingleObject() failed"); |
2072 assert(ret == WAIT_OBJECT_0, "WaitForSingleObject() failed"); |
2079 |
2073 |
2080 // were we externally suspended while we were waiting? |
2074 // were we externally suspended while we were waiting? |
2081 threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); |
2075 threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); |
2082 if (threadIsSuspended) { |
2076 if (threadIsSuspended) { |
2083 // |
|
2084 // The semaphore has been incremented, but while we were waiting |
2077 // The semaphore has been incremented, but while we were waiting |
2085 // another thread suspended us. We don't want to continue running |
2078 // another thread suspended us. We don't want to continue running |
2086 // while suspended because that would surprise the thread that |
2079 // while suspended because that would surprise the thread that |
2087 // suspended us. |
2080 // suspended us. |
2088 // |
|
2089 ret = ::ReleaseSemaphore(sig_sem, 1, NULL); |
2081 ret = ::ReleaseSemaphore(sig_sem, 1, NULL); |
2090 assert(ret != 0, "ReleaseSemaphore() failed"); |
2082 assert(ret != 0, "ReleaseSemaphore() failed"); |
2091 |
2083 |
2092 thread->java_suspend_self(); |
2084 thread->java_suspend_self(); |
2093 } |
2085 } |
2103 return check_pending_signals(true); |
2095 return check_pending_signals(true); |
2104 } |
2096 } |
2105 |
2097 |
2106 // Implicit OS exception handling |
2098 // Implicit OS exception handling |
2107 |
2099 |
2108 LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler) { |
2100 LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, |
2101 address handler) { |
|
2109 JavaThread* thread = JavaThread::current(); |
2102 JavaThread* thread = JavaThread::current(); |
2110 // Save pc in thread |
2103 // Save pc in thread |
2111 #ifdef _M_IA64 |
2104 #ifdef _M_IA64 |
2112 // Do not blow up if no thread info available. |
2105 // Do not blow up if no thread info available. |
2113 if (thread) { |
2106 if (thread) { |
2161 // included or copied here. |
2154 // included or copied here. |
2162 #define EXCEPTION_INFO_EXEC_VIOLATION 0x08 |
2155 #define EXCEPTION_INFO_EXEC_VIOLATION 0x08 |
2163 |
2156 |
2164 // Handle NAT Bit consumption on IA64. |
2157 // Handle NAT Bit consumption on IA64. |
2165 #ifdef _M_IA64 |
2158 #ifdef _M_IA64 |
2166 #define EXCEPTION_REG_NAT_CONSUMPTION STATUS_REG_NAT_CONSUMPTION |
2159 #define EXCEPTION_REG_NAT_CONSUMPTION STATUS_REG_NAT_CONSUMPTION |
2167 #endif |
2160 #endif |
2168 |
2161 |
2169 // Windows Vista/2008 heap corruption check |
2162 // Windows Vista/2008 heap corruption check |
2170 #define EXCEPTION_HEAP_CORRUPTION 0xC0000374 |
2163 #define EXCEPTION_HEAP_CORRUPTION 0xC0000374 |
2171 |
2164 |
2290 // We didn't handle this exception so pass it to the previous |
2283 // We didn't handle this exception so pass it to the previous |
2291 // UnhandledExceptionFilter. |
2284 // UnhandledExceptionFilter. |
2292 return (prev_uef_handler)(exceptionInfo); |
2285 return (prev_uef_handler)(exceptionInfo); |
2293 } |
2286 } |
2294 #else // !_WIN64 |
2287 #else // !_WIN64 |
2295 /* |
2288 // On Windows, the mxcsr control bits are non-volatile across calls |
2296 On Windows, the mxcsr control bits are non-volatile across calls |
2289 // See also CR 6192333 |
2297 See also CR 6192333 |
2290 // |
2298 */ |
|
2299 jint MxCsr = INITIAL_MXCSR; |
2291 jint MxCsr = INITIAL_MXCSR; |
2300 // we can't use StubRoutines::addr_mxcsr_std() |
2292 // we can't use StubRoutines::addr_mxcsr_std() |
2301 // because in Win64 mxcsr is not saved there |
2293 // because in Win64 mxcsr is not saved there |
2302 if (MxCsr != ctx->MxCsr) { |
2294 if (MxCsr != ctx->MxCsr) { |
2303 ctx->MxCsr = MxCsr; |
2295 ctx->MxCsr = MxCsr; |
2495 // Yellow zone violation. The o/s has unprotected the first yellow |
2487 // Yellow zone violation. The o/s has unprotected the first yellow |
2496 // zone page for us. Note: must call disable_stack_yellow_zone to |
2488 // 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. |
2489 // update the enabled status, even if the zone contains only one page. |
2498 thread->disable_stack_yellow_zone(); |
2490 thread->disable_stack_yellow_zone(); |
2499 // If not in java code, return and hope for the best. |
2491 // If not in java code, return and hope for the best. |
2500 return in_java ? Handle_Exception(exceptionInfo, |
2492 return in_java |
2501 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)) |
2493 ? Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)) |
2502 : EXCEPTION_CONTINUE_EXECUTION; |
2494 : EXCEPTION_CONTINUE_EXECUTION; |
2503 } else { |
2495 } else { |
2504 // Fatal red zone violation. |
2496 // Fatal red zone violation. |
2505 thread->disable_stack_red_zone(); |
2497 thread->disable_stack_red_zone(); |
2506 tty->print_raw_cr("An unrecoverable stack overflow has occurred."); |
2498 tty->print_raw_cr("An unrecoverable stack overflow has occurred."); |
2507 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, |
2499 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, |
2530 assert(!os::uses_stack_guard_pages(), |
2522 assert(!os::uses_stack_guard_pages(), |
2531 "should be caught by red zone code above."); |
2523 "should be caught by red zone code above."); |
2532 return Handle_Exception(exceptionInfo, |
2524 return Handle_Exception(exceptionInfo, |
2533 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)); |
2525 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)); |
2534 } |
2526 } |
2535 // |
|
2536 // Check for safepoint polling and implicit null |
2527 // Check for safepoint polling and implicit null |
2537 // We only expect null pointers in the stubs (vtable) |
2528 // We only expect null pointers in the stubs (vtable) |
2538 // the rest are checked explicitly now. |
2529 // the rest are checked explicitly now. |
2539 // |
|
2540 CodeBlob* cb = CodeCache::find_blob(pc); |
2530 CodeBlob* cb = CodeCache::find_blob(pc); |
2541 if (cb != NULL) { |
2531 if (cb != NULL) { |
2542 if (os::is_poll_address(addr)) { |
2532 if (os::is_poll_address(addr)) { |
2543 address stub = SharedRuntime::get_poll_stub(pc); |
2533 address stub = SharedRuntime::get_poll_stub(pc); |
2544 return Handle_Exception(exceptionInfo, stub); |
2534 return Handle_Exception(exceptionInfo, stub); |
2545 } |
2535 } |
2546 } |
2536 } |
2547 { |
2537 { |
2548 #ifdef _WIN64 |
2538 #ifdef _WIN64 |
2549 // |
|
2550 // If it's a legal stack address map the entire region in |
2539 // If it's a legal stack address map the entire region in |
2551 // |
2540 // |
2552 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; |
2541 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; |
2553 address addr = (address) exceptionRecord->ExceptionInformation[1]; |
2542 address addr = (address) exceptionRecord->ExceptionInformation[1]; |
2554 if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base()) { |
2543 if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base()) { |
2555 addr = (address)((uintptr_t)addr & |
2544 addr = (address)((uintptr_t)addr & |
2556 (~((uintptr_t)os::vm_page_size() - (uintptr_t)1))); |
2545 (~((uintptr_t)os::vm_page_size() - (uintptr_t)1))); |
2557 os::commit_memory((char *)addr, thread->stack_base() - addr, |
2546 os::commit_memory((char *)addr, thread->stack_base() - addr, |
2558 !ExecMem); |
2547 !ExecMem); |
2559 return EXCEPTION_CONTINUE_EXECUTION; |
2548 return EXCEPTION_CONTINUE_EXECUTION; |
2560 } |
2549 } else |
2561 else |
|
2562 #endif |
2550 #endif |
2563 { |
2551 { |
2564 // Null pointer exception. |
2552 // Null pointer exception. |
2565 #ifdef _M_IA64 |
2553 #ifdef _M_IA64 |
2566 // Process implicit null checks in compiled code. Note: Implicit null checks |
2554 // Process implicit null checks in compiled code. Note: Implicit null checks |
2650 |
2638 |
2651 } // switch |
2639 } // switch |
2652 } |
2640 } |
2653 if (((thread->thread_state() == _thread_in_Java) || |
2641 if (((thread->thread_state() == _thread_in_Java) || |
2654 (thread->thread_state() == _thread_in_native)) && |
2642 (thread->thread_state() == _thread_in_native)) && |
2655 exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION) |
2643 exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION) { |
2656 { |
|
2657 LONG result=Handle_FLT_Exception(exceptionInfo); |
2644 LONG result=Handle_FLT_Exception(exceptionInfo); |
2658 if (result==EXCEPTION_CONTINUE_EXECUTION) return result; |
2645 if (result==EXCEPTION_CONTINUE_EXECUTION) return result; |
2659 } |
2646 } |
2660 } |
2647 } |
2661 |
2648 |
2682 } |
2669 } |
2683 } |
2670 } |
2684 return EXCEPTION_CONTINUE_SEARCH; |
2671 return EXCEPTION_CONTINUE_SEARCH; |
2685 } |
2672 } |
2686 |
2673 |
2687 #define DEFINE_FAST_GETFIELD(Return,Fieldname,Result) \ |
2674 #define DEFINE_FAST_GETFIELD(Return, Fieldname, Result) \ |
2688 Return JNICALL jni_fast_Get##Result##Field_wrapper(JNIEnv *env, jobject obj, jfieldID fieldID) { \ |
2675 Return JNICALL jni_fast_Get##Result##Field_wrapper(JNIEnv *env, \ |
2689 __try { \ |
2676 jobject obj, \ |
2690 return (*JNI_FastGetField::jni_fast_Get##Result##Field_fp)(env, obj, fieldID); \ |
2677 jfieldID fieldID) { \ |
2691 } __except(fastJNIAccessorExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) { \ |
2678 __try { \ |
2692 } \ |
2679 return (*JNI_FastGetField::jni_fast_Get##Result##Field_fp)(env, \ |
2693 return 0; \ |
2680 obj, \ |
2694 } |
2681 fieldID); \ |
2682 } __except(fastJNIAccessorExceptionFilter((_EXCEPTION_POINTERS*) \ |
|
2683 _exception_info())) { \ |
|
2684 } \ |
|
2685 return 0; \ |
|
2686 } |
|
2695 |
2687 |
2696 DEFINE_FAST_GETFIELD(jboolean, bool, Boolean) |
2688 DEFINE_FAST_GETFIELD(jboolean, bool, Boolean) |
2697 DEFINE_FAST_GETFIELD(jbyte, byte, Byte) |
2689 DEFINE_FAST_GETFIELD(jbyte, byte, Byte) |
2698 DEFINE_FAST_GETFIELD(jchar, char, Char) |
2690 DEFINE_FAST_GETFIELD(jchar, char, Char) |
2699 DEFINE_FAST_GETFIELD(jshort, short, Short) |
2691 DEFINE_FAST_GETFIELD(jshort, short, Short) |
2753 // This makes Windows large page support more or less like Solaris ISM, in |
2745 // This makes Windows large page support more or less like Solaris ISM, in |
2754 // that the entire heap must be committed upfront. This probably will change |
2746 // that the entire heap must be committed upfront. This probably will change |
2755 // in the future, if so the code below needs to be revisited. |
2747 // in the future, if so the code below needs to be revisited. |
2756 |
2748 |
2757 #ifndef MEM_LARGE_PAGES |
2749 #ifndef MEM_LARGE_PAGES |
2758 #define MEM_LARGE_PAGES 0x20000000 |
2750 #define MEM_LARGE_PAGES 0x20000000 |
2759 #endif |
2751 #endif |
2760 |
2752 |
2761 static HANDLE _hProcess; |
2753 static HANDLE _hProcess; |
2762 static HANDLE _hToken; |
2754 static HANDLE _hToken; |
2763 |
2755 |
2855 bool success = false; |
2847 bool success = false; |
2856 bool use_numa_interleaving_specified = !FLAG_IS_DEFAULT(UseNUMAInterleaving); |
2848 bool use_numa_interleaving_specified = !FLAG_IS_DEFAULT(UseNUMAInterleaving); |
2857 |
2849 |
2858 // print a warning if UseNUMAInterleaving flag is specified on command line |
2850 // print a warning if UseNUMAInterleaving flag is specified on command line |
2859 bool warn_on_failure = use_numa_interleaving_specified; |
2851 bool warn_on_failure = use_numa_interleaving_specified; |
2860 # define WARN(msg) if (warn_on_failure) { warning(msg); } |
2852 #define WARN(msg) if (warn_on_failure) { warning(msg); } |
2861 |
2853 |
2862 // NUMAInterleaveGranularity cannot be less than vm_allocation_granularity (or _large_page_size if using large pages) |
2854 // NUMAInterleaveGranularity cannot be less than vm_allocation_granularity (or _large_page_size if using large pages) |
2863 size_t min_interleave_granularity = UseLargePages ? _large_page_size : os::vm_allocation_granularity(); |
2855 size_t min_interleave_granularity = UseLargePages ? _large_page_size : os::vm_allocation_granularity(); |
2864 NUMAInterleaveGranularity = align_size_up(NUMAInterleaveGranularity, min_interleave_granularity); |
2856 NUMAInterleaveGranularity = align_size_up(NUMAInterleaveGranularity, min_interleave_granularity); |
2865 |
2857 |
2889 // this routine is used whenever we need to reserve a contiguous VA range |
2881 // this routine is used whenever we need to reserve a contiguous VA range |
2890 // but we need to make separate VirtualAlloc calls for each piece of the range |
2882 // but we need to make separate VirtualAlloc calls for each piece of the range |
2891 // Reasons for doing this: |
2883 // Reasons for doing this: |
2892 // * UseLargePagesIndividualAllocation was set (normally only needed on WS2003 but possible to be set otherwise) |
2884 // * UseLargePagesIndividualAllocation was set (normally only needed on WS2003 but possible to be set otherwise) |
2893 // * UseNUMAInterleaving requires a separate node for each piece |
2885 // * UseNUMAInterleaving requires a separate node for each piece |
2894 static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags, DWORD prot, |
2886 static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags, |
2895 bool should_inject_error=false) { |
2887 DWORD prot, |
2888 bool should_inject_error = false) { |
|
2896 char * p_buf; |
2889 char * p_buf; |
2897 // note: at setup time we guaranteed that NUMAInterleaveGranularity was aligned up to a page size |
2890 // note: at setup time we guaranteed that NUMAInterleaveGranularity was aligned up to a page size |
2898 size_t page_size = UseLargePages ? _large_page_size : os::vm_allocation_granularity(); |
2891 size_t page_size = UseLargePages ? _large_page_size : os::vm_allocation_granularity(); |
2899 size_t chunk_size = UseNUMAInterleaving ? NUMAInterleaveGranularity : page_size; |
2892 size_t chunk_size = UseNUMAInterleaving ? NUMAInterleaveGranularity : page_size; |
2900 |
2893 |
3018 // print a warning if any large page related flag is specified on command line |
3011 // print a warning if any large page related flag is specified on command line |
3019 bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) || |
3012 bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) || |
3020 !FLAG_IS_DEFAULT(LargePageSizeInBytes); |
3013 !FLAG_IS_DEFAULT(LargePageSizeInBytes); |
3021 bool success = false; |
3014 bool success = false; |
3022 |
3015 |
3023 # define WARN(msg) if (warn_on_failure) { warning(msg); } |
3016 #define WARN(msg) if (warn_on_failure) { warning(msg); } |
3024 if (resolve_functions_for_large_page_init()) { |
3017 if (resolve_functions_for_large_page_init()) { |
3025 if (request_lock_memory_privilege()) { |
3018 if (request_lock_memory_privilege()) { |
3026 size_t s = os::Kernel32Dll::GetLargePageMinimum(); |
3019 size_t s = os::Kernel32Dll::GetLargePageMinimum(); |
3027 if (s) { |
3020 if (s) { |
3028 #if defined(IA32) || defined(AMD64) |
3021 #if defined(IA32) || defined(AMD64) |
3159 |
3152 |
3160 bool os::can_execute_large_page_memory() { |
3153 bool os::can_execute_large_page_memory() { |
3161 return true; |
3154 return true; |
3162 } |
3155 } |
3163 |
3156 |
3164 char* os::reserve_memory_special(size_t bytes, size_t alignment, char* addr, bool exec) { |
3157 char* os::reserve_memory_special(size_t bytes, size_t alignment, char* addr, |
3158 bool exec) { |
|
3165 assert(UseLargePages, "only for large pages"); |
3159 assert(UseLargePages, "only for large pages"); |
3166 |
3160 |
3167 if (!is_size_aligned(bytes, os::large_page_size()) || alignment > os::large_page_size()) { |
3161 if (!is_size_aligned(bytes, os::large_page_size()) || alignment > os::large_page_size()) { |
3168 return NULL; // Fallback to small pages. |
3162 return NULL; // Fallback to small pages. |
3169 } |
3163 } |
3395 |
3389 |
3396 bool os::get_page_info(char *start, page_info* info) { |
3390 bool os::get_page_info(char *start, page_info* info) { |
3397 return false; |
3391 return false; |
3398 } |
3392 } |
3399 |
3393 |
3400 char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) { |
3394 char *os::scan_pages(char *start, char* end, page_info* page_expected, |
3395 page_info* page_found) { |
|
3401 return end; |
3396 return end; |
3402 } |
3397 } |
3403 |
3398 |
3404 char* os::non_memory_address_word() { |
3399 char* os::non_memory_address_word() { |
3405 // Must never look like an address returned by reserve_memory, |
3400 // Must never look like an address returned by reserve_memory, |
3456 int os::sleep(Thread* thread, jlong ms, bool interruptable) { |
3451 int os::sleep(Thread* thread, jlong ms, bool interruptable) { |
3457 jlong limit = (jlong) MAXDWORD; |
3452 jlong limit = (jlong) MAXDWORD; |
3458 |
3453 |
3459 while (ms > limit) { |
3454 while (ms > limit) { |
3460 int res; |
3455 int res; |
3461 if ((res = sleep(thread, limit, interruptable)) != OS_TIMEOUT) |
3456 if ((res = sleep(thread, limit, interruptable)) != OS_TIMEOUT) { |
3462 return res; |
3457 return res; |
3458 } |
|
3463 ms -= limit; |
3459 ms -= limit; |
3464 } |
3460 } |
3465 |
3461 |
3466 assert(thread == Thread::current(), "thread consistency check"); |
3462 assert(thread == Thread::current(), "thread consistency check"); |
3467 OSThread* osthread = thread->osthread(); |
3463 OSThread* osthread = thread->osthread(); |
3477 // java_suspend_self() via check_and_wait_while_suspended() |
3473 // java_suspend_self() via check_and_wait_while_suspended() |
3478 |
3474 |
3479 HANDLE events[1]; |
3475 HANDLE events[1]; |
3480 events[0] = osthread->interrupt_event(); |
3476 events[0] = osthread->interrupt_event(); |
3481 HighResolutionInterval *phri=NULL; |
3477 HighResolutionInterval *phri=NULL; |
3482 if (!ForceTimeHighResolution) |
3478 if (!ForceTimeHighResolution) { |
3483 phri = new HighResolutionInterval(ms); |
3479 phri = new HighResolutionInterval(ms); |
3480 } |
|
3484 if (WaitForMultipleObjects(1, events, FALSE, (DWORD)ms) == WAIT_TIMEOUT) { |
3481 if (WaitForMultipleObjects(1, events, FALSE, (DWORD)ms) == WAIT_TIMEOUT) { |
3485 result = OS_TIMEOUT; |
3482 result = OS_TIMEOUT; |
3486 } else { |
3483 } else { |
3487 ResetEvent(osthread->interrupt_event()); |
3484 ResetEvent(osthread->interrupt_event()); |
3488 osthread->set_interrupted(false); |
3485 osthread->set_interrupted(false); |
3498 result = OS_TIMEOUT; |
3495 result = OS_TIMEOUT; |
3499 } |
3496 } |
3500 return result; |
3497 return result; |
3501 } |
3498 } |
3502 |
3499 |
3503 // |
|
3504 // Short sleep, direct OS call. |
3500 // Short sleep, direct OS call. |
3505 // |
3501 // |
3506 // ms = 0, means allow others (if any) to run. |
3502 // ms = 0, means allow others (if any) to run. |
3507 // |
3503 // |
3508 void os::naked_short_sleep(jlong ms) { |
3504 void os::naked_short_sleep(jlong ms) { |
3581 if (!UseThreadPriorities) return OS_OK; |
3577 if (!UseThreadPriorities) return OS_OK; |
3582 bool ret = SetThreadPriority(thread->osthread()->thread_handle(), priority) != 0; |
3578 bool ret = SetThreadPriority(thread->osthread()->thread_handle(), priority) != 0; |
3583 return ret ? OS_OK : OS_ERR; |
3579 return ret ? OS_OK : OS_ERR; |
3584 } |
3580 } |
3585 |
3581 |
3586 OSReturn os::get_native_priority(const Thread* const thread, int* priority_ptr) { |
3582 OSReturn os::get_native_priority(const Thread* const thread, |
3583 int* priority_ptr) { |
|
3587 if (!UseThreadPriorities) { |
3584 if (!UseThreadPriorities) { |
3588 *priority_ptr = java_to_os_priority[NormPriority]; |
3585 *priority_ptr = java_to_os_priority[NormPriority]; |
3589 return OS_OK; |
3586 return OS_OK; |
3590 } |
3587 } |
3591 int os_prio = GetThreadPriority(thread->osthread()->thread_handle()); |
3588 int os_prio = GetThreadPriority(thread->osthread()->thread_handle()); |
3601 // Hint to the underlying OS that a task switch would not be good. |
3598 // Hint to the underlying OS that a task switch would not be good. |
3602 // Void return because it's a hint and can fail. |
3599 // Void return because it's a hint and can fail. |
3603 void os::hint_no_preempt() {} |
3600 void os::hint_no_preempt() {} |
3604 |
3601 |
3605 void os::interrupt(Thread* thread) { |
3602 void os::interrupt(Thread* thread) { |
3606 assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(), |
3603 assert(!thread->is_Java_thread() || Thread::current() == thread || |
3604 Threads_lock->owned_by_self(), |
|
3607 "possibility of dangling Thread pointer"); |
3605 "possibility of dangling Thread pointer"); |
3608 |
3606 |
3609 OSThread* osthread = thread->osthread(); |
3607 OSThread* osthread = thread->osthread(); |
3610 osthread->set_interrupted(true); |
3608 osthread->set_interrupted(true); |
3611 // More than one thread can get here with the same value of osthread, |
3609 // More than one thread can get here with the same value of osthread, |
3613 // to interrupted() to be visible to other threads before we post |
3611 // to interrupted() to be visible to other threads before we post |
3614 // the interrupt event. |
3612 // the interrupt event. |
3615 OrderAccess::release(); |
3613 OrderAccess::release(); |
3616 SetEvent(osthread->interrupt_event()); |
3614 SetEvent(osthread->interrupt_event()); |
3617 // For JSR166: unpark after setting status |
3615 // For JSR166: unpark after setting status |
3618 if (thread->is_Java_thread()) |
3616 if (thread->is_Java_thread()) { |
3619 ((JavaThread*)thread)->parker()->unpark(); |
3617 ((JavaThread*)thread)->parker()->unpark(); |
3618 } |
|
3620 |
3619 |
3621 ParkEvent * ev = thread->_ParkEvent; |
3620 ParkEvent * ev = thread->_ParkEvent; |
3622 if (ev != NULL) ev->unpark(); |
3621 if (ev != NULL) ev->unpark(); |
3623 |
|
3624 } |
3622 } |
3625 |
3623 |
3626 |
3624 |
3627 bool os::is_interrupted(Thread* thread, bool clear_interrupted) { |
3625 bool os::is_interrupted(Thread* thread, bool clear_interrupted) { |
3628 assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(), |
3626 assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(), |
3665 } |
3663 } |
3666 #endif |
3664 #endif |
3667 } |
3665 } |
3668 |
3666 |
3669 // GetCurrentThreadId() returns DWORD |
3667 // GetCurrentThreadId() returns DWORD |
3670 intx os::current_thread_id() { return GetCurrentThreadId(); } |
3668 intx os::current_thread_id() { return GetCurrentThreadId(); } |
3671 |
3669 |
3672 static int _initial_pid = 0; |
3670 static int _initial_pid = 0; |
3673 |
3671 |
3674 int os::current_process_id() |
3672 int os::current_process_id() { |
3675 { |
|
3676 return (_initial_pid ? _initial_pid : _getpid()); |
3673 return (_initial_pid ? _initial_pid : _getpid()); |
3677 } |
3674 } |
3678 |
3675 |
3679 int os::win32::_vm_page_size = 0; |
3676 int os::win32::_vm_page_size = 0; |
3680 int os::win32::_vm_allocation_granularity = 0; |
3677 int os::win32::_vm_allocation_granularity = 0; |
3681 int os::win32::_processor_type = 0; |
3678 int os::win32::_processor_type = 0; |
3682 // Processor level is not available on non-NT systems, use vm_version instead |
3679 // Processor level is not available on non-NT systems, use vm_version instead |
3683 int os::win32::_processor_level = 0; |
3680 int os::win32::_processor_level = 0; |
3684 julong os::win32::_physical_memory = 0; |
3681 julong os::win32::_physical_memory = 0; |
3685 size_t os::win32::_default_stack_size = 0; |
3682 size_t os::win32::_default_stack_size = 0; |
3686 |
3683 |
3687 intx os::win32::_os_thread_limit = 0; |
3684 intx os::win32::_os_thread_limit = 0; |
3688 volatile intx os::win32::_os_thread_count = 0; |
3685 volatile intx os::win32::_os_thread_count = 0; |
3689 |
3686 |
3690 bool os::win32::_is_nt = false; |
3687 bool os::win32::_is_nt = false; |
3691 bool os::win32::_is_windows_2003 = false; |
3688 bool os::win32::_is_windows_2003 = false; |
3692 bool os::win32::_is_windows_server = false; |
3689 bool os::win32::_is_windows_server = false; |
3693 |
3690 |
3694 bool os::win32::_has_performance_count = 0; |
3691 bool os::win32::_has_performance_count = 0; |
3695 |
3692 |
3696 void os::win32::initialize_system_info() { |
3693 void os::win32::initialize_system_info() { |
3697 SYSTEM_INFO si; |
3694 SYSTEM_INFO si; |
3698 GetSystemInfo(&si); |
3695 GetSystemInfo(&si); |
3699 _vm_page_size = si.dwPageSize; |
3696 _vm_page_size = si.dwPageSize; |
3747 StarvationMonitorInterval = 6000; |
3744 StarvationMonitorInterval = 6000; |
3748 } |
3745 } |
3749 } |
3746 } |
3750 |
3747 |
3751 |
3748 |
3752 HINSTANCE os::win32::load_Windows_dll(const char* name, char *ebuf, int ebuflen) { |
3749 HINSTANCE os::win32::load_Windows_dll(const char* name, char *ebuf, |
3750 int ebuflen) { |
|
3753 char path[MAX_PATH]; |
3751 char path[MAX_PATH]; |
3754 DWORD size; |
3752 DWORD size; |
3755 DWORD pathLen = (DWORD)sizeof(path); |
3753 DWORD pathLen = (DWORD)sizeof(path); |
3756 HINSTANCE result = NULL; |
3754 HINSTANCE result = NULL; |
3757 |
3755 |
3902 guarantee(return_page != NULL, "Commit Failed for polling page"); |
3900 guarantee(return_page != NULL, "Commit Failed for polling page"); |
3903 |
3901 |
3904 os::set_polling_page(polling_page); |
3902 os::set_polling_page(polling_page); |
3905 |
3903 |
3906 #ifndef PRODUCT |
3904 #ifndef PRODUCT |
3907 if (Verbose && PrintMiscellaneous) |
3905 if (Verbose && PrintMiscellaneous) { |
3908 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page); |
3906 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", |
3907 (intptr_t)polling_page); |
|
3908 } |
|
3909 #endif |
3909 #endif |
3910 |
3910 |
3911 if (!UseMembar) { |
3911 if (!UseMembar) { |
3912 address mem_serialize_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_READWRITE); |
3912 address mem_serialize_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_READWRITE); |
3913 guarantee(mem_serialize_page != NULL, "Reserve Failed for memory serialize page"); |
3913 guarantee(mem_serialize_page != NULL, "Reserve Failed for memory serialize page"); |
3916 guarantee(return_page != NULL, "Commit Failed for memory serialize page"); |
3916 guarantee(return_page != NULL, "Commit Failed for memory serialize page"); |
3917 |
3917 |
3918 os::set_memory_serialize_page(mem_serialize_page); |
3918 os::set_memory_serialize_page(mem_serialize_page); |
3919 |
3919 |
3920 #ifndef PRODUCT |
3920 #ifndef PRODUCT |
3921 if (Verbose && PrintMiscellaneous) |
3921 if (Verbose && PrintMiscellaneous) { |
3922 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); |
3922 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", |
3923 (intptr_t)mem_serialize_page); |
|
3924 } |
|
3923 #endif |
3925 #endif |
3924 } |
3926 } |
3925 |
3927 |
3926 // Setup Windows Exceptions |
3928 // Setup Windows Exceptions |
3927 |
3929 |
4032 } |
4034 } |
4033 |
4035 |
4034 // Mark the polling page as unreadable |
4036 // Mark the polling page as unreadable |
4035 void os::make_polling_page_unreadable(void) { |
4037 void os::make_polling_page_unreadable(void) { |
4036 DWORD old_status; |
4038 DWORD old_status; |
4037 if (!VirtualProtect((char *)_polling_page, os::vm_page_size(), PAGE_NOACCESS, &old_status)) |
4039 if (!VirtualProtect((char *)_polling_page, os::vm_page_size(), |
4040 PAGE_NOACCESS, &old_status)) { |
|
4038 fatal("Could not disable polling page"); |
4041 fatal("Could not disable polling page"); |
4039 }; |
4042 } |
4043 } |
|
4040 |
4044 |
4041 // Mark the polling page as readable |
4045 // Mark the polling page as readable |
4042 void os::make_polling_page_readable(void) { |
4046 void os::make_polling_page_readable(void) { |
4043 DWORD old_status; |
4047 DWORD old_status; |
4044 if (!VirtualProtect((char *)_polling_page, os::vm_page_size(), PAGE_READONLY, &old_status)) |
4048 if (!VirtualProtect((char *)_polling_page, os::vm_page_size(), |
4049 PAGE_READONLY, &old_status)) { |
|
4045 fatal("Could not enable polling page"); |
4050 fatal("Could not enable polling page"); |
4046 }; |
4051 } |
4052 } |
|
4047 |
4053 |
4048 |
4054 |
4049 int os::stat(const char *path, struct stat *sbuf) { |
4055 int os::stat(const char *path, struct stat *sbuf) { |
4050 char pathbuf[MAX_PATH]; |
4056 char pathbuf[MAX_PATH]; |
4051 if (strlen(path) > MAX_PATH - 1) { |
4057 if (strlen(path) > MAX_PATH - 1) { |
4117 FILETIME CreationTime; |
4123 FILETIME CreationTime; |
4118 FILETIME ExitTime; |
4124 FILETIME ExitTime; |
4119 FILETIME KernelTime; |
4125 FILETIME KernelTime; |
4120 FILETIME UserTime; |
4126 FILETIME UserTime; |
4121 |
4127 |
4122 if (GetThreadTimes(thread->osthread()->thread_handle(), |
4128 if (GetThreadTimes(thread->osthread()->thread_handle(), &CreationTime, |
4123 &CreationTime, &ExitTime, &KernelTime, &UserTime) == 0) |
4129 &ExitTime, &KernelTime, &UserTime) == 0) { |
4124 return -1; |
4130 return -1; |
4125 else |
4131 } else if (user_sys_cpu_time) { |
4126 if (user_sys_cpu_time) { |
4132 return (FT2INT64(UserTime) + FT2INT64(KernelTime)) * 100; |
4127 return (FT2INT64(UserTime) + FT2INT64(KernelTime)) * 100; |
|
4128 } else { |
4133 } else { |
4129 return FT2INT64(UserTime) * 100; |
4134 return FT2INT64(UserTime) * 100; |
4130 } |
4135 } |
4131 } else { |
4136 } else { |
4132 return (jlong) timeGetTime() * 1000000; |
4137 return (jlong) timeGetTime() * 1000000; |
4153 FILETIME CreationTime; |
4158 FILETIME CreationTime; |
4154 FILETIME ExitTime; |
4159 FILETIME ExitTime; |
4155 FILETIME KernelTime; |
4160 FILETIME KernelTime; |
4156 FILETIME UserTime; |
4161 FILETIME UserTime; |
4157 |
4162 |
4158 if (GetThreadTimes(GetCurrentThread(), |
4163 if (GetThreadTimes(GetCurrentThread(), &CreationTime, &ExitTime, |
4159 &CreationTime, &ExitTime, &KernelTime, &UserTime) == 0) |
4164 &KernelTime, &UserTime) == 0) { |
4160 return false; |
4165 return false; |
4161 else |
4166 } else { |
4162 return true; |
4167 return true; |
4168 } |
|
4163 } else { |
4169 } else { |
4164 return false; |
4170 return false; |
4165 } |
4171 } |
4166 } |
4172 } |
4167 |
4173 |
4250 } |
4256 } |
4251 |
4257 |
4252 // This method is a slightly reworked copy of JDK's sysNativePath |
4258 // This method is a slightly reworked copy of JDK's sysNativePath |
4253 // from src/windows/hpi/src/path_md.c |
4259 // from src/windows/hpi/src/path_md.c |
4254 |
4260 |
4255 /* Convert a pathname to native format. On win32, this involves forcing all |
4261 // Convert a pathname to native format. On win32, this involves forcing all |
4256 separators to be '\\' rather than '/' (both are legal inputs, but Win95 |
4262 // separators to be '\\' rather than '/' (both are legal inputs, but Win95 |
4257 sometimes rejects '/') and removing redundant separators. The input path is |
4263 // sometimes rejects '/') and removing redundant separators. The input path is |
4258 assumed to have been converted into the character encoding used by the local |
4264 // assumed to have been converted into the character encoding used by the local |
4259 system. Because this might be a double-byte encoding, care is taken to |
4265 // system. Because this might be a double-byte encoding, care is taken to |
4260 treat double-byte lead characters correctly. |
4266 // treat double-byte lead characters correctly. |
4261 |
4267 // |
4262 This procedure modifies the given path in place, as the result is never |
4268 // This procedure modifies the given path in place, as the result is never |
4263 longer than the original. There is no error return; this operation always |
4269 // longer than the original. There is no error return; this operation always |
4264 succeeds. */ |
4270 // succeeds. |
4265 char * os::native_path(char *path) { |
4271 char * os::native_path(char *path) { |
4266 char *src = path, *dst = path, *end = path; |
4272 char *src = path, *dst = path, *end = path; |
4267 char *colon = NULL; /* If a drive specifier is found, this will |
4273 char *colon = NULL; // If a drive specifier is found, this will |
4268 point to the colon following the drive |
4274 // point to the colon following the drive letter |
4269 letter */ |
4275 |
4270 |
4276 // Assumption: '/', '\\', ':', and drive letters are never lead bytes |
4271 /* Assumption: '/', '\\', ':', and drive letters are never lead bytes */ |
4277 assert(((!::IsDBCSLeadByte('/')) && (!::IsDBCSLeadByte('\\')) |
4272 assert(((!::IsDBCSLeadByte('/')) |
4278 && (!::IsDBCSLeadByte(':'))), "Illegal lead byte"); |
4273 && (!::IsDBCSLeadByte('\\')) |
4279 |
4274 && (!::IsDBCSLeadByte(':'))), |
4280 // Check for leading separators |
4275 "Illegal lead byte"); |
|
4276 |
|
4277 /* Check for leading separators */ |
|
4278 #define isfilesep(c) ((c) == '/' || (c) == '\\') |
4281 #define isfilesep(c) ((c) == '/' || (c) == '\\') |
4279 while (isfilesep(*src)) { |
4282 while (isfilesep(*src)) { |
4280 src++; |
4283 src++; |
4281 } |
4284 } |
4282 |
4285 |
4283 if (::isalpha(*src) && !::IsDBCSLeadByte(*src) && src[1] == ':') { |
4286 if (::isalpha(*src) && !::IsDBCSLeadByte(*src) && src[1] == ':') { |
4284 /* Remove leading separators if followed by drive specifier. This |
4287 // Remove leading separators if followed by drive specifier. This |
4285 hack is necessary to support file URLs containing drive |
4288 // hack is necessary to support file URLs containing drive |
4286 specifiers (e.g., "file://c:/path"). As a side effect, |
4289 // specifiers (e.g., "file://c:/path"). As a side effect, |
4287 "/c:/path" can be used as an alternative to "c:/path". */ |
4290 // "/c:/path" can be used as an alternative to "c:/path". |
4288 *dst++ = *src++; |
4291 *dst++ = *src++; |
4289 colon = dst; |
4292 colon = dst; |
4290 *dst++ = ':'; |
4293 *dst++ = ':'; |
4291 src++; |
4294 src++; |
4292 } else { |
4295 } else { |
4293 src = path; |
4296 src = path; |
4294 if (isfilesep(src[0]) && isfilesep(src[1])) { |
4297 if (isfilesep(src[0]) && isfilesep(src[1])) { |
4295 /* UNC pathname: Retain first separator; leave src pointed at |
4298 // UNC pathname: Retain first separator; leave src pointed at |
4296 second separator so that further separators will be collapsed |
4299 // second separator so that further separators will be collapsed |
4297 into the second separator. The result will be a pathname |
4300 // into the second separator. The result will be a pathname |
4298 beginning with "\\\\" followed (most likely) by a host name. */ |
4301 // beginning with "\\\\" followed (most likely) by a host name. |
4299 src = dst = path + 1; |
4302 src = dst = path + 1; |
4300 path[0] = '\\'; /* Force first separator to '\\' */ |
4303 path[0] = '\\'; // Force first separator to '\\' |
4301 } |
4304 } |
4302 } |
4305 } |
4303 |
4306 |
4304 end = dst; |
4307 end = dst; |
4305 |
4308 |
4306 /* Remove redundant separators from remainder of path, forcing all |
4309 // Remove redundant separators from remainder of path, forcing all |
4307 separators to be '\\' rather than '/'. Also, single byte space |
4310 // separators to be '\\' rather than '/'. Also, single byte space |
4308 characters are removed from the end of the path because those |
4311 // characters are removed from the end of the path because those |
4309 are not legal ending characters on this operating system. |
4312 // are not legal ending characters on this operating system. |
4310 */ |
4313 // |
4311 while (*src != '\0') { |
4314 while (*src != '\0') { |
4312 if (isfilesep(*src)) { |
4315 if (isfilesep(*src)) { |
4313 *dst++ = '\\'; src++; |
4316 *dst++ = '\\'; src++; |
4314 while (isfilesep(*src)) src++; |
4317 while (isfilesep(*src)) src++; |
4315 if (*src == '\0') { |
4318 if (*src == '\0') { |
4316 /* Check for trailing separator */ |
4319 // Check for trailing separator |
4317 end = dst; |
4320 end = dst; |
4318 if (colon == dst - 2) break; /* "z:\\" */ |
4321 if (colon == dst - 2) break; // "z:\\" |
4319 if (dst == path + 1) break; /* "\\" */ |
4322 if (dst == path + 1) break; // "\\" |
4320 if (dst == path + 2 && isfilesep(path[0])) { |
4323 if (dst == path + 2 && isfilesep(path[0])) { |
4321 /* "\\\\" is not collapsed to "\\" because "\\\\" marks the |
4324 // "\\\\" is not collapsed to "\\" because "\\\\" marks the |
4322 beginning of a UNC pathname. Even though it is not, by |
4325 // beginning of a UNC pathname. Even though it is not, by |
4323 itself, a valid UNC pathname, we leave it as is in order |
4326 // itself, a valid UNC pathname, we leave it as is in order |
4324 to be consistent with the path canonicalizer as well |
4327 // to be consistent with the path canonicalizer as well |
4325 as the win32 APIs, which treat this case as an invalid |
4328 // as the win32 APIs, which treat this case as an invalid |
4326 UNC pathname rather than as an alias for the root |
4329 // UNC pathname rather than as an alias for the root |
4327 directory of the current drive. */ |
4330 // directory of the current drive. |
4328 break; |
4331 break; |
4329 } |
4332 } |
4330 end = --dst; /* Path does not denote a root directory, so |
4333 end = --dst; // Path does not denote a root directory, so |
4331 remove trailing separator */ |
4334 // remove trailing separator |
4332 break; |
4335 break; |
4333 } |
4336 } |
4334 end = dst; |
4337 end = dst; |
4335 } else { |
4338 } else { |
4336 if (::IsDBCSLeadByte(*src)) { /* Copy a double-byte character */ |
4339 if (::IsDBCSLeadByte(*src)) { // Copy a double-byte character |
4337 *dst++ = *src++; |
4340 *dst++ = *src++; |
4338 if (*src) *dst++ = *src++; |
4341 if (*src) *dst++ = *src++; |
4339 end = dst; |
4342 end = dst; |
4340 } else { /* Copy a single-byte character */ |
4343 } else { // Copy a single-byte character |
4341 char c = *src++; |
4344 char c = *src++; |
4342 *dst++ = c; |
4345 *dst++ = c; |
4343 /* Space is not a legal ending character */ |
4346 // Space is not a legal ending character |
4344 if (c != ' ') end = dst; |
4347 if (c != ' ') end = dst; |
4345 } |
4348 } |
4346 } |
4349 } |
4347 } |
4350 } |
4348 |
4351 |
4349 *end = '\0'; |
4352 *end = '\0'; |
4350 |
4353 |
4351 /* For "z:", add "." to work around a bug in the C runtime library */ |
4354 // For "z:", add "." to work around a bug in the C runtime library |
4352 if (colon == dst - 1) { |
4355 if (colon == dst - 1) { |
4353 path[2] = '.'; |
4356 path[2] = '.'; |
4354 path[3] = '\0'; |
4357 path[3] = '\0'; |
4355 } |
4358 } |
4356 |
4359 |
4388 |
4391 |
4389 int os::fsync(int fd) { |
4392 int os::fsync(int fd) { |
4390 HANDLE handle = (HANDLE)::_get_osfhandle(fd); |
4393 HANDLE handle = (HANDLE)::_get_osfhandle(fd); |
4391 |
4394 |
4392 if ((!::FlushFileBuffers(handle)) && |
4395 if ((!::FlushFileBuffers(handle)) && |
4393 (GetLastError() != ERROR_ACCESS_DENIED) ) { |
4396 (GetLastError() != ERROR_ACCESS_DENIED)) { |
4394 /* from winerror.h */ |
4397 // from winerror.h |
4395 return -1; |
4398 return -1; |
4396 } |
4399 } |
4397 return 0; |
4400 return 0; |
4398 } |
4401 } |
4399 |
4402 |
4439 |
4442 |
4440 // This code is a copy of JDK's nonSeekAvailable |
4443 // This code is a copy of JDK's nonSeekAvailable |
4441 // from src/windows/hpi/src/sys_api_md.c |
4444 // from src/windows/hpi/src/sys_api_md.c |
4442 |
4445 |
4443 static int nonSeekAvailable(int fd, long *pbytes) { |
4446 static int nonSeekAvailable(int fd, long *pbytes) { |
4444 /* This is used for available on non-seekable devices |
4447 // This is used for available on non-seekable devices |
4445 * (like both named and anonymous pipes, such as pipes |
4448 // (like both named and anonymous pipes, such as pipes |
4446 * connected to an exec'd process). |
4449 // connected to an exec'd process). |
4447 * Standard Input is a special case. |
4450 // Standard Input is a special case. |
4448 * |
|
4449 */ |
|
4450 HANDLE han; |
4451 HANDLE han; |
4451 |
4452 |
4452 if ((han = (HANDLE) ::_get_osfhandle(fd)) == (HANDLE)(-1)) { |
4453 if ((han = (HANDLE) ::_get_osfhandle(fd)) == (HANDLE)(-1)) { |
4453 return FALSE; |
4454 return FALSE; |
4454 } |
4455 } |
4455 |
4456 |
4456 if (! ::PeekNamedPipe(han, NULL, 0, NULL, (LPDWORD)pbytes, NULL)) { |
4457 if (! ::PeekNamedPipe(han, NULL, 0, NULL, (LPDWORD)pbytes, NULL)) { |
4457 /* PeekNamedPipe fails when at EOF. In that case we |
4458 // PeekNamedPipe fails when at EOF. In that case we |
4458 * simply make *pbytes = 0 which is consistent with the |
4459 // simply make *pbytes = 0 which is consistent with the |
4459 * behavior we get on Solaris when an fd is at EOF. |
4460 // behavior we get on Solaris when an fd is at EOF. |
4460 * The only alternative is to raise an Exception, |
4461 // The only alternative is to raise an Exception, |
4461 * which isn't really warranted. |
4462 // which isn't really warranted. |
4462 */ |
4463 // |
4463 if (::GetLastError() != ERROR_BROKEN_PIPE) { |
4464 if (::GetLastError() != ERROR_BROKEN_PIPE) { |
4464 return FALSE; |
4465 return FALSE; |
4465 } |
4466 } |
4466 *pbytes = 0; |
4467 *pbytes = 0; |
4467 } |
4468 } |
4473 // This code is a copy of JDK's stdinAvailable |
4474 // This code is a copy of JDK's stdinAvailable |
4474 // from src/windows/hpi/src/sys_api_md.c |
4475 // from src/windows/hpi/src/sys_api_md.c |
4475 |
4476 |
4476 static int stdinAvailable(int fd, long *pbytes) { |
4477 static int stdinAvailable(int fd, long *pbytes) { |
4477 HANDLE han; |
4478 HANDLE han; |
4478 DWORD numEventsRead = 0; /* Number of events read from buffer */ |
4479 DWORD numEventsRead = 0; // Number of events read from buffer |
4479 DWORD numEvents = 0; /* Number of events in buffer */ |
4480 DWORD numEvents = 0; // Number of events in buffer |
4480 DWORD i = 0; /* Loop index */ |
4481 DWORD i = 0; // Loop index |
4481 DWORD curLength = 0; /* Position marker */ |
4482 DWORD curLength = 0; // Position marker |
4482 DWORD actualLength = 0; /* Number of bytes readable */ |
4483 DWORD actualLength = 0; // Number of bytes readable |
4483 BOOL error = FALSE; /* Error holder */ |
4484 BOOL error = FALSE; // Error holder |
4484 INPUT_RECORD *lpBuffer; /* Pointer to records of input events */ |
4485 INPUT_RECORD *lpBuffer; // Pointer to records of input events |
4485 |
4486 |
4486 if ((han = ::GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) { |
4487 if ((han = ::GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) { |
4487 return FALSE; |
4488 return FALSE; |
4488 } |
4489 } |
4489 |
4490 |
4490 /* Construct an array of input records in the console buffer */ |
4491 // Construct an array of input records in the console buffer |
4491 error = ::GetNumberOfConsoleInputEvents(han, &numEvents); |
4492 error = ::GetNumberOfConsoleInputEvents(han, &numEvents); |
4492 if (error == 0) { |
4493 if (error == 0) { |
4493 return nonSeekAvailable(fd, pbytes); |
4494 return nonSeekAvailable(fd, pbytes); |
4494 } |
4495 } |
4495 |
4496 |
4496 /* lpBuffer must fit into 64K or else PeekConsoleInput fails */ |
4497 // lpBuffer must fit into 64K or else PeekConsoleInput fails |
4497 if (numEvents > MAX_INPUT_EVENTS) { |
4498 if (numEvents > MAX_INPUT_EVENTS) { |
4498 numEvents = MAX_INPUT_EVENTS; |
4499 numEvents = MAX_INPUT_EVENTS; |
4499 } |
4500 } |
4500 |
4501 |
4501 lpBuffer = (INPUT_RECORD *)os::malloc(numEvents * sizeof(INPUT_RECORD), mtInternal); |
4502 lpBuffer = (INPUT_RECORD *)os::malloc(numEvents * sizeof(INPUT_RECORD), mtInternal); |
4507 if (error == 0) { |
4508 if (error == 0) { |
4508 os::free(lpBuffer, mtInternal); |
4509 os::free(lpBuffer, mtInternal); |
4509 return FALSE; |
4510 return FALSE; |
4510 } |
4511 } |
4511 |
4512 |
4512 /* Examine input records for the number of bytes available */ |
4513 // Examine input records for the number of bytes available |
4513 for (i=0; i<numEvents; i++) { |
4514 for (i=0; i<numEvents; i++) { |
4514 if (lpBuffer[i].EventType == KEY_EVENT) { |
4515 if (lpBuffer[i].EventType == KEY_EVENT) { |
4515 |
4516 |
4516 KEY_EVENT_RECORD *keyRecord = (KEY_EVENT_RECORD *) |
4517 KEY_EVENT_RECORD *keyRecord = (KEY_EVENT_RECORD *) |
4517 &(lpBuffer[i].Event); |
4518 &(lpBuffer[i].Event); |
4589 CloseHandle(hFile); |
4590 CloseHandle(hFile); |
4590 return NULL; |
4591 return NULL; |
4591 } |
4592 } |
4592 } else { |
4593 } else { |
4593 HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_WRITECOPY, 0, 0, |
4594 HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_WRITECOPY, 0, 0, |
4594 NULL /*file_name*/); |
4595 NULL /* file_name */); |
4595 if (hMap == NULL) { |
4596 if (hMap == NULL) { |
4596 if (PrintMiscellaneous && Verbose) { |
4597 if (PrintMiscellaneous && Verbose) { |
4597 DWORD err = GetLastError(); |
4598 DWORD err = GetLastError(); |
4598 tty->print_cr("CreateFileMapping() failed: GetLastError->%ld.", err); |
4599 tty->print_cr("CreateFileMapping() failed: GetLastError->%ld.", err); |
4599 } |
4600 } |
4710 |
4711 |
4711 os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { |
4712 os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { |
4712 assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); |
4713 assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); |
4713 } |
4714 } |
4714 |
4715 |
4715 /* |
4716 // See the caveats for this class in os_windows.hpp |
4716 * See the caveats for this class in os_windows.hpp |
4717 // Protects the callback call so that raised OS EXCEPTIONS causes a jump back |
4717 * Protects the callback call so that raised OS EXCEPTIONS causes a jump back |
4718 // into this method and returns false. If no OS EXCEPTION was raised, returns |
4718 * into this method and returns false. If no OS EXCEPTION was raised, returns |
4719 // true. |
4719 * true. |
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 |
4785 // 1 : signaled - thread is running or ready |
4785 // 1 : signaled - thread is running or ready |
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 |
4893 |
4893 |
4894 |
4894 |
4895 // JSR166 |
4895 // JSR166 |
4896 // ------------------------------------------------------- |
4896 // ------------------------------------------------------- |
4897 |
4897 |
4898 /* |
4898 // The Windows implementation of Park is very straightforward: Basic |
4899 * The Windows implementation of Park is very straightforward: Basic |
4899 // operations on Win32 Events turn out to have the right semantics to |
4900 * operations on Win32 Events turn out to have the right semantics to |
4900 // use them directly. We opportunistically resuse the event inherited |
4901 * use them directly. We opportunistically resuse the event inherited |
4901 // from Monitor. |
4902 * from Monitor. |
|
4903 */ |
|
4904 |
|
4905 |
4902 |
4906 void Parker::park(bool isAbsolute, jlong time) { |
4903 void Parker::park(bool isAbsolute, jlong time) { |
4907 guarantee(_ParkEvent != NULL, "invariant"); |
4904 guarantee(_ParkEvent != NULL, "invariant"); |
4908 // First, demultiplex/decode time arguments |
4905 // First, demultiplex/decode time arguments |
4909 if (time < 0) { // don't wait |
4906 if (time < 0) { // don't wait |
4910 return; |
4907 return; |
4911 } |
4908 } else if (time == 0 && !isAbsolute) { |
4912 else if (time == 0 && !isAbsolute) { |
|
4913 time = INFINITE; |
4909 time = INFINITE; |
4914 } |
4910 } else if (isAbsolute) { |
4915 else if (isAbsolute) { |
|
4916 time -= os::javaTimeMillis(); // convert to relative time |
4911 time -= os::javaTimeMillis(); // convert to relative time |
4917 if (time <= 0) // already elapsed |
4912 if (time <= 0) { // already elapsed |
4918 return; |
4913 return; |
4919 } |
4914 } |
4920 else { // relative |
4915 } else { // relative |
4921 time /= 1000000; // Must coarsen from nanos to millis |
4916 time /= 1000000; // Must coarsen from nanos to millis |
4922 if (time == 0) // Wait for the minimal time unit if zero |
4917 if (time == 0) { // Wait for the minimal time unit if zero |
4923 time = 1; |
4918 time = 1; |
4919 } |
|
4924 } |
4920 } |
4925 |
4921 |
4926 JavaThread* thread = (JavaThread*)(Thread::current()); |
4922 JavaThread* thread = (JavaThread*)(Thread::current()); |
4927 assert(thread->is_Java_thread(), "Must be JavaThread"); |
4923 assert(thread->is_Java_thread(), "Must be JavaThread"); |
4928 JavaThread *jt = (JavaThread *)thread; |
4924 JavaThread *jt = (JavaThread *)thread; |
4930 // Don't wait if interrupted or already triggered |
4926 // Don't wait if interrupted or already triggered |
4931 if (Thread::is_interrupted(thread, false) || |
4927 if (Thread::is_interrupted(thread, false) || |
4932 WaitForSingleObject(_ParkEvent, 0) == WAIT_OBJECT_0) { |
4928 WaitForSingleObject(_ParkEvent, 0) == WAIT_OBJECT_0) { |
4933 ResetEvent(_ParkEvent); |
4929 ResetEvent(_ParkEvent); |
4934 return; |
4930 return; |
4935 } |
4931 } else { |
4936 else { |
|
4937 ThreadBlockInVM tbivm(jt); |
4932 ThreadBlockInVM tbivm(jt); |
4938 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); |
4933 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); |
4939 jt->set_suspend_equivalent(); |
4934 jt->set_suspend_equivalent(); |
4940 |
4935 |
4941 WaitForSingleObject(_ParkEvent, time); |
4936 WaitForSingleObject(_ParkEvent, time); |
5040 if (exception_code == EXCEPTION_ACCESS_VIOLATION) { |
5035 if (exception_code == EXCEPTION_ACCESS_VIOLATION) { |
5041 JavaThread* thread = (JavaThread*)ThreadLocalStorage::get_thread_slow(); |
5036 JavaThread* thread = (JavaThread*)ThreadLocalStorage::get_thread_slow(); |
5042 PEXCEPTION_RECORD exceptionRecord = e->ExceptionRecord; |
5037 PEXCEPTION_RECORD exceptionRecord = e->ExceptionRecord; |
5043 address addr = (address) exceptionRecord->ExceptionInformation[1]; |
5038 address addr = (address) exceptionRecord->ExceptionInformation[1]; |
5044 |
5039 |
5045 if (os::is_memory_serialize_page(thread, addr)) |
5040 if (os::is_memory_serialize_page(thread, addr)) { |
5046 return EXCEPTION_CONTINUE_EXECUTION; |
5041 return EXCEPTION_CONTINUE_EXECUTION; |
5042 } |
|
5047 } |
5043 } |
5048 |
5044 |
5049 return EXCEPTION_CONTINUE_SEARCH; |
5045 return EXCEPTION_CONTINUE_SEARCH; |
5050 } |
5046 } |
5051 |
5047 |
5161 return ::setsockopt(fd, level, optname, optval, optlen); |
5157 return ::setsockopt(fd, level, optname, optval, optlen); |
5162 } |
5158 } |
5163 |
5159 |
5164 // WINDOWS CONTEXT Flags for THREAD_SAMPLING |
5160 // WINDOWS CONTEXT Flags for THREAD_SAMPLING |
5165 #if defined(IA32) |
5161 #if defined(IA32) |
5166 # define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS) |
5162 #define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS) |
5167 #elif defined (AMD64) |
5163 #elif defined (AMD64) |
5168 # define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT) |
5164 #define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT) |
5169 #endif |
5165 #endif |
5170 |
5166 |
5171 // returns true if thread could be suspended, |
5167 // returns true if thread could be suspended, |
5172 // false otherwise |
5168 // false otherwise |
5173 static bool do_suspend(HANDLE* h) { |
5169 static bool do_suspend(HANDLE* h) { |
5187 } |
5183 } |
5188 } |
5184 } |
5189 |
5185 |
5190 // retrieve a suspend/resume context capable handle |
5186 // retrieve a suspend/resume context capable handle |
5191 // from the tid. Caller validates handle return value. |
5187 // from the tid. Caller validates handle return value. |
5192 void get_thread_handle_for_extended_context(HANDLE* h, OSThread::thread_id_t tid) { |
5188 void get_thread_handle_for_extended_context(HANDLE* h, |
5189 OSThread::thread_id_t tid) { |
|
5193 if (h != NULL) { |
5190 if (h != NULL) { |
5194 *h = OpenThread(THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, tid); |
5191 *h = OpenThread(THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, tid); |
5195 } |
5192 } |
5196 } |
5193 } |
5197 |
5194 |
5198 // |
|
5199 // Thread sampling implementation |
5195 // Thread sampling implementation |
5200 // |
5196 // |
5201 void os::SuspendedThreadTask::internal_do_task() { |
5197 void os::SuspendedThreadTask::internal_do_task() { |
5202 CONTEXT ctxt; |
5198 CONTEXT ctxt; |
5203 HANDLE h = NULL; |
5199 HANDLE h = NULL; |
5227 } |
5223 } |
5228 |
5224 |
5229 |
5225 |
5230 // Kernel32 API |
5226 // Kernel32 API |
5231 typedef SIZE_T (WINAPI* GetLargePageMinimum_Fn)(void); |
5227 typedef SIZE_T (WINAPI* GetLargePageMinimum_Fn)(void); |
5232 typedef LPVOID (WINAPI *VirtualAllocExNuma_Fn) (HANDLE, LPVOID, SIZE_T, DWORD, DWORD, DWORD); |
5228 typedef LPVOID (WINAPI *VirtualAllocExNuma_Fn)(HANDLE, LPVOID, SIZE_T, DWORD, DWORD, DWORD); |
5233 typedef BOOL (WINAPI *GetNumaHighestNodeNumber_Fn) (PULONG); |
5229 typedef BOOL (WINAPI *GetNumaHighestNodeNumber_Fn)(PULONG); |
5234 typedef BOOL (WINAPI *GetNumaNodeProcessorMask_Fn) (UCHAR, PULONGLONG); |
5230 typedef BOOL (WINAPI *GetNumaNodeProcessorMask_Fn)(UCHAR, PULONGLONG); |
5235 typedef USHORT (WINAPI* RtlCaptureStackBackTrace_Fn)(ULONG, ULONG, PVOID*, PULONG); |
5231 typedef USHORT (WINAPI* RtlCaptureStackBackTrace_Fn)(ULONG, ULONG, PVOID*, PULONG); |
5236 |
5232 |
5237 GetLargePageMinimum_Fn os::Kernel32Dll::_GetLargePageMinimum = NULL; |
5233 GetLargePageMinimum_Fn os::Kernel32Dll::_GetLargePageMinimum = NULL; |
5238 VirtualAllocExNuma_Fn os::Kernel32Dll::_VirtualAllocExNuma = NULL; |
5234 VirtualAllocExNuma_Fn os::Kernel32Dll::_VirtualAllocExNuma = NULL; |
5239 GetNumaHighestNodeNumber_Fn os::Kernel32Dll::_GetNumaHighestNodeNumber = NULL; |
5235 GetNumaHighestNodeNumber_Fn os::Kernel32Dll::_GetNumaHighestNodeNumber = NULL; |
5260 initialize(); |
5256 initialize(); |
5261 } |
5257 } |
5262 return _VirtualAllocExNuma != NULL; |
5258 return _VirtualAllocExNuma != NULL; |
5263 } |
5259 } |
5264 |
5260 |
5265 LPVOID os::Kernel32Dll::VirtualAllocExNuma(HANDLE hProc, LPVOID addr, SIZE_T bytes, DWORD flags, DWORD prot, DWORD node) { |
5261 LPVOID os::Kernel32Dll::VirtualAllocExNuma(HANDLE hProc, LPVOID addr, |
5262 SIZE_T bytes, DWORD flags, |
|
5263 DWORD prot, DWORD node) { |
|
5266 assert(initialized && _VirtualAllocExNuma != NULL, |
5264 assert(initialized && _VirtualAllocExNuma != NULL, |
5267 "NUMACallsAvailable() not yet called"); |
5265 "NUMACallsAvailable() not yet called"); |
5268 |
5266 |
5269 return _VirtualAllocExNuma(hProc, addr, bytes, flags, prot, node); |
5267 return _VirtualAllocExNuma(hProc, addr, bytes, flags, prot, node); |
5270 } |
5268 } |
5274 "NUMACallsAvailable() not yet called"); |
5272 "NUMACallsAvailable() not yet called"); |
5275 |
5273 |
5276 return _GetNumaHighestNodeNumber(ptr_highest_node_number); |
5274 return _GetNumaHighestNodeNumber(ptr_highest_node_number); |
5277 } |
5275 } |
5278 |
5276 |
5279 BOOL os::Kernel32Dll::GetNumaNodeProcessorMask(UCHAR node, PULONGLONG proc_mask) { |
5277 BOOL os::Kernel32Dll::GetNumaNodeProcessorMask(UCHAR node, |
5278 PULONGLONG proc_mask) { |
|
5280 assert(initialized && _GetNumaNodeProcessorMask != NULL, |
5279 assert(initialized && _GetNumaNodeProcessorMask != NULL, |
5281 "NUMACallsAvailable() not yet called"); |
5280 "NUMACallsAvailable() not yet called"); |
5282 |
5281 |
5283 return _GetNumaNodeProcessorMask(node, proc_mask); |
5282 return _GetNumaNodeProcessorMask(node, proc_mask); |
5284 } |
5283 } |
5285 |
5284 |
5286 USHORT os::Kernel32Dll::RtlCaptureStackBackTrace(ULONG FrameToSkip, |
5285 USHORT os::Kernel32Dll::RtlCaptureStackBackTrace(ULONG FrameToSkip, |
5287 ULONG FrameToCapture, PVOID* BackTrace, PULONG BackTraceHash) { |
5286 ULONG FrameToCapture, |
5287 PVOID* BackTrace, |
|
5288 PULONG BackTraceHash) { |
|
5288 if (!initialized) { |
5289 if (!initialized) { |
5289 initialize(); |
5290 initialize(); |
5290 } |
5291 } |
5291 |
5292 |
5292 if (_RtlCaptureStackBackTrace != NULL) { |
5293 if (_RtlCaptureStackBackTrace != NULL) { |
5331 // Help tools |
5332 // Help tools |
5332 inline BOOL os::Kernel32Dll::HelpToolsAvailable() { |
5333 inline BOOL os::Kernel32Dll::HelpToolsAvailable() { |
5333 return true; |
5334 return true; |
5334 } |
5335 } |
5335 |
5336 |
5336 inline HANDLE os::Kernel32Dll::CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessId) { |
5337 inline HANDLE os::Kernel32Dll::CreateToolhelp32Snapshot(DWORD dwFlags, |
5338 DWORD th32ProcessId) { |
|
5337 return ::CreateToolhelp32Snapshot(dwFlags, th32ProcessId); |
5339 return ::CreateToolhelp32Snapshot(dwFlags, th32ProcessId); |
5338 } |
5340 } |
5339 |
5341 |
5340 inline BOOL os::Kernel32Dll::Module32First(HANDLE hSnapshot,LPMODULEENTRY32 lpme) { |
5342 inline BOOL os::Kernel32Dll::Module32First(HANDLE hSnapshot, |
5343 LPMODULEENTRY32 lpme) { |
|
5341 return ::Module32First(hSnapshot, lpme); |
5344 return ::Module32First(hSnapshot, lpme); |
5342 } |
5345 } |
5343 |
5346 |
5344 inline BOOL os::Kernel32Dll::Module32Next(HANDLE hSnapshot,LPMODULEENTRY32 lpme) { |
5347 inline BOOL os::Kernel32Dll::Module32Next(HANDLE hSnapshot, |
5348 LPMODULEENTRY32 lpme) { |
|
5345 return ::Module32Next(hSnapshot, lpme); |
5349 return ::Module32Next(hSnapshot, lpme); |
5346 } |
5350 } |
5347 |
5351 |
5348 |
5352 |
5349 inline BOOL os::Kernel32Dll::GetNativeSystemInfoAvailable() { |
5353 inline BOOL os::Kernel32Dll::GetNativeSystemInfoAvailable() { |
5353 inline void os::Kernel32Dll::GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) { |
5357 inline void os::Kernel32Dll::GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) { |
5354 ::GetNativeSystemInfo(lpSystemInfo); |
5358 ::GetNativeSystemInfo(lpSystemInfo); |
5355 } |
5359 } |
5356 |
5360 |
5357 // PSAPI API |
5361 // PSAPI API |
5358 inline BOOL os::PSApiDll::EnumProcessModules(HANDLE hProcess, HMODULE *lpModule, DWORD cb, LPDWORD lpcbNeeded) { |
5362 inline BOOL os::PSApiDll::EnumProcessModules(HANDLE hProcess, |
5363 HMODULE *lpModule, DWORD cb, |
|
5364 LPDWORD lpcbNeeded) { |
|
5359 return ::EnumProcessModules(hProcess, lpModule, cb, lpcbNeeded); |
5365 return ::EnumProcessModules(hProcess, lpModule, cb, lpcbNeeded); |
5360 } |
5366 } |
5361 |
5367 |
5362 inline DWORD os::PSApiDll::GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize) { |
5368 inline DWORD os::PSApiDll::GetModuleFileNameEx(HANDLE hProcess, |
5369 HMODULE hModule, |
|
5370 LPTSTR lpFilename, |
|
5371 DWORD nSize) { |
|
5363 return ::GetModuleFileNameEx(hProcess, hModule, lpFilename, nSize); |
5372 return ::GetModuleFileNameEx(hProcess, hModule, lpFilename, nSize); |
5364 } |
5373 } |
5365 |
5374 |
5366 inline BOOL os::PSApiDll::GetModuleInformation(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb) { |
5375 inline BOOL os::PSApiDll::GetModuleInformation(HANDLE hProcess, |
5376 HMODULE hModule, |
|
5377 LPMODULEINFO lpmodinfo, |
|
5378 DWORD cb) { |
|
5367 return ::GetModuleInformation(hProcess, hModule, lpmodinfo, cb); |
5379 return ::GetModuleInformation(hProcess, hModule, lpmodinfo, cb); |
5368 } |
5380 } |
5369 |
5381 |
5370 inline BOOL os::PSApiDll::PSApiAvailable() { |
5382 inline BOOL os::PSApiDll::PSApiAvailable() { |
5371 return true; |
5383 return true; |
5372 } |
5384 } |
5373 |
5385 |
5374 |
5386 |
5375 // WinSock2 API |
5387 // WinSock2 API |
5376 inline BOOL os::WinSock2Dll::WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) { |
5388 inline BOOL os::WinSock2Dll::WSAStartup(WORD wVersionRequested, |
5389 LPWSADATA lpWSAData) { |
|
5377 return ::WSAStartup(wVersionRequested, lpWSAData); |
5390 return ::WSAStartup(wVersionRequested, lpWSAData); |
5378 } |
5391 } |
5379 |
5392 |
5380 inline struct hostent* os::WinSock2Dll::gethostbyname(const char *name) { |
5393 inline struct hostent* os::WinSock2Dll::gethostbyname(const char *name) { |
5381 return ::gethostbyname(name); |
5394 return ::gethostbyname(name); |
5385 return true; |
5398 return true; |
5386 } |
5399 } |
5387 |
5400 |
5388 // Advapi API |
5401 // Advapi API |
5389 inline BOOL os::Advapi32Dll::AdjustTokenPrivileges(HANDLE TokenHandle, |
5402 inline BOOL os::Advapi32Dll::AdjustTokenPrivileges(HANDLE TokenHandle, |
5390 BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, |
5403 BOOL DisableAllPrivileges, |
5391 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength) { |
5404 PTOKEN_PRIVILEGES NewState, |
5405 DWORD BufferLength, |
|
5406 PTOKEN_PRIVILEGES PreviousState, |
|
5407 PDWORD ReturnLength) { |
|
5392 return ::AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges, NewState, |
5408 return ::AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges, NewState, |
5393 BufferLength, PreviousState, ReturnLength); |
5409 BufferLength, PreviousState, ReturnLength); |
5394 } |
5410 } |
5395 |
5411 |
5396 inline BOOL os::Advapi32Dll::OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, |
5412 inline BOOL os::Advapi32Dll::OpenProcessToken(HANDLE ProcessHandle, |
5413 DWORD DesiredAccess, |
|
5397 PHANDLE TokenHandle) { |
5414 PHANDLE TokenHandle) { |
5398 return ::OpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle); |
5415 return ::OpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle); |
5399 } |
5416 } |
5400 |
5417 |
5401 inline BOOL os::Advapi32Dll::LookupPrivilegeValue(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid) { |
5418 inline BOOL os::Advapi32Dll::LookupPrivilegeValue(LPCTSTR lpSystemName, |
5419 LPCTSTR lpName, |
|
5420 PLUID lpLuid) { |
|
5402 return ::LookupPrivilegeValue(lpSystemName, lpName, lpLuid); |
5421 return ::LookupPrivilegeValue(lpSystemName, lpName, lpLuid); |
5403 } |
5422 } |
5404 |
5423 |
5405 inline BOOL os::Advapi32Dll::AdvapiAvailable() { |
5424 inline BOOL os::Advapi32Dll::AdvapiAvailable() { |
5406 return true; |
5425 return true; |
5476 } |
5495 } |
5477 |
5496 |
5478 #else |
5497 #else |
5479 // Kernel32 API |
5498 // Kernel32 API |
5480 typedef BOOL (WINAPI* SwitchToThread_Fn)(void); |
5499 typedef BOOL (WINAPI* SwitchToThread_Fn)(void); |
5481 typedef HANDLE (WINAPI* CreateToolhelp32Snapshot_Fn)(DWORD,DWORD); |
5500 typedef HANDLE (WINAPI* CreateToolhelp32Snapshot_Fn)(DWORD, DWORD); |
5482 typedef BOOL (WINAPI* Module32First_Fn)(HANDLE,LPMODULEENTRY32); |
5501 typedef BOOL (WINAPI* Module32First_Fn)(HANDLE, LPMODULEENTRY32); |
5483 typedef BOOL (WINAPI* Module32Next_Fn)(HANDLE,LPMODULEENTRY32); |
5502 typedef BOOL (WINAPI* Module32Next_Fn)(HANDLE, LPMODULEENTRY32); |
5484 typedef void (WINAPI* GetNativeSystemInfo_Fn)(LPSYSTEM_INFO); |
5503 typedef void (WINAPI* GetNativeSystemInfo_Fn)(LPSYSTEM_INFO); |
5485 |
5504 |
5486 SwitchToThread_Fn os::Kernel32Dll::_SwitchToThread = NULL; |
5505 SwitchToThread_Fn os::Kernel32Dll::_SwitchToThread = NULL; |
5487 CreateToolhelp32Snapshot_Fn os::Kernel32Dll::_CreateToolhelp32Snapshot = NULL; |
5506 CreateToolhelp32Snapshot_Fn os::Kernel32Dll::_CreateToolhelp32Snapshot = NULL; |
5488 Module32First_Fn os::Kernel32Dll::_Module32First = NULL; |
5507 Module32First_Fn os::Kernel32Dll::_Module32First = NULL; |
5528 return _CreateToolhelp32Snapshot != NULL && |
5547 return _CreateToolhelp32Snapshot != NULL && |
5529 _Module32First != NULL && |
5548 _Module32First != NULL && |
5530 _Module32Next != NULL; |
5549 _Module32Next != NULL; |
5531 } |
5550 } |
5532 |
5551 |
5533 HANDLE os::Kernel32Dll::CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessId) { |
5552 HANDLE os::Kernel32Dll::CreateToolhelp32Snapshot(DWORD dwFlags, |
5553 DWORD th32ProcessId) { |
|
5534 assert(initialized && _CreateToolhelp32Snapshot != NULL, |
5554 assert(initialized && _CreateToolhelp32Snapshot != NULL, |
5535 "HelpToolsAvailable() not yet called"); |
5555 "HelpToolsAvailable() not yet called"); |
5536 |
5556 |
5537 return _CreateToolhelp32Snapshot(dwFlags, th32ProcessId); |
5557 return _CreateToolhelp32Snapshot(dwFlags, th32ProcessId); |
5538 } |
5558 } |
5542 "HelpToolsAvailable() not yet called"); |
5562 "HelpToolsAvailable() not yet called"); |
5543 |
5563 |
5544 return _Module32First(hSnapshot, lpme); |
5564 return _Module32First(hSnapshot, lpme); |
5545 } |
5565 } |
5546 |
5566 |
5547 inline BOOL os::Kernel32Dll::Module32Next(HANDLE hSnapshot,LPMODULEENTRY32 lpme) { |
5567 inline BOOL os::Kernel32Dll::Module32Next(HANDLE hSnapshot, |
5568 LPMODULEENTRY32 lpme) { |
|
5548 assert(initialized && _Module32Next != NULL, |
5569 assert(initialized && _Module32Next != NULL, |
5549 "HelpToolsAvailable() not yet called"); |
5570 "HelpToolsAvailable() not yet called"); |
5550 |
5571 |
5551 return _Module32Next(hSnapshot, lpme); |
5572 return _Module32Next(hSnapshot, lpme); |
5552 } |
5573 } |
5568 |
5589 |
5569 // PSAPI API |
5590 // PSAPI API |
5570 |
5591 |
5571 |
5592 |
5572 typedef BOOL (WINAPI *EnumProcessModules_Fn)(HANDLE, HMODULE *, DWORD, LPDWORD); |
5593 typedef BOOL (WINAPI *EnumProcessModules_Fn)(HANDLE, HMODULE *, DWORD, LPDWORD); |
5573 typedef BOOL (WINAPI *GetModuleFileNameEx_Fn)(HANDLE, HMODULE, LPTSTR, DWORD);; |
5594 typedef BOOL (WINAPI *GetModuleFileNameEx_Fn)(HANDLE, HMODULE, LPTSTR, DWORD); |
5574 typedef BOOL (WINAPI *GetModuleInformation_Fn)(HANDLE, HMODULE, LPMODULEINFO, DWORD); |
5595 typedef BOOL (WINAPI *GetModuleInformation_Fn)(HANDLE, HMODULE, LPMODULEINFO, DWORD); |
5575 |
5596 |
5576 EnumProcessModules_Fn os::PSApiDll::_EnumProcessModules = NULL; |
5597 EnumProcessModules_Fn os::PSApiDll::_EnumProcessModules = NULL; |
5577 GetModuleFileNameEx_Fn os::PSApiDll::_GetModuleFileNameEx = NULL; |
5598 GetModuleFileNameEx_Fn os::PSApiDll::_GetModuleFileNameEx = NULL; |
5578 GetModuleInformation_Fn os::PSApiDll::_GetModuleInformation = NULL; |
5599 GetModuleInformation_Fn os::PSApiDll::_GetModuleInformation = NULL; |
5593 } |
5614 } |
5594 } |
5615 } |
5595 |
5616 |
5596 |
5617 |
5597 |
5618 |
5598 BOOL os::PSApiDll::EnumProcessModules(HANDLE hProcess, HMODULE *lpModule, DWORD cb, LPDWORD lpcbNeeded) { |
5619 BOOL os::PSApiDll::EnumProcessModules(HANDLE hProcess, HMODULE *lpModule, |
5620 DWORD cb, LPDWORD lpcbNeeded) { |
|
5599 assert(initialized && _EnumProcessModules != NULL, |
5621 assert(initialized && _EnumProcessModules != NULL, |
5600 "PSApiAvailable() not yet called"); |
5622 "PSApiAvailable() not yet called"); |
5601 return _EnumProcessModules(hProcess, lpModule, cb, lpcbNeeded); |
5623 return _EnumProcessModules(hProcess, lpModule, cb, lpcbNeeded); |
5602 } |
5624 } |
5603 |
5625 |
5604 DWORD os::PSApiDll::GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize) { |
5626 DWORD os::PSApiDll::GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule, |
5627 LPTSTR lpFilename, DWORD nSize) { |
|
5605 assert(initialized && _GetModuleFileNameEx != NULL, |
5628 assert(initialized && _GetModuleFileNameEx != NULL, |
5606 "PSApiAvailable() not yet called"); |
5629 "PSApiAvailable() not yet called"); |
5607 return _GetModuleFileNameEx(hProcess, hModule, lpFilename, nSize); |
5630 return _GetModuleFileNameEx(hProcess, hModule, lpFilename, nSize); |
5608 } |
5631 } |
5609 |
5632 |
5610 BOOL os::PSApiDll::GetModuleInformation(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb) { |
5633 BOOL os::PSApiDll::GetModuleInformation(HANDLE hProcess, HMODULE hModule, |
5634 LPMODULEINFO lpmodinfo, DWORD cb) { |
|
5611 assert(initialized && _GetModuleInformation != NULL, |
5635 assert(initialized && _GetModuleInformation != NULL, |
5612 "PSApiAvailable() not yet called"); |
5636 "PSApiAvailable() not yet called"); |
5613 return _GetModuleInformation(hProcess, hModule, lpmodinfo, cb); |
5637 return _GetModuleInformation(hProcess, hModule, lpmodinfo, cb); |
5614 } |
5638 } |
5615 |
5639 |
5686 initialized = TRUE; |
5710 initialized = TRUE; |
5687 } |
5711 } |
5688 } |
5712 } |
5689 |
5713 |
5690 BOOL os::Advapi32Dll::AdjustTokenPrivileges(HANDLE TokenHandle, |
5714 BOOL os::Advapi32Dll::AdjustTokenPrivileges(HANDLE TokenHandle, |
5691 BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, |
5715 BOOL DisableAllPrivileges, |
5692 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength) { |
5716 PTOKEN_PRIVILEGES NewState, |
5717 DWORD BufferLength, |
|
5718 PTOKEN_PRIVILEGES PreviousState, |
|
5719 PDWORD ReturnLength) { |
|
5693 assert(initialized && _AdjustTokenPrivileges != NULL, |
5720 assert(initialized && _AdjustTokenPrivileges != NULL, |
5694 "AdvapiAvailable() not yet called"); |
5721 "AdvapiAvailable() not yet called"); |
5695 return _AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges, NewState, |
5722 return _AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges, NewState, |
5696 BufferLength, PreviousState, ReturnLength); |
5723 BufferLength, PreviousState, ReturnLength); |
5697 } |
5724 } |
5698 |
5725 |
5699 BOOL os::Advapi32Dll::OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, |
5726 BOOL os::Advapi32Dll::OpenProcessToken(HANDLE ProcessHandle, |
5727 DWORD DesiredAccess, |
|
5700 PHANDLE TokenHandle) { |
5728 PHANDLE TokenHandle) { |
5701 assert(initialized && _OpenProcessToken != NULL, |
5729 assert(initialized && _OpenProcessToken != NULL, |
5702 "AdvapiAvailable() not yet called"); |
5730 "AdvapiAvailable() not yet called"); |
5703 return _OpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle); |
5731 return _OpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle); |
5704 } |
5732 } |
5705 |
5733 |
5706 BOOL os::Advapi32Dll::LookupPrivilegeValue(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid) { |
5734 BOOL os::Advapi32Dll::LookupPrivilegeValue(LPCTSTR lpSystemName, |
5735 LPCTSTR lpName, PLUID lpLuid) { |
|
5707 assert(initialized && _LookupPrivilegeValue != NULL, |
5736 assert(initialized && _LookupPrivilegeValue != NULL, |
5708 "AdvapiAvailable() not yet called"); |
5737 "AdvapiAvailable() not yet called"); |
5709 return _LookupPrivilegeValue(lpSystemName, lpName, lpLuid); |
5738 return _LookupPrivilegeValue(lpSystemName, lpName, lpLuid); |
5710 } |
5739 } |
5711 |
5740 |