summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2005-04-01 19:08:04 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2005-04-01 19:08:04 (GMT)
commitfbb5749d9fa84503a3480ab6e24a9f0436772110 (patch)
tree3bdd1551c70328f23d70c21440ec239027408d1c
parent5950047f06d1ebff15c5829817ec1ba437dacc60 (diff)
downloadtcl-fbb5749d9fa84503a3480ab6e24a9f0436772110.zip
tcl-fbb5749d9fa84503a3480ab6e24a9f0436772110.tar.gz
tcl-fbb5749d9fa84503a3480ab6e24a9f0436772110.tar.bz2
slight reduction in cost of INST_START_CMD
-rw-r--r--ChangeLog16
-rw-r--r--generic/tclExecute.c36
2 files changed, 36 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 1d33179..d11b7ad 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,18 +1,16 @@
2005-04-01 Miguel Sofer <msofer@users.sf.net>
* generic/tclExecute.c:
- * generic/tclInt.h: ExecEnv now stores two Tcl_Obj* pointing to
- the constants "0" and "1", for use by TEBC.
-
-2005-04-01 Miguel Sofer <msofer@users.sf.net>
-
- * generic/tclExecute.c:
* generic/tclInt.h:
* generic/tclObj.c:
- * generic/tclStringObj.c: defined new internal macros for creating
- and setting frequently used obj types (int,long, wideInt, double,
+ * generic/tclStringObj.c:
+ (1) defined new internal macros for creating and setting
+ frequently used obj types (int,long, wideInt, double,
string). Changed TEBC to use eg 'TclNewIntObj(objPtr, i)' to avoid
- the function call in 'objPtr = Tcl_NewIntObj(i)'
+ the function call in 'objPtr = Tcl_NewIntObj(i)'
+ (2) ExecEnv now stores two Tcl_Obj* pointing to the constants "0"
+ and "1", for use by TEBC.
+ (3) slight reduction in cost of INST_START_CMD
2005-03-31 Miguel Sofer <msofer@users.sf.net>
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 6953ff5..a66f278 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -11,7 +11,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.175 2005/04/01 16:18:55 msofer Exp $
+ * RCS: @(#) $Id: tclExecute.c,v 1.176 2005/04/01 19:08:30 msofer Exp $
*/
#include "tclInt.h"
@@ -209,7 +209,8 @@ long tclObjsShared[TCL_MAX_SHARED_OBJ_STATS] = { 0, 0, 0, 0, 0 };
tosPtr = eePtr->tosPtr
#define DECACHE_STACK_INFO() \
- eePtr->tosPtr = tosPtr
+ eePtr->tosPtr = tosPtr;\
+ checkInterp = 1
/*
@@ -1096,7 +1097,7 @@ TclCompEvalObj(interp, objPtr)
*
*----------------------------------------------------------------------
*/
-
+
static int
TclExecuteByteCode(interp, codePtr)
Tcl_Interp *interp; /* Token for command interpreter. */
@@ -1131,7 +1132,9 @@ TclExecuteByteCode(interp, codePtr)
int instructionCount = 0; /* Counter that is used to work out
* when to call Tcl_AsyncReady() */
Tcl_Obj *expandNestList = NULL;
-
+ int checkInterp = 0; /* Indicates when a check of interp readyness
+ * is necessary. Set by DECACHE_STACK_INFO() */
+
/*
* Transfer variables - needed only between opcodes, but not
* while executing an instruction.
@@ -1407,13 +1410,32 @@ TclExecuteByteCode(interp, codePtr)
* Remark that if the interpreter is marked for deletion
* its compileEpoch is modified, so that the epoch
* check also verifies that the interp is not deleted.
+ * If no outside call has been made since the last check, it is safe
+ * to omit the check.
*/
iPtr->cmdCount++;
- if (((codePtr->compileEpoch == iPtr->compileEpoch)
- && (codePtr->nsEpoch == namespacePtr->resolverEpoch))
- || (codePtr->flags & TCL_BYTECODE_PRECOMPILED)) {
+ if (!checkInterp ||
+ (((codePtr->compileEpoch == iPtr->compileEpoch)
+ && (codePtr->nsEpoch == namespacePtr->resolverEpoch))
+ || (codePtr->flags & TCL_BYTECODE_PRECOMPILED))) {
+#if !TCL_COMPILE_DEBUG
+ /*
+ * Peephole optimisations: check if there are several
+ * INST_START_CMD in a row. Many commands start by pushing a
+ * literal argument or command name; optimise that case too.
+ */
+
+ while (*(pc += 5) == INST_START_CMD) {
+ iPtr->cmdCount++;
+ }
+ if (*pc == INST_PUSH1) {
+ goto instPush1Peephole;
+ }
+ NEXT_INST_F(0, 0, 0);
+#else
NEXT_INST_F(5, 0, 0);
+#endif
} else {
char *bytes;
int length, opnd;