108 static FILETIME process_exit_time; |
108 static FILETIME process_exit_time; |
109 static FILETIME process_user_time; |
109 static FILETIME process_user_time; |
110 static FILETIME process_kernel_time; |
110 static FILETIME process_kernel_time; |
111 |
111 |
112 #ifdef _M_IA64 |
112 #ifdef _M_IA64 |
113 #define __CPU__ ia64 |
113 #define __CPU__ ia64 |
114 #elif _M_AMD64 |
|
115 #define __CPU__ amd64 |
|
116 #else |
114 #else |
117 #define __CPU__ i486 |
115 #ifdef _M_AMD64 |
|
116 #define __CPU__ amd64 |
|
117 #else |
|
118 #define __CPU__ i486 |
|
119 #endif |
118 #endif |
120 #endif |
119 |
121 |
120 // save DLL module handle, used by GetModuleFileName |
122 // save DLL module handle, used by GetModuleFileName |
121 |
123 |
122 HINSTANCE vm_lib_handle; |
124 HINSTANCE vm_lib_handle; |
2136 exceptionInfo->ContextRecord->StIIP = (DWORD64)handler; |
2138 exceptionInfo->ContextRecord->StIIP = (DWORD64)handler; |
2137 // Clear out psr.ri (= Restart Instruction) in order to continue |
2139 // Clear out psr.ri (= Restart Instruction) in order to continue |
2138 // at the beginning of the target bundle. |
2140 // at the beginning of the target bundle. |
2139 exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF; |
2141 exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF; |
2140 assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!"); |
2142 assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!"); |
2141 #elif _M_AMD64 |
2143 #else |
|
2144 #ifdef _M_AMD64 |
2142 // Do not blow up if no thread info available. |
2145 // Do not blow up if no thread info available. |
2143 if (thread) { |
2146 if (thread) { |
2144 thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip); |
2147 thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip); |
2145 } |
2148 } |
2146 // Set pc to handler |
2149 // Set pc to handler |
2147 exceptionInfo->ContextRecord->Rip = (DWORD64)handler; |
2150 exceptionInfo->ContextRecord->Rip = (DWORD64)handler; |
2148 #else |
2151 #else |
2149 // Do not blow up if no thread info available. |
2152 // Do not blow up if no thread info available. |
2150 if (thread) { |
2153 if (thread) { |
2151 thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip); |
2154 thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip); |
2152 } |
2155 } |
2153 // Set pc to handler |
2156 // Set pc to handler |
2154 exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler; |
2157 exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler; |
|
2158 #endif |
2155 #endif |
2159 #endif |
2156 |
2160 |
2157 // Continue the execution |
2161 // Continue the execution |
2158 return EXCEPTION_CONTINUE_EXECUTION; |
2162 return EXCEPTION_CONTINUE_EXECUTION; |
2159 } |
2163 } |
2248 LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { |
2252 LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { |
2249 // handle exception caused by idiv; should only happen for -MinInt/-1 |
2253 // handle exception caused by idiv; should only happen for -MinInt/-1 |
2250 // (division by zero is handled explicitly) |
2254 // (division by zero is handled explicitly) |
2251 #ifdef _M_IA64 |
2255 #ifdef _M_IA64 |
2252 assert(0, "Fix Handle_IDiv_Exception"); |
2256 assert(0, "Fix Handle_IDiv_Exception"); |
2253 #elif _M_AMD64 |
2257 #else |
|
2258 #ifdef _M_AMD64 |
2254 PCONTEXT ctx = exceptionInfo->ContextRecord; |
2259 PCONTEXT ctx = exceptionInfo->ContextRecord; |
2255 address pc = (address)ctx->Rip; |
2260 address pc = (address)ctx->Rip; |
2256 assert(pc[0] == 0xF7, "not an idiv opcode"); |
2261 assert(pc[0] == 0xF7, "not an idiv opcode"); |
2257 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands"); |
2262 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands"); |
2258 assert(ctx->Rax == min_jint, "unexpected idiv exception"); |
2263 assert(ctx->Rax == min_jint, "unexpected idiv exception"); |
2259 // set correct result values and continue after idiv instruction |
2264 // set correct result values and continue after idiv instruction |
2260 ctx->Rip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes |
2265 ctx->Rip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes |
2261 ctx->Rax = (DWORD)min_jint; // result |
2266 ctx->Rax = (DWORD)min_jint; // result |
2262 ctx->Rdx = (DWORD)0; // remainder |
2267 ctx->Rdx = (DWORD)0; // remainder |
2263 // Continue the execution |
2268 // Continue the execution |
2264 #else |
2269 #else |
2265 PCONTEXT ctx = exceptionInfo->ContextRecord; |
2270 PCONTEXT ctx = exceptionInfo->ContextRecord; |
2266 address pc = (address)ctx->Eip; |
2271 address pc = (address)ctx->Eip; |
2267 assert(pc[0] == 0xF7, "not an idiv opcode"); |
2272 assert(pc[0] == 0xF7, "not an idiv opcode"); |
2268 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands"); |
2273 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands"); |
2269 assert(ctx->Eax == min_jint, "unexpected idiv exception"); |
2274 assert(ctx->Eax == min_jint, "unexpected idiv exception"); |
2270 // set correct result values and continue after idiv instruction |
2275 // set correct result values and continue after idiv instruction |
2271 ctx->Eip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes |
2276 ctx->Eip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes |
2272 ctx->Eax = (DWORD)min_jint; // result |
2277 ctx->Eax = (DWORD)min_jint; // result |
2273 ctx->Edx = (DWORD)0; // remainder |
2278 ctx->Edx = (DWORD)0; // remainder |
2274 // Continue the execution |
2279 // Continue the execution |
|
2280 #endif |
2275 #endif |
2281 #endif |
2276 return EXCEPTION_CONTINUE_EXECUTION; |
2282 return EXCEPTION_CONTINUE_EXECUTION; |
2277 } |
2283 } |
2278 |
2284 |
2279 #ifndef _WIN64 |
2285 #ifndef _WIN64 |
2349 // Convert the pc to "Unix format", which has the slot number coded |
2355 // Convert the pc to "Unix format", which has the slot number coded |
2350 // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2 |
2356 // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2 |
2351 // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction" |
2357 // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction" |
2352 // information is saved in the Unix format. |
2358 // information is saved in the Unix format. |
2353 address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2)); |
2359 address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2)); |
2354 #elif _M_AMD64 |
2360 #else |
|
2361 #ifdef _M_AMD64 |
2355 address pc = (address) exceptionInfo->ContextRecord->Rip; |
2362 address pc = (address) exceptionInfo->ContextRecord->Rip; |
2356 #else |
2363 #else |
2357 address pc = (address) exceptionInfo->ContextRecord->Eip; |
2364 address pc = (address) exceptionInfo->ContextRecord->Eip; |
|
2365 #endif |
2358 #endif |
2366 #endif |
2359 Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady |
2367 Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady |
2360 |
2368 |
2361 // Handle SafeFetch32 and SafeFetchN exceptions. |
2369 // Handle SafeFetch32 and SafeFetchN exceptions. |
2362 if (StubRoutines::is_safefetch_fault(pc)) { |
2370 if (StubRoutines::is_safefetch_fault(pc)) { |