Mercurial > hg > graal-jvmci-8
comparison src/os/windows/vm/os_windows.cpp @ 7994:9fae07c31641
6518907: cleanup IA64 specific code in Hotspot
Summary: removed unused IA64 specific code
Reviewed-by: twisti, kvn, dholmes
author | morris |
---|---|
date | Fri, 25 Jan 2013 16:50:33 -0800 |
parents | 2ef7061f13b4 |
children | 7adae9244bc8 |
comparison
equal
deleted
inserted
replaced
7993:76341426b645 | 7994:9fae07c31641 |
---|---|
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 |
2003 | 2030 |
2004 LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler) { | 2031 LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler) { |
2005 JavaThread* thread = JavaThread::current(); | 2032 JavaThread* thread = JavaThread::current(); |
2006 // Save pc in thread | 2033 // Save pc in thread |
2007 #ifdef _M_IA64 | 2034 #ifdef _M_IA64 |
2008 thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->StIIP); | 2035 // Do not blow up if no thread info available. |
2036 if (thread) { | |
2037 // Saving PRECISE pc (with slot information) in thread. | |
2038 uint64_t precise_pc = (uint64_t) exceptionInfo->ExceptionRecord->ExceptionAddress; | |
2039 // Convert precise PC into "Unix" format | |
2040 precise_pc = (precise_pc & 0xFFFFFFFFFFFFFFF0) | ((precise_pc & 0xF) >> 2); | |
2041 thread->set_saved_exception_pc((address)precise_pc); | |
2042 } | |
2009 // Set pc to handler | 2043 // Set pc to handler |
2010 exceptionInfo->ContextRecord->StIIP = (DWORD64)handler; | 2044 exceptionInfo->ContextRecord->StIIP = (DWORD64)handler; |
2045 // Clear out psr.ri (= Restart Instruction) in order to continue | |
2046 // at the beginning of the target bundle. | |
2047 exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF; | |
2048 assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!"); | |
2011 #elif _M_AMD64 | 2049 #elif _M_AMD64 |
2012 thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->Rip); | 2050 // Do not blow up if no thread info available. |
2051 if (thread) { | |
2052 thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip); | |
2053 } | |
2013 // Set pc to handler | 2054 // Set pc to handler |
2014 exceptionInfo->ContextRecord->Rip = (DWORD64)handler; | 2055 exceptionInfo->ContextRecord->Rip = (DWORD64)handler; |
2015 #else | 2056 #else |
2016 thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->Eip); | 2057 // Do not blow up if no thread info available. |
2058 if (thread) { | |
2059 thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip); | |
2060 } | |
2017 // Set pc to handler | 2061 // Set pc to handler |
2018 exceptionInfo->ContextRecord->Eip = (LONG)handler; | 2062 exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler; |
2019 #endif | 2063 #endif |
2020 | 2064 |
2021 // Continue the execution | 2065 // Continue the execution |
2022 return EXCEPTION_CONTINUE_EXECUTION; | 2066 return EXCEPTION_CONTINUE_EXECUTION; |
2023 } | 2067 } |
2037 | 2081 |
2038 // From "Execution Protection in the Windows Operating System" draft 0.35 | 2082 // From "Execution Protection in the Windows Operating System" draft 0.35 |
2039 // Once a system header becomes available, the "real" define should be | 2083 // Once a system header becomes available, the "real" define should be |
2040 // included or copied here. | 2084 // included or copied here. |
2041 #define EXCEPTION_INFO_EXEC_VIOLATION 0x08 | 2085 #define EXCEPTION_INFO_EXEC_VIOLATION 0x08 |
2086 | |
2087 // Handle NAT Bit consumption on IA64. | |
2088 #ifdef _M_IA64 | |
2089 #define EXCEPTION_REG_NAT_CONSUMPTION STATUS_REG_NAT_CONSUMPTION | |
2090 #endif | |
2091 | |
2092 // Windows Vista/2008 heap corruption check | |
2093 #define EXCEPTION_HEAP_CORRUPTION 0xC0000374 | |
2042 | 2094 |
2043 #define def_excpt(val) #val, val | 2095 #define def_excpt(val) #val, val |
2044 | 2096 |
2045 struct siglabel { | 2097 struct siglabel { |
2046 char *name; | 2098 char *name; |
2080 def_excpt(EXCEPTION_STACK_OVERFLOW), | 2132 def_excpt(EXCEPTION_STACK_OVERFLOW), |
2081 def_excpt(EXCEPTION_INVALID_DISPOSITION), | 2133 def_excpt(EXCEPTION_INVALID_DISPOSITION), |
2082 def_excpt(EXCEPTION_GUARD_PAGE), | 2134 def_excpt(EXCEPTION_GUARD_PAGE), |
2083 def_excpt(EXCEPTION_INVALID_HANDLE), | 2135 def_excpt(EXCEPTION_INVALID_HANDLE), |
2084 def_excpt(EXCEPTION_UNCAUGHT_CXX_EXCEPTION), | 2136 def_excpt(EXCEPTION_UNCAUGHT_CXX_EXCEPTION), |
2137 def_excpt(EXCEPTION_HEAP_CORRUPTION), | |
2138 #ifdef _M_IA64 | |
2139 def_excpt(EXCEPTION_REG_NAT_CONSUMPTION), | |
2140 #endif | |
2085 NULL, 0 | 2141 NULL, 0 |
2086 }; | 2142 }; |
2087 | 2143 |
2088 const char* os::exception_name(int exception_code, char *buf, size_t size) { | 2144 const char* os::exception_name(int exception_code, char *buf, size_t size) { |
2089 for (int i = 0; exceptlabels[i].name != NULL; i++) { | 2145 for (int i = 0; exceptlabels[i].name != NULL; i++) { |
2204 //----------------------------------------------------------------------------- | 2260 //----------------------------------------------------------------------------- |
2205 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { | 2261 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { |
2206 if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH; | 2262 if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH; |
2207 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; | 2263 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; |
2208 #ifdef _M_IA64 | 2264 #ifdef _M_IA64 |
2209 address pc = (address) exceptionInfo->ContextRecord->StIIP; | 2265 // On Itanium, we need the "precise pc", which has the slot number coded |
2266 // into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format). | |
2267 address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress; | |
2268 // Convert the pc to "Unix format", which has the slot number coded | |
2269 // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2 | |
2270 // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction" | |
2271 // information is saved in the Unix format. | |
2272 address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2)); | |
2210 #elif _M_AMD64 | 2273 #elif _M_AMD64 |
2211 address pc = (address) exceptionInfo->ContextRecord->Rip; | 2274 address pc = (address) exceptionInfo->ContextRecord->Rip; |
2212 #else | 2275 #else |
2213 address pc = (address) exceptionInfo->ContextRecord->Eip; | 2276 address pc = (address) exceptionInfo->ContextRecord->Eip; |
2214 #endif | 2277 #endif |
2319 | 2382 |
2320 // Handle potential stack overflows up front. | 2383 // Handle potential stack overflows up front. |
2321 if (exception_code == EXCEPTION_STACK_OVERFLOW) { | 2384 if (exception_code == EXCEPTION_STACK_OVERFLOW) { |
2322 if (os::uses_stack_guard_pages()) { | 2385 if (os::uses_stack_guard_pages()) { |
2323 #ifdef _M_IA64 | 2386 #ifdef _M_IA64 |
2324 // | 2387 // Use guard page for register stack. |
2325 // If it's a legal stack address continue, Windows will map it in. | |
2326 // | |
2327 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; | 2388 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; |
2328 address addr = (address) exceptionRecord->ExceptionInformation[1]; | 2389 address addr = (address) exceptionRecord->ExceptionInformation[1]; |
2329 if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() ) | 2390 // Check for a register stack overflow on Itanium |
2330 return EXCEPTION_CONTINUE_EXECUTION; | 2391 if (thread->addr_inside_register_stack_red_zone(addr)) { |
2331 | 2392 // Fatal red zone violation happens if the Java program |
2332 // The register save area is the same size as the memory stack | 2393 // catches a StackOverflow error and does so much processing |
2333 // and starts at the page just above the start of the memory stack. | 2394 // that it runs beyond the unprotected yellow guard zone. As |
2334 // If we get a fault in this area, we've run out of register | 2395 // a result, we are out of here. |
2335 // stack. If we are in java, try throwing a stack overflow exception. | 2396 fatal("ERROR: Unrecoverable stack overflow happened. JVM will exit."); |
2336 if (addr > thread->stack_base() && | 2397 } else if(thread->addr_inside_register_stack(addr)) { |
2337 addr <= (thread->stack_base()+thread->stack_size()) ) { | 2398 // Disable the yellow zone which sets the state that |
2338 char buf[256]; | 2399 // we've got a stack overflow problem. |
2339 jio_snprintf(buf, sizeof(buf), | 2400 if (thread->stack_yellow_zone_enabled()) { |
2340 "Register stack overflow, addr:%p, stack_base:%p\n", | 2401 thread->disable_stack_yellow_zone(); |
2341 addr, thread->stack_base() ); | 2402 } |
2342 tty->print_raw_cr(buf); | 2403 // Give us some room to process the exception. |
2343 // If not in java code, return and hope for the best. | 2404 thread->disable_register_stack_guard(); |
2344 return in_java ? Handle_Exception(exceptionInfo, | 2405 // Tracing with +Verbose. |
2345 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)) | 2406 if (Verbose) { |
2346 : EXCEPTION_CONTINUE_EXECUTION; | 2407 tty->print_cr("SOF Compiled Register Stack overflow at " INTPTR_FORMAT " (SIGSEGV)", pc); |
2408 tty->print_cr("Register Stack access at " INTPTR_FORMAT, addr); | |
2409 tty->print_cr("Register Stack base " INTPTR_FORMAT, thread->register_stack_base()); | |
2410 tty->print_cr("Register Stack [" INTPTR_FORMAT "," INTPTR_FORMAT "]", | |
2411 thread->register_stack_base(), | |
2412 thread->register_stack_base() + thread->stack_size()); | |
2413 } | |
2414 | |
2415 // Reguard the permanent register stack red zone just to be sure. | |
2416 // We saw Windows silently disabling this without telling us. | |
2417 thread->enable_register_stack_red_zone(); | |
2418 | |
2419 return Handle_Exception(exceptionInfo, | |
2420 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)); | |
2347 } | 2421 } |
2348 #endif | 2422 #endif |
2349 if (thread->stack_yellow_zone_enabled()) { | 2423 if (thread->stack_yellow_zone_enabled()) { |
2350 // Yellow zone violation. The o/s has unprotected the first yellow | 2424 // Yellow zone violation. The o/s has unprotected the first yellow |
2351 // zone page for us. Note: must call disable_stack_yellow_zone to | 2425 // zone page for us. Note: must call disable_stack_yellow_zone to |
2416 else | 2490 else |
2417 #endif | 2491 #endif |
2418 { | 2492 { |
2419 // Null pointer exception. | 2493 // Null pointer exception. |
2420 #ifdef _M_IA64 | 2494 #ifdef _M_IA64 |
2421 // We catch register stack overflows in compiled code by doing | 2495 // Process implicit null checks in compiled code. Note: Implicit null checks |
2422 // an explicit compare and executing a st8(G0, G0) if the | 2496 // can happen even if "ImplicitNullChecks" is disabled, e.g. in vtable stubs. |
2423 // BSP enters into our guard area. We test for the overflow | 2497 if (CodeCache::contains((void*) pc_unix_format) && !MacroAssembler::needs_explicit_null_check((intptr_t) addr)) { |
2424 // condition and fall into the normal null pointer exception | 2498 CodeBlob *cb = CodeCache::find_blob_unsafe(pc_unix_format); |
2425 // code if BSP hasn't overflowed. | 2499 // Handle implicit null check in UEP method entry |
2426 if ( in_java ) { | 2500 if (cb && (cb->is_frame_complete_at(pc) || |
2427 if(thread->register_stack_overflow()) { | 2501 (cb->is_nmethod() && ((nmethod *)cb)->inlinecache_check_contains(pc)))) { |
2428 assert((address)exceptionInfo->ContextRecord->IntS3 == | 2502 if (Verbose) { |
2429 thread->register_stack_limit(), | 2503 intptr_t *bundle_start = (intptr_t*) ((intptr_t) pc_unix_format & 0xFFFFFFFFFFFFFFF0); |
2430 "GR7 doesn't contain register_stack_limit"); | 2504 tty->print_cr("trap: null_check at " INTPTR_FORMAT " (SIGSEGV)", pc_unix_format); |
2431 // Disable the yellow zone which sets the state that | 2505 tty->print_cr(" to addr " INTPTR_FORMAT, addr); |
2432 // we've got a stack overflow problem. | 2506 tty->print_cr(" bundle is " INTPTR_FORMAT " (high), " INTPTR_FORMAT " (low)", |
2433 if (thread->stack_yellow_zone_enabled()) { | 2507 *(bundle_start + 1), *bundle_start); |
2434 thread->disable_stack_yellow_zone(); | |
2435 } | 2508 } |
2436 // Give us some room to process the exception | |
2437 thread->disable_register_stack_guard(); | |
2438 // Update GR7 with the new limit so we can continue running | |
2439 // compiled code. | |
2440 exceptionInfo->ContextRecord->IntS3 = | |
2441 (ULONGLONG)thread->register_stack_limit(); | |
2442 return Handle_Exception(exceptionInfo, | 2509 return Handle_Exception(exceptionInfo, |
2443 SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)); | 2510 SharedRuntime::continuation_for_implicit_exception(thread, pc_unix_format, SharedRuntime::IMPLICIT_NULL)); |
2444 } else { | |
2445 // | |
2446 // Check for implicit null | |
2447 // We only expect null pointers in the stubs (vtable) | |
2448 // the rest are checked explicitly now. | |
2449 // | |
2450 if (((uintptr_t)addr) < os::vm_page_size() ) { | |
2451 // an access to the first page of VM--assume it is a null pointer | |
2452 address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); | |
2453 if (stub != NULL) return Handle_Exception(exceptionInfo, stub); | |
2454 } | |
2455 } | 2511 } |
2456 } // in_java | 2512 } |
2457 | 2513 |
2458 // IA64 doesn't use implicit null checking yet. So we shouldn't | 2514 // Implicit null checks were processed above. Hence, we should not reach |
2459 // get here. | 2515 // here in the usual case => die! |
2460 tty->print_raw_cr("Access violation, possible null pointer exception"); | 2516 if (Verbose) tty->print_raw_cr("Access violation, possible null pointer exception"); |
2461 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, | 2517 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, |
2462 exceptionInfo->ContextRecord); | 2518 exceptionInfo->ContextRecord); |
2463 return EXCEPTION_CONTINUE_SEARCH; | 2519 return EXCEPTION_CONTINUE_SEARCH; |
2464 #else /* !IA64 */ | 2520 |
2521 #else // !IA64 | |
2465 | 2522 |
2466 // Windows 98 reports faulting addresses incorrectly | 2523 // Windows 98 reports faulting addresses incorrectly |
2467 if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) || | 2524 if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) || |
2468 !os::win32::is_nt()) { | 2525 !os::win32::is_nt()) { |
2469 address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); | 2526 address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); |
2491 | 2548 |
2492 // Stack overflow or null pointer exception in native code. | 2549 // Stack overflow or null pointer exception in native code. |
2493 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, | 2550 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, |
2494 exceptionInfo->ContextRecord); | 2551 exceptionInfo->ContextRecord); |
2495 return EXCEPTION_CONTINUE_SEARCH; | 2552 return EXCEPTION_CONTINUE_SEARCH; |
2496 } | 2553 } // /EXCEPTION_ACCESS_VIOLATION |
2554 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
2555 #if defined _M_IA64 | |
2556 else if ((exception_code == EXCEPTION_ILLEGAL_INSTRUCTION || | |
2557 exception_code == EXCEPTION_ILLEGAL_INSTRUCTION_2)) { | |
2558 M37 handle_wrong_method_break(0, NativeJump::HANDLE_WRONG_METHOD, PR0); | |
2559 | |
2560 // Compiled method patched to be non entrant? Following conditions must apply: | |
2561 // 1. must be first instruction in bundle | |
2562 // 2. must be a break instruction with appropriate code | |
2563 if((((uint64_t) pc & 0x0F) == 0) && | |
2564 (((IPF_Bundle*) pc)->get_slot0() == handle_wrong_method_break.bits())) { | |
2565 return Handle_Exception(exceptionInfo, | |
2566 (address)SharedRuntime::get_handle_wrong_method_stub()); | |
2567 } | |
2568 } // /EXCEPTION_ILLEGAL_INSTRUCTION | |
2569 #endif | |
2570 | |
2497 | 2571 |
2498 if (in_java) { | 2572 if (in_java) { |
2499 switch (exception_code) { | 2573 switch (exception_code) { |
2500 case EXCEPTION_INT_DIVIDE_BY_ZERO: | 2574 case EXCEPTION_INT_DIVIDE_BY_ZERO: |
2501 return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO)); | 2575 return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO)); |