1# 2# 3# Nim's Runtime Library 4# (c) Copyright 2019 Andreas Rumpf 5# 6# See the file "copying.txt", included in this 7# distribution, for details about the copyright. 8# 9 10## Hooks for memory management. Can be used to implement custom garbage 11## collectors etc. 12 13type 14 GlobalMarkerProc = proc () {.nimcall, benign, raises: [], tags: [].} 15var 16 globalMarkersLen: int 17 globalMarkers: array[0..3499, GlobalMarkerProc] 18 threadLocalMarkersLen: int 19 threadLocalMarkers: array[0..3499, GlobalMarkerProc] 20 21proc nimRegisterGlobalMarker(markerProc: GlobalMarkerProc) {.compilerproc.} = 22 if globalMarkersLen <= high(globalMarkers): 23 globalMarkers[globalMarkersLen] = markerProc 24 inc globalMarkersLen 25 else: 26 cstderr.rawWrite("[GC] cannot register global variable; too many global variables") 27 quit 1 28 29proc nimRegisterThreadLocalMarker(markerProc: GlobalMarkerProc) {.compilerproc.} = 30 if threadLocalMarkersLen <= high(threadLocalMarkers): 31 threadLocalMarkers[threadLocalMarkersLen] = markerProc 32 inc threadLocalMarkersLen 33 else: 34 cstderr.rawWrite("[GC] cannot register thread local variable; too many thread local variables") 35 quit 1 36 37proc traverseGlobals*() = 38 for i in 0..globalMarkersLen-1: 39 globalMarkers[i]() 40 41proc traverseThreadLocals*() = 42 for i in 0..threadLocalMarkersLen-1: 43 threadLocalMarkers[i]() 44 45var 46 newObjHook*: proc (typ: PNimType, size: int): pointer {.nimcall, tags: [], raises: [], gcsafe.} 47 traverseObjHook*: proc (p: pointer, op: int) {.nimcall, tags: [], raises: [], gcsafe.} 48 49proc nimGCvisit(p: pointer, op: int) {.inl, compilerRtl.} = 50 traverseObjHook(p, op) 51 52proc newObj(typ: PNimType, size: int): pointer {.inl, compilerRtl.} = 53 result = newObjHook(typ, size) 54