[Python-checkins] r45235 - in python/trunk: Include/genobject.h Modules/gcmodule.c Objects/genobject.c Python/ceval.c
phillip.eby
python-checkins at python.org
Mon Apr 10 19:51:08 CEST 2006
Author: phillip.eby
Date: Mon Apr 10 19:51:05 2006
New Revision: 45235
Modified:
python/trunk/Include/genobject.h
python/trunk/Modules/gcmodule.c
python/trunk/Objects/genobject.c
python/trunk/Python/ceval.c
Log:
SF Patch #1463867: Improved generator finalization to allow generators
that are suspended outside of any try/except/finally blocks to be
garbage collected even if they are part of a cycle. Generators that
suspend inside of an active try/except or try/finally block (including
those created by a ``with`` statement) are still not GC-able if they
are part of a cycle, however.
Modified: python/trunk/Include/genobject.h
==============================================================================
--- python/trunk/Include/genobject.h (original)
+++ python/trunk/Include/genobject.h Mon Apr 10 19:51:05 2006
@@ -28,6 +28,7 @@
#define PyGen_CheckExact(op) ((op)->ob_type == &PyGen_Type)
PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *);
+PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *);
#ifdef __cplusplus
}
Modified: python/trunk/Modules/gcmodule.c
==============================================================================
--- python/trunk/Modules/gcmodule.c (original)
+++ python/trunk/Modules/gcmodule.c Mon Apr 10 19:51:05 2006
@@ -413,8 +413,12 @@
assert(delstr != NULL);
return _PyInstance_Lookup(op, delstr) != NULL;
}
- else
+ else if (PyType_HasFeature(op->ob_type, Py_TPFLAGS_HEAPTYPE))
return op->ob_type->tp_del != NULL;
+ else if (PyGen_CheckExact(op))
+ return PyGen_NeedsFinalizing((PyGenObject *)op);
+ else
+ return 0;
}
/* Move the objects in unreachable with __del__ methods into `finalizers`.
Modified: python/trunk/Objects/genobject.c
==============================================================================
--- python/trunk/Objects/genobject.c (original)
+++ python/trunk/Objects/genobject.c Mon Apr 10 19:51:05 2006
@@ -5,6 +5,7 @@
#include "genobject.h"
#include "ceval.h"
#include "structmember.h"
+#include "opcode.h"
static int
gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
@@ -358,3 +359,22 @@
_PyObject_GC_TRACK(gen);
return (PyObject *)gen;
}
+
+int
+PyGen_NeedsFinalizing(PyGenObject *gen)
+{
+ int i;
+ PyFrameObject *f = gen->gi_frame;
+
+ if ((PyObject *)f == Py_None || f->f_stacktop==NULL || f->f_iblock<=0)
+ return 0; /* no frame or no blockstack == no finalization */
+
+ for (i=f->f_iblock; i>=0; i--) {
+ if (f->f_blockstack[i].b_type != SETUP_LOOP)
+ /* any block type besides a loop requires cleanup */
+ return 1;
+ }
+
+ /* No blocks except loops, it's safe to skip finalization */
+ return 0;
+}
Modified: python/trunk/Python/ceval.c
==============================================================================
--- python/trunk/Python/ceval.c (original)
+++ python/trunk/Python/ceval.c Mon Apr 10 19:51:05 2006
@@ -2179,6 +2179,9 @@
case SETUP_LOOP:
case SETUP_EXCEPT:
case SETUP_FINALLY:
+ /* NOTE: If you add any new block-setup opcodes that are not try/except/finally
+ handlers, you may need to update the PyGen_NeedsFinalizing() function. */
+
PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg,
STACK_LEVEL());
continue;
More information about the Python-checkins
mailing list