8000 bpo-46753: Add the empty tuple to the _PyRuntimeState.global_objects. by ericsnowcurrently · Pull Request #31345 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-46753: Add the empty tuple to the _PyRuntimeState.global_objects. #31345

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7fef0be
Add the empty tuple to the _PyRuntimeState.global_objects.
ericsnowcurrently Feb 14, 2022
9f0aa44
Use the global empty tuple.
ericsnowcurrently Feb 14, 2022
21ce6aa
Merge branch 'main' into global-objects-empty-tuple
ericsnowcurrently Feb 15, 2022
ba1b4cc
Leave space for the empty GC head.
ericsnowcurrently Feb 15, 2022
67ebfd6
Revert "Leave space for the empty GC head."
ericsnowcurrently Feb 15, 2022
df35d70
Add PyTuple_Type.tp_is_gc().
ericsnowcurrently Feb 15, 2022
24ca51c
Inline tuple_get_empty().
ericsnowcurrently Feb 15, 2022
55b8eb0
Switch back to allocated an unused PyGC_Head for the empty tuple.
ericsnowcurrently Feb 15, 2022
ab721be
Skip tupledealloc() if it's the empty tuple.
ericsnowcurrently Feb 15, 2022
7b89727
Return the empty tuple when resizing to 0.
ericsnowcurrently Feb 16, 2022
2fedc9c
Use the empty tuple when appropriate in deepfreeze.c.
ericsnowcurrently Feb 16, 2022
dd0a1a2
Disassociate the empty tuple from the freelist logic.
ericsnowcurrently Feb 16, 2022
5e729d8
Merge branch 'main' into global-objects-empty-tuple
ericsnowcurrently Feb 23, 2022
deddeb5
Allow deallocating an empty tuple if a subclass.
ericsnowcurrently Feb 23, 2022
efed1d1
Return a new reference from tuple_get_empty().
ericsnowcurrently Feb 23, 2022
923c8cc
Add _PyGC_Head_UNUSED.
ericsnowcurrently Feb 24, 2022
631d12b
Clean up tupledealloc() a little.
ericsnowcurrently Feb 24, 2022
3264e8d
Drop get_tuple_state().
ericsnowcurrently Feb 24, 2022
9dfee07
Consolidate the freelist code.
ericsnowcurrently Feb 24, 2022
e272804
Merge branch 'main' into global-objects-empty-tuple
ericsnowcurrently Feb 25, 2022
597f1bd
Do not use _Py_NewRef().
ericsnowcurrently Feb 25, 2022
fa2edad
Calling tupledealloc() on the empty singleton is an error.
ericsnowcurrently Feb 25, 2022
f4acc36
Tweak _PyTuple_Resize().
ericsnowcurrently Feb 25, 2022
460ae61
Roll back the global singleton part.
ericsnowcurrently Feb 25, 2022
c163aca
Re-apply the global singleton part.
ericsnowcurrently Feb 25, 2022
4ac3d66
Make sure struct _Py_tuple_state is never empty.
ericsnowcurrently Feb 28, 2022
11a9311
Clarify about freelists a little.
ericsnowcurrently Feb 28, 2022
fdc82d2
Fix a preprocessor condition.
ericsnowcurrently Feb 28, 2022
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
Use the global empty tuple.
  • Loading branch information
ericsnowcurrently committed Feb 14, 2022
commit 9f0aa44867030a5d21f57b5fc0fa167683b6530f
1 change: 0 additions & 1 deletion Include/internal/pycore_tuple.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ extern "C" {

/* runtime lifecycle */

extern PyStatus _PyTuple_InitGlobalObjects(PyInterpreterState *);
extern PyStatus _PyTuple_InitTypes(PyInterpreterState *);
extern void _PyTuple_Fini(PyInterpreterState *);

Expand Down
68 changes: 2 additions & 66 deletions Objects/tupleobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,43 +100,11 @@ tuple_alloc(Py_ssize_t size)
return op;
}

static int
tuple_create_empty_tuple_singleton(struct _Py_tuple_state *state)
{
#if PyTuple_MAXSAVESIZE > 0
assert(state->free_list[0] == NULL);

PyTupleObject *op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, 0);
if (op == NULL) {
return -1;
}
// The empty tuple singleton is not tracked by the GC.
// It does not contain any Python object.

state->free_list[0] = op;
state->numfree[0]++;

assert(state->numfree[0] == 1);
#endif
return 0;
}


static PyObject *
tuple_get_empty(void)
{
#if PyTuple_MAXSAVESIZE > 0
struct _Py_tuple_state *state = get_tuple_state();
PyTupleObject *op = state->free_list[0];
// tuple_get_empty() must not be called before _PyTuple_Init()
// or after _PyTuple_Fini()
assert(op != NULL);
#ifdef Py_DEBUG
assert(state->numfree[0] != -1);
#endif

Py_INCREF(op);
return (PyObject *) op;
return (PyObject *)&_Py_SINGLETON(tuple_empty);
#else
return PyTuple_New(0);
#endif
Expand Down Expand Up @@ -289,19 +257,11 @@ tupledealloc(PyTupleObject *op)
goto done; /* return */
}
#endif
Py_TYPE(op)->tp_free((PyObject *)op);
}
#if defined(Py_DEBUG) && PyTuple_MAXSAVESIZE > 0
else {
assert(len == 0);
struct _Py_tuple_state *state = get_tuple_state();
// The empty tuple singleton must only be deallocated by
// _PyTuple_Fini(): not before, not after
if (op == state->free_list[0] && state->numfree[0] != 0) {
_Py_FatalRefcountError("deallocating the empty tuple singleton");
}
}
#endif
Py_TYPE(op)->tp_free((PyObject *)op);

#if PyTuple_MAXSAVESIZE > 0
done:
Expand Down Expand Up @@ -1078,22 +1038,10 @@ _PyTuple_ClearFreeList(PyInterpreterState *interp)
PyObject_GC_Del(q);
}
}
// the empty tuple singleton is only cleared by _PyTuple_Fini()
#endif
}


PyStatus
_PyTuple_InitGlobalObjects(PyInterpreterState *interp)
{
struct _Py_tuple_state *state = &interp->tuple;
if (tuple_create_empty_tuple_singleton(state) < 0) {
return _PyStatus_NO_MEMORY();
}
return _PyStatus_OK();
}


PyStatus
_PyTuple_InitTypes(PyInterpreterState *interp)
{
Expand All @@ -1116,18 +1064,6 @@ void
_PyTuple_Fini(PyInterpreterState *interp)
{
#if PyTuple_MAXSAVESIZE > 0
struct _Py_tuple_state *state = &interp->tuple;
// The empty tuple singleton must not be tracked by the GC
assert(!_PyObject_GC_IS_TRACKED(state->free_list[0]));

#ifdef Py_DEBUG
state->numfree[0] = 0;
#endif
Py_CLEAR(state->free_list[0]);
#ifdef Py_DEBUG
state->numfree[0] = -1;
#endif

_PyTuple_ClearFreeList(interp);
#endif
}
Expand Down
5 changes: 0 additions & 5 deletions Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,11 +683,6 @@ pycore_init_global_objects(PyInterpreterState *interp)

_PyUnicode_InitState(interp);

status = _PyTuple_InitGlobalObjects(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}

return _PyStatus_OK();
}

Expand Down
0