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));