implements display based subtype checking (6.4x faster without threads; 2.8x faster with threads) (#20781)

* WIP: fast 'of' operator based on the literature
* implement  display based subtype checking

Co-authored-by: Araq <rumpf_a@web.de>
This commit is contained in:
ringabout 2022-11-08 20:08:01 +08:00 • committed by GitHub
commit 7d15fdd375
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 83 additions and 52 deletions

View file

@ -12,6 +12,7 @@
# ------------------------- Name Mangling --------------------------------
import sighashes, modulegraphs
import std/md5
proc isKeyword(w: PIdent): bool =
# Nim and C++ share some keywords
@ -1321,7 +1322,37 @@ proc genHook(m: BModule; t: PType; info: TLineInfo; op: TTypeAttachedOp; result:
internalError(m.config, info, "no attached trace proc found")
result.add rope("NIM_NIL")
proc genTypeInfoV2Impl(m: BModule, t, origType: PType, name: Rope; info: TLineInfo) =
proc getObjDepth(t: PType): int16 =
var x = t
result = -1
while x != nil:
x = skipTypes(x, skipPtrs)
x = x[0]
inc(result)
proc genDisplayElem(d: MD5Digest): uint32 =
result = 0
for i in 0..3:
result += uint32(d[i])
result = result shl 8
proc genDisplay(t: PType, depth: int): Rope =
result = Rope"{"
var x = t
var seqs = newSeq[string](depth+1)
var i = 0
while x != nil:
x = skipTypes(x, skipPtrs)
seqs[i] = $genDisplayElem(MD5Digest(hashType(x)))
x = x[0]
inc i
for i in countdown(depth, 1):
result.add seqs[i] & ", "
result.add seqs[0]
result.add "}"
proc genTypeInfoV2Impl(m: BModule; t, origType: PType, name: Rope; info: TLineInfo) =
var typeName: Rope
if t.kind in {tyObject, tyDistinct}:
if incompleteType(t):
@ -1344,8 +1375,16 @@ proc genTypeInfoV2Impl(m: BModule, t, origType: PType, name: Rope; info: TLineIn
addf(typeEntry, "; $1.traceImpl = (void*)", [name])
genHook(m, t, info, attachedTrace, typeEntry)
addf(typeEntry, "; $1.name = $2;$n; $1.size = sizeof($3); $1.align = NIM_ALIGNOF($3); $1.flags = $4;",
[name, typeName, getTypeDesc(m, t), rope(flags)])
let objDepth = if t.kind == tyObject: getObjDepth(t) else: -1
addf(typeEntry, "; $1.name = $2;$n; $1.size = sizeof($3); $1.align = (NI16) NIM_ALIGNOF($3); $1.depth = $4; $1.flags = $5;",
[name, typeName, getTypeDesc(m, t), rope(objDepth), rope(flags)])
if objDepth >= 0:
let objDisplay = genDisplay(t, objDepth)
let objDisplayStore = getTempName(m)
m.s[cfsVars].addf("static $1 $2[$3] = $4;$n", [getTypeDesc(m, getSysType(m.g.graph, unknownLineInfo, tyUInt32), skVar), objDisplayStore, rope(objDepth+1), objDisplay])
addf(typeEntry, "; $1.display = $2;$n", [name, rope(objDisplayStore)])
m.s[cfsTypeInit3].add typeEntry