< prev index next >

src/os/windows/vm/os_windows.cpp

Print this page




 806 static jlong  fake_time = 0;
 807 
 808 #ifdef ASSERT
 809 // Just to be safe, recalculate the offset in debug mode
 810 static jlong _calculated_offset = 0;
 811 static int   _has_calculated_offset = 0;
 812 
 813 jlong offset() {
 814   if (_has_calculated_offset) return _calculated_offset;
 815   SYSTEMTIME java_origin;
 816   java_origin.wYear          = 1970;
 817   java_origin.wMonth         = 1;
 818   java_origin.wDayOfWeek     = 0; // ignored
 819   java_origin.wDay           = 1;
 820   java_origin.wHour          = 0;
 821   java_origin.wMinute        = 0;
 822   java_origin.wSecond        = 0;
 823   java_origin.wMilliseconds  = 0;
 824   FILETIME jot;
 825   if (!SystemTimeToFileTime(&java_origin, &jot)) {
 826     fatal(err_msg("Error = %d\nWindows error", GetLastError()));
 827   }
 828   _calculated_offset = jlong_from(jot.dwHighDateTime, jot.dwLowDateTime);
 829   _has_calculated_offset = 1;
 830   assert(_calculated_offset == _offset, "Calculated and constant time offsets must be equal");
 831   return _calculated_offset;
 832 }
 833 #else
 834 jlong offset() {
 835   return _offset;
 836 }
 837 #endif
 838 
 839 jlong windows_to_java_time(FILETIME wt) {
 840   jlong a = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime);
 841   return (a - offset()) / 10000;
 842 }
 843 
 844 // Returns time ticks in (10th of micro seconds)
 845 jlong windows_to_time_ticks(FILETIME wt) {
 846   jlong a = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime);


1919     if (n >= len) n = len - 1;
1920     strncpy(buf, s, n);
1921     buf[n] = '\0';
1922     return n;
1923   }
1924 
1925   return 0;
1926 }
1927 
1928 int os::get_last_error() {
1929   DWORD error = GetLastError();
1930   if (error == 0) {
1931     error = errno;
1932   }
1933   return (int)error;
1934 }
1935 
1936 WindowsSemaphore::WindowsSemaphore(uint value) {
1937   _semaphore = ::CreateSemaphore(NULL, value, LONG_MAX, NULL);
1938 
1939   guarantee(_semaphore != NULL, err_msg("CreateSemaphore failed with error code: %lu", GetLastError()));
1940 }
1941 
1942 WindowsSemaphore::~WindowsSemaphore() {
1943   ::CloseHandle(_semaphore);
1944 }
1945 
1946 void WindowsSemaphore::signal(uint count) {
1947   if (count > 0) {
1948     BOOL ret = ::ReleaseSemaphore(_semaphore, count, NULL);
1949 
1950     assert(ret != 0, err_msg("ReleaseSemaphore failed with error code: %lu", GetLastError()));
1951   }
1952 }
1953 
1954 void WindowsSemaphore::wait() {
1955   DWORD ret = ::WaitForSingleObject(_semaphore, INFINITE);
1956   assert(ret != WAIT_FAILED,   err_msg("WaitForSingleObject failed with error code: %lu", GetLastError()));
1957   assert(ret == WAIT_OBJECT_0, err_msg("WaitForSingleObject failed with return value: %lu", ret));
1958 }
1959 
1960 // sun.misc.Signal
1961 // NOTE that this is a workaround for an apparent kernel bug where if
1962 // a signal handler for SIGBREAK is installed then that signal handler
1963 // takes priority over the console control handler for CTRL_CLOSE_EVENT.
1964 // See bug 4416763.
1965 static void (*sigbreakHandler)(int) = NULL;
1966 
1967 static void UserHandler(int sig, void *siginfo, void *context) {
1968   os::signal_notify(sig);
1969   // We need to reinstate the signal handler each time...
1970   os::signal(sig, (void*)UserHandler);
1971 }
1972 
1973 void* os::user_handler() {
1974   return (void*) UserHandler;
1975 }
1976 
1977 void* os::signal(int signal_number, void* handler) {


2327     return (prev_uef_handler)(exceptionInfo);
2328   }
2329 #else // !_WIN64
2330   // On Windows, the mxcsr control bits are non-volatile across calls
2331   // See also CR 6192333
2332   //
2333   jint MxCsr = INITIAL_MXCSR;
2334   // we can't use StubRoutines::addr_mxcsr_std()
2335   // because in Win64 mxcsr is not saved there
2336   if (MxCsr != ctx->MxCsr) {
2337     ctx->MxCsr = MxCsr;
2338     return EXCEPTION_CONTINUE_EXECUTION;
2339   }
2340 #endif // !_WIN64
2341 
2342   return EXCEPTION_CONTINUE_SEARCH;
2343 }
2344 
2345 static inline void report_error(Thread* t, DWORD exception_code,
2346                                 address addr, void* siginfo, void* context) {
2347   VMError err(t, exception_code, addr, siginfo, context);
2348   err.report_and_die();
2349 
2350   // If UseOsErrorReporting, this will return here and save the error file
2351   // somewhere where we can find it in the minidump.
2352 }
2353 
2354 //-----------------------------------------------------------------------------
2355 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2356   if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
2357   DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2358 #ifdef _M_IA64
2359   // On Itanium, we need the "precise pc", which has the slot number coded
2360   // into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format).
2361   address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress;
2362   // Convert the pc to "Unix format", which has the slot number coded
2363   // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2
2364   // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction"
2365   // information is saved in the Unix format.
2366   address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2));
2367 #else
2368   #ifdef _M_AMD64


