Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-19 09:50:46

0001 #ifndef Py_INTERNAL_FREELIST_H
0002 #define Py_INTERNAL_FREELIST_H
0003 #ifdef __cplusplus
0004 extern "C" {
0005 #endif
0006 
0007 #ifndef Py_BUILD_CORE
0008 #  error "this header requires Py_BUILD_CORE define"
0009 #endif
0010 
0011 // PyTuple_MAXSAVESIZE - largest tuple to save on free list
0012 // PyTuple_MAXFREELIST - maximum number of tuples of each size to save
0013 
0014 #ifdef WITH_FREELISTS
0015 // with freelists
0016 #  define PyTuple_MAXSAVESIZE 20
0017 #  define PyTuple_NFREELISTS PyTuple_MAXSAVESIZE
0018 #  define PyTuple_MAXFREELIST 2000
0019 #  define PyList_MAXFREELIST 80
0020 #  define PyDict_MAXFREELIST 80
0021 #  define PyFloat_MAXFREELIST 100
0022 #  define PyContext_MAXFREELIST 255
0023 # define _PyAsyncGen_MAXFREELIST 80
0024 #  define _PyObjectStackChunk_MAXFREELIST 4
0025 #else
0026 #  define PyTuple_NFREELISTS 0
0027 #  define PyTuple_MAXFREELIST 0
0028 #  define PyList_MAXFREELIST 0
0029 #  define PyDict_MAXFREELIST 0
0030 #  define PyFloat_MAXFREELIST 0
0031 #  define PyContext_MAXFREELIST 0
0032 #  define _PyAsyncGen_MAXFREELIST 0
0033 #  define _PyObjectStackChunk_MAXFREELIST 0
0034 #endif
0035 
0036 struct _Py_list_freelist {
0037 #ifdef WITH_FREELISTS
0038     PyListObject *items[PyList_MAXFREELIST];
0039     int numfree;
0040 #endif
0041 };
0042 
0043 struct _Py_tuple_freelist {
0044 #if WITH_FREELISTS
0045     /* There is one freelist for each size from 1 to PyTuple_MAXSAVESIZE.
0046        The empty tuple is handled separately.
0047 
0048        Each tuple stored in the array is the head of the linked list
0049        (and the next available tuple) for that size.  The actual tuple
0050        object is used as the linked list node, with its first item
0051        (ob_item[0]) pointing to the next node (i.e. the previous head).
0052        Each linked list is initially NULL. */
0053     PyTupleObject *items[PyTuple_NFREELISTS];
0054     int numfree[PyTuple_NFREELISTS];
0055 #else
0056     char _unused;  // Empty structs are not allowed.
0057 #endif
0058 };
0059 
0060 struct _Py_float_freelist {
0061 #ifdef WITH_FREELISTS
0062     /* Special free list
0063        free_list is a singly-linked list of available PyFloatObjects,
0064        linked via abuse of their ob_type members. */
0065     int numfree;
0066     PyFloatObject *items;
0067 #endif
0068 };
0069 
0070 struct _Py_dict_freelist {
0071 #ifdef WITH_FREELISTS
0072     /* Dictionary reuse scheme to save calls to malloc and free */
0073     PyDictObject *items[PyDict_MAXFREELIST];
0074     int numfree;
0075 #endif
0076 };
0077 
0078 struct _Py_dictkeys_freelist {
0079 #ifdef WITH_FREELISTS
0080     /* Dictionary keys reuse scheme to save calls to malloc and free */
0081     PyDictKeysObject *items[PyDict_MAXFREELIST];
0082     int numfree;
0083 #endif
0084 };
0085 
0086 struct _Py_slice_freelist {
0087 #ifdef WITH_FREELISTS
0088     /* Using a cache is very effective since typically only a single slice is
0089        created and then deleted again. */
0090     PySliceObject *slice_cache;
0091 #endif
0092 };
0093 
0094 struct _Py_context_freelist {
0095 #ifdef WITH_FREELISTS
0096     // List of free PyContext objects
0097     PyContext *items;
0098     int numfree;
0099 #endif
0100 };
0101 
0102 struct _Py_async_gen_freelist {
0103 #ifdef WITH_FREELISTS
0104     /* Freelists boost performance 6-10%; they also reduce memory
0105        fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend
0106        are short-living objects that are instantiated for every
0107        __anext__() call. */
0108     struct _PyAsyncGenWrappedValue* items[_PyAsyncGen_MAXFREELIST];
0109     int numfree;
0110 #endif
0111 };
0112 
0113 struct _Py_async_gen_asend_freelist {
0114 #ifdef WITH_FREELISTS
0115     struct PyAsyncGenASend* items[_PyAsyncGen_MAXFREELIST];
0116     int numfree;
0117 #endif
0118 };
0119 
0120 struct _PyObjectStackChunk;
0121 
0122 struct _Py_object_stack_freelist {
0123     struct _PyObjectStackChunk *items;
0124     Py_ssize_t numfree;
0125 };
0126 
0127 struct _Py_object_freelists {
0128     struct _Py_float_freelist floats;
0129     struct _Py_tuple_freelist tuples;
0130     struct _Py_list_freelist lists;
0131     struct _Py_dict_freelist dicts;
0132     struct _Py_dictkeys_freelist dictkeys;
0133     struct _Py_slice_freelist slices;
0134     struct _Py_context_freelist contexts;
0135     struct _Py_async_gen_freelist async_gens;
0136     struct _Py_async_gen_asend_freelist async_gen_asends;
0137     struct _Py_object_stack_freelist object_stacks;
0138 };
0139 
0140 extern void _PyObject_ClearFreeLists(struct _Py_object_freelists *freelists, int is_finalization);
0141 extern void _PyTuple_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
0142 extern void _PyFloat_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
0143 extern void _PyList_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
0144 extern void _PySlice_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
0145 extern void _PyDict_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
0146 extern void _PyAsyncGen_ClearFreeLists(struct _Py_object_freelists *freelists, int is_finalization);
0147 extern void _PyContext_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
0148 extern void _PyObjectStackChunk_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
0149 
0150 #ifdef __cplusplus
0151 }
0152 #endif
0153 #endif /* !Py_INTERNAL_FREELIST_H */