gc:arc: support GC_ref/unref for ref T
This commit is contained in:
parent
eea0cb07cf
commit
25c724d38b
3 changed files with 16 additions and 5 deletions
|
|
@ -28,8 +28,8 @@ hash of ``package & "." & module & "." & name`` to save space.
|
||||||
type
|
type
|
||||||
RefHeader = object
|
RefHeader = object
|
||||||
rc: int # the object header is now a single RC field.
|
rc: int # the object header is now a single RC field.
|
||||||
# we could remove it in non-debug builds but this seems
|
# we could remove it in non-debug builds for the 'owned ref'
|
||||||
# unwise.
|
# design but this seems unwise.
|
||||||
|
|
||||||
template `+!`(p: pointer, s: int): pointer =
|
template `+!`(p: pointer, s: int): pointer =
|
||||||
cast[pointer](cast[int](p) +% s)
|
cast[pointer](cast[int](p) +% s)
|
||||||
|
|
@ -121,6 +121,17 @@ proc nimDecRefIsLast(p: pointer): bool {.compilerRtl, inl.} =
|
||||||
else:
|
else:
|
||||||
dec head(p).rc
|
dec head(p).rc
|
||||||
|
|
||||||
|
proc GC_unref*[T](x: ref T) =
|
||||||
|
## New runtime only supports this operation for 'ref T'.
|
||||||
|
if nimDecRefIsLast(cast[pointer](x)):
|
||||||
|
# XXX this does NOT work for virtual destructors!
|
||||||
|
`=destroy`(x[])
|
||||||
|
nimRawDispose(cast[pointer](x))
|
||||||
|
|
||||||
|
proc GC_ref*[T](x: ref T) =
|
||||||
|
## New runtime only supports this operation for 'ref T'.
|
||||||
|
if x != nil: nimIncRef(cast[pointer](x))
|
||||||
|
|
||||||
proc isObj(obj: PNimType, subclass: cstring): bool {.compilerRtl, inl.} =
|
proc isObj(obj: PNimType, subclass: cstring): bool {.compilerRtl, inl.} =
|
||||||
proc strstr(s, sub: cstring): cstring {.header: "<string.h>", importc.}
|
proc strstr(s, sub: cstring): cstring {.header: "<string.h>", importc.}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3269,7 +3269,7 @@ when not defined(nimscript) and hasAlloc:
|
||||||
## Expands operating GC stack range to `theStackBottom`. Does nothing
|
## Expands operating GC stack range to `theStackBottom`. Does nothing
|
||||||
## if current stack bottom is already lower than `theStackBottom`.
|
## if current stack bottom is already lower than `theStackBottom`.
|
||||||
|
|
||||||
else:
|
elif defined(JS):
|
||||||
template GC_disable* =
|
template GC_disable* =
|
||||||
{.warning: "GC_disable is a no-op in JavaScript".}
|
{.warning: "GC_disable is a no-op in JavaScript".}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -531,12 +531,12 @@ when not defined(noSignalHandler) and not defined(useNimRtl):
|
||||||
when defined(memtracker):
|
when defined(memtracker):
|
||||||
logPendingOps()
|
logPendingOps()
|
||||||
when hasSomeStackTrace:
|
when hasSomeStackTrace:
|
||||||
GC_disable()
|
when not defined(gcDestructors): GC_disable()
|
||||||
var buf = newStringOfCap(2000)
|
var buf = newStringOfCap(2000)
|
||||||
rawWriteStackTrace(buf)
|
rawWriteStackTrace(buf)
|
||||||
processSignal(sign, buf.add) # nice hu? currying a la Nim :-)
|
processSignal(sign, buf.add) # nice hu? currying a la Nim :-)
|
||||||
showErrorMessage(buf)
|
showErrorMessage(buf)
|
||||||
GC_enable()
|
when not defined(gcDestructors): GC_enable()
|
||||||
else:
|
else:
|
||||||
var msg: cstring
|
var msg: cstring
|
||||||
template asgn(y) =
|
template asgn(y) =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue