X Tutup
Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3038a78
Faster marking of reachable objects
markshannon Nov 9, 2024
c024484
Handle more classes in fast marking
markshannon Nov 10, 2024
e8497ae
Add support for asyn generators on fast path. Simplify counting
markshannon Nov 11, 2024
4c1a6bc
Check stackref before converting to PyObject *
markshannon Nov 11, 2024
6efb4c0
Rename stuff
markshannon Nov 13, 2024
b1c7ab0
Remove expand_region_transitively_reachable and use move_all_transiti…
markshannon Nov 13, 2024
07f228b
Merge branch 'main' into faster-marking
markshannon Dec 2, 2024
51ff78e
Fix compiler warnings and linkage
markshannon Dec 2, 2024
df907b5
Fix another linkage issue
markshannon Dec 2, 2024
9ca64f5
Try 'extern'
markshannon Dec 2, 2024
bda13f4
Go back to PyAPI_FUNC and move functions together
markshannon Dec 2, 2024
d9d63c8
Use _Py_FALLTHROUGH
markshannon Dec 2, 2024
57b8820
Add necessary #ifndef Py_GIL_DISABLED
markshannon Dec 2, 2024
a607059
Go back to using tp_traverse, but make traversal more efficient
markshannon Dec 3, 2024
1545508
Tidy up
markshannon Dec 3, 2024
a1a38c8
A bit more tidying up
markshannon Dec 3, 2024
68fc90b
Move all work to do calculations to one place
markshannon Dec 3, 2024
8893cf5
Assume that increments are 50% garbage for work done calculation
markshannon Dec 3, 2024
ba20c7c
Elaborate comment
markshannon Dec 4, 2024
8262bf0
More tweaking of thresholds
markshannon Dec 4, 2024
3c2116e
Do some algebra
markshannon Dec 4, 2024
72d0284
Revert to 2M+I from 3M+I
markshannon Dec 4, 2024
0f182e2
Address review comments
markshannon Dec 5, 2024
d3c21bb
Address review comments and clarify code a bit
markshannon Dec 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Merge branch 'main' into faster-marking
  • Loading branch information
markshannon committed Dec 2, 2024
commit 07f228ba7441d0c832768153ff9c7a0359a1f820
6 changes: 5 additions & 1 deletion Include/internal/pycore_stackref.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,11 @@ static const _PyStackRef PyStackRef_NULL = { .bits = 0 };

#define PyStackRef_IsNonNullMortal(stackref) (!PyStackRef_IsNull(stackref) && !_Py_IsImmortal(PyStackRef_AsPyObjectBorrow(stackref)))

// Note: this is a macro because MSVC (Windows) has trouble inlining it.
// Check if a stackref is exactly the same as another stackref, including the
// the deferred bit. This can only be used safely if you know that the deferred
// bits of `a` and `b` match.
#define PyStackRef_IsExactly(a, b) \
(assert(((a).bits & Py_TAG_BITS) == ((b).bits & Py_TAG_BITS)), (a).bits == (b).bits)

// Checks that mask out the deferred bit in the free threading build.
#define PyStackRef_IsNone(ref) (PyStackRef_AsPyObjectBorrow(ref) == Py_None)
Expand Down
48 changes: 14 additions & 34 deletions Python/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1443,7 +1443,6 @@ extern void _PyList_MoveUnvisited(PyObject *op, PyGC_Head *to, int visited_space
extern void _PyTuple_MoveUnvisited(PyObject *op, PyGC_Head *to, int visited_space);
extern void _PyType_MoveUnvisited(PyObject *op, PyGC_Head *to, int visited_space);


static Py_ssize_t
move_all_transitively_reachable(PyGC_Head *reachable, PyGC_Head *visited, int visited_space)
{
Expand Down Expand Up @@ -1520,30 +1519,7 @@ move_all_transitively_reachable(PyGC_Head *reachable, PyGC_Head *visited, int vi
return objects_marked;
}

static Py_ssize_t
mark_global_roots(PyInterpreterState *interp, PyGC_Head *visited, int visited_space)
{
PyGC_Head reachable;
gc_list_init(&reachable);
Py_ssize_t objects_marked = 0;
_PyGC_MoveUnvisited(interp->sysdict, &reachable, visited_space);
_PyGC_MoveUnvisited(interp->builtins, &reachable, visited_space);
_PyGC_MoveUnvisited(interp->dict, &reachable, visited_space);
struct types_state *types = &interp->types;
for (int i = 0; i < _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES; i++) {
_PyGC_MoveUnvisited(types->builtins.initialized[i].tp_dict, &reachable, visited_space);
_PyGC_MoveUnvisited(types->builtins.initialized[i].tp_subclasses, &reachable, visited_space);
}
for (int i = 0; i < _Py_MAX_MANAGED_STATIC_EXT_TYPES; i++) {
_PyGC_MoveUnvisited(types->for_extensions.initialized[i].tp_dict, &reachable, visited_space);
_PyGC_MoveUnvisited(types->for_extensions.initialized[i].tp_subclasses, &reachable, visited_space);
}
objects_marked += move_all_transitively_reachable(&reachable, visited, visited_space);
assert(gc_list_is_empty(&reachable));
return objects_marked + 20;
}

static Py_ssize_t
static intptr_t
mark_stacks(PyInterpreterState *interp, PyGC_Head *visited, int visited_space, bool start)
{
PyGC_Head reachable;
Expand Down Expand Up @@ -1584,19 +1560,19 @@ mark_global_roots(PyInterpreterState *interp, PyGC_Head *visited, int visited_sp
PyGC_Head reachable;
gc_list_init(&reachable);
Py_ssize_t objects_marked = 0;
objects_marked += move_to_reachable(interp->sysdict, &reachable, visited_space);
objects_marked += move_to_reachable(interp->builtins, &reachable, visited_space);
objects_marked += move_to_reachable(interp->dict, &reachable, visited_space);
_PyGC_MoveUnvisited(interp->sysdict, &reachable, visited_space);
_PyGC_MoveUnvisited(interp->builtins, &reachable, visited_space);
_PyGC_MoveUnvisited(interp->dict, &reachable, visited_space);
struct types_state *types = &interp->types;
for (int i = 0; i < _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES; i++) {
objects_marked += move_to_reachable(types->builtins.initialized[i].tp_dict, &reachable, visited_space);
objects_marked += move_to_reachable(types->builtins.initialized[i].tp_subclasses, &reachable, visited_space);
_PyGC_MoveUnvisited(types->builtins.initialized[i].tp_dict, &reachable, visited_space);
_PyGC_MoveUnvisited(types->builtins.initialized[i].tp_subclasses, &reachable, visited_space);
}
for (int i = 0; i < _Py_MAX_MANAGED_STATIC_EXT_TYPES; i++) {
objects_marked += move_to_reachable(types->for_extensions.initialized[i].tp_dict, &reachable, visited_space);
objects_marked += move_to_reachable(types->for_extensions.initialized[i].tp_subclasses, &reachable, visited_space);
_PyGC_MoveUnvisited(types->for_extensions.initialized[i].tp_dict, &reachable, visited_space);
_PyGC_MoveUnvisited(types->for_extensions.initialized[i].tp_subclasses, &reachable, visited_space);
}
objects_marked += mark_all_reachable(&reachable, visited, visited_space);
objects_marked += move_all_transitively_reachable(&reachable, visited, visited_space);
assert(gc_list_is_empty(&reachable));
return objects_marked;
}
Expand Down Expand Up @@ -1659,7 +1635,11 @@ gc_collect_increment(PyThreadState *tstate, struct gc_collection_stats *stats)
}
PyGC_Head *not_visited = &gcstate->old[gcstate->visited_space^1].head;
PyGC_Head *visited = &gcstate->old[gcstate->visited_space].head;
Py_ssize_t objects_marked = mark_stacks(tstate->interp, visited, gcstate->visited_space, false);
int scale_factor = gcstate->old[0].threshold;
if (scale_factor < 2) {
scale_factor = 2;
}
intptr_t objects_marked = mark_stacks(tstate->interp, visited, gcstate->visited_space, false);
GC_STAT_ADD(1, objects_transitively_reachable, objects_marked);
gcstate->work_to_do -= objects_marked;
gc_list_set_space(&gcstate->young.head, gcstate->visited_space);
Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.
X Tutup