added 'system.shallow'

This commit is contained in:
Araq 2012-02-09 20:13:36 +01:00
commit fb35b855d5
9 changed files with 85 additions and 68 deletions

View file

@ -411,7 +411,9 @@ var
proc newFileInfo(fullPath, projPath: string): TFileInfo = proc newFileInfo(fullPath, projPath: string): TFileInfo =
result.fullPath = fullPath result.fullPath = fullPath
shallow(result.fullPath)
result.projPath = projPath result.projPath = projPath
shallow(result.projPath)
proc fileInfoIdx*(filename: string): int32 = proc fileInfoIdx*(filename: string): int32 =
var var
@ -420,6 +422,7 @@ proc fileInfoIdx*(filename: string): int32 =
try: try:
canon = canonicalizePath(filename) canon = canonicalizePath(filename)
shallow(canon)
except: except:
canon = filename canon = filename
# The compiler uses "filenames" such as `command line` or `stdin` # The compiler uses "filenames" such as `command line` or `stdin`

View file

@ -15,7 +15,7 @@ const
defaultAsmMarkerSymbol* = '!' defaultAsmMarkerSymbol* = '!'
VersionMajor* = 0 VersionMajor* = 0
VersionMinor* = 8 VersionMinor* = 8
VersionPatch* = 14 VersionPatch* = 15
VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch
RodFileVersion* = "1209" # modify this if the rod-format changes! RodFileVersion* = "1209" # modify this if the rod-format changes!

View file

@ -1507,7 +1507,7 @@ Syntax::
Example: Example:
.. code-block:: nimrod .. code-block:: nimrod
proc p(x, y: int): int {.optional.} = proc p(x, y: int): int =
return x + y return x + y
discard p(3, 4) # discard the return value of `p` discard p(3, 4) # discard the return value of `p`
@ -3473,6 +3473,8 @@ a `thead-local`:idx: variable then:
Actor model Actor model
----------- -----------
**Caution**: This section is already outdated! XXX
Nimrod supports the `actor model`:idx: of concurrency natively: Nimrod supports the `actor model`:idx: of concurrency natively:
.. code-block:: nimrod .. code-block:: nimrod

View file

@ -1,5 +1,5 @@
In this directory you will find several examples for how to use the Nimrod In this directory you will find several examples for how to use the Nimrod
library. library.
Copyright (c) 2004-2009 Andreas Rumpf. Copyright (c) 2004-2012 Andreas Rumpf.
All rights reserved. All rights reserved.

View file

@ -145,12 +145,14 @@ proc contains*[T](s: TSlice[T], value: T): bool {.noSideEffect, inline.} =
when not defined(EcmaScript) and not defined(NimrodVM): when not defined(EcmaScript) and not defined(NimrodVM):
type type
TGenericSeq {.compilerproc, pure.} = object TGenericSeq {.compilerproc, pure.} = object
len, space: int len, reserved: int
PGenericSeq {.exportc.} = ptr TGenericSeq PGenericSeq {.exportc.} = ptr TGenericSeq
# len and space without counting the terminating zero: # len and space without counting the terminating zero:
NimStringDesc {.compilerproc, final.} = object of TGenericSeq NimStringDesc {.compilerproc, final.} = object of TGenericSeq
data: array[0..100_000_000, char] data: array[0..100_000_000, char]
NimString = ptr NimStringDesc NimString = ptr NimStringDesc
template space(s: PGenericSeq): int = s.reserved and not seqShallowFlag
include "system/hti" include "system/hti"
@ -775,6 +777,8 @@ const
## a string that describes the application type. Possible values: ## a string that describes the application type. Possible values:
## "console", "gui", "lib". ## "console", "gui", "lib".
seqShallowFlag = 1 shl (sizeof(int)*8-1)
proc compileOption*(option: string): bool {. proc compileOption*(option: string): bool {.
magic: "CompileOption", noSideEffect.} magic: "CompileOption", noSideEffect.}
## can be used to determine an on|off compile-time option. Example: ## can be used to determine an on|off compile-time option. Example:
@ -2185,6 +2189,23 @@ template doAssert*(cond: expr, msg = "") =
raiseAssert(astToStr(cond) & ' ' & msg) raiseAssert(astToStr(cond) & ' ' & msg)
proc shallow*[T](s: seq[T]) {.noSideEffect, inline.} =
## marks a sequence `s` as `shallow`:idx:. Subsequent assignments will not
## perform deep copies of `s`. This is only useful for optimization
## purposes.
when not defined(EcmaScript) and not defined(NimrodVM):
var s = cast[PGenericSeq](s)
s.reserved = s.reserved or seqShallowFlag
proc shallow*(s: string) {.noSideEffect, inline.} =
## marks a string `s` as `shallow`:idx:. Subsequent assignments will not
## perform deep copies of `s`. This is only useful for optimization
## purposes.
when not defined(EcmaScript) and not defined(NimrodVM):
var s = cast[PGenericSeq](s)
s.reserved = s.reserved or seqShallowFlag
when defined(initDebugger): when defined(initDebugger):
initDebugger() initDebugger()

