summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2008-08-20 15:41:20 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2008-08-20 15:41:20 (GMT)
commitfaa29c2fefd6d227c3dad33bb98df241a38006bf (patch)
tree47c02de5808411400f650d853de4bcf335527b8c /generic
parent37a1fa926eb75cc4aee1113d06f594adaa5e6f20 (diff)
downloadtcl-faa29c2fefd6d227c3dad33bb98df241a38006bf.zip
tcl-faa29c2fefd6d227c3dad33bb98df241a38006bf.tar.gz
tcl-faa29c2fefd6d227c3dad33bb98df241a38006bf.tar.bz2
Fix performance bug introduced by fix of [Bug 2037727]
Diffstat (limited to 'generic')
-rw-r--r--generic/tclCompile.c11
-rw-r--r--generic/tclInt.h12
-rw-r--r--generic/tclNamesp.c12
-rw-r--r--generic/tclOO.c10
-rw-r--r--generic/tclOOMethod.c29
5 files changed, 53 insertions, 21 deletions
diff --git a/generic/tclCompile.c b/generic/tclCompile.c
index 2d040b4..d79ba9d 100644
--- a/generic/tclCompile.c
+++ b/generic/tclCompile.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: tclCompile.c,v 1.154 2008/07/25 22:11:20 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclCompile.c,v 1.155 2008/08/20 15:41:21 dkf Exp $
*/
#include "tclInt.h"
@@ -1350,6 +1350,7 @@ TclCompileScript(
if ((cmdPtr != NULL)
&& (cmdPtr->compileProc != NULL)
+ && !(cmdPtr->nsPtr->flags&NS_SUPPRESS_COMPILATION)
&& !(cmdPtr->flags & CMD_HAS_EXEC_TRACES)
&& !(iPtr->flags & DONT_COMPILE_CMDS_INLINE)) {
int savedNumCmds = envPtr->numCommands;
@@ -1474,10 +1475,10 @@ TclCompileScript(
tokenPtr[1].start, tokenPtr[1].size);
if (eclPtr->type == TCL_LOCATION_SOURCE) {
- EnterCmdWordIndex (eclPtr,
- envPtr->literalArrayPtr[objIndex].objPtr,
- envPtr->codeNext - envPtr->codeStart,
- wordIdx);
+ EnterCmdWordIndex(eclPtr,
+ envPtr->literalArrayPtr[objIndex].objPtr,
+ envPtr->codeNext - envPtr->codeStart,
+ wordIdx);
}
}
TclEmitPush(objIndex, envPtr);
diff --git a/generic/tclInt.h b/generic/tclInt.h
index c40220f..811278b 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -15,7 +15,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclInt.h,v 1.391 2008/08/17 19:37:12 msofer Exp $
+ * RCS: @(#) $Id: tclInt.h,v 1.392 2008/08/20 15:41:24 dkf Exp $
*/
#ifndef _TCLINT
@@ -361,13 +361,17 @@ struct NamespacePathEntry {
* unit that refers to the namespace has been freed (i.e., when
* the namespace's refCount is 0), the namespace's storage will
* be freed.
- * NS_KILLED 1 means that TclTeardownNamespace has already been called on
- * this namespace and it should not be called again [Bug 1355942]
+ * NS_KILLED - 1 means that TclTeardownNamespace has already been called on
+ * this namespace and it should not be called again [Bug 1355942]
+ * NS_SUPPRESS_COMPILATION -
+ * Marks the commands in this namespace for not being compiled,
+ * forcing them to be looked up every time.
*/
#define NS_DYING 0x01
#define NS_DEAD 0x02
-#define NS_KILLED 0x04
+#define NS_KILLED 0x04
+#define NS_SUPPRESS_COMPILATION 0x08
/*
* Flags passed to TclGetNamespaceForQualName:
diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c
index c9f022d..535f8cc 100644
--- a/generic/tclNamesp.c
+++ b/generic/tclNamesp.c
@@ -23,7 +23,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclNamesp.c,v 1.174 2008/08/03 17:33:12 msofer Exp $
+ * RCS: @(#) $Id: tclNamesp.c,v 1.175 2008/08/20 15:41:25 dkf Exp $
*/
#include "tclInt.h"
@@ -893,6 +893,16 @@ Tcl_CreateNamespace(
Tcl_DStringFree(&buffer2);
/*
+ * If compilation of commands originating from the parent NS is
+ * suppressed, suppress it for commands originating in this one too.
+ */
+
+ if (nsPtr->parentPtr != NULL &&
+ nsPtr->parentPtr->flags & NS_SUPPRESS_COMPILATION) {
+ nsPtr->flags |= NS_SUPPRESS_COMPILATION;
+ }
+
+ /*
* Return a pointer to the new namespace.
*/
diff --git a/generic/tclOO.c b/generic/tclOO.c
index 4db39c3..95926f2 100644
--- a/generic/tclOO.c
+++ b/generic/tclOO.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclOO.c,v 1.14 2008/08/06 21:23:14 dgp Exp $
+ * RCS: @(#) $Id: tclOO.c,v 1.15 2008/08/20 15:41:26 dkf Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -455,6 +455,14 @@ AllocObject(
TclSetNsPath((Namespace *) oPtr->namespacePtr, 1, &fPtr->helpersNs);
/*
+ * Suppress use of compiled versions of the commands in this object's
+ * namespace and its children; causes wrong behaviour without expensive
+ * recompilation. [Bug 2037727]
+ */
+
+ ((Namespace *) oPtr->namespacePtr)->flags |= NS_SUPPRESS_COMPILATION;
+
+ /*
* Fill in the rest of the non-zero/NULL parts of the structure.
*/
diff --git a/generic/tclOOMethod.c b/generic/tclOOMethod.c
index c977a3b..0110283 100644
--- a/generic/tclOOMethod.c
+++ b/generic/tclOOMethod.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclOOMethod.c,v 1.13 2008/08/12 17:51:03 dgp Exp $
+ * RCS: @(#) $Id: tclOOMethod.c,v 1.14 2008/08/20 15:41:26 dkf Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -16,6 +16,7 @@
#endif
#include "tclInt.h"
#include "tclOOInt.h"
+#include "tclCompile.h"
/*
* Structure used to help delay computing names of objects or classes for
@@ -787,17 +788,25 @@ PushMethodCallFrame(
fdPtr->cmd.clientData = &fdPtr->efi;
pmPtr->procPtr->cmdPtr = &fdPtr->cmd;
- /*
- * [Bug 2037727] Always call TclProcCompileProc so that we check not
- * only that we have bytecode, but also that it remains valid.
+ /*
+ * [Bug 2037727] Always call TclProcCompileProc so that we check not only
+ * that we have bytecode, but also that it remains valid. Note that we set
+ * the namespace of the code here directly; this is a hack, but the
+ * alternative is *so* slow...
*/
- result = TclProcCompileProc(interp, pmPtr->procPtr,
- pmPtr->procPtr->bodyPtr, (Namespace *) nsPtr,
- "body of method", namePtr);
- if (result != TCL_OK) {
- return result;
- }
+ if (pmPtr->procPtr->bodyPtr->typePtr == &tclByteCodeType) {
+ ByteCode *codePtr =
+ pmPtr->procPtr->bodyPtr->internalRep.otherValuePtr;
+
+ codePtr->nsPtr = nsPtr;
+ }
+ result = TclProcCompileProc(interp, pmPtr->procPtr,
+ pmPtr->procPtr->bodyPtr, (Namespace *) nsPtr, "body of method",
+ namePtr);
+ if (result != TCL_OK) {
+ return result;
+ }
/*
* Make the stack frame and fill it out with information about this call.