[Python-Dev] iterzip()

Martin v. Loewis martin@v.loewis.de
30 Apr 2002 19:28:38 +0200


Guido van Rossum <guido@python.org> writes:

> > That could happen in gen0 already: when traversing an object, watch
> > whether it contains any tracked objects. If it doesn't, invoke
> > tp_is_immutable, if that returns true, untrack it.
> 
> Unfortunately, the visit API doesn't make it easy to watch this; a
> tuple calls visit() on its items but learns nothing except whether it
> failed.  (I've never seen a visit() implementation that could fail, so
> I'm not sure even why the return code exists.)

However, the visit function could record this result. For example, for
move_root_reachable:

struct m_r_r{
  PyGC_Head *reachable;
  int immutable_nonnested;
};

static int
visit_move(PyObject *op, struct m_r_r *tolist)
{
  if(PyObject_IS_GC(op)){
     if(GC_is_tracked(op))
       m_r_r->tolist.immutable_nonnested = 0;
     ...
  }
  return 0;
}

static void
move_root_reachable(PyGC_Head *reachable)
{
   struct m_r_r my_m_r_r;
   my_m_r_r.reachable = reachable;
	for (; gc != reachable; gc=gc->gc.gc_next) {
		/* careful, reachable list is growing here */
		PyObject *op = FROM_GC(gc);
		traverse = op->ob_type->tp_traverse;
                my_m_r_r.immutable_nonnested = 1;
		(void) traverse(op,
			       (visitproc)visit_move,
			       (void *)reachable);
                if(my_m_r_r.immutable_nonnested
                   && op->ob_type->tp_immutable(op)){
                    GC_Untrack(op);
                }
	}
}

I'm not sure whether move_root_reachable would be the right place to
untrack those objects, but the information is all there.

Regards,
Martin