From 60330938a9b4cd4f334658671a7b5bc54a13c1dc Mon Sep 17 00:00:00 2001 From: flywind Date: Tue, 26 Apr 2022 15:56:17 +0800 Subject: [PATCH] add cache --- compiler/ccgexprs.nim | 7 +++++-- lib/system/arc.nim | 20 +++++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 1a3e217b2a6c3..307dde65a6d22 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1615,8 +1615,11 @@ proc genNewFinalize(p: BProc, e: PNode) = proc genOfHelper(p: BProc; dest: PType; a: Rope; info: TLineInfo): Rope = if optTinyRtti in p.config.globalOptions: - result = ropecg(p.module, "#isObj($1.m_type, $2)", - [a, genTypeInfo2Name(p.module, dest)]) + 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 NCSTRING $#[2];$n", [cache]) + result = ropecg(p.module, "#isObjWithCache($#.m_type, $#, $#)", [a, ti, cache]) else: # unfortunately 'genTypeInfoV1' sets tfObjHasKids as a side effect, so we # have to call it here first: diff --git a/lib/system/arc.nim b/lib/system/arc.nim index 38415b5311eb0..a1ceeaf5dee38 100644 --- a/lib/system/arc.nim +++ b/lib/system/arc.nim @@ -227,8 +227,11 @@ template tearDownForeignThreadGc* = ## With `--gc:arc` a nop. discard +type ObjCheckCache = array[0..1, cstring] + +proc memcmp(str1, str2: cstring, n: csize_t): cint {.importc, header: "".} + func endsWith*(s, suffix: cstring): bool {.inline.} = - proc memcmp(str1, str2: cstring, n: csize_t): cint {.importc, header: "".} if s != nil and suffix != nil: let sLen = s.len @@ -240,6 +243,21 @@ func endsWith*(s, suffix: cstring): bool {.inline.} = proc isObj(obj: PNimTypeV2, subclass: cstring): bool {.compilerRtl, inl.} = result = endsWith(obj.name, subclass) +proc isObjSlowPath(objName: cstring, subclass: cstring, cache: var ObjCheckCache): bool {.compilerRtl, inline.} = + if endsWith(objName, subclass): + cache[1] = objName + result = true + else: + cache[0] = objName + result = false + +proc isObjWithCache(obj: PNimTypeV2, subclass: cstring, cache: var ObjCheckCache): bool {.compilerRtl.} = + let name = obj.name + if pointer(cache[0]) == pointer(name): result = false + elif pointer(cache[1]) == pointer(name): result = true + else: + result = isObjSlowPath(name, subclass, cache) + proc chckObj(obj: PNimTypeV2, subclass: cstring) {.compilerRtl.} = # checks if obj is of type subclass: if not isObj(obj, subclass): sysFatal(ObjectConversionDefect, "invalid object conversion")