summaryrefslogtreecommitdiffstats
path: root/generic/tclBasic.c
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2007-11-09 21:35:16 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2007-11-09 21:35:16 (GMT)
commitb4735e76da5d332e785a396168efb7230a88d8fe (patch)
treeeb56f5290785cb8ac4ee8de28f240ced1a4fe001 /generic/tclBasic.c
parent2ebefee1b05df6c41125e6bc8ed768c0cc4f50dc (diff)
downloadtcl-b4735e76da5d332e785a396168efb7230a88d8fe.zip
tcl-b4735e76da5d332e785a396168efb7230a88d8fe.tar.gz
tcl-b4735e76da5d332e785a396168efb7230a88d8fe.tar.bz2
* generic/tclAsync.c:
* generic/tclBasic.c: * generic/tclExecute.c: * generic/tclInt.h: * generic/tclUnixInit.c: * generic/tclUnixPort.h: new fields in interp (ekeko!) to cache TSD data that is accessed at each command invocation, access macros to replace Tcl_AsyncReady and TclpCheckStackSpace by much faster variants [Patch 1829248]
Diffstat (limited to 'generic/tclBasic.c')
-rw-r--r--generic/tclBasic.c53
1 files changed, 49 insertions, 4 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 69f1e98..222261a 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.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: tclBasic.c,v 1.270 2007/09/25 20:27:17 dkf Exp $
+ * RCS: @(#) $Id: tclBasic.c,v 1.271 2007/11/09 21:35:17 msofer Exp $
*/
#include "tclInt.h"
@@ -333,6 +333,35 @@ static const OpCmdInfo mathOpCmds[] = {
{ NULL, NULL, NULL,
{0}, NULL }
};
+
+
+#ifdef TCL_NO_STACK_CHECK
+#define CheckStackSpace(interp, localIntPtr) 1
+#else /* stack checlk enabled */
+#ifdef _TCLUNIXPORT
+/*
+ * A unix system: cache the stack check parameters.
+ */
+
+static int stackGrowsDown = 1;
+
+#define CheckStackSpace(iPtr, localIntPtr) \
+ (stackGrowsDown \
+ ? ((localIntPtr) > (iPtr)->stackBound) \
+ : ((localIntPtr) < (iPtr)->stackBound) \
+ )
+#else /* not unix */
+/*
+ * FIXME: can we do something similar for other platforms, especially windows?
+ */
+
+#define TclpGetCStackParams(foo) 1;
+#define CheckStackSpace(interp, localIntPtr) \
+ TclpCheckStackSpace()
+#endif
+#endif
+
+
/*
*----------------------------------------------------------------------
@@ -572,6 +601,20 @@ Tcl_CreateInterp(void)
TclInitLimitSupport(interp);
/*
+ * Initialise the thread-specific data ekeko.
+ */
+
+#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
+ iPtr->allocCache = TclpGetAllocCache();
+#else
+ iPtr->allocCache = NULL;
+#endif
+ iPtr->pendingObjDataPtr = NULL;
+ iPtr->asyncReadyPtr = TclGetAsyncReadyPtr();
+
+ stackGrowsDown = TclpGetCStackParams(&iPtr->stackBound);
+
+ /*
* Create the core commands. Do it here, rather than calling
* Tcl_CreateCommand, because it's faster (there's no need to check for a
* pre-existing command by the same name). If a command has a Tcl_CmdProc
@@ -3376,6 +3419,7 @@ int
TclInterpReady(
Tcl_Interp *interp)
{
+ int localInt; /* used for checking the stack */
register Interp *iPtr = (Interp *) interp;
/*
@@ -3404,7 +3448,7 @@ TclInterpReady(
*/
if (((iPtr->numLevels) > iPtr->maxNestingDepth)
- || (TclpCheckStackSpace() == 0)) {
+ || (CheckStackSpace(iPtr, &localInt) == 0)) {
Tcl_AppendResult(interp,
"too many nested evaluations (infinite loop?)", NULL);
return TCL_ERROR;
@@ -3471,7 +3515,7 @@ TclEvalObjvInternal(
Namespace *savedNsPtr = NULL;
Namespace *lookupNsPtr = iPtr->lookupNsPtr;
Tcl_Obj *commandPtr = NULL;
-
+
if (TclInterpReady(interp) == TCL_ERROR) {
return TCL_ERROR;
}
@@ -3615,7 +3659,8 @@ TclEvalObjvInternal(
TCL_DTRACE_CMD_RETURN(TclGetString(objv[0]), code);
}
}
- if (Tcl_AsyncReady()) {
+
+ if (TclAsyncReady(iPtr)) {
code = Tcl_AsyncInvoke(interp, code);
}
if (code == TCL_OK && TclLimitReady(iPtr->limit)) {