Mercurial > hg > truffle
comparison src/os/windows/vm/os_windows.cpp @ 8124:5fc51c1ecdeb
Merge.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Tue, 05 Mar 2013 23:44:54 +0100 |
parents | fbbc2ea60c4d 7adae9244bc8 |
children | b9a918201d47 |
comparison
equal
deleted
inserted
replaced
7943:a413bcd552a4 | 8124:5fc51c1ecdeb |
---|---|
347 break; | 347 break; |
348 } | 348 } |
349 | 349 |
350 #ifdef _M_IA64 | 350 #ifdef _M_IA64 |
351 // IA64 has memory and register stacks | 351 // IA64 has memory and register stacks |
352 // | |
353 // This is the stack layout you get on NT/IA64 if you specify 1MB stack limit | |
354 // at thread creation (1MB backing store growing upwards, 1MB memory stack | |
355 // growing downwards, 2MB summed up) | |
356 // | |
357 // ... | |
358 // ------- top of stack (high address) ----- | |
359 // | | |
360 // | 1MB | |
361 // | Backing Store (Register Stack) | |
362 // | | |
363 // | / \ | |
364 // | | | |
365 // | | | |
366 // | | | |
367 // ------------------------ stack base ----- | |
368 // | 1MB | |
369 // | Memory Stack | |
370 // | | |
371 // | | | |
372 // | | | |
373 // | | | |
374 // | \ / | |
375 // | | |
376 // ----- bottom of stack (low address) ----- | |
377 // ... | |
378 | |
352 stack_size = stack_size / 2; | 379 stack_size = stack_size / 2; |
353 #endif | 380 #endif |
354 return stack_bottom + stack_size; | 381 return stack_bottom + stack_size; |
355 } | 382 } |
356 | 383 |
1911 return NSIG; | 1938 return NSIG; |
1912 } | 1939 } |
1913 | 1940 |
1914 // a counter for each possible signal value, including signal_thread exit signal | 1941 // a counter for each possible signal value, including signal_thread exit signal |
1915 static volatile jint pending_signals[NSIG+1] = { 0 }; | 1942 static volatile jint pending_signals[NSIG+1] = { 0 }; |
1916 static HANDLE sig_sem; | 1943 static HANDLE sig_sem = NULL; |
1917 | 1944 |
1918 void os::signal_init_pd() { | 1945 void os::signal_init_pd() { |
1919 // Initialize signal structures | 1946 // Initialize signal structures |
1920 memset((void*)pending_signals, 0, sizeof(pending_signals)); | 1947 memset((void*)pending_signals, 0, sizeof(pending_signals)); |
1921 | 1948 |
1941 } | 1968 } |
1942 } | 1969 } |
1943 | 1970 |
1944 void os::signal_notify(int signal_number) { | 1971 void os::signal_notify(int signal_number) { |
1945 BOOL ret; | 1972 BOOL ret; |
1946 | 1973 if (sig_sem != NULL) { |
1947 Atomic::inc(&pending_signals[signal_number]); | 1974 Atomic::inc(&pending_signals[signal_number]); |
1948 ret = ::ReleaseSemaphore(sig_sem, 1, NULL); | 1975 ret = ::ReleaseSemaphore(sig_sem, 1, NULL); |
1949 assert(ret != 0, "ReleaseSemaphore() failed"); | 1976 assert(ret != 0, "ReleaseSemaphore() failed"); |
1977 } | |
1950 } | 1978 } |
1951 | 1979 |
1952 static int check_pending_signals(bool wait_for_signal) { | 1980 static int check_pending_signals(bool wait_for_signal) { |
1953 DWORD ret; | 1981 DWORD ret; |
1954 while (true) { | 1982 while (true) { |
2003 | 2031 |
2004 LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler) { | 2032 LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler) { |
2005 JavaThread* thread = JavaThread::current(); | 2033 JavaThread* thread = JavaThread::current(); |
2006 // Save pc in thread | 2034 // Save pc in thread |
2007 #ifdef _M_IA64 | 2035 #ifdef _M_IA64 |
2008 thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->StIIP); | 2036 // Do not blow up if no thread info available. |
2037 if (thread) { | |
2038 // Saving PRECISE pc (with slot information) in thread. | |
2039 uint64_t precise_pc = (uint64_t) exceptionInfo->ExceptionRecord->ExceptionAddress; | |
2040 // Convert precise PC into "Unix" format | |
2041 precise_pc = (precise_pc & 0xFFFFFFFFFFFFFFF0) | ((precise_pc & 0xF) >> 2); | |
2042 thread->set_saved_exception_pc((address)precise_pc); | |
2043 } | |
2009 // Set pc to handler | 2044 // Set pc to handler |
2010 exceptionInfo->ContextRecord->StIIP = (DWORD64)handler; | 2045 exceptionInfo->ContextRecord->StIIP = (DWORD64)handler; |
2046 // Clear out psr.ri (= Restart Instruction) in order to continue | |
2047 // at the beginning of the target bundle. | |
2048 exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF; | |
2049 assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!"); | |
2011 #elif _M_AMD64 | 2050 #elif _M_AMD64 |
2012 thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->Rip); | 2051 // Do not blow up if no thread info available. |
2052 if (thread) { | |
2053 thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip); | |
2054 } | |
2013 // Set pc to handler | 2055 // Set pc to handler |
2014 exceptionInfo->ContextRecord->Rip = (DWORD64)handler; | 2056 exceptionInfo->ContextRecord->Rip = (DWORD64)handler; |
2015 #else | 2057 #else |
2016 thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->Eip); | 2058 // Do not blow up if no thread info available. |
2059 if (thread) { | |
2060 thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip); | |
2061 } | |
2017 // Set pc to handler | 2062 // Set pc to handler |
2018 exceptionInfo->ContextRecord->Eip = (LONG)handler; | 2063 exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler; |
2019 #endif | 2064 #endif |
2020 | 2065 |
2021 // Continue the execution | 2066 // Continue the execution |
2022 return EXCEPTION_CONTINUE_EXECUTION; | 2067 return EXCEPTION_CONTINUE_EXECUTION; |
2023 } | 2068 } |
2037 | 2082 |
2038 // From "Execution Protection in the Windows Operating System" draft 0.35 | 2083 // From "Execution Protection in the Windows Operating System" draft 0.35 |
2039 // Once a system header becomes available, the "real" define should be | 2084 // Once a system header becomes available, the "real" define should be |
2040 // included or copied here. | 2085 // included or copied here. |
2041 #define EXCEPTION_INFO_EXEC_VIOLATION 0x08 | 2086 #define EXCEPTION_INFO_EXEC_VIOLATION 0x08 |
2087 | |
2088 // Handle NAT Bit consumption on IA64. | |
2089 #ifdef _M_IA64 | |
2090 #define EXCEPTION_REG_NAT_CONSUMPTION STATUS_REG_NAT_CONSUMPTION | |
2091 #endif | |
2092 | |
2093 // Windows Vista/2008 heap corruption check | |
2094 #define EXCEPTION_HEAP_CORRUPTION 0xC0000374 | |
2042 | 2095 |
2043 #define def_excpt(val) #val, val | 2096 #define def_excpt(val) #val, val |
2044 | 2097 |
2045 struct siglabel { | 2098 struct siglabel { |
2046 char *name; | 2099 char *name; |
2080 def_excpt(EXCEPTION_STACK_OVERFLOW), | 2133 def_excpt(EXCEPTION_STACK_OVERFLOW), |
2081 def_excpt(EXCEPTION_INVALID_DISPOSITION), | 2134 def_excpt(EXCEPTION_INVALID_DISPOSITION), |
2082 def_excpt(EXCEPTION_GUARD_PAGE), | 2135 def_excpt(EXCEPTION_GUARD_PAGE), |
2083 def_excpt(EXCEPTION_INVALID_HANDLE), | 2136 def_excpt(EXCEPTION_INVALID_HANDLE), |
2084 def_excpt(EXCEPTION_UNCAUGHT_CXX_EXCEPTION), | 2137 def_excpt(EXCEPTION_UNCAUGHT_CXX_EXCEPTION), |
2138 def_excpt(EXCEPTION_HEAP_CORRUPTION), | |
2139 #ifdef _M_IA64 | |
2140 def_excpt(EXCEPTION_REG_NAT_CONSUMPTION), | |
2141 #endif | |
2085 NULL, 0 | 2142 NULL, 0 |
2086 }; | 2143 }; |
2087 | 2144 |
2088 const char* os::exception_name(int exception_code, char *buf, size_t size) { | 2145 const char* os::exception_name(int exception_code, char *buf, size_t size) { |
2089 for (int i = 0; exceptlabels[i].name != NULL; i++) { | 2146 for (int i = 0; exceptlabels[i].name != NULL; i++) { |
2220 //----------------------------------------------------------------------------- | 2277 //----------------------------------------------------------------------------- |
2221 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { | 2278 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { |
2222 if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH; | 2279 if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH; |
2223 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; | 2280 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; |
2224 #ifdef _M_IA64 | 2281 #ifdef _M_IA64 |
2225 address pc = (address) exceptionInfo->ContextRecord->StIIP; | 2282 // On Itanium, we need the "precise pc", which has the slot number coded |
2283 // into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format). | |
2284 address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress; | |
2285 // Convert the pc to "Unix format", which has the slot number coded | |
2286 // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2 | |
2287 // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction" | |
2288 // information is saved in the Unix format. | |
2289 address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2)); | |
2226 #elif _M_AMD64 | 2290 #elif _M_AMD64 |
2227 address pc = (address) exceptionInfo->ContextRecord->Rip; | 2291 address pc = (address) exceptionInfo->ContextRecord->Rip; |
2228 #else | 2292 #else |
2229 address pc = (address) exceptionInfo->ContextRecord->Eip; | 2293 address pc = (address) exceptionInfo->ContextRecord->Eip; |
2230 #endif | 2294 #endif |
2335 | 2399 |
2336 // Handle potential stack overflows up front. | 2400 // Handle potential stack overflows up front. |
2337 if (exception_code == EXCEPTION_STACK_OVERFLOW) { | 2401 if (exception_code == EXCEPTION_STACK_OVERFLOW) { |
2338 if (os::uses_stack_guard_pages()) { | 2402 if (os::uses_stack_guard_pages()) { |
2339 #ifdef _M_IA64 | 2403 #ifdef _M_IA64 |
2340 // | 2404 // Use guard page for register stack. |
2341 // If it's a legal stack address continue, Windows will map it in. | |
2342 // | |
2343 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; | 2405 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; |
2344 address addr = (address) exceptionRecord->ExceptionInformation[1]; | 2406 address addr = (address) exceptionRecord->ExceptionInformation[1]; |
2345 if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() ) | 2407 // Check for a register stack overflow on Itanium |
2346 return EXCEPTION_CONTINUE_EXECUTION; | 2408 if (thread->addr_inside_register_stack_red_zone(addr)) { |
2347 | 2409 // Fatal red zone violation happens if the Java program |
2348 // The register save area is the same size as the memory stack | 2410 // catches a StackOverflow error and does so much processing |
2349 // and starts at the page just above the start of the memory stack. | 2411 // that it runs beyond the unprotected yellow guard zone. As |
2350 // If we get a fault in this area, we've run out of register | 2412 // a result, we are out of here. |
2351 // stack. If we are in java, try throwing a stack overflow exception. | 2413 fatal("ERROR: Unrecoverable stack overflow happened. JVM will exit."); |
2352 if (addr > thread->stack_base() && | 2414 } else if(thread->addr_inside_register_stack(addr)) { |
2353 addr <= (thread->stack_base()+thread->stack_size()) ) { | 2415 // Disable the yellow zone which sets the state that |
2354 char buf[256]; | 2416 // we've got a stack overflow problem. |
2355 jio_snprintf(buf, sizeof(buf), | 2417 if (thread->stack_yellow_zone_enabled()) { |
2356 "Register stack overflow, addr:%p, stack_base:%p\n", | 2418 thread->disable_stack_yellow_zone(); |
2357 addr, thread->stack_base() ); | 2419 } |
2358 tty->print_raw_cr(buf); | 2420 // Give us some room to process the exception. |
2359 // If not in java code, return and hope for the best. | 2421 thread->disable_register_stack_guard(); |
2360 return in_java ? Handle_Exception(exceptionInfo, | 2422 // Tracing with +Verbose. |
2361 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)) | 2423 if (Verbose) { |
2362 : EXCEPTION_CONTINUE_EXECUTION; | 2424 tty->print_cr("SOF Compiled Register Stack overflow at " INTPTR_FORMAT " (SIGSEGV)", pc); |
2425 tty->print_cr("Register Stack access at " INTPTR_FORMAT, addr); | |
2426 tty->print_cr("Register Stack base " INTPTR_FORMAT, thread->register_stack_base()); | |
2427 tty->print_cr("Register Stack [" INTPTR_FORMAT "," INTPTR_FORMAT "]", | |
2428 thread->register_stack_base(), | |
2429 thread->register_stack_base() + thread->stack_size()); | |
2430 } | |
2431 | |
2432 // Reguard the permanent register stack red zone just to be sure. | |
2433 // We saw Windows silently disabling this without telling us. | |
2434 thread->enable_register_stack_red_zone(); | |
2435 | |
2436 return Handle_Exception(exceptionInfo, | |
2437 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)); | |
2363 } | 2438 } |
2364 #endif | 2439 #endif |
2365 if (thread->stack_yellow_zone_enabled()) { | 2440 if (thread->stack_yellow_zone_enabled()) { |
2366 // Yellow zone violation. The o/s has unprotected the first yellow | 2441 // Yellow zone violation. The o/s has unprotected the first yellow |
2367 // zone page for us. Note: must call disable_stack_yellow_zone to | 2442 // zone page for us. Note: must call disable_stack_yellow_zone to |
2432 else | 2507 else |
2433 #endif | 2508 #endif |
2434 { | 2509 { |
2435 // Null pointer exception. | 2510 // Null pointer exception. |
2436 #ifdef _M_IA64 | 2511 #ifdef _M_IA64 |
2437 // We catch register stack overflows in compiled code by doing | 2512 // Process implicit null checks in compiled code. Note: Implicit null checks |
2438 // an explicit compare and executing a st8(G0, G0) if the | 2513 // can happen even if "ImplicitNullChecks" is disabled, e.g. in vtable stubs. |
2439 // BSP enters into our guard area. We test for the overflow | 2514 if (CodeCache::contains((void*) pc_unix_format) && !MacroAssembler::needs_explicit_null_check((intptr_t) addr)) { |
2440 // condition and fall into the normal null pointer exception | 2515 CodeBlob *cb = CodeCache::find_blob_unsafe(pc_unix_format); |
2441 // code if BSP hasn't overflowed. | 2516 // Handle implicit null check in UEP method entry |
2442 if ( in_java ) { | 2517 if (cb && (cb->is_frame_complete_at(pc) || |
2443 if(thread->register_stack_overflow()) { | 2518 (cb->is_nmethod() && ((nmethod *)cb)->inlinecache_check_contains(pc)))) { |
2444 assert((address)exceptionInfo->ContextRecord->IntS3 == | 2519 if (Verbose) { |
2445 thread->register_stack_limit(), | 2520 intptr_t *bundle_start = (intptr_t*) ((intptr_t) pc_unix_format & 0xFFFFFFFFFFFFFFF0); |
2446 "GR7 doesn't contain register_stack_limit"); | 2521 tty->print_cr("trap: null_check at " INTPTR_FORMAT " (SIGSEGV)", pc_unix_format); |
2447 // Disable the yellow zone which sets the state that | 2522 tty->print_cr(" to addr " INTPTR_FORMAT, addr); |
2448 // we've got a stack overflow problem. | 2523 tty->print_cr(" bundle is " INTPTR_FORMAT " (high), " INTPTR_FORMAT " (low)", |
2449 if (thread->stack_yellow_zone_enabled()) { | 2524 *(bundle_start + 1), *bundle_start); |
2450 thread->disable_stack_yellow_zone(); | |
2451 } | 2525 } |
2452 // Give us some room to process the exception | |
2453 thread->disable_register_stack_guard(); | |
2454 // Update GR7 with the new limit so we can continue running | |
2455 // compiled code. | |
2456 exceptionInfo->ContextRecord->IntS3 = | |
2457 (ULONGLONG)thread->register_stack_limit(); | |
2458 return Handle_Exception(exceptionInfo, | 2526 return Handle_Exception(exceptionInfo, |
2459 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)); | 2527 SharedRuntime::continuation_for_implicit_exception(thread, pc_unix_format, SharedRuntime::IMPLICIT_NULL)); |
2460 } else { | |
2461 // | |
2462 // Check for implicit null | |
2463 // We only expect null pointers in the stubs (vtable) | |
2464 // the rest are checked explicitly now. | |
2465 // | |
2466 if (((uintptr_t)addr) < os::vm_page_size() ) { | |
2467 // an access to the first page of VM--assume it is a null pointer | |
2468 address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); | |
2469 if (stub != NULL) return Handle_Exception(exceptionInfo, stub); | |
2470 } | |
2471 } | 2528 } |
2472 } // in_java | 2529 } |
2473 | 2530 |
2474 // IA64 doesn't use implicit null checking yet. So we shouldn't | 2531 // Implicit null checks were processed above. Hence, we should not reach |
2475 // get here. | 2532 // here in the usual case => die! |
2476 tty->print_raw_cr("Access violation, possible null pointer exception"); | 2533 if (Verbose) tty->print_raw_cr("Access violation, possible null pointer exception"); |
2477 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, | 2534 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, |
2478 exceptionInfo->ContextRecord); | 2535 exceptionInfo->ContextRecord); |
2479 return EXCEPTION_CONTINUE_SEARCH; | 2536 return EXCEPTION_CONTINUE_SEARCH; |
2480 #else /* !IA64 */ | 2537 |
2538 #else // !IA64 | |
2481 | 2539 |
2482 // Windows 98 reports faulting addresses incorrectly | 2540 // Windows 98 reports faulting addresses incorrectly |
2483 if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) || | 2541 if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) || |
2484 !os::win32::is_nt()) { | 2542 !os::win32::is_nt()) { |
2485 address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); | 2543 address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); |
2507 | 2565 |
2508 // Stack overflow or null pointer exception in native code. | 2566 // Stack overflow or null pointer exception in native code. |
2509 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, | 2567 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, |
2510 exceptionInfo->ContextRecord); | 2568 exceptionInfo->ContextRecord); |
2511 return EXCEPTION_CONTINUE_SEARCH; | 2569 return EXCEPTION_CONTINUE_SEARCH; |
2512 } | 2570 } // /EXCEPTION_ACCESS_VIOLATION |
2571 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
2572 #if defined _M_IA64 | |
2573 else if ((exception_code == EXCEPTION_ILLEGAL_INSTRUCTION || | |
2574 exception_code == EXCEPTION_ILLEGAL_INSTRUCTION_2)) { | |
2575 M37 handle_wrong_method_break(0, NativeJump::HANDLE_WRONG_METHOD, PR0); | |
2576 | |
2577 // Compiled method patched to be non entrant? Following conditions must apply: | |
2578 // 1. must be first instruction in bundle | |
2579 // 2. must be a break instruction with appropriate code | |
2580 if((((uint64_t) pc & 0x0F) == 0) && | |
2581 (((IPF_Bundle*) pc)->get_slot0() == handle_wrong_method_break.bits())) { | |
2582 return Handle_Exception(exceptionInfo, | |
2583 (address)SharedRuntime::get_handle_wrong_method_stub()); | |
2584 } | |
2585 } // /EXCEPTION_ILLEGAL_INSTRUCTION | |
2586 #endif | |
2587 | |
2513 | 2588 |
2514 if (in_java) { | 2589 if (in_java) { |
2515 switch (exception_code) { | 2590 switch (exception_code) { |
2516 case EXCEPTION_INT_DIVIDE_BY_ZERO: | 2591 case EXCEPTION_INT_DIVIDE_BY_ZERO: |
2517 return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO)); | 2592 return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO)); |