View file

@ -38,7 +38,8 @@ proc genericAssignAux(dest, src: Pointer, mt: PNimType, shallow: bool) =
of tyString: of tyString:
var x = cast[ppointer](dest) var x = cast[ppointer](dest)
var s2 = cast[ppointer](s)[] var s2 = cast[ppointer](s)[]
if s2 == nil or shallow: if s2 == nil or shallow or (
cast[PGenericSeq](s2).reserved and seqShallowFlag) != 0:
unsureAsgnRef(x, s2) unsureAsgnRef(x, s2)
else: else:
unsureAsgnRef(x, copyString(cast[NimString](s2))) unsureAsgnRef(x, copyString(cast[NimString](s2)))
@ -46,7 +47,7 @@ proc genericAssignAux(dest, src: Pointer, mt: PNimType, shallow: bool) =
var s2 = cast[ppointer](src)[] var s2 = cast[ppointer](src)[]
var seq = cast[PGenericSeq](s2) var seq = cast[PGenericSeq](s2)
var x = cast[ppointer](dest) var x = cast[ppointer](dest)
if s2 == nil or shallow: if s2 == nil or shallow or (seq.reserved and seqShallowFlag) != 0:
# this can happen! nil sequences are allowed # this can happen! nil sequences are allowed
unsureAsgnRef(x, s2) unsureAsgnRef(x, s2)
return return
@ -61,7 +62,7 @@ proc genericAssignAux(dest, src: Pointer, mt: PNimType, shallow: bool) =
mt.Base, shallow) mt.Base, shallow)
var dstseq = cast[PGenericSeq](dst) var dstseq = cast[PGenericSeq](dst)
dstseq.len = seq.len dstseq.len = seq.len
dstseq.space = seq.len dstseq.reserved = seq.len
of tyObject, tyTuple: of tyObject, tyTuple:
# we don't need to copy m_type field for tyObject, as they are equal anyway # we don't need to copy m_type field for tyObject, as they are equal anyway
genericAssignAux(dest, src, mt.node, shallow) genericAssignAux(dest, src, mt.node, shallow)

View file

@ -426,7 +426,7 @@ proc newSeq(typ: PNimType, len: int): pointer {.compilerRtl.} =
# `newObj` already uses locks, so no need for them here. # `newObj` already uses locks, so no need for them here.
result = newObj(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize)) result = newObj(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize))
cast[PGenericSeq](result).len = len cast[PGenericSeq](result).len = len
cast[PGenericSeq](result).space = len cast[PGenericSeq](result).reserved = len
proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} = proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
# generates a new object and sets its reference counter to 1 # generates a new object and sets its reference counter to 1
@ -457,7 +457,7 @@ proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
proc newSeqRC1(typ: PNimType, len: int): pointer {.compilerRtl.} = proc newSeqRC1(typ: PNimType, len: int): pointer {.compilerRtl.} =
result = newObjRC1(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize)) result = newObjRC1(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize))
cast[PGenericSeq](result).len = len cast[PGenericSeq](result).len = len
cast[PGenericSeq](result).space = len cast[PGenericSeq](result).reserved = len
proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer = proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
acquire(gch) acquire(gch)

