remove any traces of the old global generics cache

This commit is contained in:
Zahary Karadjov
2013-01-27 21:28:34 +02:00
parent 5d9153d420
commit 55f8ed2452
6 changed files with 65 additions and 109 deletions

View File

@@ -282,7 +282,6 @@ proc CommandCompileToC =
# rodread.gMods
# !! ropes.cache
# !! semdata.gGenericsCache
# semthreads.computed?
#
# suggest.usageSym
@@ -397,7 +396,6 @@ proc resetMemory =
ResetAllModules()
resetRopeCache()
resetSysTypes()
gGenericsCache = nil
gOwners = @[]
rangeDestructorProc = nil
for i in low(buckets)..high(buckets):
@@ -421,7 +419,6 @@ proc resetMemory =
# rodread.gMods
# !! ropes.cache
# !! semdata.gGenericsCache
# semthreads.computed?
#
# suggest.usageSym

View File

@@ -188,15 +188,15 @@ proc semConstBoolExpr(c: PContext, n: PNode): PNode =
include semtypes, semtempl, semgnrc, semstmts, semexprs
proc addCodeForGenerics(c: PContext, n: PNode) =
for i in countup(c.generics.lastGenericIdx, Len(c.generics.generics) - 1):
var prc = c.generics.generics[i].inst.sym
if prc.kind in {skProc, skMethod, skConverter} and prc.magic == mNone:
if prc.ast == nil or prc.ast.sons[bodyPos] == nil:
proc addCodeForGenerics(c: PContext, n: PNode) =
for i in countup(c.lastGenericIdx, c.generics.len - 1):
var prc = c.generics[i].inst.sym
if prc.kind in {skProc, skMethod, skConverter} and prc.magic == mNone:
if prc.ast == nil or prc.ast.sons[bodyPos] == nil:
InternalError(prc.info, "no code for " & prc.name.s)
else:
addSon(n, prc.ast)
c.generics.lastGenericIdx = Len(c.generics.generics)
c.lastGenericIdx = c.generics.len
proc semExprNoFlags(c: PContext, n: PNode): PNode {.procvar.} =
result = semExpr(c, n, {})
@@ -229,7 +229,7 @@ proc myOpenCached(module: PSym, rd: PRodReader): PPassContext =
proc SemStmtAndGenerateGenerics(c: PContext, n: PNode): PNode =
result = semStmt(c, n)
# BUGFIX: process newly generated generics here, not at the end!
if c.generics.lastGenericIdx < Len(c.generics.generics):
if c.lastGenericIdx < c.generics.len:
var a = newNodeI(nkStmtList, n.info)
addCodeForGenerics(c, a)
if sonsLen(a) > 0:

View File

@@ -39,21 +39,11 @@ type
TInstantiationPair* = object
genericSym*: PSym
inst*: PInstantiation
# If we generate an instance of a generic, we'd like to re-use that
# instance if possible across module boundaries. However, this is not
# possible if the compilation cache is enabled. So we give up then and use
# the caching of generics only per module, not per project.
TGenericsCache* {.final.} = object
generics*: seq[TInstantiationPair] # a list of the things to compile
lastGenericIdx*: int # used for the generics stack
PGenericsCache* = ref TGenericsCache
PContext* = ref TContext
TContext* = object of TPassContext # a context represents a module
module*: PSym # the module sym belonging to the context
p*: PProcCon # procedure context
generics*: PGenericsCache # may point to a global or module-local structure
friendModule*: PSym # current friend module; may access private data;
# this is used so that generic instantiations
# can access private object fields
@@ -84,9 +74,9 @@ type
evalContext*: PEvalContext
UnknownIdents*: TIntSet # ids of all unknown identifiers to prevent
# naming it multiple times
var
gGenericsCache*: PGenericsCache # save for modularity
generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile
lastGenericIdx*: int # used for the generics stack
proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
result.genericSym = s
@@ -96,10 +86,6 @@ proc filename*(c: PContext): string =
# the module's filename
return c.module.filename
proc newGenericsCache*(): PGenericsCache =
new(result)
result.generics = @[]
proc newContext*(module: PSym): PContext
proc lastOptionEntry*(c: PContext): POptionEntry
@@ -171,15 +157,7 @@ proc newContext(module: PSym): PContext =
result.patterns = @[]
result.includedFiles = initIntSet()
initStrTable(result.userPragmas)
if optSymbolFiles notin gGlobalOptions:
# re-usage of generic instantiations across module boundaries is
# very nice for code size:
if gGenericsCache == nil: gGenericsCache = newGenericsCache()
result.generics = gGenericsCache
else:
# we have to give up and use a per-module cache for generic instantiations:
result.generics = newGenericsCache()
assert gGenericsCache == nil
result.generics = @[]
result.UnknownIdents = initIntSet()
proc inclSym(sq: var TSymSeq, s: PSym) =

