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:
parent
8af562f3a0
commit
1aefd191bf
7 changed files with 167 additions and 50 deletions
|
|
@ -107,6 +107,7 @@
|
|||
|
||||
#define DohObjMalloc DOH_NAMESPACE(ObjMalloc)
|
||||
#define DohObjFree DOH_NAMESPACE(ObjFree)
|
||||
#define DohMemoryDebug DOH_NAMESPACE(MemoryDebug)
|
||||
#define DohStringType DOH_NAMESPACE(StringType)
|
||||
#define DohListType DOH_NAMESPACE(ListType)
|
||||
#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 DOH *DohNone;
|
||||
|
||||
extern void DohMemoryDebug(void);
|
||||
|
||||
#ifndef DOH_LONG_NAMES
|
||||
/* Macros to invoke the above functions. Includes the location of
|
||||
the caller to simplify debugging if something goes wrong */
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ CreatePool() {
|
|||
assert(p);
|
||||
p->ptr = (DohBase *) DohMalloc(sizeof(DohBase)*PoolSize);
|
||||
assert(p->ptr);
|
||||
memset(p->ptr,0,sizeof(DohBase)*PoolSize);
|
||||
p->len = PoolSize;
|
||||
p->blen = PoolSize*sizeof(DohBase);
|
||||
p->current = 0;
|
||||
|
|
@ -139,6 +140,7 @@ DohObjFree(DOH *ptr) {
|
|||
b = (DohBase *) ptr;
|
||||
if (b->flag_intern) return;
|
||||
b->data = (void *) FreeList;
|
||||
b->refcount = 0;
|
||||
if (b->meta) {
|
||||
Delete(b->meta);
|
||||
b->meta = 0;
|
||||
|
|
@ -146,3 +148,71 @@ DohObjFree(DOH *ptr) {
|
|||
b->type = 0;
|
||||
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
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,8 +88,8 @@ static void
|
|||
DelString(DOH *so) {
|
||||
String *s = (String *) ObjData(so);
|
||||
s->hashkey = -1;
|
||||
s->str = 0;
|
||||
DohFree(s->str);
|
||||
s->str = 0;
|
||||
DohFree(s);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -189,6 +189,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
int dump_classes = 0;
|
||||
int werror = 0;
|
||||
int depend = 0;
|
||||
int memory_debug = 0;
|
||||
|
||||
DOH *libfiles = 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) {
|
||||
dump_classes = 1;
|
||||
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) {
|
||||
//fputs("Help.\n",stderr);
|
||||
fputs(usage,stderr);
|
||||
|
|
@ -583,11 +587,13 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
|
||||
Node *top = Swig_cparse(cpps);
|
||||
|
||||
|
||||
if (Verbose) {
|
||||
Printf(stdout,"Processing types...\n");
|
||||
}
|
||||
Swig_process_types(top);
|
||||
|
||||
|
||||
if (Verbose) {
|
||||
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 (memory_debug) DohMemoryDebug();
|
||||
while (freeze);
|
||||
|
||||
|
||||
if ((werror) && (Swig_warn_count())) {
|
||||
return Swig_warn_count();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -949,7 +949,15 @@ SwigType_strip_qualifiers(SwigType *t) {
|
|||
if (SwigType_isqualifier(e)) continue;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -1587,6 +1595,7 @@ SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
|
|||
Delete(repbase);
|
||||
}
|
||||
{
|
||||
String *tsuffix;
|
||||
List *tparms = SwigType_parmlist(e);
|
||||
int j;
|
||||
String *nt = SwigType_templateprefix(e);
|
||||
|
|
@ -1596,10 +1605,13 @@ SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
|
|||
Printf(nt,"%s",Getitem(tparms,j));
|
||||
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);
|
||||
Append(e,nt);
|
||||
Delete(nt);
|
||||
Delete(tparms);
|
||||
}
|
||||
} else if (Swig_scopename_check(e)) {
|
||||
String *first, *rest;
|
||||
|
|
@ -1623,6 +1635,7 @@ SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
|
|||
if (j < (Len(fparms)-1)) Printf(e,",");
|
||||
}
|
||||
Printf(e,").");
|
||||
Delete(fparms);
|
||||
}
|
||||
Append(nt,e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -486,7 +486,6 @@ static SwigType *strip_arrays(SwigType *type) {
|
|||
return t;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_typemap_search()
|
||||
*
|
||||
|
|
@ -532,7 +531,9 @@ Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *na
|
|||
if (isarray) {
|
||||
/* If working with arrays, strip away all of the dimensions and replace with "ANY".
|
||||
See if that generates a match */
|
||||
if (!noarrays) noarrays = strip_arrays(ctype);
|
||||
if (!noarrays) {
|
||||
noarrays = strip_arrays(ctype);
|
||||
}
|
||||
tma = Getattr(typemaps[ts],noarrays);
|
||||
if (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;
|
||||
if (unstripped) {
|
||||
if (unstripped != type) {
|
||||
Delete(ctype);
|
||||
}
|
||||
Delete(ctype);
|
||||
ctype = unstripped;
|
||||
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);
|
||||
}
|
||||
}
|
||||
#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 */
|
||||
if (!primitive)
|
||||
if (!primitive) {
|
||||
primitive = SwigType_default(type);
|
||||
}
|
||||
tm = Getattr(typemaps[ts],primitive);
|
||||
if (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);
|
||||
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 */
|
||||
}
|
||||
result = backup;
|
||||
|
|
@ -634,6 +608,7 @@ Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *na
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_typemap_search_multi()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -176,6 +176,7 @@ int SwigType_typedef_class(String_or_char *name) {
|
|||
cname = NewString(name);
|
||||
Setmeta(cname,"class","1");
|
||||
Setattr(current_typetab,cname,cname);
|
||||
Delete(cname);
|
||||
flush_cache();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -506,23 +507,30 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
|
|||
String *namebase = 0;
|
||||
String *nameprefix = 0;
|
||||
int newtype = 0;
|
||||
static String *noscope = 0;
|
||||
|
||||
/*
|
||||
if (!noscope) {
|
||||
noscope = NewString("");
|
||||
}
|
||||
*/
|
||||
|
||||
resolved_scope = 0;
|
||||
|
||||
/*
|
||||
if (!typedef_resolve_cache) {
|
||||
typedef_resolve_cache = NewHash();
|
||||
}
|
||||
/*
|
||||
r = Getattr(typedef_resolve_cache,t);
|
||||
if (r) {
|
||||
if (r != DohNone) {
|
||||
if (r != noscope) {
|
||||
resolved_scope = Getmeta(r,"scope");
|
||||
return Copy(r);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
base = SwigType_base(t);
|
||||
|
||||
|
|
@ -551,6 +559,7 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
|
|||
if (nameprefix) {
|
||||
/* Name had a prefix on it. See if we can locate the proper scope for it */
|
||||
s = SwigType_find_scope(s,nameprefix);
|
||||
|
||||
/* Couldn't locate a scope for the type. */
|
||||
if (!s) {
|
||||
Delete(base);
|
||||
|
|
@ -586,7 +595,10 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
|
|||
}
|
||||
|
||||
if (type && (Strcmp(base,type) == 0)) {
|
||||
if (newtype) Delete(type);
|
||||
Delete(base);
|
||||
Delete(namebase);
|
||||
Delete(nameprefix);
|
||||
r = 0;
|
||||
goto return_result;
|
||||
}
|
||||
|
|
@ -600,6 +612,7 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
|
|||
int i,sz;
|
||||
int rep = 0;
|
||||
type = SwigType_templateprefix(base);
|
||||
newtype = 1;
|
||||
suffix = SwigType_templatesuffix(base);
|
||||
Append(type,"<(");
|
||||
tparms = SwigType_parmlist(base);
|
||||
|
|
@ -614,6 +627,7 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
|
|||
}
|
||||
if (tpr) {
|
||||
Append(type,tpr);
|
||||
Delete(tpr);
|
||||
rep = 1;
|
||||
} else {
|
||||
Append(type,tp);
|
||||
|
|
@ -631,12 +645,15 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
|
|||
}
|
||||
if (namebase) Delete(namebase);
|
||||
if (nameprefix) Delete(nameprefix);
|
||||
namebase = 0;
|
||||
nameprefix = 0;
|
||||
} else {
|
||||
if (SwigType_isfunction(base)) {
|
||||
List *parms;
|
||||
int i,sz;
|
||||
int rep = 0;
|
||||
type = NewString("f(");
|
||||
newtype = 1;
|
||||
parms = SwigType_parmlist(base);
|
||||
sz = Len(parms);
|
||||
for (i = 0; i < sz; i++) {
|
||||
|
|
@ -649,6 +666,7 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
|
|||
}
|
||||
if (tpr) {
|
||||
Append(type,tpr);
|
||||
Delete(tpr);
|
||||
rep = 1;
|
||||
} else {
|
||||
Append(type,tp);
|
||||
|
|
@ -667,6 +685,7 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
|
|||
rt = SwigType_typedef_resolve(mtype);
|
||||
if (rt) {
|
||||
type = NewStringf("m(%s).", rt);
|
||||
newtype = 1;
|
||||
Delete(rt);
|
||||
}
|
||||
Delete(mtype);
|
||||
|
|
@ -700,17 +719,25 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
|
|||
}
|
||||
|
||||
return_result:
|
||||
if (!r) {
|
||||
Setattr(typedef_resolve_cache,NewString(t),DohNone);
|
||||
} else {
|
||||
Setattr(typedef_resolve_cache,NewString(t),r);
|
||||
Setmeta(r,"scope",resolved_scope);
|
||||
r = Copy(r);
|
||||
/*
|
||||
{
|
||||
String *key = NewString(t);
|
||||
if (!r) {
|
||||
Setattr(typedef_resolve_cache,key,noscope);
|
||||
} 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;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* SwigType_typedef_resolve_all()
|
||||
*
|
||||
|
|
@ -734,8 +761,12 @@ SwigType *SwigType_typedef_resolve_all(SwigType *t) {
|
|||
r = n;
|
||||
}
|
||||
{
|
||||
String *key;
|
||||
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;
|
||||
}
|
||||
|
|
@ -841,6 +872,7 @@ SwigType *SwigType_typedef_qualified(SwigType *t)
|
|||
value = qn;
|
||||
continue;
|
||||
} else {
|
||||
Delete(qn);
|
||||
break;
|
||||
}
|
||||
} else if ((Strcmp(nodeType(n),"cdecl") == 0) && (Getattr(n,"value"))) {
|
||||
|
|
@ -852,6 +884,7 @@ SwigType *SwigType_typedef_qualified(SwigType *t)
|
|||
break;
|
||||
}
|
||||
Append(qprefix,value);
|
||||
Delete(value);
|
||||
} else {
|
||||
Append(qprefix,p);
|
||||
}
|
||||
|
|
@ -871,6 +904,7 @@ SwigType *SwigType_typedef_qualified(SwigType *t)
|
|||
Append(e,qprefix);
|
||||
Delete(tprefix);
|
||||
Delete(qprefix);
|
||||
Delete(parms);
|
||||
}
|
||||
if (Strncmp(e,"::",2) == 0) {
|
||||
Delitem(e,0);
|
||||
|
|
@ -883,7 +917,9 @@ SwigType *SwigType_typedef_qualified(SwigType *t)
|
|||
String *p;
|
||||
p = Firstitem(parms);
|
||||
while (p) {
|
||||
Append(s,SwigType_typedef_qualified(p));
|
||||
String *pq = SwigType_typedef_qualified(p);
|
||||
Append(s,pq);
|
||||
Delete(pq);
|
||||
p = Nextitem(parms);
|
||||
if (p) {
|
||||
Append(s,",");
|
||||
|
|
@ -892,6 +928,7 @@ SwigType *SwigType_typedef_qualified(SwigType *t)
|
|||
Append(s,").");
|
||||
Append(result,s);
|
||||
Delete(s);
|
||||
Delete(parms);
|
||||
} else if (SwigType_isarray(e)) {
|
||||
String *ndim;
|
||||
String *dim = SwigType_parm(e);
|
||||
|
|
@ -904,7 +941,14 @@ SwigType *SwigType_typedef_qualified(SwigType *t)
|
|||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -1157,6 +1201,7 @@ void SwigType_remember_clientdata(SwigType *t, const String_or_char *clientdata)
|
|||
Hash *h;
|
||||
SwigType *fr;
|
||||
SwigType *qr;
|
||||
String *tkey;
|
||||
|
||||
if (!r_mangled) {
|
||||
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;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue