micro optimizations for the evaluation engine

This commit is contained in:
Araq
2013-02-14 08:41:48 +01:00
parent 0f2aa053d9
commit 1c0c80ef2d
4 changed files with 64 additions and 43 deletions

View File

@@ -71,20 +71,23 @@ type
nkDotCall, # used to temporarily flag a nkCall node;
# this is used
# for transforming ``s.len`` to ``len(s)``
nkCommand, # a call like ``p 2, 4`` without parenthesis
nkCall, # a call like p(x, y) or an operation like +(a, b)
nkCallStrLit, # a call with a string literal
# x"abc" has two sons: nkIdent, nkRStrLit
# 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''
nkExprColonExpr, # a named parameter with colon: ''expr: expr''
nkIdentDefs, # a definition like `a, b: typeDesc = expr`
# either typeDesc or expr may be nil; used in
# formal parameters, var statements, etc.
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
nkCurly, # syntactic {}
nkCurlyExpr, # an expression like a{i}
@@ -109,7 +112,6 @@ type
nkHiddenStdConv, # an implicit standard type conversion
nkHiddenSubConv, # an implicit type conversion from a subtype
# to a supertype
nkHiddenCallConv, # an implicit type conversion via a type converter
nkConv, # a type conversion
nkCast, # a type cast
nkStaticExpr, # a static expr

View File

@@ -444,29 +444,35 @@ proc evalArrayAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
stackTrace(c, n, errIndexOutOfBounds)
else: stackTrace(c, n, errNilAccess)
proc evalFieldAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
proc evalFieldAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
# a real field access; proc calls have already been transformed
# XXX: field checks!
result = evalAux(c, n.sons[0], flags)
if isSpecial(result): return
if isSpecial(result): return
var x = result
if x.kind != nkPar: return raiseCannotEval(c, n.info)
# this is performance critical:
var field = n.sons[1].sym
for i in countup(0, sonsLen(x) - 1):
var it = x.sons[i]
if it.kind != nkExprColonExpr:
# lookup per index:
result = x.sons[field.position]
if result.kind == nkExprColonExpr: result = result.sons[1]
if not aliasNeeded(result, flags): result = copyTree(result)
return
#InternalError(it.info, "evalFieldAccess")
if it.sons[0].sym.name.id == field.name.id:
result = x.sons[i].sons[1]
if not aliasNeeded(result, flags): result = copyTree(result)
return
stackTrace(c, n, errFieldXNotFound, field.name.s)
result = emptyNode
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
for i in countup(0, sonsLen(x) - 1):
var it = x.sons[i]
if it.kind != nkExprColonExpr:
# lookup per index:
result = x.sons[field.position]
if result.kind == nkExprColonExpr: result = result.sons[1]
if not aliasNeeded(result, flags): result = copyTree(result)
return
#InternalError(it.info, "evalFieldAccess")
if it.sons[0].sym.name.id == field.name.id:
result = x.sons[i].sons[1]
if not aliasNeeded(result, flags): result = copyTree(result)
return
stackTrace(c, n, errFieldXNotFound, field.name.s)
result = emptyNode
proc evalAsgn(c: PEvalContext, n: PNode): PNode =
var a = n.sons[0]
@@ -1341,14 +1347,23 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
result = emptyNode
dec(gNestedEvals)
if gNestedEvals <= 0: stackTrace(c, n, errTooManyIterations)
case n.kind # atoms:
of nkEmpty: result = n
case n.kind
of nkSym: result = evalSym(c, n, flags)
of nkType..nkNilLit: result = copyNode(n) # end of atoms
of nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit, nkInfix,
nkPrefix, nkPostfix:
of nkType..nkNilLit:
# XXX nkStrLit is VERY common in the traces, so we should avoid
# 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)
of nkCurly, nkBracket, nkRange:
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:
# flags need to be passed here for mNAddMultiple :-(
# XXX this is not correct in every case!
var a = copyNode(n)
@@ -1370,12 +1385,6 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
if isSpecial(result): return
a.sons[i] = result
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 nkWhileStmt: result = evalWhile(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)
of nkRefTy:
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)
if result == nil:
InternalError(n.info, "evalAux: returned nil " & $n.kind)

View File

@@ -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
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 GC with ``GC_enableMarkAndSweep`` and ``GC_disableMarkAndSweep``. The
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
then break up the cycles explicitly with ``GC_addCycleRoot``. This can be a
very good optimization; the Nimrod compiler itself relies on this optimization
trick to improve performance.
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.
very valuable optimization; the Nimrod compiler itself relies on this
optimization trick to improve performance. Note that ``GC_addCycleRoot`` is
a quick operation; the root is only registered for the next run of the
cycle collector.
Realtime support

View File

@@ -1,7 +1,7 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2012 Andreas Rumpf
# (c) Copyright 2013 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
@@ -21,9 +21,10 @@ type
nnkUInt16Lit, nnkUInt32Lit, nnkUInt64Lit, nnkFloatLit,
nnkFloat32Lit, nnkFloat64Lit, nnkFloat128Lit, nnkStrLit, nnkRStrLit,
nnkTripleStrLit, nnkNilLit, nnkMetaNode, nnkDotCall,
nnkCommand, nnkCall, nnkCallStrLit, nnkExprEqExpr,
nnkExprColonExpr, nnkIdentDefs, nnkVarTuple, nnkInfix,
nnkPrefix, nnkPostfix, nnkPar, nnkCurly, nnkCurlyExpr,
nnkCommand, nnkCall, nnkCallStrLit, nnkInfix,
nnkPrefix, nnkPostfix, nnkHiddenCallConv,
nnkExprEqExpr,
nnkExprColonExpr, nnkIdentDefs, nnkVarTuple, nnkPar, nnkCurly, nnkCurlyExpr,
nnkBracket, nnkBracketExpr, nnkPragmaExpr, nnkRange,
nnkDotExpr, nnkCheckedFieldExpr, nnkDerefExpr, nnkIfExpr,
nnkElifExpr, nnkElseExpr, nnkLambda, nnkDo, nnkAccQuoted,
@@ -31,7 +32,7 @@ type
nnkClosedSymChoice,
nnkOpenSymChoice,
nnkHiddenStdConv,
nnkHiddenSubConv, nnkHiddenCallConv, nnkConv, nnkCast, nnkStaticExpr,
nnkHiddenSubConv, nnkConv, nnkCast, nnkStaticExpr,
nnkAddr, nnkHiddenAddr, nnkHiddenDeref, nnkObjDownConv,
nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange,
nnkStringToCString, nnkCStringToString, nnkAsgn,