Nuitka
The Python compiler
Loading...
Searching...
No Matches
freelists.h
1// Copyright 2025, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
3#ifndef __NUITKA_FREELISTS_H__
4#define __NUITKA_FREELISTS_H__
5
6#ifndef __cplusplus
7#include <stdbool.h>
8#endif
9
10#ifdef _NUITKA_EXPERIMENTAL_DISABLE_FREELIST_ALL
11static const bool use_freelists = false;
12#else
13static const bool use_freelists = true;
14#endif
15
16#define allocateFromFreeList(free_list, object_type, type_type, size) \
17 if (free_list != NULL) { \
18 result = free_list; \
19 free_list = *((object_type **)free_list); \
20 free_list##_count -= 1; \
21 assert(free_list##_count >= 0); \
22 \
23 if (Py_SIZE(result) < size) { \
24 result = PyObject_GC_Resize(object_type, result, size); \
25 assert(result != NULL); \
26 } \
27 \
28 Nuitka_Py_NewReference((PyObject *)result); \
29 } else { \
30 result = (object_type *)Nuitka_GC_NewVar(&type_type, size); \
31 } \
32 CHECK_OBJECT(result);
33
34#define allocateFromFreeListFixed(free_list, object_type, type_type) \
35 if (free_list != NULL) { \
36 result = free_list; \
37 free_list = *((object_type **)free_list); \
38 free_list##_count -= 1; \
39 assert(free_list##_count >= 0); \
40 \
41 Nuitka_Py_NewReference((PyObject *)result); \
42 } else { \
43 result = (object_type *)Nuitka_GC_New(&type_type); \
44 } \
45 CHECK_OBJECT(result);
46
47#define releaseToFreeList(free_list, object, max_free_list_count) \
48 if (free_list != NULL || max_free_list_count == 0 || use_freelists == false) { \
49 if (free_list##_count >= max_free_list_count) { \
50 PyObject_GC_Del(object); \
51 } else { \
52 *((void **)object) = (void *)free_list; \
53 free_list = object; \
54 \
55 free_list##_count += 1; \
56 } \
57 } else { \
58 free_list = object; \
59 *((void **)object) = NULL; \
60 \
61 assert(free_list##_count == 0); \
62 \
63 free_list##_count += 1; \
64 }
65
66#if PYTHON_VERSION >= 0x3d0
67
68#if PYTHON_VERSION >= 0x3e0
69
70// Like _PyFreeList_Pop but doesn't set the reference, may also be totally
71// unnecessary to have.
72static inline PyObject *Nuitka_PyFreeList_Pop(struct _Py_freelist *freelist) {
73 return _PyFreeList_PopNoStats(freelist);
74}
75
76#else
77
78NUITKA_MAY_BE_UNUSED static inline struct _Py_object_freelists *_Nuitka_object_freelists_GET(PyThreadState *tstate) {
79
80#ifdef Py_GIL_DISABLED
81 return &((_PyThreadStateImpl *)tstate)->freelists;
82#else
83 return &tstate->interp->object_state.freelists;
84#endif
85}
86#endif
87
88#endif
89
90#endif
91
92// Part of "Nuitka", an optimizing Python compiler that is compatible and
93// integrates with CPython, but also works on its own.
94//
95// Licensed under the Apache License, Version 2.0 (the "License");
96// you may not use this file except in compliance with the License.
97// You may obtain a copy of the License at
98//
99// http://www.apache.org/licenses/LICENSE-2.0
100//
101// Unless required by applicable law or agreed to in writing, software
102// distributed under the License is distributed on an "AS IS" BASIS,
103// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
104// See the License for the specific language governing permissions and
105// limitations under the License.