summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorpooryorick <com.digitalsmarties@pooryorick.com>2018-03-14 20:43:20 (GMT)
committerpooryorick <com.digitalsmarties@pooryorick.com>2018-03-14 20:43:20 (GMT)
commit73de582148b73bb111830c206bb3e6f566c21131 (patch)
tree2ce3dc9ec2f1ee3b7a6ae077b410995e918f1e2b /generic
parent90f38b1023a10f8a5518bdcd04cb4e377d709fe9 (diff)
downloadtcl-73de582148b73bb111830c206bb3e6f566c21131.zip
tcl-73de582148b73bb111830c206bb3e6f566c21131.tar.gz
tcl-73de582148b73bb111830c206bb3e6f566c21131.tar.bz2
Further work to improve Object reference accounting in order to plug leaks.
Diffstat (limited to 'generic')
-rw-r--r--generic/tclOO.c44
-rw-r--r--generic/tclOODefineCmds.c39
2 files changed, 36 insertions, 47 deletions
diff --git a/generic/tclOO.c b/generic/tclOO.c
index a129a52..83646a8 100644
--- a/generic/tclOO.c
+++ b/generic/tclOO.c
@@ -426,17 +426,17 @@ InitFoundation(
/* Rewire bootstrapped objects. */
fPtr->objectCls->thisPtr->selfCls = fPtr->classCls;
- AddRef(fPtr->objectCls->thisPtr->selfCls->thisPtr);
+ AddRef(fPtr->classCls->thisPtr);
+ TclOOAddToInstances(fPtr->objectCls->thisPtr, fPtr->classCls);
fPtr->classCls->thisPtr->selfCls = fPtr->classCls;
- AddRef(fPtr->classCls->thisPtr->selfCls->thisPtr);
+ AddRef(fPtr->classCls->thisPtr);
+ TclOOAddToInstances(fPtr->classCls->thisPtr, fPtr->classCls);
fPtr->classCls->thisPtr->flags |= ROOT_CLASS;
fPtr->classCls->flags |= ROOT_CLASS;
/* Standard initialization for new Objects */
- TclOOAddToInstances(fPtr->objectCls->thisPtr, fPtr->classCls);
- TclOOAddToInstances(fPtr->classCls->thisPtr, fPtr->classCls);
TclOOAddToSubclasses(fPtr->classCls, fPtr->objectCls);
/*
@@ -568,12 +568,6 @@ KillFoundation(
TclDecrRefCount(fPtr->destructorName);
TclDecrRefCount(fPtr->clonedName);
TclDecrRefCount(fPtr->defineName);
- if (fPtr->objectCls->thisPtr->selfCls != NULL) {
- TclOODecrRefCount(fPtr->objectCls->thisPtr->selfCls->thisPtr);
- }
- if (fPtr->classCls->thisPtr->selfCls != NULL) {
- TclOODecrRefCount(fPtr->classCls->thisPtr->selfCls->thisPtr);
- }
TclOODecrRefCount(fPtr->objectCls->thisPtr);
TclOODecrRefCount(fPtr->classCls->thisPtr);
@@ -660,6 +654,9 @@ AllocObject(
Tcl_ResetResult(interp);
}
+
+ configNamespace:
+
((Namespace *)oPtr->namespacePtr)->refCount++;
/*
@@ -667,7 +664,6 @@ AllocObject(
* to the [self] and [next] commands.
*/
- configNamespace:
if (fPtr->helpersNs != NULL) {
TclSetNsPath((Namespace *) oPtr->namespacePtr, 1, &fPtr->helpersNs);
}
@@ -1007,8 +1003,11 @@ ReleaseClassContents(
if (clsPtr->mixins.num) {
FOREACH(tmpClsPtr, clsPtr->mixins) {
TclOORemoveFromMixinSubs(clsPtr, tmpClsPtr);
+ TclOODecrRefCount(tmpClsPtr->thisPtr);
}
ckfree(clsPtr->mixins.list);
+ clsPtr->mixins.list = NULL;
+ clsPtr->mixins.num = 0;
}
if (clsPtr->superclasses.num > 0) {
@@ -1149,6 +1148,7 @@ ObjectNamespaceDeleted(
if (oPtr->mixins.num > 0) {
FOREACH(mixinPtr, oPtr->mixins) {
TclOORemoveFromInstances(oPtr, mixinPtr);
+ TclOODecrRefCount(mixinPtr->thisPtr);
}
ckfree(oPtr->mixins.list);
}
@@ -1837,16 +1837,22 @@ Tcl_CopyObjectInstance(
* Copy the object's mixin references to the new object.
*/
- FOREACH(mixinPtr, o2Ptr->mixins) {
- if (mixinPtr && mixinPtr != o2Ptr->selfCls) {
- TclOORemoveFromInstances(o2Ptr, mixinPtr);
+ if (o2Ptr->mixins.num != 0) {
+ FOREACH(mixinPtr, o2Ptr->mixins) {
+ if (mixinPtr && mixinPtr != o2Ptr->selfCls) {
+ TclOORemoveFromInstances(o2Ptr, mixinPtr);
+ }
+ TclOODecrRefCount(mixinPtr->thisPtr);
}
+ ckfree(o2Ptr->mixins.list);
}
DUPLICATE(o2Ptr->mixins, oPtr->mixins, Class *);
FOREACH(mixinPtr, o2Ptr->mixins) {
if (mixinPtr && mixinPtr != o2Ptr->selfCls) {
TclOOAddToInstances(o2Ptr, mixinPtr);
}
+ /* For the reference just created in DUPLICATE */
+ AddRef(mixinPtr->thisPtr);
}
/*
@@ -1924,6 +1930,7 @@ Tcl_CopyObjectInstance(
FOREACH(superPtr, cls2Ptr->superclasses) {
TclOORemoveFromSubclasses(cls2Ptr, superPtr);
+ TclOODecrRefCount(superPtr->thisPtr);
}
if (cls2Ptr->superclasses.num) {
cls2Ptr->superclasses.list = ckrealloc(cls2Ptr->superclasses.list,
@@ -1967,15 +1974,18 @@ Tcl_CopyObjectInstance(
* references to the duplicate).
*/
- FOREACH(mixinPtr, cls2Ptr->mixins) {
- TclOORemoveFromMixinSubs(cls2Ptr, mixinPtr);
- }
if (cls2Ptr->mixins.num != 0) {
+ FOREACH(mixinPtr, cls2Ptr->mixins) {
+ TclOORemoveFromMixinSubs(cls2Ptr, mixinPtr);
+ TclOODecrRefCount(mixinPtr->thisPtr);
+ }
ckfree(clsPtr->mixins.list);
}
DUPLICATE(cls2Ptr->mixins, clsPtr->mixins, Class *);
FOREACH(mixinPtr, cls2Ptr->mixins) {
TclOOAddToMixinSubs(cls2Ptr, mixinPtr);
+ /* For the copy just created in DUPLICATE */
+ AddRef(mixinPtr->thisPtr);
}
/*
diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c
index dfd2acf..648ad02 100644
--- a/generic/tclOODefineCmds.c
+++ b/generic/tclOODefineCmds.c
@@ -327,6 +327,7 @@ TclOOObjectSetMixins(
if (oPtr->mixins.num != 0) {
FOREACH(mixinPtr, oPtr->mixins) {
TclOORemoveFromInstances(oPtr, mixinPtr);
+ TclOODecrRefCount(mixinPtr->thisPtr);
}
ckfree(oPtr->mixins.list);
oPtr->mixins.num = 0;
@@ -338,6 +339,7 @@ TclOOObjectSetMixins(
if (mixinPtr && mixinPtr != oPtr->selfCls) {
TclOORemoveFromInstances(oPtr, mixinPtr);
}
+ TclOODecrRefCount(mixinPtr->thisPtr);
}
oPtr->mixins.list = ckrealloc(oPtr->mixins.list,
sizeof(Class *) * numMixins);
@@ -350,10 +352,8 @@ TclOOObjectSetMixins(
FOREACH(mixinPtr, oPtr->mixins) {
if (mixinPtr != oPtr->selfCls) {
TclOOAddToInstances(oPtr, mixinPtr);
- /* Corresponding TclOODecrRefCount() is in the caller of this
- * function.
- */
- TclOODecrRefCount(mixinPtr->thisPtr);
+ /* For the new copy created by memcpy */
+ AddRef(mixinPtr->thisPtr);
}
}
}
@@ -383,6 +383,7 @@ TclOOClassSetMixins(
if (classPtr->mixins.num != 0) {
FOREACH(mixinPtr, classPtr->mixins) {
TclOORemoveFromMixinSubs(classPtr, mixinPtr);
+ TclOODecrRefCount(mixinPtr->thisPtr);
}
ckfree(classPtr->mixins.list);
classPtr->mixins.num = 0;
@@ -391,6 +392,7 @@ TclOOClassSetMixins(
if (classPtr->mixins.num != 0) {
FOREACH(mixinPtr, classPtr->mixins) {
TclOORemoveFromMixinSubs(classPtr, mixinPtr);
+ TclOODecrRefCount(mixinPtr->thisPtr);
}
classPtr->mixins.list = ckrealloc(classPtr->mixins.list,
sizeof(Class *) * numMixins);
@@ -401,10 +403,8 @@ TclOOClassSetMixins(
memcpy(classPtr->mixins.list, mixins, sizeof(Class *) * numMixins);
FOREACH(mixinPtr, classPtr->mixins) {
TclOOAddToMixinSubs(classPtr, mixinPtr);
- /* Corresponding TclOODecrRefCount() is in the caller of this
- * function
- */
- TclOODecrRefCount(mixinPtr->thisPtr);
+ /* For the new copy created by memcpy */
+ AddRef(mixinPtr->thisPtr);
}
}
BumpGlobalEpoch(interp, classPtr);
@@ -1125,7 +1125,6 @@ TclOODefineClassObjCmd(
*/
if (oPtr->selfCls != clsPtr) {
-
TclOORemoveFromInstances(oPtr, oPtr->selfCls);
TclOODecrRefCount(oPtr->selfCls->thisPtr);
oPtr->selfCls = clsPtr;
@@ -1587,10 +1586,6 @@ TclOODefineMixinObjCmd(
goto freeAndError;
}
mixins[i-1] = clsPtr;
- /* Corresponding TclOODecrRefCount() is in TclOOObjectSetMixins,
- * TclOOClassSetMixinsk, or just below if this function fails.
- */
- AddRef(mixins[i-1]->thisPtr);
}
if (isInstanceMixin) {
@@ -1603,9 +1598,6 @@ TclOODefineMixinObjCmd(
return TCL_OK;
freeAndError:
- while (--i > 0) {
- TclOODecrRefCount(mixins[i]->thisPtr);
- }
TclStackFree(interp, mixins);
return TCL_ERROR;
}
@@ -2030,10 +2022,6 @@ ClassMixinSet(
Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", NULL);
goto freeAndError;
}
- /* Corresponding TclOODecrRefCount() is in TclOOClassSetMixins, or just
- * below if this function fails
- */
- AddRef(mixins[i]->thisPtr);
}
TclOOClassSetMixins(interp, oPtr->classPtr, mixinc, mixins);
@@ -2041,9 +2029,6 @@ ClassMixinSet(
return TCL_OK;
freeAndError:
- while (i-- > 0) {
- TclOODecrRefCount(mixins[i]->thisPtr);
- }
TclStackFree(interp, mixins);
return TCL_ERROR;
}
@@ -2197,6 +2182,7 @@ ClassSuperSet(
if (oPtr->classPtr->superclasses.num != 0) {
FOREACH(superPtr, oPtr->classPtr->superclasses) {
TclOORemoveFromSubclasses(oPtr->classPtr, superPtr);
+ TclOODecrRefCount(superPtr->thisPtr);
}
ckfree((char *) oPtr->classPtr->superclasses.list);
}
@@ -2494,16 +2480,9 @@ ObjMixinSet(
mixins[i] = GetClassInOuterContext(interp, mixinv[i],
"may only mix in classes");
if (mixins[i] == NULL) {
- while (i-- > 0) {
- TclOODecrRefCount(mixins[i]->thisPtr);
- }
TclStackFree(interp, mixins);
return TCL_ERROR;
}
- /* Corresponding TclOODecrRefCount() is in TclOOObjectSetMixins() or
- * just above if this function fails.
- */
- AddRef(mixins[i]->thisPtr);
}
TclOOObjectSetMixins(oPtr, mixinc, mixins);