diff options
Diffstat (limited to 'lib/system/gc_regions.nim')
-rw-r--r-- | lib/system/gc_regions.nim | 79 |
1 files changed, 47 insertions, 32 deletions
diff --git a/lib/system/gc_regions.nim b/lib/system/gc_regions.nim index e9efbdfb0..06fded86b 100644 --- a/lib/system/gc_regions.nim +++ b/lib/system/gc_regions.nim @@ -70,8 +70,9 @@ type bump: pointer head, tail: Chunk nextChunkSize, totalSize: int - freeLists: array[MaxSmallObject div MemAlign, FreeEntry] - holes: SizedFreeEntry + when false: + freeLists: array[MaxSmallObject div MemAlign, FreeEntry] + holes: SizedFreeEntry when hasThreadSupport: lock: SysLock @@ -144,22 +145,24 @@ proc allocSlowPath(r: var MemRegion; size: int) = r.tail = fresh r.remaining = s - sizeof(BaseChunk) -proc alloc(r: var MemRegion; size: int): pointer = - if size <= MaxSmallObject: - var it = r.freeLists[size div MemAlign] - if it != nil: - r.freeLists[size div MemAlign] = it.next - return pointer(it) - else: - var it = r.holes - var prev: SizedFreeEntry = nil - while it != nil: - if it.size >= size: - if prev != nil: prev.next = it.next - else: r.holes = it.next +proc allocFast(r: var MemRegion; size: int): pointer = + when false: + if size <= MaxSmallObject: + var it = r.freeLists[size div MemAlign] + if it != nil: + r.freeLists[size div MemAlign] = it.next return pointer(it) - prev = it - it = it.next + else: + var it = r.holes + var prev: SizedFreeEntry = nil + while it != nil: + if it.size >= size: + if prev != nil: prev.next = it.next + else: r.holes = it.next + return pointer(it) + prev = it + it = it.next + let size = roundup(size, MemAlign) if size > r.remaining: allocSlowPath(r, size) sysAssert(size <= r.remaining, "size <= r.remaining") @@ -184,15 +187,16 @@ proc dealloc(r: var MemRegion; p: pointer; size: int) = # it is benefitial to not use the free lists here: if r.bump -! size == p: dec r.bump, size - elif size <= MaxSmallObject: - let it = cast[FreeEntry](p) - it.next = r.freeLists[size div MemAlign] - r.freeLists[size div MemAlign] = it - else: - let it = cast[SizedFreeEntry](p) - it.size = size - it.next = r.holes - r.holes = it + when false: + if size <= MaxSmallObject: + let it = cast[FreeEntry](p) + it.next = r.freeLists[size div MemAlign] + r.freeLists[size div MemAlign] = it + else: + let it = cast[SizedFreeEntry](p) + it.size = size + it.next = r.holes + r.holes = it proc deallocAll(r: var MemRegion; head: Chunk) = var it = head @@ -220,9 +224,10 @@ proc setObstackPtr*(r: var MemRegion; sp: StackPtr) = if sp.current.next != nil: deallocAll(r, sp.current.next) sp.current.next = nil - # better leak this memory than be sorry: - for i in 0..high(r.freeLists): r.freeLists[i] = nil - r.holes = nil + when false: + # better leak this memory than be sorry: + for i in 0..high(r.freeLists): r.freeLists[i] = nil + r.holes = nil #else: # deallocAll(r, r.head) # r.head = nil @@ -270,7 +275,7 @@ proc isOnHeap*(r: MemRegion; p: pointer): bool = it = it.next proc rawNewObj(r: var MemRegion, typ: PNimType, size: int): pointer = - var res = cast[ptr ObjHeader](alloc(r, size + sizeof(ObjHeader))) + var res = cast[ptr ObjHeader](allocFast(r, size + sizeof(ObjHeader))) res.typ = typ if typ.finalizer != nil: res.nextFinal = r.head.head @@ -278,17 +283,19 @@ proc rawNewObj(r: var MemRegion, typ: PNimType, size: int): pointer = result = res +! sizeof(ObjHeader) proc rawNewSeq(r: var MemRegion, typ: PNimType, size: int): pointer = - var res = cast[ptr SeqHeader](alloc(r, size + sizeof(SeqHeader))) + var res = cast[ptr SeqHeader](allocFast(r, size + sizeof(SeqHeader))) res.typ = typ res.region = addr(r) result = res +! sizeof(SeqHeader) proc newObj(typ: PNimType, size: int): pointer {.compilerRtl.} = + sysAssert typ.kind notin {tySequence, tyString}, "newObj cannot be used to construct seqs" result = rawNewObj(tlRegion, typ, size) zeroMem(result, size) when defined(memProfiler): nimProfile(size) proc newObjNoInit(typ: PNimType, size: int): pointer {.compilerRtl.} = + sysAssert typ.kind notin {tySequence, tyString}, "newObj cannot be used to construct seqs" result = rawNewObj(tlRegion, typ, size) when defined(memProfiler): nimProfile(size) @@ -351,6 +358,11 @@ proc alloc0(r: var MemRegion; size: Natural): pointer = # but incorrect in general. XXX result = alloc0(size) +proc alloc(r: var MemRegion; size: Natural): pointer = + # ignore the region. That is correct for the channels module + # but incorrect in general. XXX + result = alloc(size) + proc dealloc(r: var MemRegion; p: pointer) = dealloc(p) proc allocShared(size: Natural): pointer = @@ -389,4 +401,7 @@ proc getFreeMem*(r: MemRegion): int = r.remaining proc getTotalMem*(r: MemRegion): int = result = r.totalSize -proc setStackBottom(theStackBottom: pointer) = discard +proc nimGC_setStackBottom(theStackBottom: pointer) = discard + +proc nimGCref(x: pointer) {.compilerProc.} = discard +proc nimGCunref(x: pointer) {.compilerProc.} = discard |