mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
gh-115124: Use _PyObject_ASSERT() in gc.c (#115125)
Replace assert() with _PyObject_ASSERT() in gc.c to dump the object when an assertion fails.
This commit is contained in:
parent
732faf17a6
commit
94f1334e52
1 changed files with 22 additions and 15 deletions
37
Python/gc.c
37
Python/gc.c
|
@ -394,16 +394,17 @@ update_refs(PyGC_Head *containers)
|
||||||
|
|
||||||
while (gc != containers) {
|
while (gc != containers) {
|
||||||
next = GC_NEXT(gc);
|
next = GC_NEXT(gc);
|
||||||
|
PyObject *op = FROM_GC(gc);
|
||||||
/* Move any object that might have become immortal to the
|
/* Move any object that might have become immortal to the
|
||||||
* permanent generation as the reference count is not accurately
|
* permanent generation as the reference count is not accurately
|
||||||
* reflecting the actual number of live references to this object
|
* reflecting the actual number of live references to this object
|
||||||
*/
|
*/
|
||||||
if (_Py_IsImmortal(FROM_GC(gc))) {
|
if (_Py_IsImmortal(op)) {
|
||||||
gc_list_move(gc, &get_gc_state()->permanent_generation.head);
|
gc_list_move(gc, &get_gc_state()->permanent_generation.head);
|
||||||
gc = next;
|
gc = next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
gc_reset_refs(gc, Py_REFCNT(FROM_GC(gc)));
|
gc_reset_refs(gc, Py_REFCNT(op));
|
||||||
/* Python's cyclic gc should never see an incoming refcount
|
/* Python's cyclic gc should never see an incoming refcount
|
||||||
* of 0: if something decref'ed to 0, it should have been
|
* of 0: if something decref'ed to 0, it should have been
|
||||||
* deallocated immediately at that time.
|
* deallocated immediately at that time.
|
||||||
|
@ -422,7 +423,7 @@ update_refs(PyGC_Head *containers)
|
||||||
* so serious that maybe this should be a release-build
|
* so serious that maybe this should be a release-build
|
||||||
* check instead of an assert?
|
* check instead of an assert?
|
||||||
*/
|
*/
|
||||||
_PyObject_ASSERT(FROM_GC(gc), gc_get_refs(gc) != 0);
|
_PyObject_ASSERT(op, gc_get_refs(gc) != 0);
|
||||||
gc = next;
|
gc = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -488,7 +489,7 @@ visit_reachable(PyObject *op, void *arg)
|
||||||
}
|
}
|
||||||
// It would be a logic error elsewhere if the collecting flag were set on
|
// It would be a logic error elsewhere if the collecting flag were set on
|
||||||
// an untracked object.
|
// an untracked object.
|
||||||
assert(gc->_gc_next != 0);
|
_PyObject_ASSERT(op, gc->_gc_next != 0);
|
||||||
|
|
||||||
if (gc->_gc_next & NEXT_MASK_UNREACHABLE) {
|
if (gc->_gc_next & NEXT_MASK_UNREACHABLE) {
|
||||||
/* This had gc_refs = 0 when move_unreachable got
|
/* This had gc_refs = 0 when move_unreachable got
|
||||||
|
@ -660,7 +661,9 @@ static void
|
||||||
move_legacy_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
|
move_legacy_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
|
||||||
{
|
{
|
||||||
PyGC_Head *gc, *next;
|
PyGC_Head *gc, *next;
|
||||||
assert((unreachable->_gc_next & NEXT_MASK_UNREACHABLE) == 0);
|
_PyObject_ASSERT(
|
||||||
|
FROM_GC(unreachable),
|
||||||
|
(unreachable->_gc_next & NEXT_MASK_UNREACHABLE) == 0);
|
||||||
|
|
||||||
/* March over unreachable. Move objects with finalizers into
|
/* March over unreachable. Move objects with finalizers into
|
||||||
* `finalizers`.
|
* `finalizers`.
|
||||||
|
@ -683,10 +686,14 @@ static inline void
|
||||||
clear_unreachable_mask(PyGC_Head *unreachable)
|
clear_unreachable_mask(PyGC_Head *unreachable)
|
||||||
{
|
{
|
||||||
/* Check that the list head does not have the unreachable bit set */
|
/* Check that the list head does not have the unreachable bit set */
|
||||||
assert(((uintptr_t)unreachable & NEXT_MASK_UNREACHABLE) == 0);
|
_PyObject_ASSERT(
|
||||||
|
FROM_GC(unreachable),
|
||||||
|
((uintptr_t)unreachable & NEXT_MASK_UNREACHABLE) == 0);
|
||||||
|
_PyObject_ASSERT(
|
||||||
|
FROM_GC(unreachable),
|
||||||
|
(unreachable->_gc_next & NEXT_MASK_UNREACHABLE) == 0);
|
||||||
|
|
||||||
PyGC_Head *gc, *next;
|
PyGC_Head *gc, *next;
|
||||||
assert((unreachable->_gc_next & NEXT_MASK_UNREACHABLE) == 0);
|
|
||||||
for (gc = GC_NEXT(unreachable); gc != unreachable; gc = next) {
|
for (gc = GC_NEXT(unreachable); gc != unreachable; gc = next) {
|
||||||
_PyObject_ASSERT((PyObject*)FROM_GC(gc), gc->_gc_next & NEXT_MASK_UNREACHABLE);
|
_PyObject_ASSERT((PyObject*)FROM_GC(gc), gc->_gc_next & NEXT_MASK_UNREACHABLE);
|
||||||
gc->_gc_next &= ~NEXT_MASK_UNREACHABLE;
|
gc->_gc_next &= ~NEXT_MASK_UNREACHABLE;
|
||||||
|
@ -840,7 +847,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
|
||||||
*/
|
*/
|
||||||
if (gc_is_collecting(AS_GC((PyObject *)wr))) {
|
if (gc_is_collecting(AS_GC((PyObject *)wr))) {
|
||||||
/* it should already have been cleared above */
|
/* it should already have been cleared above */
|
||||||
assert(wr->wr_object == Py_None);
|
_PyObject_ASSERT((PyObject*)wr, wr->wr_object == Py_None);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -851,9 +858,8 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
|
||||||
|
|
||||||
/* Move wr to wrcb_to_call, for the next pass. */
|
/* Move wr to wrcb_to_call, for the next pass. */
|
||||||
wrasgc = AS_GC((PyObject *)wr);
|
wrasgc = AS_GC((PyObject *)wr);
|
||||||
assert(wrasgc != next); /* wrasgc is reachable, but
|
// wrasgc is reachable, but next isn't, so they can't be the same
|
||||||
next isn't, so they can't
|
_PyObject_ASSERT((PyObject *)wr, wrasgc != next);
|
||||||
be the same */
|
|
||||||
gc_list_move(wrasgc, &wrcb_to_call);
|
gc_list_move(wrasgc, &wrcb_to_call);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1773,13 +1779,14 @@ _Py_ScheduleGC(PyInterpreterState *interp)
|
||||||
void
|
void
|
||||||
_PyObject_GC_Link(PyObject *op)
|
_PyObject_GC_Link(PyObject *op)
|
||||||
{
|
{
|
||||||
PyGC_Head *g = AS_GC(op);
|
PyGC_Head *gc = AS_GC(op);
|
||||||
assert(((uintptr_t)g & (sizeof(uintptr_t)-1)) == 0); // g must be correctly aligned
|
// gc must be correctly aligned
|
||||||
|
_PyObject_ASSERT(op, ((uintptr_t)gc & (sizeof(uintptr_t)-1)) == 0);
|
||||||
|
|
||||||
PyThreadState *tstate = _PyThreadState_GET();
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
GCState *gcstate = &tstate->interp->gc;
|
GCState *gcstate = &tstate->interp->gc;
|
||||||
g->_gc_next = 0;
|
gc->_gc_next = 0;
|
||||||
g->_gc_prev = 0;
|
gc->_gc_prev = 0;
|
||||||
gcstate->generations[0].count++; /* number of allocated GC objects */
|
gcstate->generations[0].count++; /* number of allocated GC objects */
|
||||||
if (gcstate->generations[0].count > gcstate->generations[0].threshold &&
|
if (gcstate->generations[0].count > gcstate->generations[0].threshold &&
|
||||||
gcstate->enabled &&
|
gcstate->enabled &&
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue