summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2017-07-20 18:42:00 +0200
committerAndreas Rumpf <rumpf_a@web.de>2017-07-20 18:42:08 +0200
commit6f89323385f3a0aedaf8e83ec72fe73477b3518c (patch)
treec4c61fecc4c37c237672a7d9fc20780eda5c59e7 /lib
parentebba9f06ae3074255830128ecb599fb22a3310ef (diff)
downloadNim-6f89323385f3a0aedaf8e83ec72fe73477b3518c.tar.gz
make the GCs more robust
Diffstat (limited to 'lib')
-rw-r--r--lib/system/gc.nim18
-rw-r--r--lib/system/gc_ms.nim14
2 files changed, 16 insertions, 16 deletions
diff --git a/lib/system/gc.nim b/lib/system/gc.nim
index e37f601b4..2cef2b636 100644
--- a/lib/system/gc.nim
+++ b/lib/system/gc.nim
@@ -754,8 +754,8 @@ proc gcMark(gch: var GcHeap, p: pointer) {.inline.} =
 
 #[
   This method is conditionally marked with an attribute so that it gets ignored by the LLVM ASAN
-  (Address SANitizer) intrumentation as it will raise false errors due to the implementation of 
-  garbage collection that is used by Nim. For more information, please see the documentation of 
+  (Address SANitizer) intrumentation as it will raise false errors due to the implementation of
+  garbage collection that is used by Nim. For more information, please see the documentation of
   `CLANG_NO_SANITIZE_ADDRESS` in `lib/nimbase.h`.
  ]#
 proc markStackAndRegisters(gch: var GcHeap) {.noinline, cdecl, codegenDecl: "CLANG_NO_SANITIZE_ADDRESS $# $#$#".} =
@@ -920,11 +920,13 @@ when not defined(useNimRtl):
     else:
       inc(gch.recGcLock)
   proc GC_enable() =
-    if gch.recGcLock > 0:
-      when hasThreadSupport and hasSharedHeap:
-        discard atomicDec(gch.recGcLock, 1)
-      else:
-        dec(gch.recGcLock)
+    if gch.recGcLock <= 0:
+      raise newException(AssertionError,
+          "API usage error: GC_enable called but GC is already enabled")
+    when hasThreadSupport and hasSharedHeap:
+      discard atomicDec(gch.recGcLock, 1)
+    else:
+      dec(gch.recGcLock)
 
   proc GC_setStrategy(strategy: GC_Strategy) =
     discard
@@ -945,7 +947,6 @@ when not defined(useNimRtl):
     release(gch)
 
   proc GC_getStatistics(): string =
-    GC_disable()
     result = "[GC] total memory: " & $(getTotalMem()) & "\n" &
              "[GC] occupied memory: " & $(getOccupiedMem()) & "\n" &
              "[GC] stack scans: " & $gch.stat.stackScans & "\n" &
@@ -961,6 +962,5 @@ when not defined(useNimRtl):
         result = result & "[GC]   stack " & stack.bottom.repr & "[GC]     max stack size " & cast[pointer](stack.maxStackSize).repr & "\n"
     else:
       result = result & "[GC] max stack size: " & $gch.stat.maxStackSize & "\n"
-    GC_enable()
 
 {.pop.} # profiler: off, stackTrace: off
diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim
index a97e974a1..ba8c569f7 100644
--- a/lib/system/gc_ms.nim
+++ b/lib/system/gc_ms.nim
@@ -506,11 +506,13 @@ when not defined(useNimRtl):
     else:
       inc(gch.recGcLock)
   proc GC_enable() =
-    if gch.recGcLock > 0:
-      when hasThreadSupport and hasSharedHeap:
-        atomicDec(gch.recGcLock, 1)
-      else:
-        dec(gch.recGcLock)
+    if gch.recGcLock <= 0:
+      raise newException(AssertionError,
+          "API usage error: GC_enable called but GC is already enabled")
+    when hasThreadSupport and hasSharedHeap:
+      atomicDec(gch.recGcLock, 1)
+    else:
+      dec(gch.recGcLock)
 
   proc GC_setStrategy(strategy: GC_Strategy) = discard
 
@@ -530,7 +532,6 @@ when not defined(useNimRtl):
     release(gch)
 
   proc GC_getStatistics(): string =
-    GC_disable()
     result = "[GC] total memory: " & $getTotalMem() & "\n" &
              "[GC] occupied memory: " & $getOccupiedMem() & "\n" &
              "[GC] collections: " & $gch.stat.collections & "\n" &
@@ -542,6 +543,5 @@ when not defined(useNimRtl):
         result = result & "[GC]   stack " & stack.bottom.repr & "[GC]     max stack size " & $stack.maxStackSize & "\n"
     else:
       result = result & "[GC] max stack size: " & $gch.stat.maxStackSize & "\n"
-    GC_enable()
 
 {.pop.}