Memory diagnostics. Huge memory leak cleanup related to templates

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@4639 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dave Beazley 2003-03-27 23:17:27 +00:00
commit 1aefd191bf
7 changed files with 167 additions and 50 deletions

View file

@ -107,6 +107,7 @@
#define DohObjMalloc DOH_NAMESPACE(ObjMalloc) #define DohObjMalloc DOH_NAMESPACE(ObjMalloc)
#define DohObjFree DOH_NAMESPACE(ObjFree) #define DohObjFree DOH_NAMESPACE(ObjFree)
#define DohMemoryDebug DOH_NAMESPACE(MemoryDebug)
#define DohStringType DOH_NAMESPACE(StringType) #define DohStringType DOH_NAMESPACE(StringType)
#define DohListType DOH_NAMESPACE(ListType) #define DohListType DOH_NAMESPACE(ListType)
#define DohHashType DOH_NAMESPACE(HashType) #define DohHashType DOH_NAMESPACE(HashType)
@ -297,6 +298,8 @@ extern DOHVoid *DohNewVoid(void *ptr, void (*del)(void *));
extern DOHList *DohSplit(DOHFile *input, char ch, int nsplits); extern DOHList *DohSplit(DOHFile *input, char ch, int nsplits);
extern DOH *DohNone; extern DOH *DohNone;
extern void DohMemoryDebug(void);
#ifndef DOH_LONG_NAMES #ifndef DOH_LONG_NAMES
/* Macros to invoke the above functions. Includes the location of /* Macros to invoke the above functions. Includes the location of
the caller to simplify debugging if something goes wrong */ the caller to simplify debugging if something goes wrong */

View file

