diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | generic/tclVar.c | 42 |
2 files changed, 39 insertions, 12 deletions
@@ -1,5 +1,14 @@ 2004-05-22 Miguel Sofer <msofer@users.sf.net> + * generic/tclVar.c (TclObjLookupVar, TclObjUnsetVar2): fix for new + (in tcl8.4) exteriorisations of [Bug 736729] due to the use of + tclNsVarNameType obj types. Reenabling the use of this objType + ("VAR ref absolute" benchmark down to 66 ms, from 230). + Added comments in TclLookupSimpleVar explaining my current + understanding of [Bug 736729]. + +2004-05-22 Miguel Sofer <msofer@users.sf.net> + * generic/tclVar.c: fix for [Bug 735335]. The use of tclNsVarNameType objs is still disabled, pending resolution of [Bug 736729]. diff --git a/generic/tclVar.c b/generic/tclVar.c index a177cf8..9097fd1 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.80 2004/05/22 03:42:56 msofer Exp $ + * RCS: @(#) $Id: tclVar.c,v 1.81 2004/05/22 16:21:17 msofer Exp $ */ #include "tclInt.h" @@ -542,17 +542,10 @@ TclObjLookupVar(interp, part1Ptr, part2, flags, msg, createPart1, createPart2, procPtr->refCount++; part1Ptr->internalRep.twoPtrValue.ptr1 = (VOID *) procPtr; part1Ptr->internalRep.twoPtrValue.ptr2 = (VOID *) index; -#if 0 - /* - * TEMPORARYLY DISABLED tclNsVarNameType - * - * This is a stop-gap fix for [Bug 736729]; it may not address the - * real issue (which I haven't pinned down yet). - * This optimisation will hopefully be turned back on soon. - * Miguel Sofer, 2004-05-22 - */ - } else if (index > -3) { + /* + * A cacheable namespace or global variable. + */ Namespace *nsPtr; nsPtr = ((index == -1)? iPtr->globalNsPtr : varFramePtr->nsPtr); @@ -560,7 +553,6 @@ TclObjLookupVar(interp, part1Ptr, part2, flags, msg, createPart1, createPart2, part1Ptr->typePtr = &tclNsVarNameType; part1Ptr->internalRep.twoPtrValue.ptr1 = (VOID *) nsPtr; part1Ptr->internalRep.twoPtrValue.ptr2 = (VOID *) varPtr; -#endif } else { /* * At least mark part1Ptr as already parsed. @@ -767,6 +759,21 @@ TclLookupSimpleVar(interp, varName, flags, create, errMsgPtr, indexPtr) } /* + * FIXME: [Bug 736729] + * + * When a varName is looked from a namespace different from the + * global one, there is no corresponding variable in the namespace and + * there is a "zombie" variable in the global namespace (ie, the + * varName is in the hash table, but the variable is unset), this code + * returns a reference to the zombie. It should instead create a + * variable in the namespace. + * + * Fix in progress - that it is not here yet may indicate that the + * picture above is incomplete or wrong. + * - Miguel Sofer, 2004-05-22 + */ + + /* * Don't pass TCL_LEAVE_ERR_MSG, we may yet create the variable, * or otherwise generate our own error! */ @@ -2277,6 +2284,17 @@ TclObjUnsetVar2(interp, part1Ptr, part2, flags) } /* + * Try to avoid keeping the Var struct allocated due to a tclNsVarNameType + * keeping a reference. This removes some additional exteriorisations of + * [Bug 736729], but may be a good thing independently of the bug. + */ + + if (part1Ptr->typePtr == &tclNsVarNameType) { + part1Ptr->typePtr->freeIntRepProc(part1Ptr); + part1Ptr->typePtr = NULL; + } + + /* * Finally, if the variable is truly not in use then free up its Var * structure and remove it from its hash table, if any. The ref count of * its value object, if any, was decremented above. |