1
2when defined(windows):
3  const goLib = "libgo.dll"
4elif defined(macosx):
5  const goLib = "libgo.dylib"
6else:
7  const goLib = "libgo.so"
8
9proc initGC() = discard
10proc GC_disable() = discard
11proc GC_enable() = discard
12proc go_gc() {.importc: "go_gc", dynlib: goLib.}
13proc GC_fullCollect() = go_gc()
14proc GC_setStrategy(strategy: GC_Strategy) = discard
15proc GC_enableMarkAndSweep() = discard
16proc GC_disableMarkAndSweep() = discard
17
18const
19  goNumSizeClasses = 67
20
21type
22  goMStats = object
23    alloc: uint64          # bytes allocated and still in use
24    total_alloc: uint64    # bytes allocated (even if freed)
25    sys: uint64            # bytes obtained from system
26    nlookup: uint64        # number of pointer lookups
27    nmalloc: uint64        # number of mallocs
28    nfree: uint64          # number of frees
29    heap_objects: uint64   # total number of allocated objects
30    pause_total_ns: uint64 # cumulative nanoseconds in GC stop-the-world pauses since the program started
31    numgc: uint32          # number of completed GC cycles
32
33proc goMemStats(): goMStats {.importc: "go_mem_stats", dynlib: goLib.}
34proc goMalloc(size: uint): pointer {.importc: "go_malloc", dynlib: goLib.}
35proc goSetFinalizer(obj: pointer, f: pointer) {.importc: "set_finalizer", codegenDecl:"$1 $2$3 __asm__ (\"main.Set_finalizer\");\n$1 $2$3", dynlib: goLib.}
36proc writebarrierptr(dest: PPointer, src: pointer) {.importc: "writebarrierptr", codegenDecl:"$1 $2$3 __asm__ (\"main.Atomic_store_pointer\");\n$1 $2$3", dynlib: goLib.}
37
38proc GC_getStatistics(): string =
39  var mstats = goMemStats()
40  result = "[GC] total allocated memory: " & $(mstats.total_alloc) & "\n" &
41           "[GC] total memory obtained from system: " & $(mstats.sys) & "\n" &
42           "[GC] occupied memory: " & $(mstats.alloc) & "\n" &
43           "[GC] number of pointer lookups: " & $(mstats.nlookup) & "\n" &
44           "[GC] number of mallocs: " & $(mstats.nmalloc) & "\n" &
45           "[GC] number of frees: " & $(mstats.nfree) & "\n" &
46           "[GC] heap objects: " & $(mstats.heap_objects) & "\n" &
47           "[GC] number of completed GC cycles: " & $(mstats.numgc) & "\n" &
48           "[GC] total GC pause time [ms]: " & $(mstats.pause_total_ns div 1000_000)
49
50proc getOccupiedMem(): int =
51  var mstats = goMemStats()
52  result = int(mstats.alloc)
53
54proc getFreeMem(): int =
55  var mstats = goMemStats()
56  result = int(mstats.sys - mstats.alloc)
57
58proc getTotalMem(): int =
59  var mstats = goMemStats()
60  result = int(mstats.sys)
61
62proc nimGC_setStackBottom(theStackBottom: pointer) = discard
63
64proc allocImpl(size: Natural): pointer =
65  result = goMalloc(size.uint)
66
67proc alloc0Impl(size: Natural): pointer =
68  result = goMalloc(size.uint)
69
70proc reallocImpl(p: pointer, newsize: Natural): pointer =
71  doAssert false, "not implemented"
72
73proc realloc0Impl(p: pointer, oldsize, newsize: Natural): pointer =
74  doAssert false, "not implemented"
75
76proc deallocImpl(p: pointer) =
77  discard
78
79proc allocSharedImpl(size: Natural): pointer = allocImpl(size)
80proc allocShared0Impl(size: Natural): pointer = alloc0Impl(size)
81proc reallocSharedImpl(p: pointer, newsize: Natural): pointer = reallocImpl(p, newsize)
82proc reallocShared0Impl(p: pointer, oldsize, newsize: Natural): pointer = realloc0Impl(p, oldsize, newsize)
83proc deallocSharedImpl(p: pointer) = deallocImpl(p)
84
85when hasThreadSupport:
86  proc getFreeSharedMem(): int = discard
87  proc getTotalSharedMem(): int = discard
88  proc getOccupiedSharedMem(): int = discard
89
90proc newObj(typ: PNimType, size: int): pointer {.compilerproc.} =
91  writebarrierptr(addr(result), goMalloc(size.uint))
92  if typ.finalizer != nil:
93    goSetFinalizer(result, typ.finalizer)
94
95proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
96  writebarrierptr(addr(result), newObj(typ, size))
97
98proc newObjNoInit(typ: PNimType, size: int): pointer =
99  writebarrierptr(addr(result), newObj(typ, size))
100
101proc newSeq(typ: PNimType, len: int): pointer {.compilerproc.} =
102  writebarrierptr(addr(result), newObj(typ, align(GenericSeqSize, typ.base.align) + len * typ.base.size))
103  cast[PGenericSeq](result).len = len
104  cast[PGenericSeq](result).reserved = len
105  cast[PGenericSeq](result).elemSize = typ.base.size
106  cast[PGenericSeq](result).elemAlign = typ.base.align
107
108proc newSeqRC1(typ: PNimType, len: int): pointer {.compilerRtl.} =
109  writebarrierptr(addr(result), newSeq(typ, len))
110
111proc nimNewSeqOfCap(typ: PNimType, cap: int): pointer {.compilerproc.} =
112  result = newObj(typ, align(GenericSeqSize, typ.base.align) + cap * typ.base.size)
113  cast[PGenericSeq](result).len = 0
114  cast[PGenericSeq](result).reserved = cap
115  cast[PGenericSeq](result).elemSize = typ.base.size
116  cast[PGenericSeq](result).elemAlign = typ.base.align
117
118proc typedMemMove(dest: pointer, src: pointer, size: uint) {.importc: "typedmemmove", dynlib: goLib.}
119
120proc growObj(old: pointer, newsize: int): pointer =
121  # the Go GC doesn't have a realloc
122  let old = cast[PGenericSeq](old)
123  var metadataOld = cast[PGenericSeq](old)
124  if metadataOld.elemSize == 0:
125    metadataOld.elemSize = 1
126
127  let oldsize = align(GenericSeqSize, old.elemAlign) + old.len * old.elemSize
128  writebarrierptr(addr(result), goMalloc(newsize.uint))
129  typedMemMove(result, old, oldsize.uint)
130
131proc nimGCref(p: pointer) {.compilerproc, inline.} = discard
132proc nimGCunref(p: pointer) {.compilerproc, inline.} = discard
133proc nimGCunrefNoCycle(p: pointer) {.compilerproc, inline.} = discard
134proc nimGCunrefRC1(p: pointer) {.compilerproc, inline.} = discard
135proc nimGCvisit(d: pointer, op: int) {.compilerRtl.} = discard
136
137proc unsureAsgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} =
138  writebarrierptr(dest, src)
139proc asgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} =
140  writebarrierptr(dest, src)
141proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline,
142  deprecated: "old compiler compat".} = asgnRef(dest, src)
143
144type
145  MemRegion = object
146
147proc alloc(r: var MemRegion, size: int): pointer =
148  result = alloc(size)
149proc alloc0(r: var MemRegion, size: int): pointer =
150  result = alloc0Impl(size)
151proc dealloc(r: var MemRegion, p: pointer) = dealloc(p)
152proc deallocOsPages(r: var MemRegion) {.inline.} = discard
153proc deallocOsPages() {.inline.} = discard
154