summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2013-02-22 18:54:56 (GMT)
committerdgp <dgp@users.sourceforge.net>2013-02-22 18:54:56 (GMT)
commitc321250dcd5875ebaf9503f4278e9c1f6a3ca30c (patch)
treea8c46824000b586d801a3996823062430d8ed34b /generic
parentf582e28a0b80cd6e3a23648d42030cafc2bb441a (diff)
downloadtcl-c321250dcd5875ebaf9503f4278e9c1f6a3ca30c.zip
tcl-c321250dcd5875ebaf9503f4278e9c1f6a3ca30c.tar.gz
tcl-c321250dcd5875ebaf9503f4278e9c1f6a3ca30c.tar.bz2
Restore the ReleaseCmdWordData cleanup routine from 8.4, to plug very
rare memory leak.
Diffstat (limited to 'generic')
-rw-r--r--generic/tclCompile.c44
1 files changed, 26 insertions, 18 deletions
diff --git a/generic/tclCompile.c b/generic/tclCompile.c
index 357a27a..fee30bd 100644
--- a/generic/tclCompile.c
+++ b/generic/tclCompile.c
@@ -431,6 +431,7 @@ static void EnterCmdWordData(ExtCmdLoc *eclPtr, int srcOffset,
Tcl_Token *tokenPtr, const char *cmd, int len,
int numWords, int line, int* clNext, int **lines,
CompileEnv* envPtr);
+static void ReleaseCmdWordData(ExtCmdLoc *eclPtr);
/*
* The structure below defines the bytecode Tcl object type by means of
@@ -797,23 +798,7 @@ TclCleanupByteCode(
Tcl_HashEntry *hePtr = Tcl_FindHashEntry(iPtr->lineBCPtr,
(char *) codePtr);
if (hePtr) {
- ExtCmdLoc *eclPtr = Tcl_GetHashValue(hePtr);
- int i;
-
- if (eclPtr->type == TCL_LOCATION_SOURCE) {
- Tcl_DecrRefCount(eclPtr->path);
- }
- for (i=0 ; i<eclPtr->nuloc ; i++) {
- ckfree((char *) eclPtr->loc[i].line);
- }
-
- if (eclPtr->loc != NULL) {
- ckfree((char *) eclPtr->loc);
- }
-
- Tcl_DeleteHashTable (&eclPtr->litInfo);
-
- ckfree((char *) eclPtr);
+ ReleaseCmdWordData(Tcl_GetHashValue(hePtr));
Tcl_DeleteHashEntry(hePtr);
}
}
@@ -825,6 +810,28 @@ TclCleanupByteCode(
TclHandleRelease(codePtr->interpHandle);
ckfree((char *) codePtr);
}
+
+static void
+ReleaseCmdWordData(
+ ExtCmdLoc *eclPtr)
+{
+ int i;
+
+ if (eclPtr->type == TCL_LOCATION_SOURCE) {
+ Tcl_DecrRefCount(eclPtr->path);
+ }
+ for (i=0 ; i<eclPtr->nuloc ; i++) {
+ ckfree((char *) eclPtr->loc[i].line);
+ }
+
+ if (eclPtr->loc != NULL) {
+ ckfree((char *) eclPtr->loc);
+ }
+
+ Tcl_DeleteHashTable (&eclPtr->litInfo);
+
+ ckfree((char *) eclPtr);
+}
/*
*----------------------------------------------------------------------
@@ -1068,7 +1075,8 @@ TclFreeCompileEnv(
ckfree((char *) envPtr->auxDataArrayPtr);
}
if (envPtr->extCmdMapPtr) {
- ckfree((char *) envPtr->extCmdMapPtr);
+ ReleaseCmdWordData(envPtr->extCmdMapPtr);
+ envPtr->extCmdMapPtr = NULL;
}
/*