summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2010-04-30 08:29:40 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2010-04-30 08:29:40 (GMT)
commit24e16718fb60e1a29dfe2c5c6f0a240de327f172 (patch)
tree239c39aa5e3e914869f4b0f2c08bb67c2b7cebe8
parentfef563336c6dc5ae1b57a63431daf9ed77de8f27 (diff)
downloadtcl-24e16718fb60e1a29dfe2c5c6f0a240de327f172.zip
tcl-24e16718fb60e1a29dfe2c5c6f0a240de327f172.tar.gz
tcl-24e16718fb60e1a29dfe2c5c6f0a240de327f172.tar.bz2
* generic/tclExecute.c (TclExecuteByteCode): Add peephole optimization
of the fact that INST_DICT_FIRST and INST_DICT_NEXT always have a conditional jump afterwards.
-rw-r--r--ChangeLog4
-rw-r--r--generic/tclExecute.c27
2 files changed, 30 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 2c4915e..de68e01 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2010-04-30 Donal K. Fellows <dkf@users.sf.net>
+ * generic/tclExecute.c (TclExecuteByteCode): Add peephole optimization
+ of the fact that INST_DICT_FIRST and INST_DICT_NEXT always have a
+ conditional jump afterwards.
+
* generic/tclBasic.c (TclNRYieldObjCmd, TclNRYieldmObjCmd)
(NRInterpCoroutine): Replace magic values for formal argument counts
for coroutine command implementations with #defines, for an increase
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 04c47f4..d6dd352 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -14,7 +14,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclExecute.c,v 1.481 2010/04/28 11:50:53 nijtmans Exp $
+ * RCS: @(#) $Id: tclExecute.c,v 1.482 2010/04/30 08:29:40 dkf Exp $
*/
#include "tclInt.h"
@@ -6088,6 +6088,31 @@ TclExecuteByteCode(
PUSH_OBJECT(valuePtr);
PUSH_OBJECT(keyPtr);
}
+
+#ifndef TCL_COMPILE_DEBUG
+ /*
+ * The INST_DICT_FIRST and INST_DICT_NEXT instructsions are always
+ * followed by a conditional jump, so we can take advantage of this to
+ * do some peephole optimization (note that we're careful to not close
+ * out someone doing something else).
+ */
+
+ pc += 5;
+ switch (*pc) {
+ case INST_JUMP_FALSE1:
+ NEXT_INST_F((done ? 2 : TclGetInt1AtPtr(pc+1)), 0, 0);
+ case INST_JUMP_FALSE4:
+ NEXT_INST_F((done ? 5 : TclGetInt4AtPtr(pc+1)), 0, 0);
+ case INST_JUMP_TRUE1:
+ NEXT_INST_F((done ? TclGetInt1AtPtr(pc+1) : 2), 0, 0);
+ case INST_JUMP_TRUE4:
+ NEXT_INST_F((done ? TclGetInt4AtPtr(pc+1) : 5), 0, 0);
+ default:
+ pc -= 5;
+ /* fall through to non-debug handling */
+ }
+#endif
+
TRACE_APPEND(("\"%.30s\" \"%.30s\" %d",
O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), done));
objResultPtr = TCONST(done);