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