src/os/windows/vm/os_windows.cpp

changeset 7808
9a23a160ca57
parent 7633
8461d0b03127
child 7994
04ff2f6cd0eb
child 8660
719accf109f5
equal deleted inserted replaced
7807:0f0188a02ecb 7808:9a23a160ca57
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)) {

mercurial