Skip to content

Commit

Permalink
move PNode.comment so a side channel, reducing memory usage
Browse files Browse the repository at this point in the history
  • Loading branch information
timotheecour committed Aug 27, 2021
1 parent 5eba372 commit 4133106
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
23 changes: 19 additions & 4 deletions compiler/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# abstract syntax tree + symbol table

import
lineinfos, hashes, options, ropes, idents, int128
lineinfos, hashes, options, ropes, idents, int128, tables
from strutils import toLowerAscii

export int128
Expand Down Expand Up @@ -774,7 +774,6 @@ type
ident*: PIdent
else:
sons*: TNodeSeq
comment*: string

TStrTable* = object # a table[PIdent] of PSym
counter*: int
Expand Down Expand Up @@ -991,6 +990,22 @@ type
TImplication* = enum
impUnknown, impNo, impYes

type Gconfig = object
# we put comments in a side channel to avoid increasing `sizeof(TNode)`, which
# reduces memory usage given that `PNode` is the most numerous type.
comments: Table[int, string] # PNode.id => comment

var gconfig {.threadvar.}: Gconfig

proc comment*(n: PNode): string =
gconfig.comments.getOrDefault(cast[int](n))

proc `comment=`*(n: PNode, a: string) =
if a.len > 0:
gconfig.comments[cast[int](n)] = a
else:
gconfig.comments.del(cast[int](n))

# BUGFIX: a module is overloadable so that a proc can have the
# same name as an imported module. This is necessary because of
# the poor naming choices in the standard library.
Expand Down Expand Up @@ -1644,8 +1659,8 @@ proc copyNode*(src: PNode): PNode =

template transitionNodeKindCommon(k: TNodeKind) =
let obj {.inject.} = n[]
n[] = TNode(kind: k, typ: obj.typ, info: obj.info, flags: obj.flags,
comment: obj.comment)
n[] = TNode(kind: k, typ: obj.typ, info: obj.info, flags: obj.flags)
# n.comment = obj.comment # shouldn't be needed, the address doesnt' change
when defined(useNodeIds):
n.id = obj.id

Expand Down
9 changes: 7 additions & 2 deletions compiler/parser.nim
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ proc rawSkipComment(p: var Parser, node: PNode) =
else:
node.comment.add p.tok.literal
else:
node.comment.add p.tok.literal
node.comment = node.comment & p.tok.literal
else:
parMessage(p, errInternal, "skipComment")
getTok(p)
Expand Down Expand Up @@ -1824,7 +1824,12 @@ proc parseRoutine(p: var Parser, kind: TNodeKind): PNode =
if result.comment.len == 0:
# proc fn*(a: int): int = a ## foo
# => moves comment `foo` to `fn`
swap(result.comment, body[0].comment)
var c1 = result.comment
var c2 = body[0].comment
if c1.len > 0 or c2.len > 0:
swap(c1, c2)
result.comment = c1
body[0].comment = c2
else: discard # xxx either `assert false` or issue a warning (otherwise we'll never know of this edge case)

proc newCommentStmt(p: var Parser): PNode =
Expand Down

0 comments on commit 4133106

Please sign in to comment.