summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2015-05-25 00:55:39 +0200
committerAndreas Rumpf <rumpf_a@web.de>2015-05-25 00:55:39 +0200
commit177129195f1380762acf780324f924e89d5de7ed (patch)
tree876cb777d34ffae1203193b5515056535635d21d /lib
parent28822c431ca6db750073eea38c210ae4b68e3095 (diff)
parent2a08bbdf31ce693ec0741ecbc9ae78a4d7b9a051 (diff)
downloadNim-177129195f1380762acf780324f924e89d5de7ed.tar.gz
Merge pull request #2671 from rbehrends/fix-register-scan
Fix GC scanning of registers on x86_64 architectures.
Diffstat (limited to 'lib')
-rw-r--r--lib/system/gc.nim9
-rw-r--r--lib/system/gc_ms.nim9
2 files changed, 18 insertions, 0 deletions
diff --git a/lib/system/gc.nim b/lib/system/gc.nim
index c4374d00c..e0d1006d9 100644
--- a/lib/system/gc.nim
+++ b/lib/system/gc.nim
@@ -922,6 +922,15 @@ else:
     if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
       var max = cast[ByteAddress](gch.stackBottom)
       var sp = cast[ByteAddress](addr(registers))
+      when defined(amd64):
+        # words within the jmp_buf structure may not be properly aligned.
+        let regEnd = sp +% sizeof(registers)
+        while sp <% regEnd:
+          gcMark(gch, cast[PPointer](sp)[])
+          gcMark(gch, cast[PPointer](sp +% sizeof(pointer) div 2)[])
+          sp = sp +% sizeof(pointer)
+      # Make sure sp is word-aligned
+      sp = sp and not (sizeof(pointer) - 1)
       # loop unrolled:
       while sp <% max - 8*sizeof(pointer):
         gcMark(gch, cast[PStackSlice](sp)[0])
diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim
index e287bf5d9..a0699f46a 100644
--- a/lib/system/gc_ms.nim
+++ b/lib/system/gc_ms.nim
@@ -514,6 +514,15 @@ else:
     if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
       var max = cast[ByteAddress](gch.stackBottom)
       var sp = cast[ByteAddress](addr(registers))
+      when defined(amd64):
+        # words within the jmp_buf structure may not be properly aligned.
+        let regEnd = sp +% sizeof(registers)
+        while sp <% regEnd:
+          gcMark(gch, cast[PPointer](sp)[])
+          gcMark(gch, cast[PPointer](sp +% sizeof(pointer) div 2)[])
+          sp = sp +% sizeof(pointer)
+      # Make sure sp is word-aligned
+      sp = sp and not (sizeof(pointer) - 1)
       # loop unrolled:
       while sp <% max - 8*sizeof(pointer):
         gcMark(gch, cast[PStackSlice](sp)[0])