--newruntime: progress
This commit is contained in:
parent
f1a945b05f
commit
e263702688
15 changed files with 111 additions and 109 deletions
|
|
@ -1956,14 +1956,14 @@ proc genDestroy(p: BProc; n: PNode) =
|
||||||
of tyString:
|
of tyString:
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, n[1].skipAddr, a)
|
initLocExpr(p, n[1].skipAddr, a)
|
||||||
linefmt(p, cpsStmts, "if ($1.len && $1.region) {$n" &
|
linefmt(p, cpsStmts, "if ($1.len && $1.p->allocator) {$n" &
|
||||||
" $1.region->dealloc($1.region, $1.p, $1.p->cap + 1 + sizeof(NI) + sizeof(void*)); }$n",
|
" $1.p->allocator->dealloc($1.p->allocator, $1.p, $1.p->cap + 1 + sizeof(NI) + sizeof(void*)); }$n",
|
||||||
[rdLoc(a)])
|
[rdLoc(a)])
|
||||||
of tySequence:
|
of tySequence:
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, n[1].skipAddr, a)
|
initLocExpr(p, n[1].skipAddr, a)
|
||||||
linefmt(p, cpsStmts, "if ($1.len && $1.region) {$n" &
|
linefmt(p, cpsStmts, "if ($1.len && $1.p->allocator) {$n" &
|
||||||
" $1.region->dealloc($1.region, $1.p, ($1.p->cap * sizeof($2)) + sizeof(NI) + sizeof(void*)); }$n",
|
" $1.p->allocator->dealloc($1.p->allocator, $1.p, ($1.p->cap * sizeof($2)) + sizeof(NI) + sizeof(void*)); }$n",
|
||||||
[rdLoc(a), getTypeDesc(p.module, t.lastSon)])
|
[rdLoc(a), getTypeDesc(p.module, t.lastSon)])
|
||||||
else: discard "nothing to do"
|
else: discard "nothing to do"
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ const
|
||||||
|
|
||||||
proc getTraverseProc(p: BProc, v: Psym): Rope =
|
proc getTraverseProc(p: BProc, v: Psym): Rope =
|
||||||
if p.config.selectedGC in {gcMarkAndSweep, gcDestructors, gcV2, gcRefc} and
|
if p.config.selectedGC in {gcMarkAndSweep, gcDestructors, gcV2, gcRefc} and
|
||||||
|
optNimV2 notin p.config.globalOptions and
|
||||||
containsGarbageCollectedRef(v.loc.t):
|
containsGarbageCollectedRef(v.loc.t):
|
||||||
# we register a specialized marked proc here; this has the advantage
|
# we register a specialized marked proc here; this has the advantage
|
||||||
# that it works out of the box for thread local storage then :-)
|
# that it works out of the box for thread local storage then :-)
|
||||||
|
|
|
||||||
|
|
@ -740,7 +740,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
|
||||||
" #TGenericSeq Sup;$n"
|
" #TGenericSeq Sup;$n"
|
||||||
if m.config.selectedGC == gcDestructors:
|
if m.config.selectedGC == gcDestructors:
|
||||||
appcg(m, m.s[cfsTypes],
|
appcg(m, m.s[cfsTypes],
|
||||||
"typedef struct{ NI cap;void* allocator;$1 data[SEQ_DECL_SIZE];}$2_Content;$n" &
|
"typedef struct{ NI cap;#AllocatorObj* allocator;$1 data[SEQ_DECL_SIZE];}$2_Content;$n" &
|
||||||
"struct $2 {$n" &
|
"struct $2 {$n" &
|
||||||
" NI len; $2_Content* p;$n" &
|
" NI len; $2_Content* p;$n" &
|
||||||
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
|
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
|
||||||
|
|
@ -1254,7 +1254,7 @@ proc genObjectInfoV2(m: BModule, t, origType: PType, name: Rope; info: TLineInfo
|
||||||
d = t.destructor.loc.r
|
d = t.destructor.loc.r
|
||||||
else:
|
else:
|
||||||
d = rope("NIM_NIL")
|
d = rope("NIM_NIL")
|
||||||
|
addf(m.s[cfsVars], "TNimType $1;$n", [name])
|
||||||
addf(m.s[cfsTypeInit3], "$1.destructor = $2; $1.size = sizeof($3); $1.name = $4;$n", [
|
addf(m.s[cfsTypeInit3], "$1.destructor = $2; $1.size = sizeof($3); $1.name = $4;$n", [
|
||||||
name, d, getTypeDesc(m, t), genTypeInfo2Name(m, t)])
|
name, d, getTypeDesc(m, t), genTypeInfo2Name(m, t)])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -141,22 +141,19 @@ proc considerAsgnOrSink(c: var TLiftCtx; t: PType; body, x, y: PNode;
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc addDestructorCall(c: var TLiftCtx; t: PType; body, x: PNode): bool =
|
proc addDestructorCall(c: var TLiftCtx; t: PType; body, x: PNode): bool =
|
||||||
let op = t.destructor
|
var op = t.destructor
|
||||||
|
if op == nil and useNoGc(c, t):
|
||||||
|
op = liftBody(c.graph, t, attachedDestructor, c.info)
|
||||||
|
doAssert op != nil
|
||||||
|
|
||||||
if op != nil:
|
if op != nil:
|
||||||
markUsed(c.graph.config, c.info, op, c.graph.usageSym)
|
markUsed(c.graph.config, c.info, op, c.graph.usageSym)
|
||||||
onUse(c.info, op)
|
onUse(c.info, op)
|
||||||
body.add destructorCall(c.graph, op, x)
|
body.add destructorCall(c.graph, op, x)
|
||||||
result = true
|
result = true
|
||||||
elif useNoGc(c, t):
|
elif useNoGc(c, t):
|
||||||
if sameType(t, c.asgnForType) and c.kind == attachedDestructor:
|
internalError(c.graph.config, c.info,
|
||||||
let op = c.fn
|
"type-bound operator could not be resolved")
|
||||||
markUsed(c.graph.config, c.info, op, c.graph.usageSym)
|
|
||||||
onUse(c.info, op)
|
|
||||||
body.add destructorCall(c.graph, op, x)
|
|
||||||
result = true
|
|
||||||
else:
|
|
||||||
internalError(c.graph.config, c.info,
|
|
||||||
"type-bound operator could not be resolved")
|
|
||||||
|
|
||||||
proc considerOverloadedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
|
proc considerOverloadedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
|
||||||
case c.kind
|
case c.kind
|
||||||
|
|
@ -479,19 +476,27 @@ proc liftBody(g: ModuleGraph; typ: PType; kind: TTypeAttachedOp;
|
||||||
if kind != attachedDestructor:
|
if kind != attachedDestructor:
|
||||||
result.typ.addParam src
|
result.typ.addParam src
|
||||||
|
|
||||||
liftBodyAux(a, typ, body, newSymNode(dest).newDeref, newSymNode(src))
|
if optNimV2 in g.config.globalOptions:
|
||||||
# recursion is handled explicitly, do not register the type based operation
|
|
||||||
# before 'liftBodyAux':
|
|
||||||
if g.config.selectedGC == gcDestructors and
|
|
||||||
typ.kind in {tySequence, tyString} and body.len == 0:
|
|
||||||
discard "do not cache it yet"
|
|
||||||
else:
|
|
||||||
case kind
|
case kind
|
||||||
of attachedAsgn: typ.assignment = result
|
of attachedAsgn: typ.assignment = result
|
||||||
of attachedSink: typ.sink = result
|
of attachedSink: typ.sink = result
|
||||||
of attachedDeepCopy: typ.deepCopy = result
|
of attachedDeepCopy: typ.deepCopy = result
|
||||||
of attachedDestructor: typ.destructor = result
|
of attachedDestructor: typ.destructor = result
|
||||||
|
|
||||||
|
liftBodyAux(a, typ, body, newSymNode(dest).newDeref, newSymNode(src))
|
||||||
|
if optNimV2 notin g.config.globalOptions:
|
||||||
|
# recursion is handled explicitly, do not register the type based operation
|
||||||
|
# before 'liftBodyAux':
|
||||||
|
if g.config.selectedGC == gcDestructors and
|
||||||
|
typ.kind in {tySequence, tyString} and body.len == 0:
|
||||||
|
discard "do not cache it yet"
|
||||||
|
else:
|
||||||
|
case kind
|
||||||
|
of attachedAsgn: typ.assignment = result
|
||||||
|
of attachedSink: typ.sink = result
|
||||||
|
of attachedDeepCopy: typ.deepCopy = result
|
||||||
|
of attachedDestructor: typ.destructor = result
|
||||||
|
|
||||||
var n = newNodeI(nkProcDef, info, bodyPos+1)
|
var n = newNodeI(nkProcDef, info, bodyPos+1)
|
||||||
for i in 0 ..< n.len: n.sons[i] = newNodeI(nkEmpty, info)
|
for i in 0 ..< n.len: n.sons[i] = newNodeI(nkEmpty, info)
|
||||||
n.sons[namePos] = newSymNode(result)
|
n.sons[namePos] = newSymNode(result)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ type
|
||||||
ThreadLocal ## the allocator is thread local only.
|
ThreadLocal ## the allocator is thread local only.
|
||||||
ZerosMem ## the allocator always zeros the memory on an allocation
|
ZerosMem ## the allocator always zeros the memory on an allocation
|
||||||
Allocator* = ptr AllocatorObj
|
Allocator* = ptr AllocatorObj
|
||||||
AllocatorObj* {.inheritable.} = object
|
AllocatorObj* {.inheritable, compilerproc.} = object
|
||||||
alloc*: proc (a: Allocator; size: int; alignment: int = 8): pointer {.nimcall, raises: [], tags: [].}
|
alloc*: proc (a: Allocator; size: int; alignment: int = 8): pointer {.nimcall, raises: [], tags: [].}
|
||||||
dealloc*: proc (a: Allocator; p: pointer; size: int) {.nimcall, raises: [], tags: [].}
|
dealloc*: proc (a: Allocator; p: pointer; size: int) {.nimcall, raises: [], tags: [].}
|
||||||
realloc*: proc (a: Allocator; p: pointer; oldSize, newSize: int): pointer {.nimcall, raises: [], tags: [].}
|
realloc*: proc (a: Allocator; p: pointer; oldSize, newSize: int): pointer {.nimcall, raises: [], tags: [].}
|
||||||
|
|
|
||||||
|
|
@ -38,15 +38,6 @@ type
|
||||||
# we could remove it in non-debug builds but this seems
|
# we could remove it in non-debug builds but this seems
|
||||||
# unwise.
|
# unwise.
|
||||||
|
|
||||||
proc isObj(obj: PNimType, subclass: cstring): bool {.compilerproc.} =
|
|
||||||
proc strstr(s, sub: cstring): cstring {.header: "<string.h>", importc.}
|
|
||||||
|
|
||||||
result = strstr(obj.name, subclass) != nil
|
|
||||||
|
|
||||||
proc chckObj(obj: PNimType, subclass: cstring) {.compilerproc.} =
|
|
||||||
# checks if obj is of type subclass:
|
|
||||||
if not isObj(obj, subclass): sysFatal(ObjectConversionError, "invalid object conversion")
|
|
||||||
|
|
||||||
template `+!`(p: pointer, s: int): pointer =
|
template `+!`(p: pointer, s: int): pointer =
|
||||||
cast[pointer](cast[int](p) +% s)
|
cast[pointer](cast[int](p) +% s)
|
||||||
|
|
||||||
|
|
@ -76,3 +67,12 @@ proc nimDestroyAndDispose(p: pointer) {.compilerRtl.} =
|
||||||
let d = cast[ptr PNimType](p)[].destructor
|
let d = cast[ptr PNimType](p)[].destructor
|
||||||
if d != nil: d(p)
|
if d != nil: d(p)
|
||||||
nimRawDispose(p)
|
nimRawDispose(p)
|
||||||
|
|
||||||
|
proc isObj(obj: PNimType, subclass: cstring): bool {.compilerproc.} =
|
||||||
|
proc strstr(s, sub: cstring): cstring {.header: "<string.h>", importc.}
|
||||||
|
|
||||||
|
result = strstr(obj.name, subclass) != nil
|
||||||
|
|
||||||
|
proc chckObj(obj: PNimType, subclass: cstring) {.compilerproc.} =
|
||||||
|
# checks if obj is of type subclass:
|
||||||
|
if not isObj(obj, subclass): sysFatal(ObjectConversionError, "invalid object conversion")
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ proc supportsCopyMem(t: typedesc): bool {.magic: "TypeTrait".}
|
||||||
type
|
type
|
||||||
NimSeqPayload[T] = object
|
NimSeqPayload[T] = object
|
||||||
cap: int
|
cap: int
|
||||||
region: Allocator
|
allocator: Allocator
|
||||||
data: UncheckedArray[T]
|
data: UncheckedArray[T]
|
||||||
|
|
||||||
NimSeqV2*[T] = object
|
NimSeqV2*[T] = object
|
||||||
|
|
@ -52,8 +52,8 @@ when not defined(nimV2):
|
||||||
mixin `=destroy`
|
mixin `=destroy`
|
||||||
when not supportsCopyMem(T):
|
when not supportsCopyMem(T):
|
||||||
for i in 0..<x.len: `=destroy`(p.data[i])
|
for i in 0..<x.len: `=destroy`(p.data[i])
|
||||||
if p.region != nil:
|
if p.allocator != nil:
|
||||||
p.region.dealloc(p.region, p, payloadSize(p.cap))
|
p.allocator.dealloc(p.allocator, p, payloadSize(p.cap))
|
||||||
x.p = nil
|
x.p = nil
|
||||||
x.len = 0
|
x.len = 0
|
||||||
|
|
||||||
|
|
@ -87,15 +87,15 @@ when not defined(nimV2):
|
||||||
type
|
type
|
||||||
PayloadBase = object
|
PayloadBase = object
|
||||||
cap: int
|
cap: int
|
||||||
region: Allocator
|
allocator: Allocator
|
||||||
|
|
||||||
proc newSeqPayload(cap, elemSize: int): pointer {.compilerRtl, raises: [].} =
|
proc newSeqPayload(cap, elemSize: int): pointer {.compilerRtl, raises: [].} =
|
||||||
# we have to use type erasure here as Nim does not support generic
|
# we have to use type erasure here as Nim does not support generic
|
||||||
# compilerProcs. Oh well, this will all be inlined anyway.
|
# compilerProcs. Oh well, this will all be inlined anyway.
|
||||||
if cap > 0:
|
if cap > 0:
|
||||||
let region = getLocalAllocator()
|
let allocator = getLocalAllocator()
|
||||||
var p = cast[ptr PayloadBase](region.alloc(region, cap * elemSize + sizeof(int) + sizeof(Allocator)))
|
var p = cast[ptr PayloadBase](allocator.alloc(allocator, cap * elemSize + sizeof(int) + sizeof(Allocator)))
|
||||||
p.region = region
|
p.allocator = allocator
|
||||||
p.cap = cap
|
p.cap = cap
|
||||||
result = p
|
result = p
|
||||||
else:
|
else:
|
||||||
|
|
@ -112,12 +112,12 @@ proc prepareSeqAdd(len: int; p: pointer; addlen, elemSize: int): pointer {.
|
||||||
# Note: this means we cannot support things that have internal pointers as
|
# Note: this means we cannot support things that have internal pointers as
|
||||||
# they get reallocated here. This needs to be documented clearly.
|
# they get reallocated here. This needs to be documented clearly.
|
||||||
var p = cast[ptr PayloadBase](p)
|
var p = cast[ptr PayloadBase](p)
|
||||||
let region = if p.region == nil: getLocalAllocator() else: p.region
|
let allocator = if p.allocator == nil: getLocalAllocator() else: p.allocator
|
||||||
let cap = max(resize(p.cap), len+addlen)
|
let cap = max(resize(p.cap), len+addlen)
|
||||||
var q = cast[ptr PayloadBase](region.realloc(region, p,
|
var q = cast[ptr PayloadBase](allocator.realloc(allocator, p,
|
||||||
sizeof(int) + sizeof(Allocator) + elemSize * p.cap,
|
sizeof(int) + sizeof(Allocator) + elemSize * p.cap,
|
||||||
sizeof(int) + sizeof(Allocator) + elemSize * cap))
|
sizeof(int) + sizeof(Allocator) + elemSize * cap))
|
||||||
q.region = region
|
q.allocator = allocator
|
||||||
q.cap = cap
|
q.cap = cap
|
||||||
result = q
|
result = q
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import allocators
|
||||||
type
|
type
|
||||||
NimStrPayload {.core.} = object
|
NimStrPayload {.core.} = object
|
||||||
cap: int
|
cap: int
|
||||||
region: Allocator
|
allocator: Allocator
|
||||||
data: UncheckedArray[char]
|
data: UncheckedArray[char]
|
||||||
|
|
||||||
NimStringV2 {.core.} = object
|
NimStringV2 {.core.} = object
|
||||||
|
|
@ -37,7 +37,7 @@ type
|
||||||
|
|
||||||
const nimStrVersion {.core.} = 2
|
const nimStrVersion {.core.} = 2
|
||||||
|
|
||||||
template isLiteral(s): bool = s.p == nil or s.p.region == nil
|
template isLiteral(s): bool = s.p == nil or s.p.allocator == nil
|
||||||
|
|
||||||
template contentSize(cap): int = cap + 1 + sizeof(int) + sizeof(Allocator)
|
template contentSize(cap): int = cap + 1 + sizeof(int) + sizeof(Allocator)
|
||||||
|
|
||||||
|
|
@ -45,7 +45,7 @@ when not defined(nimV2):
|
||||||
|
|
||||||
template frees(s) =
|
template frees(s) =
|
||||||
if not isLiteral(s):
|
if not isLiteral(s):
|
||||||
s.p.region.dealloc(s.p.region, s.p, contentSize(s.p.cap))
|
s.p.allocator.dealloc(s.p.allocator, s.p, contentSize(s.p.cap))
|
||||||
|
|
||||||
proc `=destroy`(s: var string) =
|
proc `=destroy`(s: var string) =
|
||||||
var a = cast[ptr NimStringV2](addr s)
|
var a = cast[ptr NimStringV2](addr s)
|
||||||
|
|
@ -72,12 +72,12 @@ when not defined(nimV2):
|
||||||
# we can shallow copy literals:
|
# we can shallow copy literals:
|
||||||
a.p = b.p
|
a.p = b.p
|
||||||
else:
|
else:
|
||||||
let region = if a.p != nil and a.p.region != nil: a.p.region else: getLocalAllocator()
|
let allocator = if a.p != nil and a.p.allocator != nil: a.p.allocator else: getLocalAllocator()
|
||||||
# we have to allocate the 'cap' here, consider
|
# we have to allocate the 'cap' here, consider
|
||||||
# 'let y = newStringOfCap(); var x = y'
|
# 'let y = newStringOfCap(); var x = y'
|
||||||
# on the other hand... These get turned into moves now.
|
# on the other hand... These get turned into moves now.
|
||||||
a.p = cast[ptr NimStrPayload](region.alloc(region, contentSize(b.len)))
|
a.p = cast[ptr NimStrPayload](allocator.alloc(allocator, contentSize(b.len)))
|
||||||
a.p.region = region
|
a.p.allocator = allocator
|
||||||
a.p.cap = b.len
|
a.p.cap = b.len
|
||||||
copyMem(unsafeAddr a.p.data[0], unsafeAddr b.p.data[0], b.len+1)
|
copyMem(unsafeAddr a.p.data[0], unsafeAddr b.p.data[0], b.len+1)
|
||||||
|
|
||||||
|
|
@ -90,16 +90,16 @@ proc prepareAdd(s: var NimStringV2; addlen: int) {.compilerRtl.} =
|
||||||
if isLiteral(s):
|
if isLiteral(s):
|
||||||
let oldP = s.p
|
let oldP = s.p
|
||||||
# can't mutate a literal, so we need a fresh copy here:
|
# can't mutate a literal, so we need a fresh copy here:
|
||||||
let region = getLocalAllocator()
|
let allocator = getLocalAllocator()
|
||||||
s.p = cast[ptr NimStrPayload](region.alloc(region, contentSize(s.len + addlen)))
|
s.p = cast[ptr NimStrPayload](allocator.alloc(allocator, contentSize(s.len + addlen)))
|
||||||
s.p.region = region
|
s.p.allocator = allocator
|
||||||
s.p.cap = s.len + addlen
|
s.p.cap = s.len + addlen
|
||||||
if s.len > 0:
|
if s.len > 0:
|
||||||
# we are about to append, so there is no need to copy the \0 terminator:
|
# we are about to append, so there is no need to copy the \0 terminator:
|
||||||
copyMem(unsafeAddr s.p.data[0], unsafeAddr oldP.data[0], s.len)
|
copyMem(unsafeAddr s.p.data[0], unsafeAddr oldP.data[0], s.len)
|
||||||
elif s.len + addlen > s.p.cap:
|
elif s.len + addlen > s.p.cap:
|
||||||
let cap = max(s.len + addlen, resize(s.p.cap))
|
let cap = max(s.len + addlen, resize(s.p.cap))
|
||||||
s.p = cast[ptr NimStrPayload](s.p.region.realloc(s.p.region, s.p,
|
s.p = cast[ptr NimStrPayload](s.p.allocator.realloc(s.p.allocator, s.p,
|
||||||
oldSize = contentSize(s.p.cap),
|
oldSize = contentSize(s.p.cap),
|
||||||
newSize = contentSize(cap)))
|
newSize = contentSize(cap)))
|
||||||
s.p.cap = cap
|
s.p.cap = cap
|
||||||
|
|
@ -114,9 +114,9 @@ proc toNimStr(str: cstring, len: int): NimStringV2 {.compilerProc.} =
|
||||||
if len <= 0:
|
if len <= 0:
|
||||||
result = NimStringV2(len: 0, p: nil)
|
result = NimStringV2(len: 0, p: nil)
|
||||||
else:
|
else:
|
||||||
let region = getLocalAllocator()
|
let allocator = getLocalAllocator()
|
||||||
var p = cast[ptr NimStrPayload](region.alloc(region, contentSize(len)))
|
var p = cast[ptr NimStrPayload](allocator.alloc(allocator, contentSize(len)))
|
||||||
p.region = region
|
p.allocator = allocator
|
||||||
p.cap = len
|
p.cap = len
|
||||||
if len > 0:
|
if len > 0:
|
||||||
# we are about to append, so there is no need to copy the \0 terminator:
|
# we are about to append, so there is no need to copy the \0 terminator:
|
||||||
|
|
@ -147,9 +147,9 @@ proc rawNewString(space: int): NimStringV2 {.compilerProc.} =
|
||||||
if space <= 0:
|
if space <= 0:
|
||||||
result = NimStringV2(len: 0, p: nil)
|
result = NimStringV2(len: 0, p: nil)
|
||||||
else:
|
else:
|
||||||
let region = getLocalAllocator()
|
let allocator = getLocalAllocator()
|
||||||
var p = cast[ptr NimStrPayload](region.alloc(region, contentSize(space)))
|
var p = cast[ptr NimStrPayload](allocator.alloc(allocator, contentSize(space)))
|
||||||
p.region = region
|
p.allocator = allocator
|
||||||
p.cap = space
|
p.cap = space
|
||||||
result = NimStringV2(len: 0, p: p)
|
result = NimStringV2(len: 0, p: p)
|
||||||
|
|
||||||
|
|
@ -157,9 +157,9 @@ proc mnewString(len: int): NimStringV2 {.compilerProc.} =
|
||||||
if len <= 0:
|
if len <= 0:
|
||||||
result = NimStringV2(len: 0, p: nil)
|
result = NimStringV2(len: 0, p: nil)
|
||||||
else:
|
else:
|
||||||
let region = getLocalAllocator()
|
let allocator = getLocalAllocator()
|
||||||
var p = cast[ptr NimStrPayload](region.alloc(region, contentSize(len)))
|
var p = cast[ptr NimStrPayload](allocator.alloc(allocator, contentSize(len)))
|
||||||
p.region = region
|
p.allocator = allocator
|
||||||
p.cap = len
|
p.cap = len
|
||||||
result = NimStringV2(len: len, p: p)
|
result = NimStringV2(len: len, p: p)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -679,7 +679,8 @@ when not defined(JS) and not defined(nimscript):
|
||||||
when not defined(gcDestructors):
|
when not defined(gcDestructors):
|
||||||
template space(s: PGenericSeq): int {.dirty.} =
|
template space(s: PGenericSeq): int {.dirty.} =
|
||||||
s.reserved and not (seqShallowFlag or strlitFlag)
|
s.reserved and not (seqShallowFlag or strlitFlag)
|
||||||
include "system/hti"
|
when not defined(nimV2):
|
||||||
|
include "system/hti"
|
||||||
|
|
||||||
type
|
type
|
||||||
byte* = uint8 ## This is an alias for ``uint8``, that is an unsigned
|
byte* = uint8 ## This is an alias for ``uint8``, that is an unsigned
|
||||||
|
|
@ -2925,6 +2926,14 @@ proc compiles*(x: untyped): bool {.magic: "Compiles", noSideEffect, compileTime.
|
||||||
## echo "'+' for integers is available"
|
## echo "'+' for integers is available"
|
||||||
discard
|
discard
|
||||||
|
|
||||||
|
when not defined(js) and not defined(nimscript):
|
||||||
|
include "system/ansi_c"
|
||||||
|
|
||||||
|
when not declared(sysFatal):
|
||||||
|
include "system/fatal"
|
||||||
|
|
||||||
|
when defined(nimV2) and not defined(nimscript):
|
||||||
|
include core/runtime_v2
|
||||||
|
|
||||||
import system/assertions
|
import system/assertions
|
||||||
export assertions
|
export assertions
|
||||||
|
|
@ -2995,7 +3004,7 @@ when not defined(nimscript) and hasAlloc:
|
||||||
gcOptimizeTime, ## optimize for speed
|
gcOptimizeTime, ## optimize for speed
|
||||||
gcOptimizeSpace ## optimize for memory footprint
|
gcOptimizeSpace ## optimize for memory footprint
|
||||||
|
|
||||||
when not defined(JS):
|
when not defined(JS) and not defined(nimV2):
|
||||||
proc GC_disable*() {.rtl, inl, benign.}
|
proc GC_disable*() {.rtl, inl, benign.}
|
||||||
## Disables the GC. If called `n` times, `n` calls to `GC_enable`
|
## Disables the GC. If called `n` times, `n` calls to `GC_enable`
|
||||||
## are needed to reactivate the GC.
|
## are needed to reactivate the GC.
|
||||||
|
|
@ -3242,12 +3251,6 @@ when hostOS == "standalone":
|
||||||
if s == nil or s.len == 0: result = cstring""
|
if s == nil or s.len == 0: result = cstring""
|
||||||
else: result = cstring(addr s.data)
|
else: result = cstring(addr s.data)
|
||||||
|
|
||||||
when not defined(js) and not defined(nimscript):
|
|
||||||
include "system/ansi_c"
|
|
||||||
|
|
||||||
when not declared(sysFatal):
|
|
||||||
include "system/fatal"
|
|
||||||
|
|
||||||
proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", benign.}
|
proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", benign.}
|
||||||
## Get type information for `x`.
|
## Get type information for `x`.
|
||||||
##
|
##
|
||||||
|
|
@ -3364,11 +3367,8 @@ when not defined(JS): #and not defined(nimscript):
|
||||||
{.push stack_trace: off, profiler:off.}
|
{.push stack_trace: off, profiler:off.}
|
||||||
|
|
||||||
when hasAlloc:
|
when hasAlloc:
|
||||||
when not defined(gcRegions):
|
when not defined(gcRegions) and not defined(nimV2):
|
||||||
proc initGC() {.gcsafe.}
|
proc initGC() {.gcsafe.}
|
||||||
when not defined(boehmgc) and not defined(useMalloc) and
|
|
||||||
not defined(gogc) and not defined(gcRegions):
|
|
||||||
proc initAllocator() {.inline.}
|
|
||||||
|
|
||||||
proc initStackBottom() {.inline, compilerproc.} =
|
proc initStackBottom() {.inline, compilerproc.} =
|
||||||
# WARNING: This is very fragile! An array size of 8 does not work on my
|
# WARNING: This is very fragile! An array size of 8 does not work on my
|
||||||
|
|
@ -3547,26 +3547,27 @@ when not defined(JS): #and not defined(nimscript):
|
||||||
else:
|
else:
|
||||||
const GenericSeqSize = (2 * sizeof(int))
|
const GenericSeqSize = (2 * sizeof(int))
|
||||||
|
|
||||||
proc getDiscriminant(aa: pointer, n: ptr TNimNode): int =
|
when not defined(nimV2):
|
||||||
sysAssert(n.kind == nkCase, "getDiscriminant: node != nkCase")
|
proc getDiscriminant(aa: pointer, n: ptr TNimNode): int =
|
||||||
var d: int
|
sysAssert(n.kind == nkCase, "getDiscriminant: node != nkCase")
|
||||||
var a = cast[ByteAddress](aa)
|
var d: int
|
||||||
case n.typ.size
|
var a = cast[ByteAddress](aa)
|
||||||
of 1: d = ze(cast[ptr int8](a +% n.offset)[])
|
case n.typ.size
|
||||||
of 2: d = ze(cast[ptr int16](a +% n.offset)[])
|
of 1: d = ze(cast[ptr int8](a +% n.offset)[])
|
||||||
of 4: d = int(cast[ptr int32](a +% n.offset)[])
|
of 2: d = ze(cast[ptr int16](a +% n.offset)[])
|
||||||
of 8: d = int(cast[ptr int64](a +% n.offset)[])
|
of 4: d = int(cast[ptr int32](a +% n.offset)[])
|
||||||
else: sysAssert(false, "getDiscriminant: invalid n.typ.size")
|
of 8: d = int(cast[ptr int64](a +% n.offset)[])
|
||||||
return d
|
else: sysAssert(false, "getDiscriminant: invalid n.typ.size")
|
||||||
|
return d
|
||||||
|
|
||||||
proc selectBranch(aa: pointer, n: ptr TNimNode): ptr TNimNode =
|
proc selectBranch(aa: pointer, n: ptr TNimNode): ptr TNimNode =
|
||||||
var discr = getDiscriminant(aa, n)
|
var discr = getDiscriminant(aa, n)
|
||||||
if discr <% n.len:
|
if discr <% n.len:
|
||||||
result = n.sons[discr]
|
result = n.sons[discr]
|
||||||
if result == nil: result = n.sons[n.len]
|
if result == nil: result = n.sons[n.len]
|
||||||
# n.sons[n.len] contains the ``else`` part (but may be nil)
|
# n.sons[n.len] contains the ``else`` part (but may be nil)
|
||||||
else:
|
else:
|
||||||
result = n.sons[n.len]
|
result = n.sons[n.len]
|
||||||
|
|
||||||
{.push profiler:off.}
|
{.push profiler:off.}
|
||||||
when hasAlloc: include "system/mmdisp"
|
when hasAlloc: include "system/mmdisp"
|
||||||
|
|
@ -3584,7 +3585,8 @@ when not defined(JS): #and not defined(nimscript):
|
||||||
when not defined(nimscript) and hasAlloc:
|
when not defined(nimscript) and hasAlloc:
|
||||||
when not defined(gcDestructors):
|
when not defined(gcDestructors):
|
||||||
include "system/assign"
|
include "system/assign"
|
||||||
include "system/repr"
|
when not defined(nimV2):
|
||||||
|
include "system/repr"
|
||||||
|
|
||||||
when hostOS != "standalone" and not defined(nimscript):
|
when hostOS != "standalone" and not defined(nimscript):
|
||||||
proc getCurrentException*(): ref Exception {.compilerRtl, inl, benign.} =
|
proc getCurrentException*(): ref Exception {.compilerRtl, inl, benign.} =
|
||||||
|
|
|
||||||
|
|
@ -224,10 +224,6 @@ proc addChunkToMatrix(a: var MemRegion; b: PBigChunk) =
|
||||||
setBit(sl, a.slBitmap[fl])
|
setBit(sl, a.slBitmap[fl])
|
||||||
setBit(fl, a.flBitmap)
|
setBit(fl, a.flBitmap)
|
||||||
|
|
||||||
{.push stack_trace: off.}
|
|
||||||
proc initAllocator() = discard "nothing to do anymore"
|
|
||||||
{.pop.}
|
|
||||||
|
|
||||||
proc incCurrMem(a: var MemRegion, bytes: int) {.inline.} =
|
proc incCurrMem(a: var MemRegion, bytes: int) {.inline.} =
|
||||||
inc(a.currMem, bytes)
|
inc(a.currMem, bytes)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,4 +139,11 @@ proc c_free(p: pointer) {.
|
||||||
proc c_realloc(p: pointer, newsize: csize): pointer {.
|
proc c_realloc(p: pointer, newsize: csize): pointer {.
|
||||||
importc: "realloc", header: "<stdlib.h>".}
|
importc: "realloc", header: "<stdlib.h>".}
|
||||||
|
|
||||||
|
proc c_fwrite(buf: pointer, size, n: csize, f: CFilePtr): cint {.
|
||||||
|
importc: "fwrite", header: "<stdio.h>".}
|
||||||
|
|
||||||
|
proc rawWrite(f: CFilePtr, s: cstring) {.compilerproc, nonreloadable, inline.} =
|
||||||
|
# we cannot throw an exception here!
|
||||||
|
discard c_fwrite(s, 1, s.len, f)
|
||||||
|
|
||||||
{.pop}
|
{.pop}
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,6 @@ var
|
||||||
## instead of `stdmsg.write` when printing stacktrace.
|
## instead of `stdmsg.write` when printing stacktrace.
|
||||||
## Unstable API.
|
## Unstable API.
|
||||||
|
|
||||||
proc c_fwrite(buf: pointer, size, n: csize, f: CFilePtr): cint {.
|
|
||||||
importc: "fwrite", header: "<stdio.h>".}
|
|
||||||
|
|
||||||
proc rawWrite(f: CFilePtr, s: cstring) {.compilerproc, nonreloadable, hcrInline.} =
|
|
||||||
# we cannot throw an exception here!
|
|
||||||
discard c_fwrite(s, 1, s.len, f)
|
|
||||||
|
|
||||||
when not defined(windows) or not defined(guiapp):
|
when not defined(windows) or not defined(guiapp):
|
||||||
proc writeToStdErr(msg: cstring) = rawWrite(cstderr, msg)
|
proc writeToStdErr(msg: cstring) = rawWrite(cstderr, msg)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,6 @@ when declared(threadType):
|
||||||
## This function is available only when ``--threads:on`` and ``--tlsEmulation:off``
|
## This function is available only when ``--threads:on`` and ``--tlsEmulation:off``
|
||||||
## switches are used
|
## switches are used
|
||||||
if threadType == ThreadType.None:
|
if threadType == ThreadType.None:
|
||||||
initAllocator()
|
|
||||||
var stackTop {.volatile.}: pointer
|
var stackTop {.volatile.}: pointer
|
||||||
nimGC_setStackBottom(addr(stackTop))
|
nimGC_setStackBottom(addr(stackTop))
|
||||||
initGC()
|
initGC()
|
||||||
|
|
|
||||||
|
|
@ -497,7 +497,8 @@ else:
|
||||||
# XXX due to bootstrapping reasons, we cannot use compileOption("gc", "stack") here
|
# XXX due to bootstrapping reasons, we cannot use compileOption("gc", "stack") here
|
||||||
include "system/gc_regions"
|
include "system/gc_regions"
|
||||||
elif defined(nimV2):
|
elif defined(nimV2):
|
||||||
include "core/runtime_v2"
|
var allocator {.rtlThreadVar.}: MemRegion
|
||||||
|
instantiateForRegion(allocator)
|
||||||
elif defined(gcMarkAndSweep) or defined(gcDestructors):
|
elif defined(gcMarkAndSweep) or defined(gcDestructors):
|
||||||
# XXX use 'compileOption' here
|
# XXX use 'compileOption' here
|
||||||
include "system/gc_ms"
|
include "system/gc_ms"
|
||||||
|
|
|
||||||
|
|
@ -456,8 +456,6 @@ template threadProcWrapperBody(closure: untyped): untyped =
|
||||||
var thrd = cast[ptr Thread[TArg]](closure)
|
var thrd = cast[ptr Thread[TArg]](closure)
|
||||||
var core = thrd.core
|
var core = thrd.core
|
||||||
when declared(globalsSlot): threadVarSetValue(globalsSlot, thrd.core)
|
when declared(globalsSlot): threadVarSetValue(globalsSlot, thrd.core)
|
||||||
when declared(initAllocator):
|
|
||||||
initAllocator()
|
|
||||||
threadProcWrapStackFrame(thrd)
|
threadProcWrapStackFrame(thrd)
|
||||||
# Since an unhandled exception terminates the whole process (!), there is
|
# Since an unhandled exception terminates the whole process (!), there is
|
||||||
# no need for a ``try finally`` here, nor would it be correct: The current
|
# no need for a ``try finally`` here, nor would it be correct: The current
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue