hotspot/src/os/windows/vm/os_windows.cpp
changeset 33160 c59f1676d27e
parent 32748 6cb8b6ab9081
child 33198 b37ad9fbf681
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Thu Oct 08 10:25:45 2015 +0000
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Thu Oct 08 12:49:30 2015 -1000
@@ -2272,12 +2272,17 @@
   #ifdef  _M_AMD64
   PCONTEXT ctx = exceptionInfo->ContextRecord;
   address pc = (address)ctx->Rip;
-  assert(pc[0] == 0xF7, "not an idiv opcode");
-  assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
-  assert(ctx->Rax == min_jint, "unexpected idiv exception");
-  // set correct result values and continue after idiv instruction
-  ctx->Rip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
-  ctx->Rax = (DWORD)min_jint;      // result
+  assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && pc[1] == 0xF7 || pc[0] == 0xF7, "not an idiv opcode");
+  assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && (pc[2] & ~0x7) == 0xF8 || (pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
+  if (pc[0] == 0xF7) {
+    // set correct result values and continue after idiv instruction
+    ctx->Rip = (DWORD64)pc + 2;        // idiv reg, reg  is 2 bytes
+  } else {
+    ctx->Rip = (DWORD64)pc + 3;        // REX idiv reg, reg  is 3 bytes
+  }
+  // Do not set ctx->Rax as it already contains the correct value (either 32 or 64 bit, depending on the operation)
+  // this is the case because the exception only happens for -MinValue/-1 and -MinValue is always in rax because of the
+  // idiv opcode (0xF7).
   ctx->Rdx = (DWORD)0;             // remainder
   // Continue the execution
   #else