Implemented two new functions in sys:

getcounts() returns a list of counts of allocations and
		deallocations for all different object types.
	getobjects(n [, type ]) returns a list of recently allocated
		and not-yet-freed objects of the given type (all
		objects if no type given).  Only the n most recent
		(all if n==0) objects are returned.
getcounts is only available if compiled with -DCOUNT_ALLOCS,
getobjects is only available if compiled with -DTRACE_REFS.  Note that
everything must be compiled with these options!
This commit is contained in:
Sjoerd Mullender 1995-08-29 09:18:14 +00:00
parent b0a2ce515b
commit 6ec3c653da
2 changed files with 92 additions and 0 deletions

View File

@ -56,6 +56,33 @@ dump_counts()
null_strings, one_strings);
}
PyObject *
get_counts()
{
PyTypeObject *tp;
PyObject *result;
PyObject *v;
result = PyList_New(0);
if (result == NULL)
return NULL;
for (tp = type_list; tp; tp = tp->tp_next) {
v = Py_BuildValue("(siii)", tp->tp_name, tp->tp_alloc,
tp->tp_free, tp->tp_maxalloc);
if (v == NULL) {
Py_DECREF(result);
return NULL;
}
if (PyList_Append(result, v) < 0) {
Py_DECREF(v);
Py_DECREF(result);
return NULL;
}
Py_DECREF(v);
}
return result;
}
void
inc_count(tp)
typeobject *tp;
@ -513,4 +540,35 @@ printrefs(fp)
}
}
PyObject *
getobjects(self, args)
PyObject *self;
PyObject *args;
{
int i, n;
PyObject *t = NULL;
PyObject *res, *op;
if (!PyArg_ParseTuple(args, "i|O", &n, &t))
return NULL;
op = refchain._ob_next;
res = PyList_New(0);
if (res == NULL)
return NULL;
for (i = 0; (n == 0 || i < n) && op != &refchain; i++) {
while (op == self || op == args || op == res || op == t ||
t != NULL && op->ob_type != (PyTypeObject *) t) {
op = op->_ob_next;
if (op == &refchain)
return res;
}
if (PyList_Append(res, op) < 0) {
Py_DECREF(res);
return NULL;
}
op = op->_ob_next;
}
return res;
}
#endif

View File

@ -154,8 +154,42 @@ sys_mdebug(self, args)
}
#endif /* USE_MALLOPT */
static object *
sys_getrefcount(self, args)
object *self;
object *args;
{
object *arg;
if (!getargs(args, "O", &arg))
return NULL;
return newintobject((long) arg->ob_refcnt);
}
#ifdef COUNT_ALLOCS
static PyObject *
sys_getcounts(self, args)
PyObject *self, *args;
{
extern PyObject *get_counts Py_PROTO((void));
if (!PyArg_Parse(args, ""))
return NULL;
return get_counts();
}
#endif
#ifdef TRACE_REFS
extern PyObject *getobjects Py_PROTO((PyObject *, PyObject *));
#endif
static struct methodlist sys_methods[] = {
{"exit", sys_exit, 0},
{"getrefcount", sys_getrefcount, 0},
#ifdef COUNT_ALLOCS
{"getcounts", sys_getcounts, 0},
#endif
#ifdef TRACE_REFS
{"getobjects", getobjects, 1},
#endif
#ifdef USE_MALLOPT
{"mdebug", sys_mdebug, 0},
#endif