@ -45,6 +45,7 @@ CreatePool() {
assert(p); assert(p);
p->ptr = (DohBase *) DohMalloc(sizeof(DohBase)*PoolSize); p->ptr = (DohBase *) DohMalloc(sizeof(DohBase)*PoolSize);
assert(p->ptr); assert(p->ptr);
memset(p->ptr,0,sizeof(DohBase)*PoolSize);
p->len = PoolSize; p->len = PoolSize;
p->blen = PoolSize*sizeof(DohBase); p->blen = PoolSize*sizeof(DohBase);
p->current = 0; p->current = 0;
@ -139,6 +140,7 @@ DohObjFree(DOH *ptr) {
b = (DohBase *) ptr; b = (DohBase *) ptr;
if (b->flag_intern) return; if (b->flag_intern) return;
b->data = (void *) FreeList; b->data = (void *) FreeList;
b->refcount = 0;
if (b->meta) { if (b->meta) {
Delete(b->meta); Delete(b->meta);
b->meta = 0; b->meta = 0;
@ -146,3 +148,71 @@ DohObjFree(DOH *ptr) {
b->type = 0; b->type = 0;
FreeList = b; FreeList = b;
} }
/* ----------------------------------------------------------------------
* DohMemoryDebug()
*
* Display memory usage statistics
* ---------------------------------------------------------------------- */
void
DohMemoryDebug(void) {
extern DohObjInfo DohStringType;
extern DohObjInfo DohListType;
extern DohObjInfo DohHashType;
Pool *p;
int totsize = 0;
int totused = 0;
int totfree = 0;
int numstring = 0;
int numlist = 0;
int numhash = 0;
printf("Memory statistics:\n\n");
printf("Pools:\n");
p = Pools;
while(p) {
/* Calculate number of used, free items */
int i;
int nused = 0, nfree = 0;
for (i = 0; i < p->len; i++) {
if (p->ptr[i].refcount <= 0) nfree++;
else {
nused++;
if (p->ptr[i].type == &DohStringType) numstring++;
else if (p->ptr[i].type == &DohListType) numlist++;
else if (p->ptr[i].type == &DohHashType) numhash++;
}
}
printf(" Pool %8x: size = %10d. used = %10d. free = %10d\n", p, p->len, nused, nfree);
totsize += p->len;
totused+= nused;
totfree+= nfree;
p = p->next;
}
printf("\n Total: size = %d, used = %d, free = %d\n", totsize, totused, totfree);
printf("\nObject types\n");
printf(" Strings : %d\n", numstring);
printf(" Lists : %d\n", numlist);
printf(" Hashes : %d\n", numhash);
#if 0
p = Pools;
while(p) {
int i;
for (i = 0; i < p->len; i++) {
if (p->ptr[i].refcount > 0) {
if (p->ptr[i].type == &DohStringType) {
Printf(stdout,"%s\n", p->ptr+i);
}
}
}
p = p->next;
}
#endif
}

View file

@ -88,8 +88,8 @@ static void
DelString(DOH *so) { DelString(DOH *so) {
String *s = (String *) ObjData(so); String *s = (String *) ObjData(so);
s->hashkey = -1; s->hashkey = -1;
s->str = 0;
DohFree(s->str); DohFree(s->str);
s->str = 0;
DohFree(s); DohFree(s);
} }

View file

@ -189,6 +189,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
int dump_classes = 0; int dump_classes = 0;
int werror = 0; int werror = 0;
int depend = 0; int depend = 0;
int memory_debug = 0;
DOH *libfiles = 0; DOH *libfiles = 0;
DOH *cpps = 0 ; DOH *cpps = 0 ;
@ -427,6 +428,9 @@ int SWIG_main(int argc, char *argv[], Language *l) {
} else if (strcmp(argv[i],"-dump_classes") == 0) { } else if (strcmp(argv[i],"-dump_classes") == 0) {
dump_classes = 1; dump_classes = 1;
Swig_mark_arg(i); Swig_mark_arg(i);
} else if (strcmp(argv[i],"-dump_memory") == 0) {
memory_debug =1;
Swig_mark_arg(i);
} else if (strcmp(argv[i],"-help") == 0) { } else if (strcmp(argv[i],"-help") == 0) {
//fputs("Help.\n",stderr); //fputs("Help.\n",stderr);
fputs(usage,stderr); fputs(usage,stderr);
@ -583,11 +587,13 @@ int SWIG_main(int argc, char *argv[], Language *l) {
Node *top = Swig_cparse(cpps); Node *top = Swig_cparse(cpps);
if (Verbose) { if (Verbose) {
Printf(stdout,"Processing types...\n"); Printf(stdout,"Processing types...\n");
} }
Swig_process_types(top); Swig_process_types(top);
if (Verbose) { if (Verbose) {
Printf(stdout,"C++ analysis...\n"); Printf(stdout,"C++ analysis...\n");
} }
@ -652,7 +658,10 @@ int SWIG_main(int argc, char *argv[], Language *l) {
} }
} }
if (tm_debug) Swig_typemap_debug(); if (tm_debug) Swig_typemap_debug();
if (memory_debug) DohMemoryDebug();
while (freeze); while (freeze);
if ((werror) && (Swig_warn_count())) { if ((werror) && (Swig_warn_count())) {
return Swig_warn_count(); return Swig_warn_count();
} }

View file

@ -949,7 +949,15 @@ SwigType_strip_qualifiers(SwigType *t) {
if (SwigType_isqualifier(e)) continue; if (SwigType_isqualifier(e)) continue;
Append(r,e); Append(r,e);
} }
Setattr(memoize_stripped,Copy(t),Copy(r)); Delete(l);
{
String *key, *value;
key = Copy(t);
value = Copy(r);
Setattr(memoize_stripped,key,value);
Delete(key);
Delete(value);
}
return r; return r;
} }
@ -1587,6 +1595,7 @@ SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
Delete(repbase); Delete(repbase);
} }
{ {
String *tsuffix;
List *tparms = SwigType_parmlist(e); List *tparms = SwigType_parmlist(e);
int j; int j;
String *nt = SwigType_templateprefix(e); String *nt = SwigType_templateprefix(e);
@ -1596,10 +1605,13 @@ SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
Printf(nt,"%s",Getitem(tparms,j)); Printf(nt,"%s",Getitem(tparms,j));
if (j < (Len(tparms)-1)) Printf(nt,","); if (j < (Len(tparms)-1)) Printf(nt,",");
} }
Printf(nt,")>%s", SwigType_templatesuffix(e)); tsuffix = SwigType_templatesuffix(e);
Printf(nt,")>%s", tsuffix);
Delete(tsuffix);
Clear(e); Clear(e);
Append(e,nt); Append(e,nt);
Delete(nt); Delete(nt);
Delete(tparms);
} }
} else if (Swig_scopename_check(e)) { } else if (Swig_scopename_check(e)) {
String *first, *rest; String *first, *rest;
@ -1623,6 +1635,7 @@ SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
if (j < (Len(fparms)-1)) Printf(e,","); if (j < (Len(fparms)-1)) Printf(e,",");
} }
Printf(e,")."); Printf(e,").");
Delete(fparms);
} }
Append(nt,e); Append(nt,e);
} }

View file

@ -486,7 +486,6 @@ static SwigType *strip_arrays(SwigType *type) {
return t; return t;
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Swig_typemap_search() * Swig_typemap_search()
* *
@ -532,7 +531,9 @@ Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *na
if (isarray) { if (isarray) {
/* If working with arrays, strip away all of the dimensions and replace with "ANY". /* If working with arrays, strip away all of the dimensions and replace with "ANY".
See if that generates a match */ See if that generates a match */
if (!noarrays) noarrays = strip_arrays(ctype); if (!noarrays) {
noarrays = strip_arrays(ctype);
}
tma = Getattr(typemaps[ts],noarrays); tma = Getattr(typemaps[ts],noarrays);
if (tma && cname) { if (tma && cname) {
tm1 = Getattr(tma,cname); tm1 = Getattr(tma,cname);
@ -565,9 +566,7 @@ Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *na
{ {
String *octype; String *octype;
if (unstripped) { if (unstripped) {
if (unstripped != type) { Delete(ctype);
Delete(ctype);
}
ctype = unstripped; ctype = unstripped;
unstripped = 0; unstripped = 0;
} }
@ -576,36 +575,11 @@ Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *na
if (octype != type) Delete(octype); if (octype != type) Delete(octype);
} }
} }
#ifdef NEW
/* No match seems to be found at all. Try a SWIGTYPE substitution */
if (!primitive) {
SwigType *base = SwigType_base(type);
primitive = SwigType_prefix(type);
if (Strstr(base,"enum ")) {
Append(primitive,"enum SWIGTYPE");
} else {
Append(primitive,"SWIGTYPE");
}
tm = Getattr(typemaps[ts],primitive);
if (tm && cname) {
tm1 = Getattr(tm, cname);
if (tm1) {
result = Getattr(tm1,tmop);
if (result) goto ret_result;
}
}
if (tm) {
result = Getattr(tm,tmop);
if (result) goto ret_result;
}
Delete(primitive);
primitive = 0;
}
#endif
/* Hmmm. Well, no match seems to be found at all. See if there is some kind of default mapping */ /* Hmmm. Well, no match seems to be found at all. See if there is some kind of default mapping */
if (!primitive) if (!primitive) {
primitive = SwigType_default(type); primitive = SwigType_default(type);
}
tm = Getattr(typemaps[ts],primitive); tm = Getattr(typemaps[ts],primitive);
if (tm && cname) { if (tm && cname) {
tm1 = Getattr(tm,cname); tm1 = Getattr(tm,cname);
@ -618,7 +592,7 @@ Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *na
result = Getattr(tm,tmop); result = Getattr(tm,tmop);
if (result) goto ret_result; if (result) goto ret_result;
} }
if (ctype != type) Delete(ctype); if (ctype != type) { Delete(ctype); ctype = 0; }
ts--; /* Hmmm. Nothing found in this scope. Guess we'll go try another scope */ ts--; /* Hmmm. Nothing found in this scope. Guess we'll go try another scope */
} }
result = backup; result = backup;
@ -634,6 +608,7 @@ Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *na
return result; return result;
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Swig_typemap_search_multi() * Swig_typemap_search_multi()
* *

View file

@ -176,6 +176,7 @@ int SwigType_typedef_class(String_or_char *name) {
cname = NewString(name); cname = NewString(name);
Setmeta(cname,"class","1"); Setmeta(cname,"class","1");
Setattr(current_typetab,cname,cname); Setattr(current_typetab,cname,cname);
Delete(cname);
flush_cache(); flush_cache();
return 0; return 0;
} }
@ -506,23 +507,30 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
String *namebase = 0; String *namebase = 0;
String *nameprefix = 0; String *nameprefix = 0;
int newtype = 0; int newtype = 0;
static String *noscope = 0;
/*
if (!noscope) {
noscope = NewString("");
}
*/
resolved_scope = 0; resolved_scope = 0;
/*
if (!typedef_resolve_cache) { if (!typedef_resolve_cache) {
typedef_resolve_cache = NewHash(); typedef_resolve_cache = NewHash();
} }
/*
r = Getattr(typedef_resolve_cache,t); r = Getattr(typedef_resolve_cache,t);
if (r) { if (r) {
if (r != DohNone) { if (r != noscope) {
resolved_scope = Getmeta(r,"scope"); resolved_scope = Getmeta(r,"scope");
return Copy(r); return Copy(r);
} else { } else {
return 0; return 0;
} }
} }
*/ */
base = SwigType_base(t); base = SwigType_base(t);
@ -551,6 +559,7 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
if (nameprefix) { if (nameprefix) {
/* Name had a prefix on it. See if we can locate the proper scope for it */ /* Name had a prefix on it. See if we can locate the proper scope for it */
s = SwigType_find_scope(s,nameprefix); s = SwigType_find_scope(s,nameprefix);
/* Couldn't locate a scope for the type. */ /* Couldn't locate a scope for the type. */
if (!s) { if (!s) {
Delete(base); Delete(base);
@ -586,7 +595,10 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
} }
if (type && (Strcmp(base,type) == 0)) { if (type && (Strcmp(base,type) == 0)) {
if (newtype) Delete(type);
Delete(base); Delete(base);
Delete(namebase);
Delete(nameprefix);
r = 0; r = 0;
goto return_result; goto return_result;
} }
@ -600,6 +612,7 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
int i,sz; int i,sz;
int rep = 0; int rep = 0;
type = SwigType_templateprefix(base); type = SwigType_templateprefix(base);
newtype = 1;
suffix = SwigType_templatesuffix(base); suffix = SwigType_templatesuffix(base);
Append(type,"<("); Append(type,"<(");
tparms = SwigType_parmlist(base); tparms = SwigType_parmlist(base);
@ -614,6 +627,7 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
} }
if (tpr) { if (tpr) {
Append(type,tpr); Append(type,tpr);
Delete(tpr);
rep = 1; rep = 1;
} else { } else {
Append(type,tp); Append(type,tp);
@ -631,12 +645,15 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
} }
if (namebase) Delete(namebase); if (namebase) Delete(namebase);
if (nameprefix) Delete(nameprefix); if (nameprefix) Delete(nameprefix);
namebase = 0;
nameprefix = 0;
} else { } else {
if (SwigType_isfunction(base)) { if (SwigType_isfunction(base)) {
List *parms; List *parms;
int i,sz; int i,sz;
int rep = 0; int rep = 0;
type = NewString("f("); type = NewString("f(");
newtype = 1;
parms = SwigType_parmlist(base); parms = SwigType_parmlist(base);
sz = Len(parms); sz = Len(parms);
for (i = 0; i < sz; i++) { for (i = 0; i < sz; i++) {
@ -649,6 +666,7 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
} }
if (tpr) { if (tpr) {
Append(type,tpr); Append(type,tpr);
Delete(tpr);
rep = 1; rep = 1;
} else { } else {
Append(type,tp); Append(type,tp);
@ -667,6 +685,7 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
rt = SwigType_typedef_resolve(mtype); rt = SwigType_typedef_resolve(mtype);
if (rt) { if (rt) {
type = NewStringf("m(%s).", rt); type = NewStringf("m(%s).", rt);
newtype = 1;
Delete(rt); Delete(rt);
} }
Delete(mtype); Delete(mtype);
@ -700,17 +719,25 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
} }
return_result: return_result:
if (!r) { /*
Setattr(typedef_resolve_cache,NewString(t),DohNone); {
} else { String *key = NewString(t);
Setattr(typedef_resolve_cache,NewString(t),r); if (!r) {
Setmeta(r,"scope",resolved_scope); Setattr(typedef_resolve_cache,key,noscope);
r = Copy(r); } else {
SwigType *r1;
Setattr(typedef_resolve_cache,key,r);
Setmeta(r,"scope",resolved_scope);
r1 = Copy(r);
Delete(r);
r = r1;
}
Delete(key);
} }
*/
return r; return r;
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* SwigType_typedef_resolve_all() * SwigType_typedef_resolve_all()
* *
@ -734,8 +761,12 @@ SwigType *SwigType_typedef_resolve_all(SwigType *t) {
r = n; r = n;
} }
{ {
String *key;
SwigType *rr = Copy(r); SwigType *rr = Copy(r);
Setattr(typedef_all_cache,NewString(t),rr); key = NewString(t);
Setattr(typedef_all_cache,key,rr);
Delete(key);
Delete(rr);
} }
return r; return r;
} }
@ -841,6 +872,7 @@ SwigType *SwigType_typedef_qualified(SwigType *t)
value = qn; value = qn;
continue; continue;
} else { } else {
Delete(qn);
break; break;
} }
} else if ((Strcmp(nodeType(n),"cdecl") == 0) && (Getattr(n,"value"))) { } else if ((Strcmp(nodeType(n),"cdecl") == 0) && (Getattr(n,"value"))) {
@ -852,6 +884,7 @@ SwigType *SwigType_typedef_qualified(SwigType *t)
break; break;
} }
Append(qprefix,value); Append(qprefix,value);
Delete(value);
} else { } else {
Append(qprefix,p); Append(qprefix,p);
} }
@ -871,6 +904,7 @@ SwigType *SwigType_typedef_qualified(SwigType *t)
Append(e,qprefix); Append(e,qprefix);
Delete(tprefix); Delete(tprefix);
Delete(qprefix); Delete(qprefix);
Delete(parms);
} }
if (Strncmp(e,"::",2) == 0) { if (Strncmp(e,"::",2) == 0) {
Delitem(e,0); Delitem(e,0);
@ -883,7 +917,9 @@ SwigType *SwigType_typedef_qualified(SwigType *t)
String *p; String *p;
p = Firstitem(parms); p = Firstitem(parms);
while (p) { while (p) {
Append(s,SwigType_typedef_qualified(p)); String *pq = SwigType_typedef_qualified(p);
Append(s,pq);
Delete(pq);
p = Nextitem(parms); p = Nextitem(parms);
if (p) { if (p) {
Append(s,","); Append(s,",");
@ -892,6 +928,7 @@ SwigType *SwigType_typedef_qualified(SwigType *t)
Append(s,")."); Append(s,").");
Append(result,s); Append(result,s);
Delete(s); Delete(s);
Delete(parms);
} else if (SwigType_isarray(e)) { } else if (SwigType_isarray(e)) {
String *ndim; String *ndim;
String *dim = SwigType_parm(e); String *dim = SwigType_parm(e);
@ -904,7 +941,14 @@ SwigType *SwigType_typedef_qualified(SwigType *t)
} }
} }
Delete(elements); Delete(elements);
Setattr(typedef_qualified_cache,NewString(t),NewString(result)); {
String *key, *cresult;
key = NewString(t);
cresult = NewString(result);
Setattr(typedef_qualified_cache,key,cresult);
Delete(key);
Delete(cresult);
}
return result; return result;
} }
@ -1157,6 +1201,7 @@ void SwigType_remember_clientdata(SwigType *t, const String_or_char *clientdata)
Hash *h; Hash *h;
SwigType *fr; SwigType *fr;
SwigType *qr; SwigType *qr;
String *tkey;
if (!r_mangled) { if (!r_mangled) {
r_mangled = NewHash(); r_mangled = NewHash();
@ -1172,7 +1217,9 @@ void SwigType_remember_clientdata(SwigType *t, const String_or_char *clientdata)
if (last && (Cmp(last,clientdata) == 0)) return; if (last && (Cmp(last,clientdata) == 0)) return;
} }
Setattr(r_remembered, Copy(t), clientdata ? NewString(clientdata) : (void *) ""); tkey = Copy(t);
Setattr(r_remembered, tkey, clientdata ? NewString(clientdata) : (void *) "");
Delete(tkey);
mt = SwigType_manglestr(t); /* Create mangled string */ mt = SwigType_manglestr(t); /* Create mangled string */