src/os/windows/vm/os_windows.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
6518907 Cdiff src/os/windows/vm/os_windows.cpp
src/os/windows/vm/os_windows.cpp
Print this page
*** 350,359 ****
--- 350,386 ----
break;
}
#ifdef _M_IA64
// IA64 has memory and register stacks
+ //
+ // This is the stack layout you get on NT/IA64 if you specify 1MB stack limit
+ // at thread creation (1MB backing store growing upwards, 1MB memory stack
+ // growing downwards, 2MB summed up)
+ //
+ // ...
+ // ------- top of stack (high address) -----
+ // |
+ // | 1MB
+ // | Backing Store (Register Stack)
+ // |
+ // | / \
+ // | |
+ // | |
+ // | |
+ // ------------------------ stack base -----
+ // | 1MB
+ // | Memory Stack
+ // |
+ // | |
+ // | |
+ // | |
+ // | \ /
+ // |
+ // ----- bottom of stack (low address) -----
+ // ...
+
stack_size = stack_size / 2;
#endif
return stack_bottom + stack_size;
}
*** 1992,2012 ****
LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler) {
JavaThread* thread = JavaThread::current();
// Save pc in thread
#ifdef _M_IA64
! thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->StIIP);
// Set pc to handler
exceptionInfo->ContextRecord->StIIP = (DWORD64)handler;
#elif _M_AMD64
! thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->Rip);
// Set pc to handler
exceptionInfo->ContextRecord->Rip = (DWORD64)handler;
#else
! thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->Eip);
// Set pc to handler
! exceptionInfo->ContextRecord->Eip = (LONG)handler;
#endif
// Continue the execution
return EXCEPTION_CONTINUE_EXECUTION;
}
--- 2019,2056 ----
LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler) {
JavaThread* thread = JavaThread::current();
// Save pc in thread
#ifdef _M_IA64
! // Do not blow up if no thread info available.
! if (thread) {
! // Saving PRECISE pc (with slot information) in thread.
! uint64_t precise_pc = (uint64_t) exceptionInfo->ExceptionRecord->ExceptionAddress;
! // Convert precise PC into "Unix" format
! precise_pc = (precise_pc & 0xFFFFFFFFFFFFFFF0) | ((precise_pc & 0xF) >> 2);
! thread->set_saved_exception_pc((address)precise_pc);
! }
// Set pc to handler
exceptionInfo->ContextRecord->StIIP = (DWORD64)handler;
+ // Clear out psr.ri (= Restart Instruction) in order to continue
+ // at the beginning of the target bundle.
+ exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF;
+ assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!");
#elif _M_AMD64
! // Do not blow up if no thread info available.
! if (thread) {
! thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);
! }
// Set pc to handler
exceptionInfo->ContextRecord->Rip = (DWORD64)handler;
#else
! // Do not blow up if no thread info available.
! if (thread) {
! thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip);
! }
// Set pc to handler
! exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler;
#endif
// Continue the execution
return EXCEPTION_CONTINUE_EXECUTION;
}
*** 2027,2036 ****
--- 2071,2085 ----
// From "Execution Protection in the Windows Operating System" draft 0.35
// Once a system header becomes available, the "real" define should be
// included or copied here.
#define EXCEPTION_INFO_EXEC_VIOLATION 0x08
+ // Handle NAT Bit consumption on IA64.
+ #ifdef _M_IA64
+ #define EXCEPTION_REG_NAT_CONSUMPTION STATUS_REG_NAT_CONSUMPTION
+ #endif
+
#define def_excpt(val) #val, val
struct siglabel {
char *name;
int number;
*** 2069,2078 ****
--- 2118,2134 ----
def_excpt(EXCEPTION_STACK_OVERFLOW),
def_excpt(EXCEPTION_INVALID_DISPOSITION),
def_excpt(EXCEPTION_GUARD_PAGE),
def_excpt(EXCEPTION_INVALID_HANDLE),
def_excpt(EXCEPTION_UNCAUGHT_CXX_EXCEPTION),
+ #ifdef _M_IA64
+ def_excpt(EXCEPTION_REG_NAT_CONSUMPTION),
+ #endif
+ def_excpt(EXCEPTION_HEAP_CORRUPTION),
+ #ifdef _M_IA64
+ def_excpt(EXCEPTION_REG_NAT_CONSUMPTION),
+ #endif
NULL, 0
};
const char* os::exception_name(int exception_code, char *buf, size_t size) {
for (int i = 0; exceptlabels[i].name != NULL; i++) {
*** 2193,2203 ****
//-----------------------------------------------------------------------------
LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
#ifdef _M_IA64
! address pc = (address) exceptionInfo->ContextRecord->StIIP;
#elif _M_AMD64
address pc = (address) exceptionInfo->ContextRecord->Rip;
#else
address pc = (address) exceptionInfo->ContextRecord->Eip;
#endif
--- 2249,2266 ----
//-----------------------------------------------------------------------------
LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
#ifdef _M_IA64
! // On Itanium, we need the "precise pc", which has the slot number coded
! // into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format).
! address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress;
! // Convert the pc to "Unix format", which has the slot number coded
! // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2
! // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction"
! // information is saved in the Unix format.
! address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2));
#elif _M_AMD64
address pc = (address) exceptionInfo->ContextRecord->Rip;
#else
address pc = (address) exceptionInfo->ContextRecord->Eip;
#endif
*** 2308,2340 ****
// Handle potential stack overflows up front.
if (exception_code == EXCEPTION_STACK_OVERFLOW) {
if (os::uses_stack_guard_pages()) {
#ifdef _M_IA64
! //
! // If it's a legal stack address continue, Windows will map it in.
! //
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
address addr = (address) exceptionRecord->ExceptionInformation[1];
! if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() )
! return EXCEPTION_CONTINUE_EXECUTION;
! // The register save area is the same size as the memory stack
! // and starts at the page just above the start of the memory stack.
! // If we get a fault in this area, we've run out of register
! // stack. If we are in java, try throwing a stack overflow exception.
! if (addr > thread->stack_base() &&
! addr <= (thread->stack_base()+thread->stack_size()) ) {
! char buf[256];
! jio_snprintf(buf, sizeof(buf),
! "Register stack overflow, addr:%p, stack_base:%p\n",
! addr, thread->stack_base() );
! tty->print_raw_cr(buf);
! // If not in java code, return and hope for the best.
! return in_java ? Handle_Exception(exceptionInfo,
! SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW))
! : EXCEPTION_CONTINUE_EXECUTION;
}
#endif
if (thread->stack_yellow_zone_enabled()) {
// Yellow zone violation. The o/s has unprotected the first yellow
// zone page for us. Note: must call disable_stack_yellow_zone to
--- 2371,2414 ----
// Handle potential stack overflows up front.
if (exception_code == EXCEPTION_STACK_OVERFLOW) {
if (os::uses_stack_guard_pages()) {
#ifdef _M_IA64
! // Use guard page for register stack.
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
address addr = (address) exceptionRecord->ExceptionInformation[1];
! // Check for a register stack overflow on Itanium
! if (thread->addr_inside_register_stack_red_zone(addr)) {
! // Fatal red zone violation happens if the Java program
! // catches a StackOverflow error and does so much processing
! // that it runs beyond the unprotected yellow guard zone. As
! // a result, we are out of here.
! fatal("ERROR: Unrecoverable stack overflow happened. JVM will exit.");
! } else if(thread->addr_inside_register_stack(addr)) {
! // Disable the yellow zone which sets the state that
! // we've got a stack overflow problem.
! if (thread->stack_yellow_zone_enabled()) {
! thread->disable_stack_yellow_zone();
! }
! // Give us some room to process the exception.
! thread->disable_register_stack_guard();
! // Tracing with +Verbose.
! if (Verbose) {
! tty->print_cr("SOF Compiled Register Stack overflow at " INTPTR_FORMAT " (SIGSEGV)", pc);
! tty->print_cr("Register Stack access at " INTPTR_FORMAT, addr);
! tty->print_cr("Register Stack base " INTPTR_FORMAT, thread->register_stack_base());
! tty->print_cr("Register Stack [" INTPTR_FORMAT "," INTPTR_FORMAT "]",
! thread->register_stack_base(),
! thread->register_stack_base() + thread->stack_size());
! }
! // Reguard the permanent register stack red zone just to be sure.
! // We saw Windows silently disabling this without telling us.
! thread->enable_register_stack_red_zone();
!
! return Handle_Exception(exceptionInfo,
! SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
}
#endif
if (thread->stack_yellow_zone_enabled()) {
// Yellow zone violation. The o/s has unprotected the first yellow
// zone page for us. Note: must call disable_stack_yellow_zone to
*** 2405,2459 ****
else
#endif
{
// Null pointer exception.
#ifdef _M_IA64
! // We catch register stack overflows in compiled code by doing
! // an explicit compare and executing a st8(G0, G0) if the
! // BSP enters into our guard area. We test for the overflow
! // condition and fall into the normal null pointer exception
! // code if BSP hasn't overflowed.
! if ( in_java ) {
! if(thread->register_stack_overflow()) {
! assert((address)exceptionInfo->ContextRecord->IntS3 ==
! thread->register_stack_limit(),
! "GR7 doesn't contain register_stack_limit");
! // Disable the yellow zone which sets the state that
! // we've got a stack overflow problem.
! if (thread->stack_yellow_zone_enabled()) {
! thread->disable_stack_yellow_zone();
}
- // Give us some room to process the exception
- thread->disable_register_stack_guard();
- // Update GR7 with the new limit so we can continue running
- // compiled code.
- exceptionInfo->ContextRecord->IntS3 =
- (ULONGLONG)thread->register_stack_limit();
return Handle_Exception(exceptionInfo,
! SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
! } else {
! //
! // Check for implicit null
! // We only expect null pointers in the stubs (vtable)
! // the rest are checked explicitly now.
! //
! if (((uintptr_t)addr) < os::vm_page_size() ) {
! // an access to the first page of VM--assume it is a null pointer
! address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
! if (stub != NULL) return Handle_Exception(exceptionInfo, stub);
}
}
- } // in_java
! // IA64 doesn't use implicit null checking yet. So we shouldn't
! // get here.
! tty->print_raw_cr("Access violation, possible null pointer exception");
report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
exceptionInfo->ContextRecord);
return EXCEPTION_CONTINUE_SEARCH;
- #else /* !IA64 */
// Windows 98 reports faulting addresses incorrectly
if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) ||
!os::win32::is_nt()) {
address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
if (stub != NULL) return Handle_Exception(exceptionInfo, stub);
--- 2479,2516 ----
else
#endif
{
// Null pointer exception.
#ifdef _M_IA64
! // Process implicit null checks in compiled code. Note: Implicit null checks
! // can happen even if "ImplicitNullChecks" is disabled, e.g. in vtable stubs.
! if (CodeCache::contains((void*) pc_unix_format) && !MacroAssembler::needs_explicit_null_check((intptr_t) addr)) {
! CodeBlob *cb = CodeCache::find_blob_unsafe(pc_unix_format);
! // Handle implicit null check in UEP method entry
! if (cb && (cb->is_frame_complete_at(pc) ||
! (cb->is_nmethod() && ((nmethod *)cb)->inlinecache_check_contains(pc)))) {
! if (Verbose) {
! intptr_t *bundle_start = (intptr_t*) ((intptr_t) pc_unix_format & 0xFFFFFFFFFFFFFFF0);
! tty->print_cr("trap: null_check at " INTPTR_FORMAT " (SIGSEGV)", pc_unix_format);
! tty->print_cr(" to addr " INTPTR_FORMAT, addr);
! tty->print_cr(" bundle is " INTPTR_FORMAT " (high), " INTPTR_FORMAT " (low)",
! *(bundle_start + 1), *bundle_start);
}
return Handle_Exception(exceptionInfo,
! SharedRuntime::continuation_for_implicit_exception(thread, pc_unix_format, SharedRuntime::IMPLICIT_NULL));
}
}
! // Implicit null checks were processed above. Hence, we should not reach
! // here in the usual case => die!
! if (Verbose) tty->print_raw_cr("Access violation, possible null pointer exception");
report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
exceptionInfo->ContextRecord);
return EXCEPTION_CONTINUE_SEARCH;
+ #else // !IA64
+
// Windows 98 reports faulting addresses incorrectly
if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) ||
!os::win32::is_nt()) {
address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
if (stub != NULL) return Handle_Exception(exceptionInfo, stub);
*** 2480,2491 ****
--- 2537,2565 ----
// Stack overflow or null pointer exception in native code.
report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
exceptionInfo->ContextRecord);
return EXCEPTION_CONTINUE_SEARCH;
+ } // /EXCEPTION_ACCESS_VIOLATION
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ #if defined _M_IA64
+ else if ((exception_code == EXCEPTION_ILLEGAL_INSTRUCTION ||
+ exception_code == EXCEPTION_ILLEGAL_INSTRUCTION_2)) {
+ M37 handle_wrong_method_break(0, NativeJump::HANDLE_WRONG_METHOD, PR0);
+
+ // Compiled method patched to be non entrant? Following conditions must apply:
+ // 1. must be first instruction in bundle
+ // 2. must be a break instruction with appropriate code
+ if((((uint64_t) pc & 0x0F) == 0) &&
+ (((IPF_Bundle*) pc)->get_slot0() == handle_wrong_method_break.bits())) {
+ return Handle_Exception(exceptionInfo,
+ (address)SharedRuntime::get_handle_wrong_method_stub());
}
+ } // /EXCEPTION_ILLEGAL_INSTRUCTION
+ #endif
+
if (in_java) {
switch (exception_code) {
case EXCEPTION_INT_DIVIDE_BY_ZERO:
return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO));
src/os/windows/vm/os_windows.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File