3308       }
3309       bytes_remaining -= bytes_to_rq;
3310       next_alloc_addr += bytes_to_rq;
3311     }
3312   }
3313   // if we made it this far, return true
3314   return true;
3315 }
3316 
3317 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
3318                           bool exec) {
3319   // alignment_hint is ignored on this OS
3320   return pd_commit_memory(addr, size, exec);
3321 }
3322 
3323 void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
3324                                   const char* mesg) {
3325   assert(mesg != NULL, "mesg must be specified");
3326   if (!pd_commit_memory(addr, size, exec)) {
3327     warn_fail_commit_memory(addr, size, exec);
3328     vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
3329   }
3330 }
3331 
3332 void os::pd_commit_memory_or_exit(char* addr, size_t size,
3333                                   size_t alignment_hint, bool exec,
3334                                   const char* mesg) {
3335   // alignment_hint is ignored on this OS
3336   pd_commit_memory_or_exit(addr, size, exec, mesg);
3337 }
3338 
3339 bool os::pd_uncommit_memory(char* addr, size_t bytes) {
3340   if (bytes == 0) {
3341     // Don't bother the OS with noops.
3342     return true;
3343   }
3344   assert((size_t) addr % os::vm_page_size() == 0, "uncommit on page boundaries");
3345   assert(bytes % os::vm_page_size() == 0, "uncommit in page-sized chunks");
3346   return (VirtualFree(addr, bytes, MEM_DECOMMIT) != 0);
3347 }
3348 


