diff options
author | Miguel Sofer <miguel.sofer@gmail.com> | 2007-07-05 11:49:12 (GMT) |
---|---|---|
committer | Miguel Sofer <miguel.sofer@gmail.com> | 2007-07-05 11:49:12 (GMT) |
commit | 7ce3408e22a5d7aedd6e01a5fcdfaa2d6876cb37 (patch) | |
tree | f10d9c5f0790c77712ef5452f0dc8eda26315cd0 /generic/tclNamesp.c | |
parent | 56b81839c7271c23ed51776a7a922d3a49fce775 (diff) | |
download | tcl-7ce3408e22a5d7aedd6e01a5fcdfaa2d6876cb37.zip tcl-7ce3408e22a5d7aedd6e01a5fcdfaa2d6876cb37.tar.gz tcl-7ce3408e22a5d7aedd6e01a5fcdfaa2d6876cb37.tar.bz2 |
* generic/tclNamesp.c (SetNsNameFromAny):
* generic/tclObj.c (SetCmdNameFromAny): Avoid unnecessary
ckfree/ckalloc when the old structs can be reused.
Diffstat (limited to 'generic/tclNamesp.c')
-rw-r--r-- | generic/tclNamesp.c | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index 8e25637..564be56 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -22,7 +22,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.144 2007/07/04 23:56:58 msofer Exp $ + * RCS: @(#) $Id: tclNamesp.c,v 1.145 2007/07/05 11:49:16 msofer Exp $ */ #include "tclInt.h" @@ -4819,29 +4819,45 @@ SetNsNameFromAny( register ResolvedNsName *resNamePtr; /* - * Get the string representation. Make it up-to-date if necessary. - */ - - name = TclGetString(objPtr); - - /* * Look for the namespace "name" in the current namespace. If there is an * error parsing the (possibly qualified) name, return an error. If the * namespace isn't found, we convert the object to an nsName object with a * NULL ResolvedNsName* internal rep. */ + name = TclGetString(objPtr); TclGetNamespaceForQualName(interp, name, NULL, TCL_FIND_ONLY_NS, &nsPtr, &dummy1Ptr, &dummy2Ptr, &dummy); /* * If we found a namespace, then create a new ResolvedNsName structure * that holds a reference to it. + * + * Free the old internalRep before setting the new one. Do this after + * getting the string rep to allow the conversion code (in particular, + * Tcl_GetStringFromObj) to use that old internalRep. */ - if (nsPtr != NULL) { + if (nsPtr) { nsPtr->refCount++; - resNamePtr = (ResolvedNsName *) ckalloc(sizeof(ResolvedNsName)); + resNamePtr = (ResolvedNsName *) objPtr->internalRep.otherValuePtr; + if ((objPtr->typePtr == &tclNsNameType) + && resNamePtr && (resNamePtr->refCount == 1)) { + /* + * Reuse the old ResolvedNsName struct after freeing it + */ + + Namespace *oldNsPtr = resNamePtr->nsPtr; + if ((--oldNsPtr->refCount == 0) && (oldNsPtr->flags & NS_DEAD)) { + NamespaceFree(oldNsPtr); + } + } else { + TclFreeIntRep(objPtr); + resNamePtr = (ResolvedNsName *) ckalloc(sizeof(ResolvedNsName)); + resNamePtr->refCount = 1; + objPtr->internalRep.otherValuePtr = (void *) resNamePtr; + objPtr->typePtr = &tclNsNameType; + } resNamePtr->nsPtr = nsPtr; resNamePtr->nsId = nsPtr->nsId; if ((*name++ == ':') && (*name == ':')) { @@ -4850,20 +4866,11 @@ SetNsNameFromAny( resNamePtr->refNsPtr = (Namespace *) TclGetCurrentNamespace(interp); } - resNamePtr->refCount = 1; } else { - resNamePtr = NULL; + TclFreeIntRep(objPtr); + objPtr->internalRep.otherValuePtr = (void *) NULL; + objPtr->typePtr = &tclNsNameType; } - - /* - * Free the old internalRep before setting the new one. We do this as late - * as possible to allow the conversion code (in particular, - * Tcl_GetStringFromObj) to use that old internalRep. - */ - - TclFreeIntRep(objPtr); - objPtr->internalRep.otherValuePtr = (void *) resNamePtr; - objPtr->typePtr = &tclNsNameType; return TCL_OK; } |