From 580724e069e7de6cbe19b235d60d6a6abe6712e3 Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Tue, 29 Jul 2008 20:53:20 +0000 Subject: a timid start at cleaning up --- ChangeLog | 4 ++ generic/tclBasic.c | 119 +++++++++++++++++++++++++-------------------------- generic/tclExecute.c | 25 +---------- generic/tclNRE.h | 21 +++------ 4 files changed, 72 insertions(+), 97 deletions(-) diff --git a/ChangeLog b/ChangeLog index e471e99..942c603 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2008-07-29 Miguel Sofer + * generic/tclBasic.c: Clean up + * generic/tclNRE.h: + * generic/tclExecute.c: + * generic/tclBasic.c: Made use of the thread's alloc cache * generic/tclInt.h: stored in the ekeko at interp creation * generic/tclNRE.h: to avoid hitting the TSD each time an diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 3e5c1cf..0524d5b 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -16,7 +16,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.334 2008/07/29 18:19:10 msofer Exp $ + * RCS: @(#) $Id: tclBasic.c,v 1.335 2008/07/29 20:53:21 msofer Exp $ */ #include "tclInt.h" @@ -5661,34 +5661,35 @@ TclNREvalObjEx( int numSrcBytes; int result; int allowExceptions = (iPtr->evalFlags & TCL_ALLOW_EXCEPTIONS); + List *listRepPtr = objPtr->internalRep.twoPtrValue.ptr1; Tcl_IncrRefCount(objPtr); - /* - * Pure List Optimization (no string representation). In this case, we can - * safely use Tcl_EvalObjv instead and get an appreciable improvement in - * execution speed. This is because it allows us to avoid a setFromAny - * step that would just pack everything into a string and back out again. - * - * This also preserves any associations between list elements and location - * information for such elements. - * - * This restriction has been relaxed a bit by storing in lists whether - * they are "canonical" or not (a canonical list being one that is either - * pure or that has its string rep derived by UpdateStringOfList from the - * internal rep). - */ - - if (objPtr->typePtr == &tclListType) { /* is a list... */ - List *listRepPtr = objPtr->internalRep.twoPtrValue.ptr1; + if ((objPtr->typePtr == &tclListType) && /* is a list... */ + ((objPtr->bytes == NULL || /* ...without a string rep */ + listRepPtr->canonicalFlag))) { /* ...or that is canonical */ + Tcl_Obj *listPtr = objPtr; + CmdFrame *eoFramePtr = NULL; + int objc; + Tcl_Obj **objv; + + /* + * Pure List Optimization (no string representation). In this case, we + * can safely use Tcl_EvalObjv instead and get an appreciable + * improvement in execution speed. This is because it allows us to + * avoid a setFromAny step that would just pack everything into a + * string and back out again. + * + * This also preserves any associations between list elements and + * location information for such elements. + * + * This restriction has been relaxed a bit by storing in lists whether + * they are "canonical" or not (a canonical list being one that is either + * pure or that has its string rep derived by UpdateStringOfList from + * the internal rep). + */ - if (objPtr->bytes == NULL || /* ...without a string rep */ - listRepPtr->canonicalFlag) { /* ...or that is canonical */ - Tcl_Obj *listPtr = objPtr; - CmdFrame *eoFramePtr = NULL; - int objc; - Tcl_Obj **objv; - + if (word != INT_MIN) { /* * TIP #280 Structures for tracking lines. As we know that this is * dynamic execution we ignore the invoker, even if known. @@ -5704,41 +5705,39 @@ TclNREvalObjEx( * Note that we use (word==INTMIN) to signal that no command frame * should be pushed, as needed by alias and ensemble redirections. */ - - if (word != INT_MIN) { - eoFramePtr = (CmdFrame *) TclStackAlloc(interp, sizeof(CmdFrame)); - eoFramePtr->nline = 0; - eoFramePtr->line = NULL; - - eoFramePtr->type = TCL_LOCATION_EVAL_LIST; - eoFramePtr->level = (iPtr->cmdFramePtr == NULL? - 1 : iPtr->cmdFramePtr->level + 1); - eoFramePtr->numLevels = iPtr->numLevels; - eoFramePtr->framePtr = iPtr->framePtr; - eoFramePtr->nextPtr = iPtr->cmdFramePtr; - - eoFramePtr->cmd.listPtr = objPtr; - eoFramePtr->data.eval.path = NULL; - - iPtr->cmdFramePtr = eoFramePtr; - } - - /* - * Shimmer protection! Always pass an unshared obj. The caller could - * incr the refCount of objPtr AFTER calling us! To be completely safe - * we always make a copy. - * - * FIXME OPT: preserve just the internal rep? - */ - - listPtr = TclListObjCopy(interp, objPtr); - Tcl_IncrRefCount(listPtr); - TclNRAddCallback(interp, TEOEx_ListCallback, objPtr, eoFramePtr, - listPtr, NULL); - - ListObjGetElements(listPtr, objc, objv); - return TclNREvalObjv(interp, objc, objv, flags, NULL); + + eoFramePtr = (CmdFrame *) TclStackAlloc(interp, sizeof(CmdFrame)); + eoFramePtr->nline = 0; + eoFramePtr->line = NULL; + + eoFramePtr->type = TCL_LOCATION_EVAL_LIST; + eoFramePtr->level = (iPtr->cmdFramePtr == NULL? + 1 : iPtr->cmdFramePtr->level + 1); + eoFramePtr->numLevels = iPtr->numLevels; + eoFramePtr->framePtr = iPtr->framePtr; + eoFramePtr->nextPtr = iPtr->cmdFramePtr; + + eoFramePtr->cmd.listPtr = objPtr; + eoFramePtr->data.eval.path = NULL; + + iPtr->cmdFramePtr = eoFramePtr; } + + /* + * Shimmer protection! Always pass an unshared obj. The caller could + * incr the refCount of objPtr AFTER calling us! To be completely safe + * we always make a copy. + * + * FIXME OPT: preserve just the internal rep? + */ + + listPtr = TclListObjCopy(interp, objPtr); + Tcl_IncrRefCount(listPtr); + TclNRAddCallback(interp, TEOEx_ListCallback, objPtr, eoFramePtr, + listPtr, NULL); + + ListObjGetElements(listPtr, objc, objv); + return TclNREvalObjv(interp, objc, objv, flags, NULL); } if (!(flags & TCL_EVAL_DIRECT)) { @@ -5765,7 +5764,7 @@ TclNREvalObjEx( TclNRAddCallback(interp, NRRunBytecode, codePtr, NULL, NULL, NULL); return TCL_OK; } - + /* * We're not supposed to use the compiler or byte-code interpreter. Let * Tcl_EvalEx evaluate the command directly (and probably more slowly). diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 0965d48..9574e0f 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.389 2008/07/29 13:45:17 msofer Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.390 2008/07/29 20:53:21 msofer Exp $ */ #include "tclInt.h" @@ -1137,25 +1137,6 @@ StackReallocWords( } void -TclStackPurge( - Tcl_Interp *interp, - Tcl_Obj **tosPtr) -{ - Tcl_Obj **newTosPtr = GET_TOSPTR(interp); - - if (!tosPtr) { - Tcl_Panic("TclStackPurge: cannot purge to NULL"); - } - while (newTosPtr && (newTosPtr != tosPtr)) { - TclStackFree(interp, NULL); - newTosPtr = GET_TOSPTR(interp); - } - if (newTosPtr != tosPtr) { - Tcl_Panic("TclStackPurge: requested tosPtr not here"); - } -} - -void TclStackFree( Tcl_Interp *interp, void *freePtr) @@ -1490,9 +1471,7 @@ TclCompileObj( { register Interp *iPtr = (Interp *) interp; register ByteCode *codePtr; /* Tcl Internal type of bytecode. */ - Namespace *namespacePtr; - - namespacePtr = iPtr->varFramePtr->nsPtr; + Namespace *namespacePtr = iPtr->varFramePtr->nsPtr; /* * If the object is not already of tclByteCodeType, compile it (and reset diff --git a/generic/tclNRE.h b/generic/tclNRE.h index 3943cfb..3a5af55 100644 --- a/generic/tclNRE.h +++ b/generic/tclNRE.h @@ -11,7 +11,7 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. * * // FIXME: RCS numbering? - * RCS: @(#) $Id: tclNRE.h,v 1.9 2008/07/29 18:19:17 msofer Exp $ + * RCS: @(#) $Id: tclNRE.h,v 1.10 2008/07/29 20:53:22 msofer Exp $ */ @@ -22,20 +22,16 @@ * Stuff during devel *****************************************************************************/ -#define USE_SMALL_ALLOC 1 /* perf is important for some of these things! */ -#define ENABLE_ASSERTS 1 - -/***************************************************************************** - * Private api fo NRE - *****************************************************************************/ +#define ENABLE_ASSERTS 0 +#define USE_SMALL_ALLOC 1 /* Only turn off for debugging purposes. */ /* - * Main data struct for representing NR commands (generated at runtime). + * TEOV_callback - + * + * Main data struct for representing NR commands. It is designed to fit in + * sizeof(Tcl_Obj) in order to exploit the fastest memory allocator available. */ -struct ByteCode; - -/* Fill up a SmallAlloc: 4 free ptrs for the user */ typedef struct TEOV_callback { Tcl_NRPostProc *procPtr; ClientData data[4]; @@ -44,9 +40,6 @@ typedef struct TEOV_callback { #define TOP_CB(iPtr) (((Interp *)(iPtr))->execEnvPtr->callbackPtr) -#define GET_TOSPTR(iPtr) \ - (((Interp *)iPtr)->execEnvPtr->execStackPtr->tosPtr) - /* * Inline version of Tcl_NRAddCallback */ -- cgit v0.12