• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef Py_INTERNAL_FREELIST_H
2 #define Py_INTERNAL_FREELIST_H
3 #ifdef __cplusplus
4 extern "C" {
5 #endif
6 
7 #ifndef Py_BUILD_CORE
8 #  error "this header requires Py_BUILD_CORE define"
9 #endif
10 
11 // PyTuple_MAXSAVESIZE - largest tuple to save on free list
12 // PyTuple_MAXFREELIST - maximum number of tuples of each size to save
13 
14 #ifdef WITH_FREELISTS
15 // with freelists
16 #  define PyTuple_MAXSAVESIZE 20
17 #  define PyTuple_NFREELISTS PyTuple_MAXSAVESIZE
18 #  define PyTuple_MAXFREELIST 2000
19 #  define PyList_MAXFREELIST 80
20 #  define PyDict_MAXFREELIST 80
21 #  define PyFloat_MAXFREELIST 100
22 #  define PyContext_MAXFREELIST 255
23 # define _PyAsyncGen_MAXFREELIST 80
24 #  define _PyObjectStackChunk_MAXFREELIST 4
25 #else
26 #  define PyTuple_NFREELISTS 0
27 #  define PyTuple_MAXFREELIST 0
28 #  define PyList_MAXFREELIST 0
29 #  define PyDict_MAXFREELIST 0
30 #  define PyFloat_MAXFREELIST 0
31 #  define PyContext_MAXFREELIST 0
32 #  define _PyAsyncGen_MAXFREELIST 0
33 #  define _PyObjectStackChunk_MAXFREELIST 0
34 #endif
35 
36 struct _Py_list_freelist {
37 #ifdef WITH_FREELISTS
38     PyListObject *items[PyList_MAXFREELIST];
39     int numfree;
40 #endif
41 };
42 
43 struct _Py_tuple_freelist {
44 #if WITH_FREELISTS
45     /* There is one freelist for each size from 1 to PyTuple_MAXSAVESIZE.
46        The empty tuple is handled separately.
47 
48        Each tuple stored in the array is the head of the linked list
49        (and the next available tuple) for that size.  The actual tuple
50        object is used as the linked list node, with its first item
51        (ob_item[0]) pointing to the next node (i.e. the previous head).
52        Each linked list is initially NULL. */
53     PyTupleObject *items[PyTuple_NFREELISTS];
54     int numfree[PyTuple_NFREELISTS];
55 #else
56     char _unused;  // Empty structs are not allowed.
57 #endif
58 };
59 
60 struct _Py_float_freelist {
61 #ifdef WITH_FREELISTS
62     /* Special free list
63        free_list is a singly-linked list of available PyFloatObjects,
64        linked via abuse of their ob_type members. */
65     int numfree;
66     PyFloatObject *items;
67 #endif
68 };
69 
70 struct _Py_dict_freelist {
71 #ifdef WITH_FREELISTS
72     /* Dictionary reuse scheme to save calls to malloc and free */
73     PyDictObject *items[PyDict_MAXFREELIST];
74     int numfree;
75 #endif
76 };
77 
78 struct _Py_dictkeys_freelist {
79 #ifdef WITH_FREELISTS
80     /* Dictionary keys reuse scheme to save calls to malloc and free */
81     PyDictKeysObject *items[PyDict_MAXFREELIST];
82     int numfree;
83 #endif
84 };
85 
86 struct _Py_slice_freelist {
87 #ifdef WITH_FREELISTS
88     /* Using a cache is very effective since typically only a single slice is
89        created and then deleted again. */
90     PySliceObject *slice_cache;
91 #endif
92 };
93 
94 struct _Py_context_freelist {
95 #ifdef WITH_FREELISTS
96     // List of free PyContext objects
97     PyContext *items;
98     int numfree;
99 #endif
100 };
101 
102 struct _Py_async_gen_freelist {
103 #ifdef WITH_FREELISTS
104     /* Freelists boost performance 6-10%; they also reduce memory
105        fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend
106        are short-living objects that are instantiated for every
107        __anext__() call. */
108     struct _PyAsyncGenWrappedValue* items[_PyAsyncGen_MAXFREELIST];
109     int numfree;
110 #endif
111 };
112 
113 struct _Py_async_gen_asend_freelist {
114 #ifdef WITH_FREELISTS
115     struct PyAsyncGenASend* items[_PyAsyncGen_MAXFREELIST];
116     int numfree;
117 #endif
118 };
119 
120 struct _PyObjectStackChunk;
121 
122 struct _Py_object_stack_freelist {
123     struct _PyObjectStackChunk *items;
124     Py_ssize_t numfree;
125 };
126 
127 struct _Py_object_freelists {
128     struct _Py_float_freelist floats;
129     struct _Py_tuple_freelist tuples;
130     struct _Py_list_freelist lists;
131     struct _Py_dict_freelist dicts;
132     struct _Py_dictkeys_freelist dictkeys;
133     struct _Py_slice_freelist slices;
134     struct _Py_context_freelist contexts;
135     struct _Py_async_gen_freelist async_gens;
136     struct _Py_async_gen_asend_freelist async_gen_asends;
137     struct _Py_object_stack_freelist object_stacks;
138 };
139 
140 extern void _PyObject_ClearFreeLists(struct _Py_object_freelists *freelists, int is_finalization);
141 extern void _PyTuple_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
142 extern void _PyFloat_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
143 extern void _PyList_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
144 extern void _PySlice_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
145 extern void _PyDict_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
146 extern void _PyAsyncGen_ClearFreeLists(struct _Py_object_freelists *freelists, int is_finalization);
147 extern void _PyContext_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
148 extern void _PyObjectStackChunk_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
149 
150 #ifdef __cplusplus
151 }
152 #endif
153 #endif /* !Py_INTERNAL_FREELIST_H */
154