View File

@@ -1359,7 +1359,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
let oldInUnrolledContext = c.InUnrolledContext
let oldInGenericInst = c.InGenericInst
let oldProcCon = c.p
c.generics = newGenericsCache()
c.generics = @[]
try:
result = semExpr(c, n, flags)
if msgs.gErrorCounter != oldErrorCount: result = nil

View File

@@ -104,9 +104,9 @@ proc instantiateBody(c: PContext, n: PNode, result: PSym) =
popProcCon(c)
proc fixupInstantiatedSymbols(c: PContext, s: PSym) =
for i in countup(0, Len(c.generics.generics) - 1):
if c.generics.generics[i].genericSym.id == s.id:
var oldPrc = c.generics.generics[i].inst.sym
for i in countup(0, c.generics.len - 1):
if c.generics[i].genericSym.id == s.id:
var oldPrc = c.generics[i].inst.sym
pushInfoContext(oldPrc.info)
openScope(c.tab)
var n = oldPrc.ast
@@ -166,7 +166,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
var oldPrc = GenericCacheGet(fn, entry[])
if oldPrc == nil:
fn.procInstCache.safeAdd(entry)
c.generics.generics.add(makeInstPair(fn, entry))
c.generics.add(makeInstPair(fn, entry))
if n.sons[pragmasPos].kind != nkEmpty:
pragma(c, result, n.sons[pragmasPos], allRoutinePragmas)
if isNil(n.sons[bodyPos]):

View File

