fixes #18612; apply cache and memcmp for methods in arc/orc (#19749)

* try using endsWith

* use memcmp

* add cache

* cleanup

* better

* minor

* fix

* improve test coverage for methods with ARC
This commit is contained in:
flywind 2022-04-27 02:14:39 +08:00 • committed by GitHub
commit 8bfc396a4d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 45 additions and 7 deletions

View file

@ -227,10 +227,34 @@ template tearDownForeignThreadGc* =
## With `--gc:arc` a nop.
discard
proc isObj(obj: PNimTypeV2, subclass: cstring): bool {.compilerRtl, inl.} =
proc strstr(s, sub: cstring): cstring {.header: "<string.h>", importc.}
type ObjCheckCache = array[0..1, PNimTypeV2]
result = strstr(obj.name, subclass) != nil
proc memcmp(str1, str2: cstring, n: csize_t): cint {.importc, header: "<string.h>".}
func endsWith(s, suffix: cstring): bool {.inline.} =
let
sLen = s.len
suffixLen = suffix.len
if suffixLen <= sLen:
result = memcmp(cstring(addr s[sLen - suffixLen]), suffix, csize_t(suffixLen)) == 0
proc isObj(obj: PNimTypeV2, subclass: cstring): bool {.compilerRtl, inl.} =
result = endsWith(obj.name, subclass)
proc isObjSlowPath(obj: PNimTypeV2, subclass: cstring, cache: var ObjCheckCache): bool {.compilerRtl, inline.} =
if endsWith(obj.name, subclass):
cache[1] = obj
result = true
else:
cache[0] = obj
result = false
proc isObjWithCache(obj: PNimTypeV2, subclass: cstring, cache: var ObjCheckCache): bool {.compilerRtl.} =
if cache[0] == obj: result = false
elif cache[1] == obj: result = true
else:
result = isObjSlowPath(obj, subclass, cache)
proc chckObj(obj: PNimTypeV2, subclass: cstring) {.compilerRtl.} =
# checks if obj is of type subclass: