removed nimdat in favor of per-module dat init procs

This commit is contained in:
Zahary Karadjov
2012-07-19 19:04:18 +03:00
parent 035b715dfd
commit 4841b6390c
6 changed files with 73 additions and 75 deletions

View File

@@ -567,6 +567,8 @@ type
# for a conditional:
# 1 iff the symbol is defined, else 0
# (or not in symbol table)
# for modules, a unique index correspinding
# to the order of compilation
offset*: int # offset of record field
loc*: TLoc
annex*: PLib # additional fields (seldom used, so we use a

View File

@@ -1004,15 +1004,10 @@ proc genNewFinalize(p: BProc, e: PNode) =
oldModule: BModule
refType = skipTypes(e.sons[1].typ, abstractVarRange)
InitLocExpr(p, e.sons[1], a)
# This is a little hack:
# XXX this is also a bug, if the finalizer expression produces side-effects
oldModule = p.module
p.module = gNimDat
InitLocExpr(p, e.sons[2], f)
p.module = oldModule
initLoc(b, locExpr, a.t, OnHeap)
ti = genTypeInfo(p.module, refType)
appf(gNimDat.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
appf(p.module.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [
getTypeDesc(p.module, refType),
ti, getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))])

View File

@@ -886,41 +886,43 @@ include ccgtrav
proc genTypeInfo(m: BModule, typ: PType): PRope =
var t = getUniqueType(typ)
# gNimDat contains all the type information nowadays:
var dataGenerated = ContainsOrIncl(gNimDat.typeInfoMarker, t.id)
result = ropef("NTI$1", [toRope(t.id)])
if not ContainsOrIncl(m.typeInfoMarker, t.id):
# declare type information structures:
let owner = typ.skipTypes(abstractPtrs).owner.getModule
if owner != m.module:
# make sure the type info is created in the owner module
discard genTypeInfo(owner.bmod, typ)
# refenrece the type info as extern here
discard cgsym(m, "TNimType")
discard cgsym(m, "TNimNode")
appf(m.s[cfsVars], "extern TNimType* $1; /* $2 */$n",
[result, toRope(typeToString(t))])
if dataGenerated: return
return
if ContainsOrIncl(m.typeInfoMarker, t.id): return
case t.kind
of tyEmpty: result = toRope"0"
of tyPointer, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64, tyVar:
genTypeInfoAuxBase(gNimDat, t, result, toRope"0")
genTypeInfoAuxBase(m, t, result, toRope"0")
of tyProc:
if t.callConv != ccClosure:
genTypeInfoAuxBase(gNimDat, t, result, toRope"0")
genTypeInfoAuxBase(m, t, result, toRope"0")
else:
genTupleInfo(gNimDat, fakeClosureType(t.owner), result)
genTupleInfo(m, fakeClosureType(t.owner), result)
of tySequence, tyRef:
genTypeInfoAux(gNimDat, t, result)
genTypeInfoAux(m, t, result)
if optRefcGC in gGlobalOptions:
let markerProc = genTraverseProc(gNimDat, t, tiNew)
appf(gNimDat.s[cfsTypeInit3], "$1->marker = $2;$n", [result, markerProc])
of tyPtr, tyRange: genTypeInfoAux(gNimDat, t, result)
of tyArrayConstr, tyArray: genArrayInfo(gNimDat, t, result)
of tySet: genSetInfo(gNimDat, t, result)
of tyEnum: genEnumInfo(gNimDat, t, result)
of tyObject: genObjectInfo(gNimDat, t, result)
let markerProc = genTraverseProc(m, t, tiNew)
appf(m.s[cfsTypeInit3], "$1->marker = $2;$n", [result, markerProc])
of tyPtr, tyRange: genTypeInfoAux(m, t, result)
of tyArrayConstr, tyArray: genArrayInfo(m, t, result)
of tySet: genSetInfo(m, t, result)
of tyEnum: genEnumInfo(m, t, result)
of tyObject: genObjectInfo(m, t, result)
of tyTuple:
# if t.n != nil: genObjectInfo(gNimDat, t, result)
# if t.n != nil: genObjectInfo(m, t, result)
# else:
# BUGFIX: use consistently RTTI without proper field names; otherwise
# results are not deterministic!
genTupleInfo(gNimDat, t, result)
genTupleInfo(m, t, result)
else: InternalError("genTypeInfo(" & $t.kind & ')')
proc genTypeSection(m: BModule, n: PNode) =

View File