@@ -42,6 +42,11 @@ proc searchInstTypes(key: PType): PType =
for inst in genericTyp.sym.typeInstCache:
if inst.id == key.id: return inst
if inst.sons.len < key.sons.len:
# XXX: This happens for prematurely cached
# types such as TChannel[empty]. Why?
# See the notes for PActor in handleGenericInvokation
return
block MatchType:
for j in 1 .. high(key.sons):
# XXX sameType is not really correct for nested generics?
@@ -138,75 +143,51 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType =
var body = t.sons[0]
if body.kind != tyGenericBody: InternalError(cl.info, "no generic body")
var header: PType = nil
when true:
# search for some instantiation here:
result = searchInstTypes(t)
if result != nil: return
for i in countup(1, sonsLen(t) - 1):
var x = t.sons[i]
if x.kind == tyGenericParam:
x = lookupTypeVar(cl, x)
if header == nil: header = copyType(t, t.owner, false)
header.sons[i] = x
#idTablePut(cl.typeMap, body.sons[i-1], x)
if header != nil:
# search again after first pass:
result = searchInstTypes(header)
if result != nil: return
else:
header = copyType(t, t.owner, false)
# ugh need another pass for deeply recursive generic types (e.g. PActor)
# we need to add the candidate here, before it's fully instantiated for
# recursive instantions:
result = newType(tyGenericInst, t.sons[0].owner)
result.rawAddSon(header.sons[0])
cacheTypeInst(result)
for i in countup(1, sonsLen(t) - 1):
var x = replaceTypeVarsT(cl, t.sons[i])
assert x.kind != tyGenericInvokation
# search for some instantiation here:
result = searchInstTypes(t)
if result != nil: return
for i in countup(1, sonsLen(t) - 1):
var x = t.sons[i]
if x.kind == tyGenericParam:
x = lookupTypeVar(cl, x)
if header == nil: header = copyType(t, t.owner, false)
header.sons[i] = x
idTablePut(cl.typeMap, body.sons[i-1], x)
for i in countup(1, sonsLen(t) - 1):
# if one of the params is not concrete, we cannot do anything
# but we already raised an error!
rawAddSon(result, header.sons[i])
var newbody = ReplaceTypeVarsT(cl, lastSon(body))
newbody.flags = newbody.flags + t.flags + body.flags
result.flags = result.flags + newbody.flags
newbody.callConv = body.callConv
newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n)
# This type may be a generic alias and we want to resolve it here.
# One step is enough, because the recursive nature of
# handleGenericInvokation will handle the alias-to-alias-to-alias case
if newbody.isGenericAlias: newbody = newbody.skipGenericAlias
rawAddSon(result, newbody)
checkPartialConstructedType(cl.info, newbody)
#idTablePut(cl.typeMap, body.sons[i-1], x)
if header != nil:
# search again after first pass:
result = searchInstTypes(header)
if result != nil: return
else:
for i in countup(1, sonsLen(t) - 1):
if PType(idTableGet(cl.typeMap, t.sons[i])) == nil: debug(t)
var x = replaceTypeVarsT(cl, t.sons[i])
if t.sons[i].kind == tyGenericParam:
if header == nil: header = copyType(t, t.owner, false)
header.sons[i] = x
assert x.kind != tyGenericInvokation
idTablePut(cl.typeMap, body.sons[i-1], x)
if header == nil: header = t
result = searchInstTypes(cl.c.generics.InstTypes, header)
if result != nil: return
result = newType(tyGenericInst, t.sons[0].owner)
for i in countup(0, sonsLen(t) - 1):
# if one of the params is not concrete, we cannot do anything
# but we already raised an error!
addSon(result, header.sons[i])
idTablePut(cl.c.generics.InstTypes, header, result)
var newbody = ReplaceTypeVarsT(cl, lastSon(body))
newbody.flags = newbody.flags + t.flags + body.flags
newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n)
addSon(result, newbody)
checkPartialConstructedType(cl.info, newbody)
header = copyType(t, t.owner, false)
# ugh need another pass for deeply recursive generic types (e.g. PActor)
# we need to add the candidate here, before it's fully instantiated for
# recursive instantions:
result = newType(tyGenericInst, t.sons[0].owner)
result.rawAddSon(header.sons[0])
cacheTypeInst(result)
for i in countup(1, sonsLen(t) - 1):
var x = replaceTypeVarsT(cl, t.sons[i])
assert x.kind != tyGenericInvokation
header.sons[i] = x
idTablePut(cl.typeMap, body.sons[i-1], x)
for i in countup(1, sonsLen(t) - 1):
# if one of the params is not concrete, we cannot do anything
# but we already raised an error!
rawAddSon(result, header.sons[i])
var newbody = ReplaceTypeVarsT(cl, lastSon(body))
newbody.flags = newbody.flags + t.flags + body.flags
result.flags = result.flags + newbody.flags
newbody.callConv = body.callConv
newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n)
# This type may be a generic alias and we want to resolve it here.
# One step is enough, because the recursive nature of
# handleGenericInvokation will handle the alias-to-alias-to-alias case
if newbody.isGenericAlias: newbody = newbody.skipGenericAlias
rawAddSon(result, newbody)
checkPartialConstructedType(cl.info, newbody)
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
result = t