2088 exceptionInfo->ContextRecord->StIIP = (DWORD64)handler; |
2090 exceptionInfo->ContextRecord->StIIP = (DWORD64)handler; |
2089 // Clear out psr.ri (= Restart Instruction) in order to continue |
2091 // Clear out psr.ri (= Restart Instruction) in order to continue |
2090 // at the beginning of the target bundle. |
2092 // at the beginning of the target bundle. |
2091 exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF; |
2093 exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF; |
2092 assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!"); |
2094 assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!"); |
2093 #elif _M_AMD64 |
2095 #else |
|
2096 #ifdef _M_AMD64 |
2094 // Do not blow up if no thread info available. |
2097 // Do not blow up if no thread info available. |
2095 if (thread) { |
2098 if (thread) { |
2096 thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip); |
2099 thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip); |
2097 } |
2100 } |
2098 // Set pc to handler |
2101 // Set pc to handler |
2099 exceptionInfo->ContextRecord->Rip = (DWORD64)handler; |
2102 exceptionInfo->ContextRecord->Rip = (DWORD64)handler; |
2100 #else |
2103 #else |
2101 // Do not blow up if no thread info available. |
2104 // Do not blow up if no thread info available. |
2102 if (thread) { |
2105 if (thread) { |
2103 thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip); |
2106 thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip); |
2104 } |
2107 } |
2105 // Set pc to handler |
2108 // Set pc to handler |
2106 exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler; |
2109 exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler; |
|
2110 #endif |
2107 #endif |
2111 #endif |
2108 |
2112 |
2109 // Continue the execution |
2113 // Continue the execution |
2110 return EXCEPTION_CONTINUE_EXECUTION; |
2114 return EXCEPTION_CONTINUE_EXECUTION; |
2111 } |
2115 } |
2200 LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { |
2204 LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { |
2201 // handle exception caused by idiv; should only happen for -MinInt/-1 |
2205 // handle exception caused by idiv; should only happen for -MinInt/-1 |
2202 // (division by zero is handled explicitly) |
2206 // (division by zero is handled explicitly) |
2203 #ifdef _M_IA64 |
2207 #ifdef _M_IA64 |
2204 assert(0, "Fix Handle_IDiv_Exception"); |
2208 assert(0, "Fix Handle_IDiv_Exception"); |
2205 #elif _M_AMD64 |
2209 #else |
|
2210 #ifdef _M_AMD64 |
2206 PCONTEXT ctx = exceptionInfo->ContextRecord; |
2211 PCONTEXT ctx = exceptionInfo->ContextRecord; |
2207 address pc = (address)ctx->Rip; |
2212 address pc = (address)ctx->Rip; |
2208 assert(pc[0] == 0xF7, "not an idiv opcode"); |
2213 assert(pc[0] == 0xF7, "not an idiv opcode"); |
2209 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands"); |
2214 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands"); |
2210 assert(ctx->Rax == min_jint, "unexpected idiv exception"); |
2215 assert(ctx->Rax == min_jint, "unexpected idiv exception"); |
2211 // set correct result values and continue after idiv instruction |
2216 // set correct result values and continue after idiv instruction |
2212 ctx->Rip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes |
2217 ctx->Rip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes |
2213 ctx->Rax = (DWORD)min_jint; // result |
2218 ctx->Rax = (DWORD)min_jint; // result |
2214 ctx->Rdx = (DWORD)0; // remainder |
2219 ctx->Rdx = (DWORD)0; // remainder |
2215 // Continue the execution |
2220 // Continue the execution |
2216 #else |
2221 #else |
2217 PCONTEXT ctx = exceptionInfo->ContextRecord; |
2222 PCONTEXT ctx = exceptionInfo->ContextRecord; |
2218 address pc = (address)ctx->Eip; |
2223 address pc = (address)ctx->Eip; |
2219 assert(pc[0] == 0xF7, "not an idiv opcode"); |
2224 assert(pc[0] == 0xF7, "not an idiv opcode"); |
2220 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands"); |
2225 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands"); |
2221 assert(ctx->Eax == min_jint, "unexpected idiv exception"); |
2226 assert(ctx->Eax == min_jint, "unexpected idiv exception"); |
2222 // set correct result values and continue after idiv instruction |
2227 // set correct result values and continue after idiv instruction |
2223 ctx->Eip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes |
2228 ctx->Eip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes |
2224 ctx->Eax = (DWORD)min_jint; // result |
2229 ctx->Eax = (DWORD)min_jint; // result |
2225 ctx->Edx = (DWORD)0; // remainder |
2230 ctx->Edx = (DWORD)0; // remainder |
2226 // Continue the execution |
2231 // Continue the execution |
|
2232 #endif |
2227 #endif |
2233 #endif |
2228 return EXCEPTION_CONTINUE_EXECUTION; |
2234 return EXCEPTION_CONTINUE_EXECUTION; |
2229 } |
2235 } |
2230 |
2236 |
2231 //----------------------------------------------------------------------------- |
2237 //----------------------------------------------------------------------------- |
2294 // Convert the pc to "Unix format", which has the slot number coded |
2300 // Convert the pc to "Unix format", which has the slot number coded |
2295 // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2 |
2301 // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2 |
2296 // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction" |
2302 // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction" |
2297 // information is saved in the Unix format. |
2303 // information is saved in the Unix format. |
2298 address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2)); |
2304 address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2)); |
2299 #elif _M_AMD64 |
2305 #else |
|
2306 #ifdef _M_AMD64 |
2300 address pc = (address) exceptionInfo->ContextRecord->Rip; |
2307 address pc = (address) exceptionInfo->ContextRecord->Rip; |
2301 #else |
2308 #else |
2302 address pc = (address) exceptionInfo->ContextRecord->Eip; |
2309 address pc = (address) exceptionInfo->ContextRecord->Eip; |
|
2310 #endif |
2303 #endif |
2311 #endif |
2304 Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady |
2312 Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady |
2305 |
2313 |
2306 // Handle SafeFetch32 and SafeFetchN exceptions. |
2314 // Handle SafeFetch32 and SafeFetchN exceptions. |
2307 if (StubRoutines::is_safefetch_fault(pc)) { |
2315 if (StubRoutines::is_safefetch_fault(pc)) { |