ORC and stdlib optimizations (#15362)

This commit is contained in:
Andreas Rumpf
2020-09-19 00:27:43 +02:00
committed by GitHub
parent 8ae4a774b7
commit 9a34009f00
6 changed files with 45 additions and 29 deletions

BIN
build.out

Binary file not shown.

View File

@@ -1247,9 +1247,13 @@ else:
# Descriptor is still present in the queue.
case event
of Event.Read:
fdData.readList = newList & fdData.readList
let oldReadList = move fdData.readList
fdData.readList = move newList
fdData.readList.add oldReadList
of Event.Write:
fdData.writeList = newList & fdData.writeList
let oldWriteList = move fdData.writeList
fdData.writeList = move newList
fdData.writeList.add oldWriteList
else:
assert false, "Cannot process callbacks for " & $event

View File

@@ -310,6 +310,10 @@ proc skipWhile*(s: string, toSkip: set[char], start = 0): int {.inline.} =
result = 0
while start+result < s.len and s[result+start] in toSkip: inc(result)
proc fastSubstr(s: string; token: var string; start, length: int) =
token.setLen length
for i in 0 ..< length: token[i] = s[i+start]
proc parseUntil*(s: string, token: var string, until: set[char],
start = 0): int {.inline.} =
## Parses a token and stores it in ``token``. Returns
@@ -326,7 +330,8 @@ proc parseUntil*(s: string, token: var string, until: set[char],
var i = start
while i < s.len and s[i] notin until: inc(i)
result = i-start
token = substr(s, start, i-1)
fastSubstr(s, token, start, result)
#token = substr(s, start, i-1)
proc parseUntil*(s: string, token: var string, until: char,
start = 0): int {.inline.} =
@@ -344,7 +349,8 @@ proc parseUntil*(s: string, token: var string, until: char,
var i = start
while i < s.len and s[i] != until: inc(i)
result = i-start
token = substr(s, start, i-1)
fastSubstr(s, token, start, result)
#token = substr(s, start, i-1)
proc parseUntil*(s: string, token: var string, until: string,
start = 0): int {.inline.} =
@@ -370,7 +376,8 @@ proc parseUntil*(s: string, token: var string, until: string,
if u >= until.len: break
inc(i)
result = i-start
token = substr(s, start, i-1)
fastSubstr(s, token, start, result)
#token = substr(s, start, i-1)
proc parseWhile*(s: string, token: var string, validChars: set[char],
start = 0): int {.inline.} =
@@ -386,7 +393,8 @@ proc parseWhile*(s: string, token: var string, validChars: set[char],
var i = start
while i < s.len and s[i] in validChars: inc(i)
result = i-start
token = substr(s, start, i-1)
fastSubstr(s, token, start, result)
#token = substr(s, start, i-1)
proc captureBetween*(s: string, first: char, second = '\0', start = 0): string =
## Finds the first occurrence of ``first``, then returns everything from there

View File

@@ -68,7 +68,7 @@ const
when defined(nimArcDebug):
include cellsets
const traceId = 7739 # 1037
const traceId = 20 # 1037
var gRefId: int
var freedCells: CellSet
@@ -90,6 +90,9 @@ proc nimNewObj(size: int): pointer {.compilerRtl.} =
when defined(nimArcDebug) or defined(nimArcIds):
head(result).refId = gRefId
atomicInc gRefId
if head(result).refId == traceId:
writeStackTrace()
cfprintf(cstderr, "[nimNewObj] %p %ld\n", result, head(result).rc shr rcShift)
when traceCollector:
cprintf("[Allocated] %p result: %p\n", result -! sizeof(RefHeader), result)
@@ -112,6 +115,10 @@ proc nimNewObjUninit(size: int): pointer {.compilerRtl.} =
when defined(nimArcDebug):
head(result).refId = gRefId
atomicInc gRefId
if head(result).refId == traceId:
writeStackTrace()
cfprintf(cstderr, "[nimNewObjUninit] %p %ld\n", result, head(result).rc shr rcShift)
when traceCollector:
cprintf("[Allocated] %p result: %p\n", result -! sizeof(RefHeader), result)

View File

@@ -26,6 +26,8 @@ const
jumpStackFlag = 0b1000
colorMask = 0b011
logOrc = defined(nimArcIds)
type
TraceProc = proc (p, env: pointer) {.nimcall, benign.}
DisposeProc = proc (p: pointer) {.nimcall, benign.}
@@ -59,19 +61,17 @@ proc trace(s: Cell; desc: PNimTypeV2; j: var GcEnv) {.inline.} =
var p = s +! sizeof(RefHeader)
cast[TraceProc](desc.traceImpl)(p, addr(j))
when true:
template debug(str: cstring; s: Cell) = discard
else:
proc debug(str: cstring; s: Cell) =
let p = s +! sizeof(RefHeader)
cprintf("[%s] name %s RC %ld\n", str, p, s.rc shr rcShift)
when logOrc:
proc writeCell(msg: cstring; s: Cell; desc: PNimTypeV2) =
cfprintf(cstderr, "%s %s %ld root index: %ld; RC: %ld; color: %ld\n",
msg, desc.name, s.refId, s.rootIdx, s.rc shr rcShift, s.color)
proc free(s: Cell; desc: PNimTypeV2) {.inline.} =
when traceCollector:
cprintf("[From ] %p rc %ld color %ld\n", s, s.rc shr rcShift, s.color)
let p = s +! sizeof(RefHeader)
debug("free", s)
when logOrc: writeCell("free", s, desc)
if desc.disposeImpl != nil:
cast[DisposeProc](desc.disposeImpl)(p)
@@ -90,13 +90,13 @@ proc free(s: Cell; desc: PNimTypeV2) {.inline.} =
nimRawDispose(p)
proc nimTraceRef(q: pointer; desc: PNimTypeV2; env: pointer) {.compilerRtl.} =
proc nimTraceRef(q: pointer; desc: PNimTypeV2; env: pointer) {.compilerRtl, inline.} =
let p = cast[ptr pointer](q)
if p[] != nil:
var j = cast[ptr GcEnv](env)
j.traceStack.add(head p[], desc)
proc nimTraceRefDyn(q: pointer; env: pointer) {.compilerRtl.} =
proc nimTraceRefDyn(q: pointer; env: pointer) {.compilerRtl, inline.} =
let p = cast[ptr pointer](q)
if p[] != nil:
var j = cast[ptr GcEnv](env)
@@ -121,11 +121,6 @@ proc unregisterCycle(s: Cell) =
roots.d[idx][0].rootIdx = idx
dec roots.len
when false:
proc writeCell(msg: cstring; s: Cell; desc: PNimTypeV2) =
cfprintf(cstderr, "%s %s %ld root index: %ld; RC: %ld; color: %ld\n",
msg, desc.name, s.refId, s.rootIdx, s.rc shr rcShift, s.color)
proc scanBlack(s: Cell; desc: PNimTypeV2; j: var GcEnv) =
#[
proc scanBlack(s: Cell) =
@@ -135,19 +130,17 @@ proc scanBlack(s: Cell; desc: PNimTypeV2; j: var GcEnv) =
if t.color != colBlack:
scanBlack(t)
]#
debug "scanBlack", s
s.setColor colBlack
let until = j.traceStack.len
trace(s, desc, j)
#writeCell("root still alive", s, desc)
when logOrc: writeCell("root still alive", s, desc)
while j.traceStack.len > until:
let (t, desc) = j.traceStack.pop()
inc t.rc, rcIncrement
debug "incRef", t
if t.color != colBlack:
t.setColor colBlack
trace(t, desc, j)
#writeCell("child still alive", t, desc)
when logOrc: writeCell("child still alive", t, desc)
proc markGray(s: Cell; desc: PNimTypeV2; j: var GcEnv) =
#[
@@ -278,8 +271,11 @@ proc collectCyclesBacon(j: var GcEnv) =
s.buffered = false
collectWhite(s)
]#
when logOrc:
for i in 0 ..< roots.len:
writeCell("root", roots.d[i][0], roots.d[i][1])
for i in 0 ..< roots.len:
#writeCell("root", roots.d[i][0], roots.d[i][1])
markGray(roots.d[i][0], roots.d[i][1], j)
for i in 0 ..< roots.len:
scan(roots.d[i][0], roots.d[i][1], j)
@@ -305,7 +301,7 @@ var
proc collectCycles() =
## Collect cycles.
when false:
when logOrc:
cfprintf(cstderr, "[collectCycles] begin\n")
var j: GcEnv
@@ -335,7 +331,7 @@ proc collectCycles() =
#cfprintf(cstderr, "[collectCycles] freed %ld, touched %ld new threshold %ld\n", j.freed, j.touched, rootsThreshold)
elif rootsThreshold < high(int) div 4:
rootsThreshold = rootsThreshold * 3 div 2
when false:
when logOrc:
cfprintf(cstderr, "[collectCycles] end; freed %ld new threshold %ld touched: %ld mem: %ld\n", j.freed, rootsThreshold, j.touched,
getOccupiedMem())

View File

@@ -52,7 +52,8 @@ proc prepareAdd(s: var NimStringV2; addlen: int) {.compilerRtl.} =
s.p = cast[ptr NimStrPayload](reallocShared0(s.p, contentSize(oldCap), contentSize(newCap)))
s.p.cap = newCap
proc nimAddCharV1(s: var NimStringV2; c: char) {.compilerRtl.} =
proc nimAddCharV1(s: var NimStringV2; c: char) {.compilerRtl, inline.} =
#if (s.p == nil) or (s.len+1 > s.p.cap and not strlitFlag):
prepareAdd(s, 1)
s.p.data[s.len] = c
s.p.data[s.len+1] = '\0'