summary refs log tree commit diff stats
path: root/compiler/debuginfo.nim
Commit message (Expand)AuthorAgeFilesLines
* happy new yearAraq2017-01-071-1/+1
* use a full MD5 hash with no collision detection for proc namesAraq2016-11-081-3/+3
* C codegen: first version of signature hashing for better incremental buildsAraq2016-11-081-10/+7
* fixes #4144Andreas Rumpf2016-05-111-24/+16
* better debugging support for native debuggers; changed name mangling; fixes #...Araq2016-05-101-0/+89
n68'>68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
#
#
#            Nimrod's Runtime Library
#        (c) Copyright 2011 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

# Nimrod high-level memory manager: It supports Boehm's GC, no GC and the
# native Nimrod GC. The native Nimrod GC is the default.

#{.push checks:on, assertions:on.}
{.push checks:off.}

const
  debugGC = false # we wish to debug the GC...
  logGC = false
  traceGC = false # extensive debugging
  reallyDealloc = true # for debugging purposes this can be set to false
  cycleGC = true # (de)activate the cycle GC
  stressGC = false
  reallyOsDealloc = true
  coalescRight = true
  coalescLeft = true
  overwriteFree = false

type
  PPointer = ptr pointer
  TByteArray = array[0..1000_0000, byte]
  PByte = ptr TByteArray
  PString = ptr string

# Page size of the system; in most cases 4096 bytes. For exotic OS or
# CPU this needs to be changed:
const
  PageShift = 12
  PageSize = 1 shl PageShift
  PageMask = PageSize-1

  MemAlign = 8 # also minimal allocatable memory block

  BitsPerPage = PageSize div MemAlign
  UnitsPerPage = BitsPerPage div (sizeof(int)*8)
    # how many ints do we need to describe a page:
    # on 32 bit systems this is only 16 (!)

  TrunkShift = 9
  BitsPerTrunk = 1 shl TrunkShift # needs to be power of 2 and divisible by 64
  TrunkMask = BitsPerTrunk - 1
  IntsPerTrunk = BitsPerTrunk div (sizeof(int)*8)
  IntShift = 5 + ord(sizeof(int) == 8) # 5 or 6, depending on int width
  IntMask = 1 shl IntShift - 1

proc raiseOutOfMem() {.noinline.} =
  if outOfMemHook != nil: outOfMemHook()
  echo("out of memory")
  quit(1)

when defined(boehmgc):
  when defined(windows):
    const boehmLib = "boehmgc.dll"
  elif defined(macosx):
    const boehmLib = "libgc.dylib"
  else:
    const boehmLib = "/usr/lib/libgc.so.1"
    
  proc boehmGCinit {.importc: "GC_init", dynlib: boehmLib.}
  proc boehmGC_disable {.importc: "GC_disable", dynlib: boehmLib.} 
  proc boehmGC_enable {.importc: "GC_enable", dynlib: boehmLib.} 
  proc boehmGCincremental {.
    importc: "GC_enable_incremental", dynlib: boehmLib.} 
  proc boehmGCfullCollect {.importc: "GC_gcollect", dynlib: boehmLib.}  
  proc boehmAlloc(size: int): pointer {.
    importc: "GC_malloc", dynlib: boehmLib.}
  proc boehmAllocAtomic(size: int): pointer {.
    importc: "GC_malloc_atomic", dynlib: boehmLib.}
  proc boehmRealloc(p: pointer, size: int): pointer {.
    importc: "GC_realloc", dynlib: boehmLib.}
  proc boehmDealloc(p: pointer) {.importc: "GC_free", dynlib: boehmLib.}
  
  when not defined(useNimRtl):
    
    proc alloc(size: int): pointer =
      result = boehmAlloc(size)
      if result == nil: raiseOutOfMem()
    proc alloc0(size: int): pointer =
      result = alloc(size)
      zeroMem(result, size)
    proc realloc(p: Pointer, newsize: int): pointer =
      result = boehmRealloc(p, newsize)
      if result == nil: raiseOutOfMem()
    proc dealloc(p: Pointer) = boehmDealloc(p)

    proc allocShared(size: int): pointer =
      result = boehmAlloc(size)
      if result == nil: raiseOutOfMem()
    proc allocShared0(size: int): pointer =
      result = alloc(size)
      zeroMem(result, size)
    proc reallocShared(p: Pointer, newsize: int): pointer =
      result = boehmRealloc(p, newsize)
      if result == nil: raiseOutOfMem()
    proc deallocShared(p: Pointer) = boehmDealloc(p)

    #boehmGCincremental()

    proc GC_disable() = boehmGC_disable()
    proc GC_enable() = boehmGC_enable()
    proc GC_fullCollect() = boehmGCfullCollect()
    proc GC_setStrategy(strategy: TGC_Strategy) = nil
    proc GC_enableMarkAndSweep() = nil
    proc GC_disableMarkAndSweep() = nil
    proc GC_getStatistics(): string = return ""
    
    proc getOccupiedMem(): int = return -1
    proc getFreeMem(): int = return -1
    proc getTotalMem(): int = return -1

    proc setStackBottom(theStackBottom: pointer) = nil

  proc initGC() = 
    when defined(macosx): boehmGCinit()

  proc newObj(typ: PNimType, size: int): pointer {.compilerproc.} =
    result = alloc(size)
  proc newSeq(typ: PNimType, len: int): pointer {.compilerproc.} =
    result = newObj(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize))
    cast[PGenericSeq](result).len = len
    cast[PGenericSeq](result).space = len

  proc growObj(old: pointer, newsize: int): pointer =
    result = realloc(old, newsize)

  proc nimGCref(p: pointer) {.compilerproc, inline.} = nil
  proc nimGCunref(p: pointer) {.compilerproc, inline.} = nil
  
  proc unsureAsgnRef(dest: ppointer, src: pointer) {.compilerproc, inline.} =
    dest[] = src
  proc asgnRef(dest: ppointer, src: pointer) {.compilerproc, inline.} =
    dest[] = src
  proc asgnRefNoCycle(dest: ppointer, src: pointer) {.compilerproc, inline.} =
    dest[] = src

  type
    TMemRegion = object {.final, pure.}
  
  proc Alloc(r: var TMemRegion, size: int): pointer =
    result = boehmAlloc(size)
    if result == nil: raiseOutOfMem()
  proc Alloc0(r: var TMemRegion, size: int): pointer =
    result = alloc(size)
    zeroMem(result, size)
  proc Dealloc(r: var TMemRegion, p: Pointer) = boehmDealloc(p)  
  proc deallocOsPages(r: var TMemRegion) {.inline.} = nil
  proc deallocOsPages() {.inline.} = nil

  include "system/cellsets"
elif defined(nogc):
  # Even though we don't want the GC, we cannot simply use C's memory manager
  # because Nimrod's runtime wants ``realloc`` to zero out the additional
  # space which C's ``realloc`` does not. And we cannot get the old size of an
  # object, because C does not support this operation... Even though every
  # possible implementation has to have a way to determine the object's size.
  # C just sucks.
  when appType == "lib": 
    {.warning: "nogc in a library context may not work".}
  
  include "system/alloc"

  proc initGC() = nil
  proc GC_disable() = nil
  proc GC_enable() = nil
  proc GC_fullCollect() = nil
  proc GC_setStrategy(strategy: TGC_Strategy) = nil
  proc GC_enableMarkAndSweep() = nil
  proc GC_disableMarkAndSweep() = nil
  proc GC_getStatistics(): string = return ""
  
  
  proc newObj(typ: PNimType, size: int): pointer {.compilerproc.} =
    result = alloc0(size)
  proc newSeq(typ: PNimType, len: int): pointer {.compilerproc.} =
    result = newObj(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize))
    cast[PGenericSeq](result).len = len
    cast[PGenericSeq](result).space = len
  proc growObj(old: pointer, newsize: int): pointer =
    result = realloc(old, newsize)

  proc setStackBottom(theStackBottom: pointer) = nil
  proc nimGCref(p: pointer) {.compilerproc, inline.} = nil
  proc nimGCunref(p: pointer) {.compilerproc, inline.} = nil
  
  proc unsureAsgnRef(dest: ppointer, src: pointer) {.compilerproc, inline.} =
    dest[] = src
  proc asgnRef(dest: ppointer, src: pointer) {.compilerproc, inline.} =
    dest[] = src
  proc asgnRefNoCycle(dest: ppointer, src: pointer) {.compilerproc, inline.} =
    dest[] = src

  var allocator {.rtlThreadVar.}: TMemRegion
  InstantiateForRegion(allocator)

  include "system/cellsets"

else:
  include "system/alloc"

  include "system/cellsets"
  sysAssert(sizeof(TCell) == sizeof(TFreeCell), "sizeof TFreeCell")
  include "system/gc"
  
{.pop.}