Skip to content

Commit 4c1a6bc

Browse files
committed
Check stackref before converting to PyObject *
1 parent e8497ae commit 4c1a6bc

File tree

2 files changed

+14
-16
lines changed

2 files changed

+14
-16
lines changed

Include/internal/pycore_stackref.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ static const _PyStackRef PyStackRef_NULL = { .bits = 0 };
190190

191191
#endif // Py_GIL_DISABLED
192192

193+
#define PyStackRef_IsNonNullMortal(stackref) (!PyStackRef_IsNull(stackref) && !_Py_IsImmortal(PyStackRef_AsPyObjectBorrow(stackref)))
194+
193195
// Note: this is a macro because MSVC (Windows) has trouble inlining it.
194196

195197
#define PyStackRef_Is(a, b) ((a).bits == (b).bits)

Python/gc.c

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,6 +1431,8 @@ _PyGC_MoveToReachable(PyObject *op, PyGC_Head *reachable, int visited_space)
14311431
}
14321432
}
14331433

1434+
/* TO DO -- Move this into pycore_stackref.h */
1435+
14341436
void
14351437
_PyFrame_MoveToReachable(_PyInterpreterFrame *frame, PyGC_Head *reachable, int visited_space)
14361438
{
@@ -1441,27 +1443,21 @@ _PyFrame_MoveToReachable(_PyInterpreterFrame *frame, PyGC_Head *reachable, int v
14411443
_PyGC_MoveToReachable(func, reachable, visited_space);
14421444
while (sp > locals) {
14431445
sp--;
1444-
if (PyStackRef_IsNull(*sp)) {
1445-
continue;
1446-
}
1447-
PyObject *op = PyStackRef_AsPyObjectBorrow(*sp);
1448-
if (!_Py_IsImmortal(op) && _PyObject_IS_GC(op)) {
1449-
PyGC_Head *gc = AS_GC(op);
1450-
if (_PyObject_GC_IS_TRACKED(op) &&
1451-
gc_old_space(gc) != visited_space) {
1452-
gc_flip_old_space(gc);
1453-
gc_list_move(gc, reachable);
1446+
_PyStackRef ref = *sp;
1447+
if (PyStackRef_IsNonNullMortal(ref)) {
1448+
PyObject *op = PyStackRef_AsPyObjectBorrow(ref);
1449+
if (_PyObject_IS_GC(op)) {
1450+
PyGC_Head *gc = AS_GC(op);
1451+
if (_PyObject_GC_IS_TRACKED(op) &&
1452+
gc_old_space(gc) != visited_space) {
1453+
gc_flip_old_space(gc);
1454+
gc_list_move(gc, reachable);
1455+
}
14541456
}
14551457
}
14561458
}
14571459
}
14581460

1459-
/* This should be refactored:
1460-
* 1. Make `move_to_reachable` an inline "private API" function
1461-
* 2. Move bodies of each case below into a _PyXXX_MarkReachable function in file for type XXX.
1462-
* 3. Trust lto to inline those functions.
1463-
*/
1464-
14651461
extern void _PySet_MoveToReachable(PyObject *op, PyGC_Head *reachable, int visited_space);
14661462
extern void _PyDict_MoveToReachable(PyObject *op, PyGC_Head *reachable, int visited_space);
14671463
extern void _PyGen_MoveToReachable(PyObject *op, PyGC_Head *reachable, int visited_space);

0 commit comments

Comments
 (0)