diff options
-rwxr-xr-x | compiler/cgen.nim | 4 | ||||
-rwxr-xr-x | compiler/crc.nim | 11 | ||||
-rwxr-xr-x | compiler/nimrod.nim | 6 | ||||
-rwxr-xr-x | compiler/treetab.nim | 47 | ||||
-rwxr-xr-x | koch.nim | 6 | ||||
-rwxr-xr-x | lib/core/macros.nim | 112 | ||||
-rwxr-xr-x | lib/core/threads.nim | 2 | ||||
-rw-r--r-- | lib/pure/collections/hashtables.nim | 9 | ||||
-rwxr-xr-x | lib/system/cgprocs.nim | 57 | ||||
-rwxr-xr-x | lib/system/dyncalls.nim | 4 | ||||
-rwxr-xr-x | lib/system/gc.nim | 71 | ||||
-rwxr-xr-x | lib/system/mmdisp.nim | 2 | ||||
-rwxr-xr-x | todo.txt | 9 |
13 files changed, 185 insertions, 155 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim index d76793c9a..619caf250 100755 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -677,8 +677,8 @@ proc genProcAux(m: BModule, prc: PSym) = if optStackTrace in prc.options: app(generatedProc, deinitFrame(p)) if (optProfiler in prc.options) and (gCmd != cmdCompileToLLVM): appf(generatedProc, - "profileData[$1].total += elapsed(getticks(), NIM_profilingStart);$n", - [toRope(prc.loc.a)]) + "profileData[$1].total += elapsed(getticks(), NIM_profilingStart);$n", + [toRope(prc.loc.a)]) app(generatedProc, returnStmt) app(generatedProc, '}' & tnl) app(m.s[cfsProcs], generatedProc) diff --git a/compiler/crc.nim b/compiler/crc.nim index be1aee16b..b1801d9dc 100755 --- a/compiler/crc.nim +++ b/compiler/crc.nim @@ -100,19 +100,16 @@ proc crcFromBuf(buf: Pointer, length: int): TCrc32 = proc crcFromFile(filename: string): TCrc32 = const - bufSize = 8 * 1024 + bufSize = 8000 # don't use 8K for the memory allocator! var bin: tfile - buf: Pointer - readBytes: int - p: PByteArray result = InitCrc32 if not open(bin, filename): return # not equal if file does not exist - buf = alloc(BufSize) - p = cast[PByteArray](buf) + var buf = alloc(BufSize) + var p = cast[PByteArray](buf) while true: - readBytes = readBuffer(bin, buf, bufSize) + var readBytes = readBuffer(bin, buf, bufSize) for i in countup(0, readBytes - 1): result = updateCrc32(p[i], result) if readBytes != bufSize: break dealloc(buf) diff --git a/compiler/nimrod.nim b/compiler/nimrod.nim index 05c7a2af1..d9580d955 100755 --- a/compiler/nimrod.nim +++ b/compiler/nimrod.nim @@ -50,7 +50,7 @@ proc ProcessCmdLine(pass: TCmdLinePass, command, filename: var string) = rawMessage(errArgsNeedRunOption, []) proc HandleCmdLine() = - var start = getTime() + var start = epochTime() if paramCount() == 0: writeCommandLineUsage() else: @@ -73,7 +73,8 @@ proc HandleCmdLine() = if gCmd == cmdRun: tccgen.run() if gCmd notin {cmdInterpret, cmdRun}: - rawMessage(hintSuccessX, [$gLinesCompiled, $(getTime() - start)]) + rawMessage(hintSuccessX, [$gLinesCompiled, + formatFloat(epochTime() - start, ffDecimal, 3)]) if optRun in gGlobalOptions: when defined(unix): var prog = "./" & quoteIfContainsWhite(changeFileExt(filename, "")) @@ -81,6 +82,7 @@ proc HandleCmdLine() = var prog = quoteIfContainsWhite(changeFileExt(filename, "")) execExternalProgram(prog & ' ' & arguments) +#GC_disableMarkAndSweep() cmdLineInfo = newLineInfo("command line", -1, -1) condsyms.InitDefines() HandleCmdLine() diff --git a/compiler/treetab.nim b/compiler/treetab.nim index 797ef5029..92a329ecc 100755 --- a/compiler/treetab.nim +++ b/compiler/treetab.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2008 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -12,13 +12,7 @@ import nhashes, ast, astalgo, types -proc NodeTableGet*(t: TNodeTable, key: PNode): int -proc NodeTablePut*(t: var TNodeTable, key: PNode, val: int) -proc NodeTableTestOrSet*(t: var TNodeTable, key: PNode, val: int): int -# implementation - proc hashTree(n: PNode): THash = - result = 0 if n == nil: return result = ord(n.kind) case n.kind @@ -41,7 +35,6 @@ proc hashTree(n: PNode): THash = result = concHash(result, hashTree(n.sons[i])) proc TreesEquivalent(a, b: PNode): bool = - result = false if a == b: result = true elif (a != nil) and (b != nil) and (a.kind == b.kind): @@ -60,36 +53,31 @@ proc TreesEquivalent(a, b: PNode): bool = if result: result = sameTypeOrNil(a.typ, b.typ) proc NodeTableRawGet(t: TNodeTable, k: THash, key: PNode): int = - var h: THash - h = k and high(t.data) + var h: THash = k and high(t.data) while t.data[h].key != nil: if (t.data[h].h == k) and TreesEquivalent(t.data[h].key, key): return h h = nextTry(h, high(t.data)) - result = - 1 + result = -1 -proc NodeTableGet(t: TNodeTable, key: PNode): int = - var index: int - index = NodeTableRawGet(t, hashTree(key), key) +proc NodeTableGet*(t: TNodeTable, key: PNode): int = + var index = NodeTableRawGet(t, hashTree(key), key) if index >= 0: result = t.data[index].val else: result = low(int) -proc NodeTableRawInsert(data: var TNodePairSeq, k: THash, key: PNode, val: int) = - var h: THash - h = k and high(data) +proc NodeTableRawInsert(data: var TNodePairSeq, k: THash, key: PNode, + val: int) = + var h: THash = k and high(data) while data[h].key != nil: h = nextTry(h, high(data)) assert(data[h].key == nil) data[h].h = k data[h].key = key data[h].val = val -proc NodeTablePut(t: var TNodeTable, key: PNode, val: int) = - var - index: int - n: TNodePairSeq - k: THash - k = hashTree(key) - index = NodeTableRawGet(t, k, key) +proc NodeTablePut*(t: var TNodeTable, key: PNode, val: int) = + var n: TNodePairSeq + var k: THash = hashTree(key) + var index = NodeTableRawGet(t, k, key) if index >= 0: assert(t.data[index].key != nil) t.data[index].val = val @@ -103,13 +91,10 @@ proc NodeTablePut(t: var TNodeTable, key: PNode, val: int) = NodeTableRawInsert(t.data, k, key, val) inc(t.counter) -proc NodeTableTestOrSet(t: var TNodeTable, key: PNode, val: int): int = - var - index: int - n: TNodePairSeq - k: THash - k = hashTree(key) - index = NodeTableRawGet(t, k, key) +proc NodeTableTestOrSet*(t: var TNodeTable, key: PNode, val: int): int = + var n: TNodePairSeq + var k: THash = hashTree(key) + var index = NodeTableRawGet(t, k, key) if index >= 0: assert(t.data[index].key != nil) result = t.data[index].val diff --git a/koch.nim b/koch.nim index 4524ed3e8..29fa86cb3 100755 --- a/koch.nim +++ b/koch.nim @@ -157,10 +157,8 @@ proc cleanAux(dir: string) = of "nimcache": echo "removing dir: ", path removeDir(path) - of "dist", ".git": - nil - else: - cleanAux(path) + of "dist", ".git": nil + else: cleanAux(path) else: nil proc removePattern(pattern: string) = diff --git a/lib/core/macros.nim b/lib/core/macros.nim index e262ec012..e51141025 100755 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -13,60 +13,60 @@ ## .. include:: ../doc/astspec.txt -type - TNimrodNodeKind* = enum - nnkNone, nnkEmpty, nnkIdent, nnkSym, - nnkType, nnkCharLit, nnkIntLit, nnkInt8Lit, - nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkFloatLit, - nnkFloat32Lit, nnkFloat64Lit, nnkStrLit, nnkRStrLit, - nnkTripleStrLit, nnkMetaNode, nnkNilLit, nnkDotCall, - nnkCommand, nnkCall, nnkCallStrLit, nnkExprEqExpr, - nnkExprColonExpr, nnkIdentDefs, nnkVarTuple, nnkInfix, - nnkPrefix, nnkPostfix, nnkPar, nnkCurly, - nnkBracket, nnkBracketExpr, nnkPragmaExpr, nnkRange, - nnkDotExpr, nnkCheckedFieldExpr, nnkDerefExpr, nnkIfExpr, - nnkElifExpr, nnkElseExpr, nnkLambda, nnkAccQuoted, - nnkTableConstr, nnkBind, nnkSymChoice, nnkHiddenStdConv, - nnkHiddenSubConv, nnkHiddenCallConv, nnkConv, nnkCast, - nnkAddr, nnkHiddenAddr, nnkHiddenDeref, nnkObjDownConv, - nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange, - nnkStringToCString, nnkCStringToString, nnkPassAsOpenArray, nnkAsgn, - nnkFastAsgn, nnkGenericParams, nnkFormalParams, nnkOfInherit, - nnkModule, nnkProcDef, nnkMethodDef, nnkConverterDef, - nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkOfBranch, - nnkElifBranch, nnkExceptBranch, nnkElse, nnkMacroStmt, - nnkAsmStmt, nnkPragma, nnkIfStmt, nnkWhenStmt, - nnkForStmt, nnkWhileStmt, nnkCaseStmt, nnkVarSection, - nnkConstSection, nnkConstDef, nnkTypeSection, nnkTypeDef, - nnkYieldStmt, nnkTryStmt, nnkFinally, nnkRaiseStmt, - nnkReturnStmt, nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, - nnkDiscardStmt, nnkStmtList, nnkImportStmt, nnkFromStmt, - nnkIncludeStmt, nnkCommentStmt, nnkStmtListExpr, nnkBlockExpr, - nnkStmtListType, nnkBlockType, nnkTypeOfExpr, nnkObjectTy, - nnkTupleTy, nnkRecList, nnkRecCase, nnkRecWhen, - nnkRefTy, nnkPtrTy, nnkVarTy, nnkDistinctTy, - nnkProcTy, nnkEnumTy, nnkEnumFieldDef, nnkReturnToken - TNimNodeKinds* = set[TNimrodNodeKind] - TNimrodTypeKind* = enum - ntyNone, ntyBool, ntyChar, ntyEmpty, - ntyArrayConstr, ntyNil, ntyExpr, ntyStmt, - ntyTypeDesc, ntyGenericInvokation, ntyGenericBody, ntyGenericInst, - ntyGenericParam, ntyDistinct, ntyEnum, ntyOrdinal, - ntyArray, ntyObject, ntyTuple, ntySet, - ntyRange, ntyPtr, ntyRef, ntyVar, - ntySequence, ntyProc, ntyPointer, ntyOpenArray, - ntyString, ntyCString, ntyForward, ntyInt, - ntyInt8, ntyInt16, ntyInt32, ntyInt64, - ntyFloat, ntyFloat32, ntyFloat64, ntyFloat128 - TNimTypeKinds* = set[TNimrodTypeKind] - TNimrodSymKind* = enum - nskUnknown, nskConditional, nskDynLib, nskParam, - nskGenericParam, nskTemp, nskType, nskConst, - nskVar, nskProc, nskMethod, nskIterator, - nskConverter, nskMacro, nskTemplate, nskField, - nskEnumField, nskForVar, nskModule, nskLabel, - nskStub - TNimSymKinds* = set[TNimrodSymKind] +type + TNimrodNodeKind* = enum + nnkNone, nnkEmpty, nnkIdent, nnkSym, + nnkType, nnkCharLit, nnkIntLit, nnkInt8Lit, + nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkFloatLit, + nnkFloat32Lit, nnkFloat64Lit, nnkStrLit, nnkRStrLit, + nnkTripleStrLit, nnkMetaNode, nnkNilLit, nnkDotCall, + nnkCommand, nnkCall, nnkCallStrLit, nnkExprEqExpr, + nnkExprColonExpr, nnkIdentDefs, nnkVarTuple, nnkInfix, + nnkPrefix, nnkPostfix, nnkPar, nnkCurly, + nnkBracket, nnkBracketExpr, nnkPragmaExpr, nnkRange, + nnkDotExpr, nnkCheckedFieldExpr, nnkDerefExpr, nnkIfExpr, + nnkElifExpr, nnkElseExpr, nnkLambda, nnkAccQuoted, + nnkTableConstr, nnkBind, nnkSymChoice, nnkHiddenStdConv, + nnkHiddenSubConv, nnkHiddenCallConv, nnkConv, nnkCast, + nnkAddr, nnkHiddenAddr, nnkHiddenDeref, nnkObjDownConv, + nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange, + nnkStringToCString, nnkCStringToString, nnkPassAsOpenArray, nnkAsgn, + nnkFastAsgn, nnkGenericParams, nnkFormalParams, nnkOfInherit, + nnkModule, nnkProcDef, nnkMethodDef, nnkConverterDef, + nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkOfBranch, + nnkElifBranch, nnkExceptBranch, nnkElse, nnkMacroStmt, + nnkAsmStmt, nnkPragma, nnkIfStmt, nnkWhenStmt, + nnkForStmt, nnkWhileStmt, nnkCaseStmt, nnkVarSection, + nnkConstSection, nnkConstDef, nnkTypeSection, nnkTypeDef, + nnkYieldStmt, nnkTryStmt, nnkFinally, nnkRaiseStmt, + nnkReturnStmt, nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, + nnkDiscardStmt, nnkStmtList, nnkImportStmt, nnkFromStmt, + nnkIncludeStmt, nnkCommentStmt, nnkStmtListExpr, nnkBlockExpr, + nnkStmtListType, nnkBlockType, nnkTypeOfExpr, nnkObjectTy, + nnkTupleTy, nnkRecList, nnkRecCase, nnkRecWhen, + nnkRefTy, nnkPtrTy, nnkVarTy, nnkDistinctTy, + nnkProcTy, nnkEnumTy, nnkEnumFieldDef, nnkReturnToken + TNimNodeKinds* = set[TNimrodNodeKind] + TNimrodTypeKind* = enum + ntyNone, ntyBool, ntyChar, ntyEmpty, + ntyArrayConstr, ntyNil, ntyExpr, ntyStmt, + ntyTypeDesc, ntyGenericInvokation, ntyGenericBody, ntyGenericInst, + ntyGenericParam, ntyDistinct, ntyEnum, ntyOrdinal, + ntyArray, ntyObject, ntyTuple, ntySet, + ntyRange, ntyPtr, ntyRef, ntyVar, + ntySequence, ntyProc, ntyPointer, ntyOpenArray, + ntyString, ntyCString, ntyForward, ntyInt, + ntyInt8, ntyInt16, ntyInt32, ntyInt64, + ntyFloat, ntyFloat32, ntyFloat64, ntyFloat128 + TNimTypeKinds* = set[TNimrodTypeKind] + TNimrodSymKind* = enum + nskUnknown, nskConditional, nskDynLib, nskParam, + nskGenericParam, nskTemp, nskType, nskConst, + nskVar, nskProc, nskMethod, nskIterator, + nskConverter, nskMacro, nskTemplate, nskField, + nskEnumField, nskForVar, nskModule, nskLabel, + nskStub + TNimSymKinds* = set[TNimrodSymKind] type TNimrodIdent* = object of TObject @@ -88,7 +88,7 @@ type # Nodes should be reference counted to make the `copy` operation very fast! # However, this is difficult to achieve: modify(n[0][1]) should propagate to -# its father. How to do this without back references? Hm, BS, it works without +# its father. How to do this without back references? Hm, BS, it works without # them. proc `[]`* (n: PNimrodNode, i: int): PNimrodNode {.magic: "NChild".} @@ -105,7 +105,7 @@ proc `$`*(i: TNimrodIdent): string {.magic: "IdentToStr".} proc `==`* (a, b: TNimrodIdent): bool {.magic: "EqIdent", noSideEffect.} ## compares two Nimrod identifiers - + proc `==`* (a, b: PNimrodNode): bool {.magic: "EqNimrodNode", noSideEffect.} ## compares two Nimrod nodes diff --git a/lib/core/threads.nim b/lib/core/threads.nim index fc120f1a3..a1c16fc85 100755 --- a/lib/core/threads.nim +++ b/lib/core/threads.nim @@ -100,7 +100,7 @@ when defined(Windows): stdcall, dynlib: "kernel32", importc: "WaitForMultipleObjects".} proc WaitForSingleObject(hHandle: THANDLE, dwMilliseconds: int32): int32 {. - stdcall, dynlib: "kernel32", importc: "WaitForSingleObject".} + stdcall, dynlib: "kernel32", importc: "WaitForSingleObject".} proc TerminateThread(hThread: THandle, dwExitCode: int32): int32 {. stdcall, dynlib: "kernel32", importc: "TerminateThread".} diff --git a/lib/pure/collections/hashtables.nim b/lib/pure/collections/hashtables.nim index 29ba6bf6f..4f4c4f5a0 100644 --- a/lib/pure/collections/hashtables.nim +++ b/lib/pure/collections/hashtables.nim @@ -216,9 +216,16 @@ proc `[]=`*[A, B](t: TOrderedHashTable[A, B], key: A, val: B) = inc(t.counter) proc del*[A, B](t: TOrderedHashTable[A, B], key: A) = - ## deletes `key` from hash table `t`. + ## deletes `key` from hash table `t`. Warning: It's inefficient for ordered + ## tables: O(n). var index = RawGet(t, key) if index >= 0: + var i = t.first + while i >= 0: + var nxt = t.data[i].next + if nxt == index: XXX + i = nxt + t.data[index].slot = seDeleted dec(t.counter) diff --git a/lib/system/cgprocs.nim b/lib/system/cgprocs.nim index 945ce4692..f77768a7a 100755 --- a/lib/system/cgprocs.nim +++ b/lib/system/cgprocs.nim @@ -23,28 +23,39 @@ proc nimLoadLibraryError(path: string) {.compilerproc, noinline.} proc setStackBottom(theStackBottom: pointer) {.compilerRtl, noinline.} - # Support for thread local storage: -when false: - when defined(windows): - proc TlsAlloc(): int32 {.importc: "TlsAlloc", stdcall, dynlib: "kernel32".} - proc TlsSetValue(dwTlsIndex: int32, lpTlsValue: pointer) {. - importc: "TlsSetValue", stdcall, dynlib: "kernel32".} - proc TlsGetValue(dwTlsIndex: int32): pointer {. - importc: "TlsGetValue", stdcall, dynlib: "kernel32".} - - else: - type - Tpthread_key {.importc: "pthread_key_t", header: "<sys/types.h>".} = int - - proc pthread_getspecific(a1: Tpthread_key): pointer {. - importc: "pthread_getspecific", header: "<pthread.h>".} - proc pthread_key_create(a1: ptr Tpthread_key, - a2: proc (x: pointer) {.noconv.}): int32 {. - importc: "pthread_key_create", header: "<pthread.h>".} - proc pthread_key_delete(a1: Tpthread_key): int32 {. - importc: "pthread_key_delete", header: "<pthread.h>".} - - proc pthread_setspecific(a1: Tpthread_key, a2: pointer): int32 {. - importc: "pthread_setspecific", header: "<pthread.h>".} +when defined(windows): + type + TThreadVarSlot {.compilerproc.} = distinct int32 + + proc TlsAlloc(): TThreadVarSlot {. + importc: "TlsAlloc", stdcall, dynlib: "kernel32".} + proc TlsSetValue(dwTlsIndex: TThreadVarSlot, lpTlsValue: pointer) {. + importc: "TlsSetValue", stdcall, dynlib: "kernel32".} + proc TlsGetValue(dwTlsIndex: TThreadVarSlot): pointer {. + importc: "TlsGetValue", stdcall, dynlib: "kernel32".} + + proc ThreadVarAlloc(): TThreadVarSlot {.compilerproc, inline.} = + result = TlsAlloc() + proc ThreadVarSetValue(s: TThreadVarSlot, value: pointer) {.compilerproc.} = + TlsSetValue(s, value) + proc ThreadVarGetValue(s: TThreadVarSlot): pointer {.compilerproc.} = + result = TlsGetValue(s) + +else: + type + Tpthread_key {.importc: "pthread_key_t", + header: "<sys/types.h>".} = distinct int + TThreadVarSlot {.compilerproc.} = Tpthread_key + + proc pthread_getspecific(a1: Tpthread_key): pointer {. + importc: "pthread_getspecific", header: "<pthread.h>".} + proc pthread_key_create(a1: ptr Tpthread_key, + destruct: proc (x: pointer) {.noconv.}): int32 {. + importc: "pthread_key_create", header: "<pthread.h>".} + proc pthread_key_delete(a1: Tpthread_key): int32 {. + importc: "pthread_key_delete", header: "<pthread.h>".} + + proc pthread_setspecific(a1: Tpthread_key, a2: pointer): int32 {. + importc: "pthread_setspecific", header: "<pthread.h>".} diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim index 88870a209..fb1130938 100755 --- a/lib/system/dyncalls.nim +++ b/lib/system/dyncalls.nim @@ -1,7 +1,7 @@ # # # Nimrod's Runtime Library -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -21,8 +21,6 @@ proc rawWrite(f: TFile, s: string) = proc nimLoadLibraryError(path: string) = # carefully written to avoid memory allocation: - #stdout.write("could not load: ") - #quit(path) stdout.rawWrite("could not load: ") stdout.rawWrite(path) stdout.rawWrite("\n") diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 950b60c27..1edc33375 100755 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -23,7 +23,7 @@ const CycleIncrease = 2 # is a multiplicative increase InitialCycleThreshold = 4*1024*1024 # X MB because cycle checking is slow - ZctThreshold = 256 # we collect garbage if the ZCT's size + ZctThreshold = 500 # we collect garbage if the ZCT's size # reaches this threshold # this seems to be a good value @@ -294,31 +294,32 @@ proc initGC() = proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) = var d = cast[TAddress](dest) case n.kind - of nkNone: assert(false) of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op) of nkList: for i in 0..n.len-1: forAllSlotsAux(dest, n.sons[i], op) of nkCase: var m = selectBranch(dest, n) if m != nil: forAllSlotsAux(dest, m, op) + of nkNone: assert(false) proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp) = var d = cast[TAddress](dest) if dest == nil: return # nothing to do if ntfNoRefs notin mt.flags: case mt.Kind - of tyArray, tyArrayConstr, tyOpenArray: - for i in 0..(mt.size div mt.base.size)-1: - forAllChildrenAux(cast[pointer](d +% i *% mt.base.size), mt.base, op) of tyRef, tyString, tySequence: # leaf: doOperation(cast[ppointer](d)[], op) of tyObject, tyTuple, tyPureObject: forAllSlotsAux(dest, mt.node, op) + of tyArray, tyArrayConstr, tyOpenArray: + for i in 0..(mt.size div mt.base.size)-1: + forAllChildrenAux(cast[pointer](d +% i *% mt.base.size), mt.base, op) else: nil proc forAllChildren(cell: PCell, op: TWalkOp) = assert(cell != nil) assert(cell.typ != nil) + assert cell.typ.kind in {tyRef, tySequence, tyString} case cell.typ.Kind of tyRef: # common case forAllChildrenAux(cellToUsr(cell), cell.typ.base, op) @@ -329,14 +330,57 @@ proc forAllChildren(cell: PCell, op: TWalkOp) = for i in 0..s.len-1: forAllChildrenAux(cast[pointer](d +% i *% cell.typ.base.size +% GenericSeqSize), cell.typ.base, op) - of tyString: nil - else: assert(false) + else: nil proc checkCollection {.inline.} = # checks if a collection should be done if recGcLock == 0: collectCT(gch) +proc addNewObjToZCT(res: PCell) {.inline.} = + # we check the last 8 entries (cache line) for a slot that could be reused. + # In 63% of all cases we succeed here! But we have to optimize the heck + # out of this small linear search so that ``newObj`` is not slowed down. + # + # Slots to try cache hit + # 1 32% + # 4 59% + # 8 63% + # 16 66% + # all slots 68% + var L = gch.zct.len + var d = gch.zct.d + when true: + # loop unrolled for performance: + template replaceZctEntry(i: expr) = + c = d[i] + if c.refcount >=% rcIncrement: + c.refcount = c.refcount and not colorMask + d[i] = res + return + if L > 8: + var c: PCell + replaceZctEntry(L-1) + replaceZctEntry(L-2) + replaceZctEntry(L-3) + replaceZctEntry(L-4) + replaceZctEntry(L-5) + replaceZctEntry(L-6) + replaceZctEntry(L-7) + replaceZctEntry(L-8) + add(gch.zct, res) + else: + d[L] = res + inc(gch.zct.len) + else: + for i in countdown(L-1, max(0, L-8)): + var c = d[i] + if c.refcount >=% rcIncrement: + c.refcount = c.refcount and not colorMask + d[i] = res + return + add(gch.zct, res) + proc newObj(typ: PNimType, size: int): pointer {.compilerRtl.} = # generates a new object and sets its reference counter to 0 aquire(gch) @@ -354,18 +398,7 @@ proc newObj(typ: PNimType, size: int): pointer {.compilerRtl.} = res.refcount = rcZct # refcount is zero, but mark it to be in the ZCT assert(isAllocatedPtr(allocator, res)) # its refcount is zero, so add it to the ZCT: - block addToZCT: - # we check the last 8 entries (cache line) for a slot - # that could be reused - var L = gch.zct.len - var d = gch.zct.d - for i in countdown(L-1, max(0, L-8)): - var c = d[i] - if c.refcount >=% rcIncrement: - c.refcount = c.refcount and not colorMask - d[i] = res - break addToZCT - add(gch.zct, res) + addNewObjToZCT(res) when logGC: writeCell("new cell", res) gcTrace(res, csAllocated) release(gch) diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim index de604869b..bd377c5df 100755 --- a/lib/system/mmdisp.nim +++ b/lib/system/mmdisp.nim @@ -1,7 +1,7 @@ # # # Nimrod's Runtime Library -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. diff --git a/todo.txt b/todo.txt index 75a347e5d..1f1c31301 100755 --- a/todo.txt +++ b/todo.txt @@ -1,11 +1,13 @@ +* thread support: threadvar on Windows seems broken; + add --deadlock_prevention:on|off switch - implicit ref/ptr->var conversion -- warning for implicit openArray -> varargs convention -- implement explicit varargs High priority (version 0.9.0) ============================= +- warning for implicit openArray -> varargs convention +- implement explicit varargs - tests: run modules that contain "#RUN_ME", compile the other modules; run the GC tests - fix implicit generic routines @@ -32,11 +34,8 @@ To implement * hash tables and sets; count tables; ordered dicts * distinct types for array/seq indexes - * implement closures for the C code generator * GC: marker procs for native Nimrod GC and Boehm GC -* thread support: threadvar on Windows seems broken; - add --deadlock_prevention:on|off switch * built-in serialization |