summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2007-06-24 18:18:28 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2007-06-24 18:18:28 (GMT)
commite4adf4810fc98f034ee61c63c74cc33877cd4a56 (patch)
tree86bc98ac4619c1b671cb4411699e1f549198d694
parentef5e016071297f4dcb42c24beabf771feb1f1c68 (diff)
downloadtcl-e4adf4810fc98f034ee61c63c74cc33877cd4a56.zip
tcl-e4adf4810fc98f034ee61c63c74cc33877cd4a56.tar.gz
tcl-e4adf4810fc98f034ee61c63c74cc33877cd4a56.tar.bz2
* generic/tclVar.c (TclDeleteCompiledLocalVars): removed inlining
that ended up not really optimising (limited benchmarks). Now calling UnsetVarStruct (streamlined old code is #ifdef'ed out, in case better benchmarks do show a difference).
-rw-r--r--ChangeLog5
-rw-r--r--generic/tclVar.c119
2 files changed, 67 insertions, 57 deletions
diff --git a/ChangeLog b/ChangeLog
index 0c8fd00..2d71789 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2007-06-24 Miguel Sofer <msofer@users.sf.net>
+ * generic/tclVar.c (TclDeleteCompiledLocalVars): removed inlining
+ that ended up not really optimising (limited benchmarks). Now
+ calling UnsetVarStruct (streamlined old code is #ifdef'ed out, in
+ case better benchmarks do show a difference).
+
* generic/tclVar.c (UnsetVarStruct): fixed a leak introduced in
last commit.
diff --git a/generic/tclVar.c b/generic/tclVar.c
index e7ee850..87a293a 100644
--- a/generic/tclVar.c
+++ b/generic/tclVar.c
@@ -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: tclVar.c,v 1.139 2007/06/24 16:05:29 msofer Exp $
+ * RCS: @(#) $Id: tclVar.c,v 1.140 2007/06/24 18:18:28 msofer Exp $
*/
#include "tclInt.h"
@@ -4212,73 +4212,78 @@ TclDeleteCompiledLocalVars(
* assigned local variables to delete. */
{
register Var *varPtr;
- int flags; /* Flags passed to trace functions. */
- Var *linkPtr;
- ActiveVarTrace *activePtr;
int numLocals, i;
- flags = TCL_TRACE_UNSETS;
numLocals = framePtr->numCompiledLocals;
varPtr = framePtr->compiledLocals;
for (i=0 ; i<numLocals ; i++) {
+#if 1
+ UnsetVarStruct(varPtr, NULL, iPtr, varPtr->name, NULL, TCL_TRACE_UNSETS, 0);
+ varPtr++;
+#else
+ if (!TclIsVarUntraced(varPtr)) {
+ ActiveVarTrace *activePtr;
+
+ varPtr->flags &= ~VAR_TRACE_ACTIVE;
+ TclCallVarTraces(iPtr, NULL, varPtr, varPtr->name, NULL,
+ TCL_TRACE_UNSETS, /* leaveErrMsg */ 0);
+ while (varPtr->tracePtr != NULL) {
+ VarTrace *tracePtr = varPtr->tracePtr;
+ varPtr->tracePtr = tracePtr->nextPtr;
+ Tcl_EventuallyFree((ClientData) tracePtr, TCL_DYNAMIC);
+ }
+ for (activePtr = iPtr->activeVarTracePtr; activePtr != NULL;
+ activePtr = activePtr->nextPtr) {
+ if (activePtr->varPtr == varPtr) {
+ activePtr->nextTracePtr = NULL;
+ }
+ }
+ }
+
+ if (TclIsVarScalar(varPtr)
+ && (varPtr->value.objPtr != NULL)) {
+ /*
+ * Decrement the ref count of the var's value
+ */
+
+ Tcl_Obj *objPtr = varPtr->value.objPtr;
+ TclDecrRefCount(objPtr);
+ varPtr->value.objPtr = NULL;
+ } else if (TclIsVarArray(varPtr) && !TclIsVarUndefined(varPtr)) {
/*
- * Invoke traces on the variable that is being deleted. Then delete
- * the variable's trace records.
+ * If the variable is an array, delete all of its elements. This must
+ * be done after calling the traces on the array, above (that's the
+ * way traces are defined). If the array is traced, its name is
+ * already in part1. If not, and the name is required for some
+ * element, it will be computed at DeleteArray.
*/
-
- if (!TclIsVarUntraced(varPtr)) {
- TclCallVarTraces(iPtr, NULL, varPtr, varPtr->name, NULL, flags,
- /* leaveErrMsg */ 0);
- while (varPtr->tracePtr != NULL) {
- VarTrace *tracePtr = varPtr->tracePtr;
- varPtr->tracePtr = tracePtr->nextPtr;
- Tcl_EventuallyFree((ClientData) tracePtr, TCL_DYNAMIC);
- }
- for (activePtr = iPtr->activeVarTracePtr; activePtr != NULL;
- activePtr = activePtr->nextPtr) {
- if (activePtr->varPtr == varPtr) {
- activePtr->nextTracePtr = NULL;
- }
+
+ DeleteArray(iPtr, varPtr->name, varPtr, TCL_TRACE_UNSETS);
+ } else if (TclIsVarLink(varPtr)) {
+ /*
+ * For global/upvar variables referenced in procedures, decrement the
+ * reference count on the variable referred to, and free the
+ * referenced variable if it's no longer needed.
+ */
+ Var *linkPtr = varPtr->value.linkPtr;
+ linkPtr->refCount--;
+ if ((linkPtr->refCount == 0) && TclIsVarUndefined(linkPtr)
+ && (linkPtr->tracePtr == NULL)
+ && (linkPtr->flags & VAR_IN_HASHTABLE)) {
+ if (linkPtr->hPtr != NULL) {
+ Tcl_DeleteHashEntry(linkPtr->hPtr);
}
+ ckfree((char *) linkPtr);
}
+ }
- if (TclIsVarScalar(varPtr) && (varPtr->value.objPtr != NULL)) {
- /*
- * Decrement the ref count of the var's value
- */
-
- TclDecrRefCount(varPtr->value.objPtr);
- varPtr->value.objPtr = NULL;
- } else if (TclIsVarArray(varPtr) && (varPtr->value.tablePtr != NULL)) {
- /*
- * Delete the variable's element hash table.
- */
+ TclSetVarUndefined(varPtr);
+ TclSetVarScalar(varPtr);
+ varPtr->tracePtr = NULL;
+ varPtr->searchPtr = NULL;
- DeleteArray(iPtr, varPtr->name, varPtr, flags);
- } else if (TclIsVarLink(varPtr)) {
- /*
- * For global/upvar variables referenced in procedures, decrement the
- * reference count on the variable referred to, and free the
- * referenced variable if it's no longer needed. Don't delete the hash
- * entry for the other variable if it's in the same table as us: this
- * will happen automatically later on.
- */
- linkPtr = varPtr->value.linkPtr;
- linkPtr->refCount--;
- if ((linkPtr->refCount == 0) && TclIsVarUndefined(linkPtr)
- && (linkPtr->tracePtr == NULL)
- && (linkPtr->flags & VAR_IN_HASHTABLE)) {
- if (linkPtr->hPtr == NULL) {
- ckfree((char *) linkPtr);
- } else {
- Tcl_DeleteHashEntry(linkPtr->hPtr);
- ckfree((char *) linkPtr);
- }
- }
- }
- TclSetVarUndefined(varPtr);
- TclSetVarScalar(varPtr);
- varPtr++;
+ varPtr++;
+#endif
}
}