micro optimizations for the evaluation engine
This commit is contained in:
parent
0f2aa053d9
commit
1c0c80ef2d
4 changed files with 64 additions and 43 deletions
|
|
@ -71,20 +71,23 @@ type
|
||||||
nkDotCall, # used to temporarily flag a nkCall node;
|
nkDotCall, # used to temporarily flag a nkCall node;
|
||||||
# this is used
|
# this is used
|
||||||
# for transforming ``s.len`` to ``len(s)``
|
# for transforming ``s.len`` to ``len(s)``
|
||||||
|
|
||||||
nkCommand, # a call like ``p 2, 4`` without parenthesis
|
nkCommand, # a call like ``p 2, 4`` without parenthesis
|
||||||
nkCall, # a call like p(x, y) or an operation like +(a, b)
|
nkCall, # a call like p(x, y) or an operation like +(a, b)
|
||||||
nkCallStrLit, # a call with a string literal
|
nkCallStrLit, # a call with a string literal
|
||||||
# x"abc" has two sons: nkIdent, nkRStrLit
|
# x"abc" has two sons: nkIdent, nkRStrLit
|
||||||
# x"""abc""" has two sons: nkIdent, nkTripleStrLit
|
# x"""abc""" has two sons: nkIdent, nkTripleStrLit
|
||||||
|
nkInfix, # a call like (a + b)
|
||||||
|
nkPrefix, # a call like !a
|
||||||
|
nkPostfix, # something like a! (also used for visibility)
|
||||||
|
nkHiddenCallConv, # an implicit type conversion via a type converter
|
||||||
|
|
||||||
nkExprEqExpr, # a named parameter with equals: ''expr = expr''
|
nkExprEqExpr, # a named parameter with equals: ''expr = expr''
|
||||||
nkExprColonExpr, # a named parameter with colon: ''expr: expr''
|
nkExprColonExpr, # a named parameter with colon: ''expr: expr''
|
||||||
nkIdentDefs, # a definition like `a, b: typeDesc = expr`
|
nkIdentDefs, # a definition like `a, b: typeDesc = expr`
|
||||||
# either typeDesc or expr may be nil; used in
|
# either typeDesc or expr may be nil; used in
|
||||||
# formal parameters, var statements, etc.
|
# formal parameters, var statements, etc.
|
||||||
nkVarTuple, # a ``var (a, b) = expr`` construct
|
nkVarTuple, # a ``var (a, b) = expr`` construct
|
||||||
nkInfix, # a call like (a + b)
|
|
||||||
nkPrefix, # a call like !a
|
|
||||||
nkPostfix, # something like a! (also used for visibility)
|
|
||||||
nkPar, # syntactic (); may be a tuple constructor
|
nkPar, # syntactic (); may be a tuple constructor
|
||||||
nkCurly, # syntactic {}
|
nkCurly, # syntactic {}
|
||||||
nkCurlyExpr, # an expression like a{i}
|
nkCurlyExpr, # an expression like a{i}
|
||||||
|
|
@ -109,7 +112,6 @@ type
|
||||||
nkHiddenStdConv, # an implicit standard type conversion
|
nkHiddenStdConv, # an implicit standard type conversion
|
||||||
nkHiddenSubConv, # an implicit type conversion from a subtype
|
nkHiddenSubConv, # an implicit type conversion from a subtype
|
||||||
# to a supertype
|
# to a supertype
|
||||||
nkHiddenCallConv, # an implicit type conversion via a type converter
|
|
||||||
nkConv, # a type conversion
|
nkConv, # a type conversion
|
||||||
nkCast, # a type cast
|
nkCast, # a type cast
|
||||||
nkStaticExpr, # a static expr
|
nkStaticExpr, # a static expr
|
||||||
|
|
|
||||||
|
|
@ -451,6 +451,12 @@ proc evalFieldAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var x = result
|
var x = result
|
||||||
if x.kind != nkPar: return raiseCannotEval(c, n.info)
|
if x.kind != nkPar: return raiseCannotEval(c, n.info)
|
||||||
|
# this is performance critical:
|
||||||
|
var field = n.sons[1].sym
|
||||||
|
result = x.sons[field.position]
|
||||||
|
if result.kind == nkExprColonExpr: result = result.sons[1]
|
||||||
|
if not aliasNeeded(result, flags): result = copyTree(result)
|
||||||
|
when false:
|
||||||
var field = n.sons[1].sym
|
var field = n.sons[1].sym
|
||||||
for i in countup(0, sonsLen(x) - 1):
|
for i in countup(0, sonsLen(x) - 1):
|
||||||
var it = x.sons[i]
|
var it = x.sons[i]
|
||||||
|
|
@ -1341,13 +1347,22 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
dec(gNestedEvals)
|
dec(gNestedEvals)
|
||||||
if gNestedEvals <= 0: stackTrace(c, n, errTooManyIterations)
|
if gNestedEvals <= 0: stackTrace(c, n, errTooManyIterations)
|
||||||
case n.kind # atoms:
|
case n.kind
|
||||||
of nkEmpty: result = n
|
|
||||||
of nkSym: result = evalSym(c, n, flags)
|
of nkSym: result = evalSym(c, n, flags)
|
||||||
of nkType..nkNilLit: result = copyNode(n) # end of atoms
|
of nkType..nkNilLit:
|
||||||
of nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit, nkInfix,
|
# XXX nkStrLit is VERY common in the traces, so we should avoid
|
||||||
nkPrefix, nkPostfix:
|
# the 'copyNode' here. However, for now we cannot do this for unknown
|
||||||
|
# reasons.
|
||||||
|
result = n.copyNode
|
||||||
|
of nkAsgn, nkFastAsgn: result = evalAsgn(c, n)
|
||||||
|
of nkCommand..nkHiddenCallConv:
|
||||||
result = evalMagicOrCall(c, n)
|
result = evalMagicOrCall(c, n)
|
||||||
|
of nkDotExpr: result = evalFieldAccess(c, n, flags)
|
||||||
|
of nkBracketExpr:
|
||||||
|
result = evalArrayAccess(c, n, flags)
|
||||||
|
of nkDerefExpr, nkHiddenDeref: result = evalDeref(c, n, flags)
|
||||||
|
of nkAddr, nkHiddenAddr: result = evalAddr(c, n, flags)
|
||||||
|
of nkHiddenStdConv, nkHiddenSubConv, nkConv: result = evalConv(c, n)
|
||||||
of nkCurly, nkBracket, nkRange:
|
of nkCurly, nkBracket, nkRange:
|
||||||
# flags need to be passed here for mNAddMultiple :-(
|
# flags need to be passed here for mNAddMultiple :-(
|
||||||
# XXX this is not correct in every case!
|
# XXX this is not correct in every case!
|
||||||
|
|
@ -1370,12 +1385,6 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
a.sons[i] = result
|
a.sons[i] = result
|
||||||
result = a
|
result = a
|
||||||
of nkBracketExpr: result = evalArrayAccess(c, n, flags)
|
|
||||||
of nkDotExpr: result = evalFieldAccess(c, n, flags)
|
|
||||||
of nkDerefExpr, nkHiddenDeref: result = evalDeref(c, n, flags)
|
|
||||||
of nkAddr, nkHiddenAddr: result = evalAddr(c, n, flags)
|
|
||||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv: result = evalConv(c, n)
|
|
||||||
of nkAsgn, nkFastAsgn: result = evalAsgn(c, n)
|
|
||||||
of nkWhenStmt, nkIfStmt, nkIfExpr: result = evalIf(c, n)
|
of nkWhenStmt, nkIfStmt, nkIfExpr: result = evalIf(c, n)
|
||||||
of nkWhileStmt: result = evalWhile(c, n)
|
of nkWhileStmt: result = evalWhile(c, n)
|
||||||
of nkCaseStmt: result = evalCase(c, n)
|
of nkCaseStmt: result = evalCase(c, n)
|
||||||
|
|
@ -1414,6 +1423,9 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
result = raiseCannotEval(c, n.info)
|
result = raiseCannotEval(c, n.info)
|
||||||
of nkRefTy:
|
of nkRefTy:
|
||||||
result = evalAux(c, n.sons[0], flags)
|
result = evalAux(c, n.sons[0], flags)
|
||||||
|
of nkEmpty:
|
||||||
|
# nkEmpty occurs once in each trace that I looked at
|
||||||
|
result = n
|
||||||
else: InternalError(n.info, "evalAux: " & $n.kind)
|
else: InternalError(n.info, "evalAux: " & $n.kind)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
InternalError(n.info, "evalAux: returned nil " & $n.kind)
|
InternalError(n.info, "evalAux: returned nil " & $n.kind)
|
||||||
|
|
|
||||||
16
doc/gc.txt
16
doc/gc.txt
|
|
@ -22,6 +22,13 @@ delta-subgraph of the heap that changed since its last run.
|
||||||
The GC is only triggered in a memory allocation operation. It it not triggered
|
The GC is only triggered in a memory allocation operation. It it not triggered
|
||||||
by some timer and does not run in a background thread.
|
by some timer and does not run in a background thread.
|
||||||
|
|
||||||
|
To force a full collection call ``GC_fullCollect``. Note that it is generally
|
||||||
|
better to let the GC do its work and not enforce a full collection.
|
||||||
|
|
||||||
|
|
||||||
|
Cycle collector
|
||||||
|
===============
|
||||||
|
|
||||||
The cycle collector can be en-/disabled independently from the other parts of
|
The cycle collector can be en-/disabled independently from the other parts of
|
||||||
the GC with ``GC_enableMarkAndSweep`` and ``GC_disableMarkAndSweep``. The
|
the GC with ``GC_enableMarkAndSweep`` and ``GC_disableMarkAndSweep``. The
|
||||||
compiler analyses the types for their possibility to build cycles, but often
|
compiler analyses the types for their possibility to build cycles, but often
|
||||||
|
|
@ -30,11 +37,10 @@ it is necessary to help this analysis with the ``acyclic`` pragma (see
|
||||||
|
|
||||||
You can also use the ``acyclic`` pragma for data that is cyclic in reality and
|
You can also use the ``acyclic`` pragma for data that is cyclic in reality and
|
||||||
then break up the cycles explicitly with ``GC_addCycleRoot``. This can be a
|
then break up the cycles explicitly with ``GC_addCycleRoot``. This can be a
|
||||||
very good optimization; the Nimrod compiler itself relies on this optimization
|
very valuable optimization; the Nimrod compiler itself relies on this
|
||||||
trick to improve performance.
|
optimization trick to improve performance. Note that ``GC_addCycleRoot`` is
|
||||||
|
a quick operation; the root is only registered for the next run of the
|
||||||
To force a full collection call ``GC_fullCollect``. Note that it is generally
|
cycle collector.
|
||||||
better to let the GC do its work and not enforce a full collection.
|
|
||||||
|
|
||||||
|
|
||||||
Realtime support
|
Realtime support
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2012 Andreas Rumpf
|
# (c) Copyright 2013 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -21,9 +21,10 @@ type
|
||||||
nnkUInt16Lit, nnkUInt32Lit, nnkUInt64Lit, nnkFloatLit,
|
nnkUInt16Lit, nnkUInt32Lit, nnkUInt64Lit, nnkFloatLit,
|
||||||
nnkFloat32Lit, nnkFloat64Lit, nnkFloat128Lit, nnkStrLit, nnkRStrLit,
|
nnkFloat32Lit, nnkFloat64Lit, nnkFloat128Lit, nnkStrLit, nnkRStrLit,
|
||||||
nnkTripleStrLit, nnkNilLit, nnkMetaNode, nnkDotCall,
|
nnkTripleStrLit, nnkNilLit, nnkMetaNode, nnkDotCall,
|
||||||
nnkCommand, nnkCall, nnkCallStrLit, nnkExprEqExpr,
|
nnkCommand, nnkCall, nnkCallStrLit, nnkInfix,
|
||||||
nnkExprColonExpr, nnkIdentDefs, nnkVarTuple, nnkInfix,
|
nnkPrefix, nnkPostfix, nnkHiddenCallConv,
|
||||||
nnkPrefix, nnkPostfix, nnkPar, nnkCurly, nnkCurlyExpr,
|
nnkExprEqExpr,
|
||||||
|
nnkExprColonExpr, nnkIdentDefs, nnkVarTuple, nnkPar, nnkCurly, nnkCurlyExpr,
|
||||||
nnkBracket, nnkBracketExpr, nnkPragmaExpr, nnkRange,
|
nnkBracket, nnkBracketExpr, nnkPragmaExpr, nnkRange,
|
||||||
nnkDotExpr, nnkCheckedFieldExpr, nnkDerefExpr, nnkIfExpr,
|
nnkDotExpr, nnkCheckedFieldExpr, nnkDerefExpr, nnkIfExpr,
|
||||||
nnkElifExpr, nnkElseExpr, nnkLambda, nnkDo, nnkAccQuoted,
|
nnkElifExpr, nnkElseExpr, nnkLambda, nnkDo, nnkAccQuoted,
|
||||||
|
|
@ -31,7 +32,7 @@ type
|
||||||
nnkClosedSymChoice,
|
nnkClosedSymChoice,
|
||||||
nnkOpenSymChoice,
|
nnkOpenSymChoice,
|
||||||
nnkHiddenStdConv,
|
nnkHiddenStdConv,
|
||||||
nnkHiddenSubConv, nnkHiddenCallConv, nnkConv, nnkCast, nnkStaticExpr,
|
nnkHiddenSubConv, nnkConv, nnkCast, nnkStaticExpr,
|
||||||
nnkAddr, nnkHiddenAddr, nnkHiddenDeref, nnkObjDownConv,
|
nnkAddr, nnkHiddenAddr, nnkHiddenDeref, nnkObjDownConv,
|
||||||
nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange,
|
nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange,
|
||||||
nnkStringToCString, nnkCStringToString, nnkAsgn,
|
nnkStringToCString, nnkCStringToString, nnkAsgn,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue