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:
parent
ca3b6cba5d
commit
7d15fdd375
5 changed files with 83 additions and 52 deletions
|
|
@ -1704,11 +1704,8 @@ proc genNewFinalize(p: BProc, e: PNode) =
|
|||
|
||||
proc genOfHelper(p: BProc; dest: PType; a: Rope; info: TLineInfo; result: var Rope) =
|
||||
if optTinyRtti in p.config.globalOptions:
|
||||
let ti = genTypeInfo2Name(p.module, dest)
|
||||
inc p.module.labels
|
||||
let cache = "Nim_OfCheck_CACHE" & p.module.labels.rope
|
||||
p.module.s[cfsVars].addf("static TNimTypeV2* $#[2];$n", [cache])
|
||||
appcg(p.module, result, "#isObjWithCache($#.m_type, $#, $#)", [a, ti, cache])
|
||||
let token = $genDisplayElem(MD5Digest(hashType(dest)))
|
||||
appcg(p.module, result, "#isObjDisplayCheck($#.m_type, $#, $#)", [a, getObjDepth(dest), token])
|
||||
else:
|
||||
# unfortunately 'genTypeInfoV1' sets tfObjHasKids as a side effect, so we
|
||||
# have to call it here first:
|
||||
|
|
@ -1722,10 +1719,6 @@ proc genOfHelper(p: BProc; dest: PType; a: Rope; info: TLineInfo; result: var Ro
|
|||
let cache = "Nim_OfCheck_CACHE" & p.module.labels.rope
|
||||
p.module.s[cfsVars].addf("static TNimType* $#[2];$n", [cache])
|
||||
appcg(p.module, result, "#isObjWithCache($#.m_type, $#, $#)", [a, ti, cache])
|
||||
when false:
|
||||
# former version:
|
||||
appcg(p.module, result, "#isObj($1.m_type, $2)",
|
||||
[a, genTypeInfoV1(p.module, dest, info)])
|
||||
|
||||
proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
|
||||
var a: TLoc
|
||||
|
|
@ -2775,16 +2768,23 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
|
|||
var nilCheck = ""
|
||||
var r = newRopeAppender()
|
||||
rdMType(p, a, nilCheck, r)
|
||||
let checkFor = if optTinyRtti in p.config.globalOptions:
|
||||
genTypeInfo2Name(p.module, dest)
|
||||
else:
|
||||
genTypeInfoV1(p.module, dest, n.info)
|
||||
if nilCheck != "":
|
||||
linefmt(p, cpsStmts, "if ($1 && !#isObj($2, $3)){ #raiseObjectConversionError(); ",
|
||||
[nilCheck, r, checkFor])
|
||||
if optTinyRtti in p.config.globalOptions:
|
||||
let checkFor = $getObjDepth(dest)
|
||||
let token = $genDisplayElem(MD5Digest(hashType(dest)))
|
||||
if nilCheck != "":
|
||||
linefmt(p, cpsStmts, "if ($1 && !#isObjDisplayCheck($2, $3, $4)){ #raiseObjectConversionError(); ",
|
||||
[nilCheck, r, checkFor, token])
|
||||
else:
|
||||
linefmt(p, cpsStmts, "if (!#isObjDisplayCheck($1, $2, $3)){ #raiseObjectConversionError(); ",
|
||||
[r, checkFor, token])
|
||||
else:
|
||||
linefmt(p, cpsStmts, "if (!#isObj($1, $2)){ #raiseObjectConversionError(); ",
|
||||
[r, checkFor])
|
||||
let checkFor = genTypeInfoV1(p.module, dest, n.info)
|
||||
if nilCheck != "":
|
||||
linefmt(p, cpsStmts, "if ($1 && !#isObj($2, $3)){ #raiseObjectConversionError(); ",
|
||||
[nilCheck, r, checkFor])
|
||||
else:
|
||||
linefmt(p, cpsStmts, "if (!#isObj($1, $2)){ #raiseObjectConversionError(); ",
|
||||
[r, checkFor])
|
||||
raiseInstr(p, p.s(cpsStmts))
|
||||
linefmt p, cpsStmts, "}$n", []
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue