--gc:destructors now means Nim uses pure refcounting (#12557)
This commit is contained in:
parent
b5bb581642
commit
1746da2d9e
12 changed files with 123 additions and 35 deletions
|
|
@ -57,13 +57,13 @@ proc nimNewObj(size: int): pointer {.compilerRtl.} =
|
|||
else:
|
||||
inc allocs
|
||||
|
||||
proc nimDecWeakRef(p: pointer) {.compilerRtl.} =
|
||||
proc nimDecWeakRef(p: pointer) {.compilerRtl, inl.} =
|
||||
when hasThreadSupport:
|
||||
atomicDec head(p).rc
|
||||
else:
|
||||
dec head(p).rc
|
||||
|
||||
proc nimIncWeakRef(p: pointer) {.compilerRtl.} =
|
||||
proc nimIncRef(p: pointer) {.compilerRtl, inl.} =
|
||||
when hasThreadSupport:
|
||||
atomicInc head(p).rc
|
||||
else:
|
||||
|
|
@ -106,11 +106,25 @@ proc nimDestroyAndDispose(p: pointer) {.compilerRtl.} =
|
|||
cstderr.rawWrite "has destructor!\n"
|
||||
nimRawDispose(p)
|
||||
|
||||
proc isObj(obj: PNimType, subclass: cstring): bool {.compilerproc.} =
|
||||
proc nimDecRefIsLast(p: pointer): bool {.compilerRtl, inl.} =
|
||||
if p != nil:
|
||||
when hasThreadSupport:
|
||||
if atomicLoadN(addr head(p).rc, ATOMIC_RELAXED) == 0:
|
||||
result = true
|
||||
else:
|
||||
if atomicDec(head(p).rc) <= 0:
|
||||
result = true
|
||||
else:
|
||||
if head(p).rc == 0:
|
||||
result = true
|
||||
else:
|
||||
dec head(p).rc
|
||||
|
||||
proc isObj(obj: PNimType, subclass: cstring): bool {.compilerRtl, inl.} =
|
||||
proc strstr(s, sub: cstring): cstring {.header: "<string.h>", importc.}
|
||||
|
||||
result = strstr(obj.name, subclass) != nil
|
||||
|
||||
proc chckObj(obj: PNimType, subclass: cstring) {.compilerproc.} =
|
||||
proc chckObj(obj: PNimType, subclass: cstring) {.compilerRtl.} =
|
||||
# checks if obj is of type subclass:
|
||||
if not isObj(obj, subclass): sysFatal(ObjectConversionError, "invalid object conversion")
|
||||
|
|
|
|||
|
|
@ -1722,12 +1722,12 @@ template `isnot`*(x, y: untyped): untyped = not (x is y)
|
|||
## assert 42 isnot float
|
||||
## assert @[1, 2] isnot enum
|
||||
|
||||
when (defined(nimV2) and not defined(nimscript)) or defined(nimFixedOwned):
|
||||
when (defined(nimOwnedEnabled) and not defined(nimscript)) or defined(nimFixedOwned):
|
||||
type owned*[T]{.magic: "BuiltinType".} ## type constructor to mark a ref/ptr or a closure as `owned`.
|
||||
else:
|
||||
template owned*(t: typedesc): typedesc = t
|
||||
|
||||
when defined(nimV2) and not defined(nimscript):
|
||||
when defined(nimOwnedEnabled) and not defined(nimscript):
|
||||
proc new*[T](a: var owned(ref T)) {.magic: "New", noSideEffect.}
|
||||
## Creates a new object of type ``T`` and returns a safe (traced)
|
||||
## reference to it in ``a``.
|
||||
|
|
@ -3237,6 +3237,8 @@ proc `<`*[T: tuple](x, y: T): bool =
|
|||
|
||||
|
||||
# ----------------- GC interface ---------------------------------------------
|
||||
const
|
||||
usesDestructors = defined(gcDestructors) or defined(gcHooks)
|
||||
|
||||
when not defined(nimscript) and hasAlloc:
|
||||
type
|
||||
|
|
@ -3246,7 +3248,7 @@ when not defined(nimscript) and hasAlloc:
|
|||
gcOptimizeTime, ## optimize for speed
|
||||
gcOptimizeSpace ## optimize for memory footprint
|
||||
|
||||
when not defined(JS) and not defined(gcDestructors):
|
||||
when not defined(JS) and not usesDestructors:
|
||||
proc GC_disable*() {.rtl, inl, benign.}
|
||||
## Disables the GC. If called `n` times, `n` calls to `GC_enable`
|
||||
## are needed to reactivate the GC.
|
||||
|
|
@ -3602,7 +3604,7 @@ when not defined(JS): #and not defined(nimscript):
|
|||
{.push stack_trace: off, profiler:off.}
|
||||
|
||||
when hasAlloc:
|
||||
when not defined(gcRegions) and not defined(gcDestructors):
|
||||
when not defined(gcRegions) and not usesDestructors:
|
||||
proc initGC() {.gcsafe.}
|
||||
|
||||
proc initStackBottom() {.inline, compilerproc.} =
|
||||
|
|
@ -3620,7 +3622,7 @@ when not defined(JS): #and not defined(nimscript):
|
|||
when declared(nimGC_setStackBottom):
|
||||
nimGC_setStackBottom(locals)
|
||||
|
||||
when not defined(gcDestructors):
|
||||
when not usesDestructors:
|
||||
{.push profiler: off.}
|
||||
var
|
||||
strDesc = TNimType(size: sizeof(string), kind: tyString, flags: {ntfAcyclic})
|
||||
|
|
@ -3792,10 +3794,10 @@ when not defined(JS): #and not defined(nimscript):
|
|||
when hasAlloc: include "system/strmantle"
|
||||
|
||||
when hasThreadSupport:
|
||||
when hostOS != "standalone" and not defined(gcDestructors): include "system/channels"
|
||||
when hostOS != "standalone" and not usesDestructors: include "system/channels"
|
||||
|
||||
when not defined(nimscript) and hasAlloc:
|
||||
when not defined(gcDestructors):
|
||||
when not usesDestructors:
|
||||
include "system/assign"
|
||||
when not defined(nimV2):
|
||||
include "system/repr"
|
||||
|
|
@ -4396,7 +4398,7 @@ proc locals*(): RootObj {.magic: "Plugin", noSideEffect.} =
|
|||
discard
|
||||
|
||||
when hasAlloc and not defined(nimscript) and not defined(JS) and
|
||||
not defined(gcDestructors):
|
||||
not usesDestructors:
|
||||
# XXX how to implement 'deepCopy' is an open problem.
|
||||
proc deepCopy*[T](x: var T, y: T) {.noSideEffect, magic: "DeepCopy".} =
|
||||
## Performs a deep copy of `y` and copies it into `x`.
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ type
|
|||
ntfEnumHole = 2 # enum has holes and thus `$` for them needs the slow
|
||||
# version
|
||||
TNimType {.compilerproc.} = object
|
||||
when defined(gcDestructors):
|
||||
when defined(gcHooks):
|
||||
head*: pointer
|
||||
size*: int
|
||||
kind: TNimKind
|
||||
|
|
@ -103,7 +103,7 @@ type
|
|||
instances: int # count the number of instances
|
||||
sizes: int # sizes of all instances in bytes
|
||||
|
||||
when defined(gcDestructors):
|
||||
when defined(gcHooks):
|
||||
type
|
||||
PNimType* = ptr TNimType
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -507,10 +507,10 @@ else:
|
|||
elif defined(gcRegions):
|
||||
# XXX due to bootstrapping reasons, we cannot use compileOption("gc", "stack") here
|
||||
include "system/gc_regions"
|
||||
elif defined(nimV2) or defined(gcDestructors):
|
||||
elif defined(nimV2) or usesDestructors:
|
||||
var allocator {.rtlThreadVar.}: MemRegion
|
||||
instantiateForRegion(allocator)
|
||||
when defined(gcDestructors):
|
||||
when defined(gcHooks):
|
||||
include "system/gc_hooks"
|
||||
elif defined(gcMarkAndSweep):
|
||||
# XXX use 'compileOption' here
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ when not defined(useNimRtl):
|
|||
cl: var ReprClosure) =
|
||||
# we know that p is not nil here:
|
||||
when declared(CellSet):
|
||||
when defined(boehmGC) or defined(gogc) or defined(nogc) or defined(gcDestructors):
|
||||
when defined(boehmGC) or defined(gogc) or defined(nogc) or usesDestructors:
|
||||
var cell = cast[PCell](p)
|
||||
else:
|
||||
var cell = usrToCell(p)
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ else:
|
|||
proc threadProcWrapStackFrame[TArg](thrd: ptr Thread[TArg]) =
|
||||
when defined(boehmgc):
|
||||
boehmGC_call_with_stack_base(threadProcWrapDispatch[TArg], thrd)
|
||||
elif not defined(nogc) and not defined(gogc) and not defined(gcRegions) and not defined(gcDestructors):
|
||||
elif not defined(nogc) and not defined(gogc) and not defined(gcRegions) and not usesDestructors:
|
||||
var p {.volatile.}: proc(a: ptr Thread[TArg]) {.nimcall, gcsafe.} =
|
||||
threadProcWrapDispatch[TArg]
|
||||
# init the GC for refc/markandsweep
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue