go.nim 6.1 KB

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