Fixes 8535 (#8591)
* Goodbye postInitProc * Give preInitProc its own scope Avoid any conflict between the variables introduced by preInitProc and initProc since both are codegen'd in the same function body. * Fix codegen for global var init in emulated TLS Fixes #8535 * Add test for #8535 * Keep a bogus stack frame around * Remove more dead code
This commit is contained in:
parent
af037546b0
commit
ac0f5c83ca
4 changed files with 45 additions and 16 deletions
|
|
@ -256,7 +256,15 @@ proc genSingleVar(p: BProc, a: PNode) =
|
||||||
# That's why we are doing the construction inside the preInitProc.
|
# That's why we are doing the construction inside the preInitProc.
|
||||||
# genObjectInit relies on the C runtime's guarantees that
|
# genObjectInit relies on the C runtime's guarantees that
|
||||||
# global variables will be initialized to zero.
|
# global variables will be initialized to zero.
|
||||||
genObjectInit(p.module.preInitProc, cpsInit, v.typ, v.loc, true)
|
var loc = v.loc
|
||||||
|
|
||||||
|
# When the native TLS is unavailable, a global thread-local variable needs
|
||||||
|
# one more layer of indirection in order to access the TLS block.
|
||||||
|
# Only do this for complex types that may need a call to `objectInit`
|
||||||
|
if sfThread in v.flags and emulatedThreadVars(p.config) and
|
||||||
|
isComplexValueType(v.typ):
|
||||||
|
initLocExprSingleUse(p.module.preInitProc, vn, loc)
|
||||||
|
genObjectInit(p.module.preInitProc, cpsInit, v.typ, loc, true)
|
||||||
# Alternative construction using default constructor (which may zeromem):
|
# Alternative construction using default constructor (which may zeromem):
|
||||||
# if sfImportc notin v.flags: constructLoc(p.module.preInitProc, v.loc)
|
# if sfImportc notin v.flags: constructLoc(p.module.preInitProc, v.loc)
|
||||||
if sfExportc in v.flags and p.module.g.generatedHeader != nil:
|
if sfExportc in v.flags and p.module.g.generatedHeader != nil:
|
||||||
|
|
|
||||||
|
|
@ -1136,12 +1136,29 @@ proc genInitCode(m: BModule) =
|
||||||
appcg(m, m.s[cfsTypeInit1], "static #TNimType $1[$2];$n",
|
appcg(m, m.s[cfsTypeInit1], "static #TNimType $1[$2];$n",
|
||||||
[m.nimTypesName, rope(m.nimTypes)])
|
[m.nimTypesName, rope(m.nimTypes)])
|
||||||
|
|
||||||
|
# Give this small function its own scope
|
||||||
|
addf(prc, "{$N", [])
|
||||||
|
block:
|
||||||
|
# Keep a bogus frame in case the code needs one
|
||||||
|
add(prc, ~"\tTFrame FR_; FR_.len = 0;$N")
|
||||||
|
|
||||||
|
add(prc, genSectionStart(cpsLocals, m.config))
|
||||||
|
add(prc, m.preInitProc.s(cpsLocals))
|
||||||
|
add(prc, genSectionEnd(cpsLocals, m.config))
|
||||||
|
|
||||||
|
add(prc, genSectionStart(cpsInit, m.config))
|
||||||
|
add(prc, m.preInitProc.s(cpsInit))
|
||||||
|
add(prc, genSectionEnd(cpsInit, m.config))
|
||||||
|
|
||||||
|
add(prc, genSectionStart(cpsStmts, m.config))
|
||||||
|
add(prc, m.preInitProc.s(cpsStmts))
|
||||||
|
add(prc, genSectionEnd(cpsStmts, m.config))
|
||||||
|
addf(prc, "}$N", [])
|
||||||
|
|
||||||
add(prc, initGCFrame(m.initProc))
|
add(prc, initGCFrame(m.initProc))
|
||||||
|
|
||||||
add(prc, genSectionStart(cpsLocals, m.config))
|
add(prc, genSectionStart(cpsLocals, m.config))
|
||||||
add(prc, m.preInitProc.s(cpsLocals))
|
|
||||||
add(prc, m.initProc.s(cpsLocals))
|
add(prc, m.initProc.s(cpsLocals))
|
||||||
add(prc, m.postInitProc.s(cpsLocals))
|
|
||||||
add(prc, genSectionEnd(cpsLocals, m.config))
|
add(prc, genSectionEnd(cpsLocals, m.config))
|
||||||
|
|
||||||
if optStackTrace in m.initProc.options and frameDeclared notin m.flags:
|
if optStackTrace in m.initProc.options and frameDeclared notin m.flags:
|
||||||
|
|
@ -1155,16 +1172,13 @@ proc genInitCode(m: BModule) =
|
||||||
add(prc, ~"\tTFrame FR_; FR_.len = 0;$N")
|
add(prc, ~"\tTFrame FR_; FR_.len = 0;$N")
|
||||||
|
|
||||||
add(prc, genSectionStart(cpsInit, m.config))
|
add(prc, genSectionStart(cpsInit, m.config))
|
||||||
add(prc, m.preInitProc.s(cpsInit))
|
|
||||||
add(prc, m.initProc.s(cpsInit))
|
add(prc, m.initProc.s(cpsInit))
|
||||||
add(prc, m.postInitProc.s(cpsInit))
|
|
||||||
add(prc, genSectionEnd(cpsInit, m.config))
|
add(prc, genSectionEnd(cpsInit, m.config))
|
||||||
|
|
||||||
add(prc, genSectionStart(cpsStmts, m.config))
|
add(prc, genSectionStart(cpsStmts, m.config))
|
||||||
add(prc, m.preInitProc.s(cpsStmts))
|
|
||||||
add(prc, m.initProc.s(cpsStmts))
|
add(prc, m.initProc.s(cpsStmts))
|
||||||
add(prc, m.postInitProc.s(cpsStmts))
|
|
||||||
add(prc, genSectionEnd(cpsStmts, m.config))
|
add(prc, genSectionEnd(cpsStmts, m.config))
|
||||||
|
|
||||||
if optStackTrace in m.initProc.options and preventStackTrace notin m.flags:
|
if optStackTrace in m.initProc.options and preventStackTrace notin m.flags:
|
||||||
add(prc, deinitFrame(m.initProc))
|
add(prc, deinitFrame(m.initProc))
|
||||||
add(prc, deinitGCFrame(m.initProc))
|
add(prc, deinitGCFrame(m.initProc))
|
||||||
|
|
@ -1210,11 +1224,6 @@ proc newPreInitProc(m: BModule): BProc =
|
||||||
# little hack so that unique temporaries are generated:
|
# little hack so that unique temporaries are generated:
|
||||||
result.labels = 100_000
|
result.labels = 100_000
|
||||||
|
|
||||||
proc newPostInitProc(m: BModule): BProc =
|
|
||||||
result = newProc(nil, m)
|
|
||||||
# little hack so that unique temporaries are generated:
|
|
||||||
result.labels = 200_000
|
|
||||||
|
|
||||||
proc initProcOptions(m: BModule): TOptions =
|
proc initProcOptions(m: BModule): TOptions =
|
||||||
let opts = m.config.options
|
let opts = m.config.options
|
||||||
if sfSystemModule in m.module.flags: opts-{optStackTrace} else: opts
|
if sfSystemModule in m.module.flags: opts-{optStackTrace} else: opts
|
||||||
|
|
@ -1236,7 +1245,6 @@ proc rawNewModule(g: BModuleList; module: PSym, filename: string): BModule =
|
||||||
result.initProc = newProc(nil, result)
|
result.initProc = newProc(nil, result)
|
||||||
result.initProc.options = initProcOptions(result)
|
result.initProc.options = initProcOptions(result)
|
||||||
result.preInitProc = newPreInitProc(result)
|
result.preInitProc = newPreInitProc(result)
|
||||||
result.postInitProc = newPostInitProc(result)
|
|
||||||
initNodeTable(result.dataCache)
|
initNodeTable(result.dataCache)
|
||||||
result.typeStack = @[]
|
result.typeStack = @[]
|
||||||
result.forwardedProcs = @[]
|
result.forwardedProcs = @[]
|
||||||
|
|
@ -1247,7 +1255,6 @@ proc rawNewModule(g: BModuleList; module: PSym, filename: string): BModule =
|
||||||
if sfSystemModule in module.flags:
|
if sfSystemModule in module.flags:
|
||||||
incl result.flags, preventStackTrace
|
incl result.flags, preventStackTrace
|
||||||
excl(result.preInitProc.options, optStackTrace)
|
excl(result.preInitProc.options, optStackTrace)
|
||||||
excl(result.postInitProc.options, optStackTrace)
|
|
||||||
let ndiName = if optCDebug in g.config.globalOptions: changeFileExt(completeCFilePath(g.config, filename), "ndi")
|
let ndiName = if optCDebug in g.config.globalOptions: changeFileExt(completeCFilePath(g.config, filename), "ndi")
|
||||||
else: ""
|
else: ""
|
||||||
open(result.ndi, ndiName, g.config)
|
open(result.ndi, ndiName, g.config)
|
||||||
|
|
@ -1265,7 +1272,6 @@ proc resetModule*(m: BModule) =
|
||||||
m.initProc = newProc(nil, m)
|
m.initProc = newProc(nil, m)
|
||||||
m.initProc.options = initProcOptions(m)
|
m.initProc.options = initProcOptions(m)
|
||||||
m.preInitProc = newPreInitProc(m)
|
m.preInitProc = newPreInitProc(m)
|
||||||
m.postInitProc = newPostInitProc(m)
|
|
||||||
initNodeTable(m.dataCache)
|
initNodeTable(m.dataCache)
|
||||||
m.typeStack = @[]
|
m.typeStack = @[]
|
||||||
m.forwardedProcs = @[]
|
m.forwardedProcs = @[]
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,6 @@ type
|
||||||
headerFiles*: seq[string] # needed headers to include
|
headerFiles*: seq[string] # needed headers to include
|
||||||
typeInfoMarker*: TypeCache # needed for generating type information
|
typeInfoMarker*: TypeCache # needed for generating type information
|
||||||
initProc*: BProc # code for init procedure
|
initProc*: BProc # code for init procedure
|
||||||
postInitProc*: BProc # code to be executed after the init proc
|
|
||||||
preInitProc*: BProc # code executed before the init proc
|
preInitProc*: BProc # code executed before the init proc
|
||||||
typeStack*: TTypeSeq # used for type generation
|
typeStack*: TTypeSeq # used for type generation
|
||||||
dataCache*: TNodeTable
|
dataCache*: TNodeTable
|
||||||
|
|
|
||||||
16
tests/threads/t8535.nim
Normal file
16
tests/threads/t8535.nim
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
discard """
|
||||||
|
output: "0"
|
||||||
|
"""
|
||||||
|
|
||||||
|
type
|
||||||
|
CircAlloc* [Size: static[int] , T] = tuple
|
||||||
|
baseArray : array[Size,T]
|
||||||
|
index : uint16
|
||||||
|
|
||||||
|
type
|
||||||
|
Job = object of RootObj
|
||||||
|
|
||||||
|
var foo {.threadvar.}: CircAlloc[1,Job]
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
echo foo.index
|
||||||
Loading…
Add table
Add a link
Reference in a new issue