summaryrefslogtreecommitdiffstats
path: root/generic/tclLiteral.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclLiteral.c')
-rw-r--r--generic/tclLiteral.c40
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.
*/