diff options
author | Miguel Sofer <miguel.sofer@gmail.com> | 2004-07-08 18:46:02 (GMT) |
---|---|---|
committer | Miguel Sofer <miguel.sofer@gmail.com> | 2004-07-08 18:46:02 (GMT) |
commit | 5f7664fb28c03bce899572a39a9e3b343c223f3a (patch) | |
tree | 83ca945a044386ae90882b24cb30d198aa440f7e /generic/tclLiteral.c | |
parent | 2e5d02410d31161822705b1b28f1743b8af402fc (diff) | |
download | tcl-5f7664fb28c03bce899572a39a9e3b343c223f3a.zip tcl-5f7664fb28c03bce899572a39a9e3b343c223f3a.tar.gz tcl-5f7664fb28c03bce899572a39a9e3b343c223f3a.tar.bz2 |
Modified the logic of literal table cleanup at interp deletion time,
insuring that the fix of [Bug 983660] does not have a negative perf
impact.
Diffstat (limited to 'generic/tclLiteral.c')
-rw-r--r-- | generic/tclLiteral.c | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/generic/tclLiteral.c b/generic/tclLiteral.c index 2dfe37f..19042fd 100644 --- a/generic/tclLiteral.c +++ b/generic/tclLiteral.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclLiteral.c,v 1.15 2004/07/05 22:41:02 msofer Exp $ + * RCS: @(#) $Id: tclLiteral.c,v 1.16 2004/07/08 18:46:06 msofer Exp $ */ #include "tclInt.h" @@ -81,7 +81,8 @@ TclInitLiteralTable(tablePtr) * TclDeleteLiteralTable -- * * This procedure frees up everything associated with a literal table - * except for the table's structure itself. + * except for the table's structure itself. It is called when the + * interpreter is deleted. * * Results: * None. @@ -101,9 +102,10 @@ TclDeleteLiteralTable(interp, tablePtr) * referenced by the table to delete. */ LiteralTable *tablePtr; /* Points to the literal table to delete. */ { - LiteralEntry *entryPtr; - int i, start; - + LiteralEntry *entryPtr, *nextPtr; + Tcl_Obj *objPtr; + int i; + /* * Release remaining literals in the table. Note that releasing a * literal might release other literals, modifying the table, so we @@ -114,18 +116,26 @@ TclDeleteLiteralTable(interp, tablePtr) TclVerifyGlobalLiteralTable((Interp *) interp); #endif /*TCL_COMPILE_DEBUG*/ - start = 0; - while (tablePtr->numEntries > 0) { - for (i = start; i < tablePtr->numBuckets; i++) { - entryPtr = tablePtr->buckets[i]; - if (entryPtr != NULL) { - TclReleaseLiteral(interp, entryPtr->objPtr); - start = i; - break; - } + /* + * We used to call TclReleaseLiteral for each literal in the table, which + * is rather inefficient as it causes one lookup-by-hash for each + * reference to the literal. + * We now rely at interp-deletion on each bytecode object to release its + * references to the literal Tcl_Obj without requiring that it updates the + * global table itself, and deal here only with the table. + */ + + for (i = 0; i < tablePtr->numBuckets; i++) { + entryPtr = tablePtr->buckets[i]; + while (entryPtr != NULL) { + objPtr = entryPtr->objPtr; + TclDecrRefCount(objPtr); + nextPtr = entryPtr->nextPtr; + ckfree((char *) entryPtr); + entryPtr = nextPtr; } } - + /* * Free up the table's bucket array if it was dynamically allocated. */ |