mmdisp.nim 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2015 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. # Nim high-level memory manager: It supports Boehm's GC, Go's GC, no GC and the
  10. # native Nim GC. The native Nim GC is the default.
  11. #{.push checks:on, assertions:on.}
  12. {.push checks:off.}
  13. const
  14. debugGC = false # we wish to debug the GC...
  15. logGC = false
  16. traceGC = false # extensive debugging
  17. alwaysCycleGC = defined(nimSmokeCycles)
  18. alwaysGC = defined(nimFulldebug) # collect after every memory
  19. # allocation (for debugging)
  20. leakDetector = defined(nimLeakDetector)
  21. overwriteFree = defined(nimBurnFree) # overwrite memory with 0xFF before free
  22. trackAllocationSource = leakDetector
  23. cycleGC = true # (de)activate the cycle GC
  24. reallyDealloc = true # for debugging purposes this can be set to false
  25. reallyOsDealloc = true
  26. coalescRight = true
  27. coalescLeft = true
  28. logAlloc = false
  29. useCellIds = defined(nimCorruption)
  30. type
  31. PPointer = ptr pointer
  32. ByteArray = UncheckedArray[byte]
  33. PByte = ptr ByteArray
  34. PString = ptr string
  35. when declared(IntsPerTrunk):
  36. discard
  37. else:
  38. include bitmasks
  39. proc raiseOutOfMem() {.noinline.} =
  40. if outOfMemHook != nil: outOfMemHook()
  41. cstderr.rawWrite("out of memory\n")
  42. rawQuit(1)
  43. when defined(boehmgc):
  44. include system / mm / boehm
  45. elif defined(gogc):
  46. include system / mm / go
  47. elif (defined(nogc) or defined(gcDestructors)) and defined(useMalloc):
  48. include system / mm / malloc
  49. when defined(nogc):
  50. proc GC_getStatistics(): string = ""
  51. proc newObj(typ: PNimType, size: int): pointer {.compilerproc.} =
  52. result = alloc0(size)
  53. proc newSeq(typ: PNimType, len: int): pointer {.compilerproc.} =
  54. result = newObj(typ, align(GenericSeqSize, typ.align) + len * typ.base.size)
  55. cast[PGenericSeq](result).len = len
  56. cast[PGenericSeq](result).reserved = len
  57. elif defined(nogc):
  58. include system / mm / none
  59. else:
  60. when not defined(gcRegions):
  61. include "system/alloc"
  62. when not usesDestructors:
  63. include "system/cellsets"
  64. when not leakDetector and not useCellIds and not defined(nimV2):
  65. sysAssert(sizeof(Cell) == sizeof(FreeCell), "sizeof FreeCell")
  66. when defined(gcRegions):
  67. # XXX due to bootstrapping reasons, we cannot use compileOption("gc", "stack") here
  68. include "system/gc_regions"
  69. elif defined(nimV2) or usesDestructors:
  70. when not defined(useNimRtl):
  71. var allocator {.rtlThreadVar.}: MemRegion
  72. instantiateForRegion(allocator)
  73. when defined(gcHooks):
  74. include "system/gc_hooks"
  75. elif defined(gcMarkAndSweep):
  76. # XXX use 'compileOption' here
  77. include "system/gc_ms"
  78. else:
  79. include "system/gc"
  80. when not declared(nimNewSeqOfCap) and not defined(nimSeqsV2):
  81. {.push overflowChecks: on.}
  82. proc nimNewSeqOfCap(typ: PNimType, cap: int): pointer {.compilerproc.} =
  83. when defined(gcRegions):
  84. let s = cap * typ.base.size # newStr already adds GenericSeqSize
  85. result = newStr(typ, s, ntfNoRefs notin typ.base.flags)
  86. else:
  87. let s = align(GenericSeqSize, typ.base.align) + cap * typ.base.size
  88. when declared(newObjNoInit):
  89. result = if ntfNoRefs in typ.base.flags: newObjNoInit(typ, s) else: newObj(typ, s)
  90. else:
  91. result = newObj(typ, s)
  92. cast[PGenericSeq](result).len = 0
  93. cast[PGenericSeq](result).reserved = cap
  94. {.pop.}
  95. {.pop.}
  96. when not declared(ForeignCell):
  97. type ForeignCell* = object
  98. data*: pointer
  99. proc protect*(x: pointer): ForeignCell = ForeignCell(data: x)
  100. proc dispose*(x: ForeignCell) = discard
  101. proc isNotForeign*(x: ForeignCell): bool = false