summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2020-09-19 00:27:43 +0200
committerGitHub <noreply@github.com>2020-09-19 00:27:43 +0200
commit9a34009f00749bb29f3c58256648994940533e06 (patch)
tree22f515a99e1a89e9effc9c8f6a0f51e7d0c87052
parent8ae4a774b77d492f997f72d36cc3b8705bc080af (diff)
downloadNim-9a34009f00749bb29f3c58256648994940533e06.tar.gz
ORC and stdlib optimizations (#15362)
-rwxr-xr-xbuild.outbin430264 -> 0 bytes
-rw-r--r--lib/pure/asyncdispatch.nim8
-rw-r--r--lib/pure/parseutils.nim16
-rw-r--r--lib/system/arc.nim9
-rw-r--r--lib/system/orc.nim38
-rw-r--r--lib/system/strs_v2.nim3
6 files changed, 45 insertions, 29 deletions
diff --git a/build.out b/build.out
deleted file mode 100755
index 9edb996b0..000000000
--- a/build.out
+++ /dev/null
Binary files differdiff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim
index 6f38583d8..5cb56f4e4 100644
--- a/lib/pure/asyncdispatch.nim
+++ b/lib/pure/asyncdispatch.nim
@@ -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
 
diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim
index baf238843..4b123117a 100644
--- a/lib/pure/parseutils.nim
+++ b/lib/pure/parseutils.nim
@@ -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
diff --git a/lib/system/arc.nim b/lib/system/arc.nim
index 3cbd02806..973b951d4 100644
--- a/lib/system/arc.nim
+++ b/lib/system/arc.nim
@@ -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)
 
diff --git a/lib/system/orc.nim b/lib/system/orc.nim
index 5deed1d14..ac6211ebb 100644
--- a/lib/system/orc.nim
+++ b/lib/system/orc.nim
@@ -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())
 
diff --git a/lib/system/strs_v2.nim b/lib/system/strs_v2.nim
index 85c0af190..57fdd5ee1 100644
--- a/lib/system/strs_v2.nim
+++ b/lib/system/strs_v2.nim
@@ -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'