From 6ec3c653da9ffd098f522261d5592e64ff8e7889 Mon Sep 17 00:00:00 2001
From: Sjoerd Mullender <sjoerd@acm.org>
Date: Tue, 29 Aug 1995 09:18:14 +0000
Subject: 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!

---
 Objects/object.c   | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Python/sysmodule.c | 34 ++++++++++++++++++++++++++++++++
 2 files changed, 92 insertions(+)

diff --git a/Objects/object.c b/Objects/object.c
index 1643ec6..4899ef1 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -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
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 6e153e4..5fc098d 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -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
-- 
cgit v0.12