5242     // wrong; at these points, eax contains the address of the offending block (I think).
5243     // To get to the exlicit error message(s) below, just continue twice.
5244     HANDLE heap = GetProcessHeap();
5245 
5246     // If we fail to lock the heap, then gflags.exe has been used
5247     // or some other special heap flag has been set that prevents
5248     // locking. We don't try to walk a heap we can't lock.
5249     if (HeapLock(heap) != 0) {
5250       PROCESS_HEAP_ENTRY phe;
5251       phe.lpData = NULL;
5252       while (HeapWalk(heap, &phe) != 0) {
5253         if ((phe.wFlags & PROCESS_HEAP_ENTRY_BUSY) &&
5254             !HeapValidate(heap, 0, phe.lpData)) {
5255           tty->print_cr("C heap has been corrupted (time: %d allocations)", mallocDebugCounter);
5256           tty->print_cr("corrupted block near address %#x, length %d", phe.lpData, phe.cbData);
5257           fatal("corrupted C heap");
5258         }
5259       }
5260       DWORD err = GetLastError();
5261       if (err != ERROR_NO_MORE_ITEMS && err != ERROR_CALL_NOT_IMPLEMENTED) {
5262         fatal(err_msg("heap walk aborted with error %d", err));
5263       }
5264       HeapUnlock(heap);
5265     }
5266     mallocDebugIntervalCounter = 0;
5267   }
5268   return true;
5269 }
5270 
5271 
5272 bool os::find(address addr, outputStream* st) {
5273   // Nothing yet
5274   return false;
5275 }
5276 
5277 LONG WINAPI os::win32::serialize_fault_filter(struct _EXCEPTION_POINTERS* e) {
5278   DWORD exception_code = e->ExceptionRecord->ExceptionCode;
5279 
5280   if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
5281     JavaThread* thread = (JavaThread*)ThreadLocalStorage::get_thread_slow();
5282     PEXCEPTION_RECORD exceptionRecord = e->ExceptionRecord;


5961                           large_allocation_size);
5962     }
5963   } else {
5964     os::release_memory_special(result, large_allocation_size);
5965 
5966     // allocate another page within the recently allocated memory area which seems to be a good location. At least
5967     // we managed to get it once.
5968     const size_t expected_allocation_size = os::large_page_size();
5969     char* expected_location = result + os::large_page_size();
5970     char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false);
5971     if (actual_location == NULL) {
5972       if (VerboseInternalVMTests) {
5973         gclog_or_tty->print("Failed to allocate any memory at " PTR_FORMAT " size " SIZE_FORMAT ". Skipping remainder of test.",
5974                             expected_location, large_allocation_size);
5975       }
5976     } else {
5977       // release memory
5978       os::release_memory_special(actual_location, expected_allocation_size);
5979       // only now check, after releasing any memory to avoid any leaks.
5980       assert(actual_location == expected_location,
5981              err_msg("Failed to allocate memory at requested location " PTR_FORMAT " of size " SIZE_FORMAT ", is " PTR_FORMAT " instead",
5982              expected_location, expected_allocation_size, actual_location));
5983     }
5984   }
5985 
5986   // restore globals
5987   UseLargePagesIndividualAllocation = old_use_large_pages_individual_allocation;
5988   UseNUMAInterleaving = old_use_numa_interleaving;
5989 }
5990 #endif // PRODUCT


 806 static jlong  fake_time = 0;
 807 
 808 #ifdef ASSERT
 809 // Just to be safe, recalculate the offset in debug mode
 810 static jlong _calculated_offset = 0;
 811 static int   _has_calculated_offset = 0;
 812 
 813 jlong offset() {
 814   if (_has_calculated_offset) return _calculated_offset;
 815   SYSTEMTIME java_origin;
 816   java_origin.wYear          = 1970;
 817   java_origin.wMonth         = 1;
 818   java_origin.wDayOfWeek     = 0; // ignored
 819   java_origin.wDay           = 1;
 820   java_origin.wHour          = 0;
 821   java_origin.wMinute        = 0;
 822   java_origin.wSecond        = 0;
 823   java_origin.wMilliseconds  = 0;
 824   FILETIME jot;
 825   if (!SystemTimeToFileTime(&java_origin, &jot)) {
 826     fatal("Error = %d\nWindows error", GetLastError());
 827   }
 828   _calculated_offset = jlong_from(jot.dwHighDateTime, jot.dwLowDateTime);
 829   _has_calculated_offset = 1;
 830   assert(_calculated_offset == _offset, "Calculated and constant time offsets must be equal");
 831   return _calculated_offset;
 832 }
 833 #else
 834 jlong offset() {
 835   return _offset;
 836 }
 837 #endif
 838 
 839 jlong windows_to_java_time(FILETIME wt) {
 840   jlong a = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime);
 841   return (a - offset()) / 10000;
 842 }
 843 
 844 // Returns time ticks in (10th of micro seconds)
 845 jlong windows_to_time_ticks(FILETIME wt) {
 846   jlong a = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime);