@@ -819,11 +819,12 @@ proc getFileHeader(cfilenoext: string): PRope =
proc genMainProc(m: BModule) =
const
CommonMainBody =
"\tnim__datInit();$n" &
"\tsystemInit();$n" &
"\tsystemDatInit();$n" &
"$1" &
"$2" &
"$3"
"\tsystemInit();$n" &
"$3" &
"$4"
PosixNimMain =
"int cmdCount;$n" &
"char** cmdLine;$n" &
@@ -877,7 +878,7 @@ proc genMainProc(m: BModule) =
platform.targetOS == osStandalone: "".toRope
else: ropecg(m, "\t#initStackBottom();$n")
inc(m.labels)
appcg(m, m.s[cfsProcs], nimMain, [initStackBottomCall,
appcg(m, m.s[cfsProcs], nimMain, [mainDatInit, initStackBottomCall,
gBreakpoints, mainModInit, toRope(m.labels)])
if optNoMain notin gGlobalOptions:
appcg(m, m.s[cfsProcs], otherMain, [])
@@ -885,12 +886,20 @@ proc genMainProc(m: BModule) =
proc getInitName(m: PSym): PRope =
result = ropeff("$1Init", "@$1Init", [toRope(m.name.s)])
proc getDatInitName(m: PSym): PRope =
result = ropeff("$1DatInit", "@$1DatInit", [toRope(m.name.s)])
proc registerModuleToMain(m: PSym) =
var initname = getInitName(m)
appff(mainModProcs, "N_NOINLINE(void, $1)(void);$n",
"declare void $1() noinline$n", [initname])
if not (sfSystemModule in m.flags):
appff(mainModInit, "$1();$n", "call void ()* $1$n", [initname])
var
init = m.getInitName
datInit = m.getDatInitName
appff(mainModProcs, "N_NOINLINE(void, $1)(void);$N",
"declare void $1() noinline$N", [init])
appff(mainModProcs, "N_NOINLINE(void, $1)(void);$N",
"declare void $1() noinline$N", [datInit])
if not (sfSystemModule in m.flags):
appff(mainModInit, "\t$1();$n", "call void ()* $1$n", [init])
appff(mainDatInit, "\t$1();$n", "call void ()* $1$n", [datInit])
proc genInitCode(m: BModule) =
if optProfiler in m.initProc.options:
@@ -914,25 +923,17 @@ proc genInitCode(m: BModule) =
getFrameDecl(m.initProc)
app(prc, initGCFrame(m.initProc))
app(prc, genSectionStart(cpsLocals))
app(prc, m.initProc.s(cpsLocals))
app(prc, m.preInitProc.s(cpsLocals))
app(prc, genSectionEnd(cpsLocals))
app(prc, genSectionStart(cfsTypeInit1))
app(prc, m.s[cfsTypeInit1])
if optStackTrace in m.initProc.options and not m.PreventStackTrace:
var procname = CStringLit(m.initProc, prc, m.module.name.s)
var filename = CStringLit(m.initProc, prc, toFilename(m.module.info))
app(prc, initFrame(m.initProc, procname, filename))
app(prc, genSectionEnd(cfsTypeInit1))
for i in cfsTypeInit2..cfsDynLibInit:
app(prc, genSectionStart(i))
app(prc, m.s[i])
app(prc, genSectionEnd(i))
app(prc, genSectionStart(cpsInit))
app(prc, m.preInitProc.s(cpsInit))
app(prc, m.initProc.s(cpsInit))
@@ -945,7 +946,17 @@ proc genInitCode(m: BModule) =
app(prc, deinitFrame(m.initProc))
app(prc, genSectionEnd(cpsStmts))
app(prc, deinitGCFrame(m.initProc))
appf(prc, "}$n$n")
appf(prc, "}$N$N")
prc.appff("N_NOINLINE(void, $1)(void) {$n",
"define void $1() noinline {$n", [getDatInitName(m.module)])
for i in cfsTypeInit1..cfsDynLibInit:
app(prc, genSectionStart(i))
app(prc, m.s[i])
app(prc, genSectionEnd(i))
appf(prc, "}$N$N")
# we cannot simply add the init proc to ``m.s[cfsProcs]`` anymore because
# that would lead to a *nesting* of merge sections which the merger does
# not support. So we add it to another special section: ``cfsInitProc``
@@ -987,22 +998,15 @@ proc rawNewModule(module: PSym, filename: string): BModule =
proc newModule(module: PSym, filename: string): BModule =
result = rawNewModule(module, filename)
if gModules.len <= module.position: gModules.setLen(module.position + 1)
gModules[module.position] = result
if (optDeadCodeElim in gGlobalOptions):
if (sfDeadCodeElim in module.flags):
InternalError("added pending module twice: " & filename)
addPendingModule(result)
proc registerTypeInfoModule() =
const moduleName = "nim__dat"
var s = NewSym(skModule, getIdent(moduleName), nil)
gNimDat = rawNewModule(s, (options.gProjectPath / moduleName) & ".nim")
gNimDat.PreventStackTrace = true
addPendingModule(gNimDat)
appff(mainModProcs, "N_NOINLINE(void, $1)(void);$n",
"declare void $1() noinline$n", [getInitName(s)])
proc myOpen(module: PSym, filename: string): PPassContext =
if gNimDat == nil: registerTypeInfoModule()
result = newModule(module, filename)
proc getCFile(m: BModule): string =
@@ -1010,11 +1014,6 @@ proc getCFile(m: BModule): string =
proc myOpenCached(module: PSym, filename: string,
rd: PRodReader): PPassContext =
if gNimDat == nil:
registerTypeInfoModule()
gNimDat.fromCache = true
readMergeInfo(getCFile(gNimDat), gNimDat)
var m = newModule(module, filename)
readMergeInfo(getCFile(m), m)
result = m
@@ -1100,9 +1099,6 @@ proc myClose(b: PPassContext, n: PNode): PNode =
# cached modules need to registered too:
registerModuleToMain(m.module)
if optDeadCodeElim notin gGlobalOptions and
sfDeadCodeElim notin m.module.flags:
finishModule(m)
if sfMainModule in m.module.flags:
var disp = generateMethodDispatchers()
for i in 0..sonsLen(disp)-1: genProcAux(m, disp.sons[i].sym)
@@ -1111,16 +1107,12 @@ proc myClose(b: PPassContext, n: PNode): PNode =
# deps are allowed (and the system module is processed in the wrong
# order anyway)
while gForwardedProcsCounter > 0:
for i in countup(0, high(gPendingModules)):
finishModule(gPendingModules[i])
for i in countup(0, high(gPendingModules)):
writeModule(gPendingModules[i], pending=true)
setlen(gPendingModules, 0)
if optDeadCodeElim notin gGlobalOptions and
sfDeadCodeElim notin m.module.flags:
writeModule(m, pending=false)
if sfMainModule in m.module.flags: writeMapping(gMapping)
for i in countup(0, high(gModules)):
finishModule(gModules[i])
for i in countup(0, high(gModules)):
writeModule(gModules[i], pending=true)
writeMapping(gMapping)
proc cgenPass(): TPass =
initPass(result)
result.open = myOpen

View File

@@ -112,14 +112,14 @@ type
labels*: natural # for generating unique module-scope names
var
mainModProcs*, mainModInit*: PRope # parts of the main module
mainModProcs*, mainModInit*, mainDatInit*: PRope # parts of the main module
gMapping*: PRope # the generated mapping file (if requested)
gProcProfile*: Natural # proc profile counter
gPendingModules*: seq[BModule] = @[] # list of modules that are not
# finished with code generation
gModules*: seq[BModule] = @[] # list of all compiled modules
gForwardedProcsCounter*: int = 0
gNimDat*: BModule # generated global data
proc s*(p: BProc, s: TCProcSection): var PRope {.inline.} =
# section in the current block
result = p.blocks[p.blocks.len - 1].sections[s]
@@ -128,6 +128,10 @@ proc procSec*(p: BProc, s: TCProcSection): var PRope {.inline.} =
# top level proc sections
result = p.blocks[0].sections[s]
proc bmod*(module: PSym): BModule =
# obtains the BModule for a given module PSym
result = gModules[module.position]
proc newProc*(prc: PSym, module: BModule): BProc =
new(result)
result.prc = prc

View File

@@ -39,6 +39,7 @@ proc registerModule(filename: string, module: PSym) =
proc getModule(filename: string): PSym =
result = compMods[filename]
var gModulesCount = 0
proc newModule(filename: string): PSym =
# We cannot call ``newSym`` here, because we have to circumvent the ID
# mechanism, which we do in order to assign each module a persistent ID.
@@ -51,6 +52,8 @@ proc newModule(filename: string): PSym =
result.owner = result # a module belongs to itself
result.info = newLineInfo(filename, 1, 1)
result.position = gModulesCount
inc gModulesCount
incl(result.flags, sfUsed)
initStrTable(result.tab)
RegisterModule(filename, result)