don't generate memset calls for C++ objects

This commit is contained in:
Araq 2015-03-17 21:36:40 +01:00
commit 1fc590b6ea
5 changed files with 448 additions and 440 deletions

View file

@ -956,6 +956,9 @@ proc genAsmStmt(p: BProc, t: PNode) =
assert(t.kind == nkAsmStmt) assert(t.kind == nkAsmStmt)
genLineDir(p, t) genLineDir(p, t)
var s = genAsmOrEmitStmt(p, t, isAsmStmt=true) var s = genAsmOrEmitStmt(p, t, isAsmStmt=true)
# see bug #2362, "top level asm statements" seem to be a mis-feature
# but even if we don't do this, the example in #2362 cannot possibly
# work:
if p.prc == nil: if p.prc == nil:
# top level asm statement? # top level asm statement?
appf(p.module.s[cfsProcHeaders], CC[cCompiler].asmStmtFrmt, [s]) appf(p.module.s[cfsProcHeaders], CC[cCompiler].asmStmtFrmt, [s])

View file

@ -261,7 +261,9 @@ proc isComplexValueType(t: PType): bool {.inline.} =
proc resetLoc(p: BProc, loc: var TLoc) = proc resetLoc(p: BProc, loc: var TLoc) =
let containsGcRef = containsGarbageCollectedRef(loc.t) let containsGcRef = containsGarbageCollectedRef(loc.t)
if not isComplexValueType(skipTypes(loc.t, abstractVarRange)): let typ = skipTypes(loc.t, abstractVarRange)
if isImportedCppType(typ): return
if not isComplexValueType(typ):
if containsGcRef: if containsGcRef:
var nilLoc: TLoc var nilLoc: TLoc
initLoc(nilLoc, locTemp, loc.t, OnStack) initLoc(nilLoc, locTemp, loc.t, OnStack)
@ -287,15 +289,17 @@ proc resetLoc(p: BProc, loc: var TLoc) =
genObjectInit(p, cpsStmts, loc.t, loc, true) genObjectInit(p, cpsStmts, loc.t, loc, true)
proc constructLoc(p: BProc, loc: TLoc, isTemp = false) = proc constructLoc(p: BProc, loc: TLoc, isTemp = false) =
if not isComplexValueType(skipTypes(loc.t, abstractRange)): let typ = skipTypes(loc.t, abstractRange)
if not isComplexValueType(typ):
linefmt(p, cpsStmts, "$1 = 0;$n", rdLoc(loc)) linefmt(p, cpsStmts, "$1 = 0;$n", rdLoc(loc))
else: else:
if not isTemp or containsGarbageCollectedRef(loc.t): if not isTemp or containsGarbageCollectedRef(loc.t):
# don't use memset for temporary values for performance if we can # don't use memset for temporary values for performance if we can
# avoid it: # avoid it:
useStringh(p.module) if not isImportedCppType(typ):
linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n", useStringh(p.module)
addrLoc(loc), rdLoc(loc)) linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n",
addrLoc(loc), rdLoc(loc))
genObjectInit(p, cpsStmts, loc.t, loc, true) genObjectInit(p, cpsStmts, loc.t, loc, true)
proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) = proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) =

View file

@ -87,14 +87,14 @@ proc searchInScopes*(c: PContext, s: PIdent): PSym =
if result != nil: return if result != nil: return
result = nil result = nil
proc debugScopes*(c: PContext) {.deprecated.} = proc debugScopes*(c: PContext; limit=0) {.deprecated.} =
var i = 0 var i = 0
for scope in walkScopes(c.currentScope): for scope in walkScopes(c.currentScope):
echo "scope ", i echo "scope ", i
for h in 0 .. high(scope.symbols.data): for h in 0 .. high(scope.symbols.data):
if scope.symbols.data[h] != nil: if scope.symbols.data[h] != nil:
echo scope.symbols.data[h].name.s echo scope.symbols.data[h].name.s
if i == 2: break if i == limit: break
inc i inc i
proc searchInScopes*(c: PContext, s: PIdent, filter: TSymKinds): PSym = proc searchInScopes*(c: PContext, s: PIdent, filter: TSymKinds): PSym =

View file

@ -5,6 +5,7 @@ version 0.10.4
- make 'nil' work for 'add' and 'len' - make 'nil' work for 'add' and 'len'
- disallow negative indexing - disallow negative indexing
- improve the parser; deal with echo $foo gotcha - improve the parser; deal with echo $foo gotcha
- add "all threads are blocked" detection to 'spawn'
version 1.0 version 1.0