diff options
author | Miguel Sofer <miguel.sofer@gmail.com> | 2015-10-24 21:52:12 (GMT) |
---|---|---|
committer | Miguel Sofer <miguel.sofer@gmail.com> | 2015-10-24 21:52:12 (GMT) |
commit | 8ac915184090c5219ee491442969c426c734cfeb (patch) | |
tree | b4e4b662888e8e4d74808c207837488adbd49c1d /generic | |
parent | fc05f351f9478572fd86efa3a864267ba9ddd6ba (diff) | |
download | tcl-8ac915184090c5219ee491442969c426c734cfeb.zip tcl-8ac915184090c5219ee491442969c426c734cfeb.tar.gz tcl-8ac915184090c5219ee491442969c426c734cfeb.tar.bz2 |
(by drh) micro-opt of INST_LOAD_SCALAR1 (the hottest instruction) in the non-varLink (most frequent) case
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclExecute.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 853c0d6..4292479 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -3202,20 +3202,28 @@ TEBCresume( case INST_LOAD_SCALAR1: instLoadScalar1: + /* + * micro-optimization by drh: eliminate a compare-and-jump on the + * hottest path (no var link), at the cost of adding a few comparisons + * in the less frequent cases (var links: upvar, global, + * variable). We used to follow links first (causing a C&J in the + * non-link case), now we check for direct-readability first + */ + opnd = TclGetUInt1AtPtr(pc+1); varPtr = LOCAL(opnd); - while (TclIsVarLink(varPtr)) { - varPtr = varPtr->value.linkPtr; - } - TRACE(("%u => ", opnd)); - if (TclIsVarDirectReadable(varPtr)) { - /* - * No errors, no traces: just get the value. - */ - - objResultPtr = varPtr->value.objPtr; - TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); - NEXT_INST_F(2, 0, 1); + while (1) { + if (TclIsVarDirectReadable(varPtr)) { + TRACE(("%u => ", opnd)); + objResultPtr = varPtr->value.objPtr; + TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); + NEXT_INST_F(2, 0, 1); + } + if (TclIsVarLink(varPtr)) { + varPtr = varPtr->value.linkPtr; + continue; + } + break; } pcAdjustment = 2; cleanup = 0; |