1919     if (n >= len) n = len - 1;
1920     strncpy(buf, s, n);
1921     buf[n] = '\0';
1922     return n;
1923   }
1924 
1925   return 0;
1926 }
1927 
1928 int os::get_last_error() {
1929   DWORD error = GetLastError();
1930   if (error == 0) {
1931     error = errno;
1932   }
1933   return (int)error;
1934 }
1935 
1936 WindowsSemaphore::WindowsSemaphore(uint value) {
1937   _semaphore = ::CreateSemaphore(NULL, value, LONG_MAX, NULL);
1938 
1939   guarantee(_semaphore != NULL, "CreateSemaphore failed with error code: %lu", GetLastError());
1940 }
1941 
1942 WindowsSemaphore::~WindowsSemaphore() {
1943   ::CloseHandle(_semaphore);
1944 }
1945 
1946 void WindowsSemaphore::signal(uint count) {
1947   if (count > 0) {
1948     BOOL ret = ::ReleaseSemaphore(_semaphore, count, NULL);
1949 
1950     assert(ret != 0, "ReleaseSemaphore failed with error code: %lu", GetLastError());
1951   }
1952 }
1953 
1954 void WindowsSemaphore::wait() {
1955   DWORD ret = ::WaitForSingleObject(_semaphore, INFINITE);
1956   assert(ret != WAIT_FAILED,   "WaitForSingleObject failed with error code: %lu", GetLastError());
1957   assert(ret == WAIT_OBJECT_0, "WaitForSingleObject failed with return value: %lu", ret);
1958 }
1959 
1960 // sun.misc.Signal
1961 // NOTE that this is a workaround for an apparent kernel bug where if
1962 // a signal handler for SIGBREAK is installed then that signal handler
1963 // takes priority over the console control handler for CTRL_CLOSE_EVENT.
1964 // See bug 4416763.
1965 static void (*sigbreakHandler)(int) = NULL;
1966 
1967 static void UserHandler(int sig, void *siginfo, void *context) {
1968   os::signal_notify(sig);
1969   // We need to reinstate the signal handler each time...
1970   os::signal(sig, (void*)UserHandler);
1971 }
1972 
1973 void* os::user_handler() {
1974   return (void*) UserHandler;
1975 }
1976 
1977 void* os::signal(int signal_number, void* handler) {


2327     return (prev_uef_handler)(exceptionInfo);
2328   }
2329 #else // !_WIN64
2330   // On Windows, the mxcsr control bits are non-volatile across calls
2331   // See also CR 6192333
2332   //
2333   jint MxCsr = INITIAL_MXCSR;
2334   // we can't use StubRoutines::addr_mxcsr_std()
2335   // because in Win64 mxcsr is not saved there
2336   if (MxCsr != ctx->MxCsr) {
2337     ctx->MxCsr = MxCsr;
2338     return EXCEPTION_CONTINUE_EXECUTION;
2339   }
2340 #endif // !_WIN64
2341 
2342   return EXCEPTION_CONTINUE_SEARCH;
2343 }
2344 
2345 static inline void report_error(Thread* t, DWORD exception_code,
2346                                 address addr, void* siginfo, void* context) {
2347   VMError::report_and_die(t, exception_code, addr, siginfo, context);

2348 
2349   // If UseOsErrorReporting, this will return here and save the error file
2350   // somewhere where we can find it in the minidump.
2351 }
2352 
2353 //-----------------------------------------------------------------------------
2354 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2355   if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
2356   DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2357 #ifdef _M_IA64
2358   // On Itanium, we need the "precise pc", which has the slot number coded
2359   // into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format).
2360   address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress;
2361   // Convert the pc to "Unix format", which has the slot number coded
2362   // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2
2363   // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction"
2364   // information is saved in the Unix format.
2365   address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2));
2366 #else
2367   #ifdef _M_AMD64


3307       }
3308       bytes_remaining -= bytes_to_rq;
3309       next_alloc_addr += bytes_to_rq;
3310     }
3311   }
3312   // if we made it this far, return true
3313   return true;
3314 }
3315 
3316 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
3317                           bool exec) {
3318   // alignment_hint is ignored on this OS
3319   return pd_commit_memory(addr, size, exec);
3320 }
3321 
3322 void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
3323                                   const char* mesg) {
3324   assert(mesg != NULL, "mesg must be specified");
3325   if (!pd_commit_memory(addr, size, exec)) {
3326     warn_fail_commit_memory(addr, size, exec);
3327     vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "%s", mesg);
3328   }
3329 }
3330 
3331 void os::pd_commit_memory_or_exit(char* addr, size_t size,
3332                                   size_t alignment_hint, bool exec,
3333                                   const char* mesg) {
3334   // alignment_hint is ignored on this OS
3335   pd_commit_memory_or_exit(addr, size, exec, mesg);
3336 }
3337 
3338 bool os::pd_uncommit_memory(char* addr, size_t bytes) {
3339   if (bytes == 0) {
3340     // Don't bother the OS with noops.
3341     return true;
3342   }
3343   assert((size_t) addr % os::vm_page_size() == 0, "uncommit on page boundaries");
3344   assert(bytes % os::vm_page_size() == 0, "uncommit in page-sized chunks");
3345   return (VirtualFree(addr, bytes, MEM_DECOMMIT) != 0);
3346 }
3347 


5241     // wrong; at these points, eax contains the address of the offending block (I think).
5242     // To get to the exlicit error message(s) below, just continue twice.
5243     HANDLE heap = GetProcessHeap();
5244 
5245     // If we fail to lock the heap, then gflags.exe has been used
5246     // or some other special heap flag has been set that prevents
5247     // locking. We don't try to walk a heap we can't lock.
5248     if (HeapLock(heap) != 0) {
5249       PROCESS_HEAP_ENTRY phe;
5250       phe.lpData = NULL;
5251       while (HeapWalk(heap, &phe) != 0) {
5252         if ((phe.wFlags & PROCESS_HEAP_ENTRY_BUSY) &&
5253             !HeapValidate(heap, 0, phe.lpData)) {
5254           tty->print_cr("C heap has been corrupted (time: %d allocations)", mallocDebugCounter);
5255           tty->print_cr("corrupted block near address %#x, length %d", phe.lpData, phe.cbData);
5256           fatal("corrupted C heap");
5257         }
5258       }
5259       DWORD err = GetLastError();
5260       if (err != ERROR_NO_MORE_ITEMS && err != ERROR_CALL_NOT_IMPLEMENTED) {
5261         fatal("heap walk aborted with error %d", err);
5262       }
5263       HeapUnlock(heap);
5264     }
5265     mallocDebugIntervalCounter = 0;
5266   }
5267   return true;
5268 }
5269 
5270 
5271 bool os::find(address addr, outputStream* st) {
5272   // Nothing yet
5273   return false;
5274 }
5275 
5276 LONG WINAPI os::win32::serialize_fault_filter(struct _EXCEPTION_POINTERS* e) {
5277   DWORD exception_code = e->ExceptionRecord->ExceptionCode;
5278 
5279   if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
5280     JavaThread* thread = (JavaThread*)ThreadLocalStorage::get_thread_slow();
5281     PEXCEPTION_RECORD exceptionRecord = e->ExceptionRecord;


5960                           large_allocation_size);
5961     }
5962   } else {
5963     os::release_memory_special(result, large_allocation_size);
5964 
5965     // allocate another page within the recently allocated memory area which seems to be a good location. At least
5966     // we managed to get it once.
5967     const size_t expected_allocation_size = os::large_page_size();
5968     char* expected_location = result + os::large_page_size();
5969     char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false);
5970     if (actual_location == NULL) {
5971       if (VerboseInternalVMTests) {
5972         gclog_or_tty->print("Failed to allocate any memory at " PTR_FORMAT " size " SIZE_FORMAT ". Skipping remainder of test.",
5973                             expected_location, large_allocation_size);
5974       }
5975     } else {
5976       // release memory
5977       os::release_memory_special(actual_location, expected_allocation_size);
5978       // only now check, after releasing any memory to avoid any leaks.
5979       assert(actual_location == expected_location,
5980              "Failed to allocate memory at requested location " PTR_FORMAT " of size " SIZE_FORMAT ", is " PTR_FORMAT " instead",
5981              expected_location, expected_allocation_size, actual_location);
5982     }
5983   }
5984 
5985   // restore globals
5986   UseLargePagesIndividualAllocation = old_use_large_pages_individual_allocation;
5987   UseNUMAInterleaving = old_use_numa_interleaving;
5988 }
5989 #endif // PRODUCT
< prev index next >