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 all commits
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
1 change: 1 addition & 0 deletions Include/internal/pycore_gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ typedef struct {
} PyGC_Head;

#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1)
#define _PyGC_Head_UNUSED PyGC_Head

/* True if the object is currently tracked by the GC. */
#define _PyObject_GC_IS_TRACKED(o) (_Py_AS_GC(o)->_gc_next != 0)
Expand Down
4 changes: 4 additions & 0 deletions Include/internal/pycore_global_objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif

#include "pycore_gc.h" // PyGC_Head
#include "pycore_global_strings.h" // struct _Py_global_strings


Expand Down Expand Up @@ -40,6 +41,9 @@ struct _Py_global_objects {
} bytes_characters[256];

struct _Py_global_strings strings;

_PyGC_Head_UNUSED _tuple_empty_gc_not_used;
PyTupleObject tuple_empty;
} singletons;
};

Expand Down
4 changes: 4 additions & 0 deletions Include/internal/pycore_runtime_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,10 @@ extern "C" {
INIT_ID(zipimporter), \
}, \
}, \
\
.tuple_empty = { \
.ob_base = _PyVarObject_IMMORTAL_INIT(&PyTuple_Type, 0) \
}, \
}, \
}
/* End auto-generated code */
Expand Down
55 changes: 35 additions & 20 deletions Include/internal/pycore_tuple.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,45 @@ extern void _PyTuple_Fini(PyInterpreterState *);

/* other API */

#ifndef WITH_FREELISTS
// without freelists
// for tuples only store empty tuple singleton
# define PyTuple_MAXSAVESIZE 1
# define PyTuple_MAXFREELIST 1
#endif
// PyTuple_MAXSAVESIZE - largest tuple to save on free list
// PyTuple_MAXFREELIST - maximum number of tuples of each size to save

/* Speed optimization to avoid frequent malloc/free of small tuples */
#ifndef PyTuple_MAXSAVESIZE
// Largest tuple to save on free list
# define PyTuple_MAXSAVESIZE 20
#endif
#ifndef PyTuple_MAXFREELIST
// Maximum number of tuples of each size to save
# define PyTuple_MAXFREELIST 2000
#if defined(PyTuple_MAXSAVESIZE) && PyTuple_MAXSAVESIZE <= 0
// A build indicated that tuple freelists should not be used.
# define PyTuple_NFREELISTS 0
# undef PyTuple_MAXSAVESIZE
# undef PyTuple_MAXFREELIST

#elif !defined(WITH_FREELISTS)
# define PyTuple_NFREELISTS 0
# undef PyTuple_MAXSAVESIZE
# undef PyTuple_MAXFREELIST

#else
// We are using a freelist for tuples.
# ifndef PyTuple_MAXSAVESIZE
# define PyTuple_MAXSAVESIZE 20
# endif
# define PyTuple_NFREELISTS PyTuple_MAXSAVESIZE
# ifndef PyTuple_MAXFREELIST
# define PyTuple_MAXFREELIST 2000
# endif
#endif

struct _Py_tuple_state {
#if PyTuple_MAXSAVESIZE > 0
/* Entries 1 up to PyTuple_MAXSAVESIZE are free lists,
entry 0 is the empty tuple () of which at most one instance
will be allocated. */
PyTupleObject *free_list[PyTuple_MAXSAVESIZE];
int numfree[PyTuple_MAXSAVESIZE];
#if PyTuple_NFREELISTS > 0
/* There is one freelist for each size from 1 to PyTuple_MAXSAVESIZE.
The empty tuple is handled separately.

Each tuple stored in the array is the head of the linked list
(and the next available tuple) for that size. The actual tuple
object is used as the linked list node, with its first item
(ob_item[0]) pointing to the next node (i.e. the previous head).
Each linked list is initially NULL. */
PyTupleObject *free_list[PyTuple_NFREELISTS];
int numfree[PyTuple_NFREELISTS];
#else
char _unused; // Empty structs are not allowed.
#endif
};

Expand Down
Loading
0