View file

@ -43,7 +43,7 @@ proc rawNewString(space: int): NimString {.compilerProc.} =
var s = space var s = space
if s < 8: s = 7 if s < 8: s = 7
result = allocStr(sizeof(TGenericSeq) + s + 1) result = allocStr(sizeof(TGenericSeq) + s + 1)
result.space = s result.reserved = s
proc mnewString(len: int): NimString {.compilerProc.} = proc mnewString(len: int): NimString {.compilerProc.} =
result = rawNewString(len) result = rawNewString(len)
@ -73,7 +73,9 @@ proc cstrToNimstr(str: CString): NimString {.compilerProc.} =
result = toNimstr(str, c_strlen(str)) result = toNimstr(str, c_strlen(str))
proc copyString(src: NimString): NimString {.compilerProc.} = proc copyString(src: NimString): NimString {.compilerProc.} =
if src != nil: if (src.reserved and seqShallowFlag) != 0:
result = src
elif src != nil:
result = rawNewString(src.space) result = rawNewString(src.space)
result.len = src.len result.len = src.len
c_memcpy(result.data, src.data, (src.len + 1) * sizeof(Char)) c_memcpy(result.data, src.data, (src.len + 1) * sizeof(Char))
@ -87,7 +89,7 @@ proc copyStringRC1(src: NimString): NimString {.compilerProc.} =
s+1)) s+1))
else: else:
result = allocStr(sizeof(TGenericSeq) + s + 1) result = allocStr(sizeof(TGenericSeq) + s + 1)
result.space = s result.reserved = s
result.len = src.len result.len = src.len
c_memcpy(result.data, src.data, src.len + 1) c_memcpy(result.data, src.data, src.len + 1)
@ -108,13 +110,9 @@ proc addChar(s: NimString, c: char): NimString =
# is compilerproc! # is compilerproc!
result = s result = s
if result.len >= result.space: if result.len >= result.space:
result.space = resize(result.space) result.reserved = resize(result.space)
result = cast[NimString](growObj(result, result = cast[NimString](growObj(result,
sizeof(TGenericSeq) + (result.space+1) * sizeof(char))) sizeof(TGenericSeq) + (result.reserved+1) * sizeof(char)))
#var space = resize(result.space)
#result = rawNewString(space)
#copyMem(result, s, s.len * sizeof(char) + sizeof(TGenericSeq))
#result.space = space
result.data[result.len] = c result.data[result.len] = c
result.data[result.len+1] = '\0' result.data[result.len+1] = '\0'
inc(result.len) inc(result.len)
@ -156,7 +154,7 @@ proc resizeString(dest: NimString, addlen: int): NimString {.compilerproc.} =
else: # slow path: else: # slow path:
var sp = max(resize(dest.space), dest.len + addLen) var sp = max(resize(dest.space), dest.len + addLen)
result = cast[NimString](growObj(dest, sizeof(TGenericSeq) + sp + 1)) result = cast[NimString](growObj(dest, sizeof(TGenericSeq) + sp + 1))
result.space = sp result.reserved = sp
#result = rawNewString(sp) #result = rawNewString(sp)
#copyMem(result, dest, dest.len * sizeof(char) + sizeof(TGenericSeq)) #copyMem(result, dest, dest.len * sizeof(char) + sizeof(TGenericSeq))
# DO NOT UPDATE LEN YET: dest.len = newLen # DO NOT UPDATE LEN YET: dest.len = newLen
@ -188,55 +186,31 @@ proc incrSeq(seq: PGenericSeq, elemSize: int): PGenericSeq {.compilerProc.} =
# add(seq, x) generates: # add(seq, x) generates:
# seq = incrSeq(seq, sizeof(x)); # seq = incrSeq(seq, sizeof(x));
# seq[seq->len-1] = x; # seq[seq->len-1] = x;
when false: result = seq
# broken version: if result.len >= result.space:
result = seq result.reserved = resize(result.space)
if result.len >= result.space: result = cast[PGenericSeq](growObj(result, elemSize * result.reserved +
var s = resize(result.space) GenericSeqSize))
result = cast[PGenericSeq](newSeq(extGetCellType(seq), s)) inc(result.len)
genericSeqAssign(result, seq, XXX)
#copyMem(result, seq, seq.len * elemSize + GenericSeqSize)
inc(result.len)
else:
result = seq
if result.len >= result.space:
result.space = resize(result.space)
result = cast[PGenericSeq](growObj(result, elemSize * result.space +
GenericSeqSize))
# set new elements to zero:
#var s = cast[TAddress](result)
#zeroMem(cast[pointer](s + GenericSeqSize + (result.len * elemSize)),
# (result.space - result.len) * elemSize)
# for i in len .. space-1:
# seq->data[i] = 0
inc(result.len)
proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {. proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
compilerRtl.} = compilerRtl.} =
when false: result = seq
# broken version: if result.space < newLen:
result = seq result.reserved = max(resize(result.space), newLen)
if result.space < newLen: result = cast[PGenericSeq](growObj(result, elemSize * result.reserved +
var s = max(resize(result.space), newLen) GenericSeqSize))
result = cast[PGenericSeq](newSeq(extGetCellType(seq), s)) elif newLen < result.len:
result.len = newLen # we need to decref here, otherwise the GC leaks!
else: when not defined(boehmGC) and not defined(nogc):
result = seq for i in newLen..result.len-1:
if result.space < newLen: forAllChildrenAux(cast[pointer](cast[TAddress](result) +%
result.space = max(resize(result.space), newLen) GenericSeqSize +% (i*%elemSize)),
result = cast[PGenericSeq](growObj(result, elemSize * result.space + extGetCellType(result).base, waZctDecRef)
GenericSeqSize)) # and set the memory to nil:
elif newLen < result.len: zeroMem(cast[pointer](cast[TAddress](result) +% GenericSeqSize +%
# we need to decref here, otherwise the GC leaks! (newLen*%elemSize)), (result.len-%newLen) *% elemSize)
when not defined(boehmGC) and not defined(nogc): result.len = newLen
for i in newLen..result.len-1:
forAllChildrenAux(cast[pointer](cast[TAddress](result) +%
GenericSeqSize +% (i*%elemSize)),
extGetCellType(result).base, waZctDecRef)
# and set the memory to nil:
zeroMem(cast[pointer](cast[TAddress](result) +% GenericSeqSize +%
(newLen*%elemSize)), (result.len-%newLen) *% elemSize)
result.len = newLen
# --------------- other string routines ---------------------------------- # --------------- other string routines ----------------------------------
proc nimIntToStr(x: int): string {.compilerRtl.} = proc nimIntToStr(x: int): string {.compilerRtl.} =

View file

@ -2,10 +2,26 @@
News News
==== ====
2012-XX-XX Version 0.8.XX released
==================================
Version 0.8.XX has been released! Get it `here <download.html>`_.
Bugfixes
--------
Library Additions
-----------------
- Added ``system.shallow`` that can be used to speed up string and sequence
assignments.
2012-02-09 Version 0.8.14 released 2012-02-09 Version 0.8.14 released
================================== ==================================
Version 0.8.14 has been released! Get it `here <download.html>`_. Version 0.8.14 has been released!
Bugfixes Bugfixes
-------- --------