obmalloc.c revision b331802f976c85954efbeb7a49f2591951460be2
11221c0a435135143632d986e861d9243d3d2ad35Tim Peters#include "Python.h"
21221c0a435135143632d986e861d9243d3d2ad35Tim Peters
31221c0a435135143632d986e861d9243d3d2ad35Tim Peters#ifdef WITH_PYMALLOC
41221c0a435135143632d986e861d9243d3d2ad35Tim Peters
5a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/* An object allocator for Python.
6a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
7a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer   Here is an introduction to the layers of the Python memory architecture,
8a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer   showing where the object allocator is actually used (layer +2), It is
9a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer   called for every object allocation and deallocation (PyObject_New/Del),
10a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer   unless the object-specific allocators implement a proprietary allocation
11a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer   scheme (ex.: ints use a simple free list). This is also the place where
12a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer   the cyclic garbage collector operates selectively on container objects.
13a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
14a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
15a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer        Object-specific allocators
16a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer    _____   ______   ______       ________
17a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer   [ int ] [ dict ] [ list ] ... [ string ]       Python core         |
18a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer+3 | <----- Object-specific memory -----> | <-- Non-object memory --> |
19a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer    _______________________________       |                           |
20a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer   [   Python's object allocator   ]      |                           |
21a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer+2 | ####### Object memory ####### | <------ Internal buffers ------> |
22a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer    ______________________________________________________________    |
23a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer   [          Python's raw memory allocator (PyMem_ API)          ]   |
24a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer+1 | <----- Python memory (under PyMem manager's control) ------> |   |
25a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer    __________________________________________________________________
26a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer   [    Underlying general-purpose allocator (ex: C library malloc)   ]
27a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer 0 | <------ Virtual memory allocated for the python process -------> |
28a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
29a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer   =========================================================================
30a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer    _______________________________________________________________________
31a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer   [                OS-specific Virtual Memory Manager (VMM)               ]
32a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer-1 | <--- Kernel dynamic storage allocation & management (page-based) ---> |
33a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer    __________________________________   __________________________________
34a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer   [                                  ] [                                  ]
35a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer-2 | <-- Physical memory: ROM/RAM --> | | <-- Secondary storage (swap) --> |
36a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
37a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer*/
38a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*==========================================================================*/
39a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
40a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/* A fast, special-purpose memory allocator for small blocks, to be used
41a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer   on top of a general-purpose malloc -- heavily based on previous art. */
42a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
43a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/* Vladimir Marangozov -- August 2000 */
44a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
45a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
46a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * "Memory management is where the rubber meets the road -- if we do the wrong
47a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * thing at any level, the results will not be good. And if we don't make the
48a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * levels work well together, we are in serious trouble." (1)
49a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *
50a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * (1) Paul R. Wilson, Mark S. Johnstone, Michael Neely, and David Boles,
51a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *    "Dynamic Storage Allocation: A Survey and Critical Review",
52a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *    in Proc. 1995 Int'l. Workshop on Memory Management, September 1995.
53a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
54a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
55a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/* #undef WITH_MEMORY_LIMITS */		/* disable mem limit checks  */
56a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
57a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*==========================================================================*/
58a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
59a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
60a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Allocation strategy abstract:
61a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *
62a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * For small requests, the allocator sub-allocates <Big> blocks of memory.
63a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Requests greater than 256 bytes are routed to the system's allocator.
64ce7fb9b5151f7238bdbaeb16c3041c9990ca8e9dTim Peters *
65a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Small requests are grouped in size classes spaced 8 bytes apart, due
66a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * to the required valid alignment of the returned address. Requests of
67a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * a particular size are serviced from memory pools of 4K (one VMM page).
68a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Pools are fragmented on demand and contain free lists of blocks of one
69a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * particular size class. In other words, there is a fixed-size allocator
70a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * for each size class. Free pools are shared by the different allocators
71a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * thus minimizing the space reserved for a particular size class.
72a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *
73a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * This allocation strategy is a variant of what is known as "simple
74a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * segregated storage based on array of free lists". The main drawback of
75a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * simple segregated storage is that we might end up with lot of reserved
76a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * memory for the different free lists, which degenerate in time. To avoid
77a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * this, we partition each free list in pools and we share dynamically the
78a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * reserved space between all free lists. This technique is quite efficient
79a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * for memory intensive programs which allocate mainly small-sized blocks.
80a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *
81a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * For small requests we have the following table:
82a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *
83a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Request in bytes	Size of allocated block      Size class idx
84a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * ----------------------------------------------------------------
85a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *        1-8                     8                       0
86a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *	  9-16                   16                       1
87a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *	 17-24                   24                       2
88a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *	 25-32                   32                       3
89a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *	 33-40                   40                       4
90a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *	 41-48                   48                       5
91a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *	 49-56                   56                       6
92a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *	 57-64                   64                       7
93a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *	 65-72                   72                       8
94a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *	  ...                   ...                     ...
95a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *	241-248                 248                      30
96a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *	249-256                 256                      31
97ce7fb9b5151f7238bdbaeb16c3041c9990ca8e9dTim Peters *
98a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *	0, 257 and up: routed to the underlying allocator.
99a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
100a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
101a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*==========================================================================*/
102a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
103a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
104a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * -- Main tunable settings section --
105a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
106a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
107a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
108a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Alignment of addresses returned to the user. 8-bytes alignment works
109a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * on most current architectures (with 32-bit or 64-bit address busses).
110a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * The alignment value is also used for grouping small requests in size
111a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * classes spaced ALIGNMENT bytes apart.
112a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *
113a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * You shouldn't change this unless you know what you are doing.
114a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
115a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define ALIGNMENT		8		/* must be 2^N */
116a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define ALIGNMENT_SHIFT		3
117a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define ALIGNMENT_MASK		(ALIGNMENT - 1)
118a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
119e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters/* Return the number of bytes in size class I, as a uint. */
120e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters#define INDEX2SIZE(I) (((uint)(I) + 1) << ALIGNMENT_SHIFT)
121e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters
122a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
123a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Max size threshold below which malloc requests are considered to be
124a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * small enough in order to use preallocated memory pools. You can tune
125a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * this value according to your application behaviour and memory needs.
126a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *
127a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * The following invariants must hold:
128a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *	1) ALIGNMENT <= SMALL_REQUEST_THRESHOLD <= 256
129d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters *	2) SMALL_REQUEST_THRESHOLD is evenly divisible by ALIGNMENT
130a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *
131a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Although not required, for better performance and space efficiency,
132a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * it is recommended that SMALL_REQUEST_THRESHOLD is set to a power of 2.
133a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
134d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters#define SMALL_REQUEST_THRESHOLD	256
135a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define NB_SMALL_SIZE_CLASSES	(SMALL_REQUEST_THRESHOLD / ALIGNMENT)
136a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
137a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
138a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * The system's VMM page size can be obtained on most unices with a
139a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * getpagesize() call or deduced from various header files. To make
140a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * things simpler, we assume that it is 4K, which is OK for most systems.
141a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * It is probably better if this is the native page size, but it doesn't
142ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters * have to be.  In theory, if SYSTEM_PAGE_SIZE is larger than the native page
143ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters * size, then `POOL_ADDR(p)->arenaindex' could rarely cause a segmentation
144ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters * violation fault.  4K is apparently OK for all the platforms that python
1458c1402869ba0cb0a690a5168ac4067483d39e02eMartin v. Löwis * currently targets.
146a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
147a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define SYSTEM_PAGE_SIZE	(4 * 1024)
148a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define SYSTEM_PAGE_SIZE_MASK	(SYSTEM_PAGE_SIZE - 1)
149a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
150a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
151a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Maximum amount of memory managed by the allocator for small requests.
152a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
153a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#ifdef WITH_MEMORY_LIMITS
154a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#ifndef SMALL_MEMORY_LIMIT
155a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define SMALL_MEMORY_LIMIT	(64 * 1024 * 1024)	/* 64 MB -- more? */
156a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif
157a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif
158a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
159a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
160a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * The allocator sub-allocates <Big> blocks of memory (called arenas) aligned
161a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * on a page boundary. This is a reserved virtual address space for the
162a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * current process (obtained through a malloc call). In no way this means
163a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * that the memory arenas will be used entirely. A malloc(<Big>) is usually
164a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * an address range reservation for <Big> bytes, unless all pages within this
165a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * space are referenced subsequently. So malloc'ing big blocks and not using
166a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * them does not mean "wasting memory". It's an addressable range wastage...
167a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *
168a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Therefore, allocating arenas with malloc is not optimal, because there is
169a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * some address space wastage, but this is the most portable way to request
170d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters * memory from the system across various platforms.
171a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
1723c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters#define ARENA_SIZE		(256 << 10)	/* 256KB */
173a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
174a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#ifdef WITH_MEMORY_LIMITS
175a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define MAX_ARENAS		(SMALL_MEMORY_LIMIT / ARENA_SIZE)
176a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif
177a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
178a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
179a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Size of the pools used for small blocks. Should be a power of 2,
180c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters * between 1K and SYSTEM_PAGE_SIZE, that is: 1k, 2k, 4k.
181a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
182a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define POOL_SIZE		SYSTEM_PAGE_SIZE	/* must be 2^N */
183a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define POOL_SIZE_MASK		SYSTEM_PAGE_SIZE_MASK
184a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
185a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
186a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * -- End of tunable settings section --
187a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
188a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
189a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*==========================================================================*/
190a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
191a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
192a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Locking
193a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *
194a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * To reduce lock contention, it would probably be better to refine the
195a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * crude function locking with per size class locking. I'm not positive
196a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * however, whether it's worth switching to such locking policy because
197a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * of the performance penalty it might introduce.
198a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *
199a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * The following macros describe the simplest (should also be the fastest)
200a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * lock object on a particular platform and the init/fini/lock/unlock
201a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * operations on it. The locks defined here are not expected to be recursive
202a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * because it is assumed that they will always be called in the order:
203a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * INIT, [LOCK, UNLOCK]*, FINI.
204a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
205a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
206a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
207a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Python's threads are serialized, so object malloc locking is disabled.
208a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
209a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define SIMPLELOCK_DECL(lock)	/* simple lock declaration		*/
210a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define SIMPLELOCK_INIT(lock)	/* allocate (if needed) and initialize	*/
211a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define SIMPLELOCK_FINI(lock)	/* free/destroy an existing lock 	*/
212a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define SIMPLELOCK_LOCK(lock)	/* acquire released lock */
213a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define SIMPLELOCK_UNLOCK(lock)	/* release acquired lock */
214a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
215a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
216a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Basic types
217a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * I don't care if these are defined in <sys/types.h> or elsewhere. Axiom.
218a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
219a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#undef  uchar
220cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters#define uchar	unsigned char	/* assuming == 8 bits  */
221a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
222a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#undef  uint
223cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters#define uint	unsigned int	/* assuming >= 16 bits */
224a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
225a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#undef  ulong
226cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters#define ulong	unsigned long	/* assuming >= 32 bits */
227a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
228d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters#undef uptr
229cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters#define uptr	Py_uintptr_t
230d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
231a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/* When you say memory, my mind reasons in terms of (pointers to) blocks */
232a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauertypedef uchar block;
233a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
234e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters/* Pool for small blocks. */
235a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauerstruct pool_header {
236b2336529ef548181d53af151cf3fc116274846d6Tim Peters	union { block *_padding;
237a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		uint count; } ref;	/* number of allocated blocks    */
238a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	block *freeblock;		/* pool's free list head         */
239a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	struct pool_header *nextpool;	/* next pool of this size class  */
240a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	struct pool_header *prevpool;	/* previous pool       ""        */
2411d99af8d6960a3b6adc5ed25a8b27e59e21970d3Tim Peters	uint arenaindex;		/* index into arenas of base adr */
242a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	uint szidx;			/* block size class index	 */
243e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters	uint nextoffset;		/* bytes to virgin block	 */
244e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters	uint maxnextoffset;		/* largest valid nextoffset	 */
245a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer};
246a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
247a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauertypedef struct pool_header *poolp;
248a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
249cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters/* Record keeping for arenas. */
250cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersstruct arena_object {
251cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	/* The address of the arena, as returned by malloc.  Note that 0
252cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 * will never be returned by a successful malloc, and is used
253cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 * here to mark an arena_object that doesn't correspond to an
254cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 * allocated arena.
255cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 */
256cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	uptr address;
257cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
258cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	/* Pool-aligned pointer to the next pool to be carved off. */
259cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	block* pool_address;
260cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
261cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	/* The number of available pools in the arena:  free pools + never-
262cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 * allocated pools.
263cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 */
264cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	uint nfreepools;
265cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
266cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	/* The total number of pools in the arena, whether or not available. */
267cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	uint ntotalpools;
268cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
269cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	/* Singly-linked list of available pools. */
270cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	struct pool_header* freepools;
271cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
272cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	/* Whenever this arena_object is not associated with an allocated
273cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 * arena, the nextarena member is used to link all unassociated
274cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 * arena_objects in the singly-linked `unused_arena_objects` list.
275cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 * The prevarena member is unused in this case.
276cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 *
277cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 * When this arena_object is associated with an allocated arena
278cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 * with at least one available pool, both members are used in the
279cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 * doubly-linked `usable_arenas` list, which is maintained in
280cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 * increasing order of `nfreepools` values.
281cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 *
282cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 * Else this arena_object is associated with an allocated arena
283cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 * all of whose pools are in use.  `nextarena` and `prevarena`
284cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 * are both meaningless in this case.
285cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 */
286cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	struct arena_object* nextarena;
287cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	struct arena_object* prevarena;
288cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters};
289cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
290a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#undef  ROUNDUP
291a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define ROUNDUP(x)		(((x) + ALIGNMENT_MASK) & ~ALIGNMENT_MASK)
292a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define POOL_OVERHEAD		ROUNDUP(sizeof(struct pool_header))
293a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
294a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define DUMMY_SIZE_IDX		0xffff	/* size class of newly cached pools */
295a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
296d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters/* Round pointer P down to the closest pool-aligned address <= P, as a poolp */
297e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters#define POOL_ADDR(P) ((poolp)((uptr)(P) & ~(uptr)POOL_SIZE_MASK))
298e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters
29916bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters/* Return total number of blocks in pool of size index I, as a uint. */
30016bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters#define NUMBLOCKS(I) ((uint)(POOL_SIZE - POOL_OVERHEAD) / INDEX2SIZE(I))
301d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
302a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*==========================================================================*/
303a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
304a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
305a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * This malloc lock
306a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
307d1fedb6ab59547f914a1958804a0658b68e4d6b2Jeremy HyltonSIMPLELOCK_DECL(_malloc_lock)
308b2336529ef548181d53af151cf3fc116274846d6Tim Peters#define LOCK()		SIMPLELOCK_LOCK(_malloc_lock)
309b2336529ef548181d53af151cf3fc116274846d6Tim Peters#define UNLOCK()	SIMPLELOCK_UNLOCK(_malloc_lock)
310b2336529ef548181d53af151cf3fc116274846d6Tim Peters#define LOCK_INIT()	SIMPLELOCK_INIT(_malloc_lock)
311b2336529ef548181d53af151cf3fc116274846d6Tim Peters#define LOCK_FINI()	SIMPLELOCK_FINI(_malloc_lock)
312a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
313a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
3141e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters * Pool table -- headed, circular, doubly-linked lists of partially used pools.
3151e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
3161e16db6d3b542b5cc146245055be0a04263c4e5eTim PetersThis is involved.  For an index i, usedpools[i+i] is the header for a list of
3171e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersall partially used pools holding small blocks with "size class idx" i. So
3181e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersusedpools[0] corresponds to blocks of size 8, usedpools[2] to blocks of size
3191e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters16, and so on:  index 2*i <-> blocks of size (i+1)<<ALIGNMENT_SHIFT.
3201e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
321cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersPools are carved off an arena's highwater mark (an arena_object's pool_address
322cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersmember) as needed.  Once carved off, a pool is in one of three states forever
323cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersafter:
324338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters
325338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Petersused == partially used, neither empty nor full
326338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    At least one block in the pool is currently allocated, and at least one
327338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    block in the pool is not currently allocated (note this implies a pool
328338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    has room for at least two blocks).
329338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    This is a pool's initial state, as a pool is created only when malloc
330338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    needs space.
331338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    The pool holds blocks of a fixed size, and is in the circular list headed
332338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    at usedpools[i] (see above).  It's linked to the other used pools of the
333338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    same size class via the pool_header's nextpool and prevpool members.
334338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    If all but one block is currently allocated, a malloc can cause a
335338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    transition to the full state.  If all but one block is not currently
336338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    allocated, a free can cause a transition to the empty state.
337338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters
338338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Petersfull == all the pool's blocks are currently allocated
339338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    On transition to full, a pool is unlinked from its usedpools[] list.
340338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    It's not linked to from anything then anymore, and its nextpool and
341338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    prevpool members are meaningless until it transitions back to used.
342338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    A free of a block in a full pool puts the pool back in the used state.
343338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    Then it's linked in at the front of the appropriate usedpools[] list, so
344338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    that the next allocation for its size class will reuse the freed block.
345338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters
346338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Petersempty == all the pool's blocks are currently available for allocation
347338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    On transition to empty, a pool is unlinked from its usedpools[] list,
348cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters    and linked to the front of its arena_object's singly-linked freepools list,
349338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    via its nextpool member.  The prevpool member has no meaning in this case.
350338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    Empty pools have no inherent size class:  the next time a malloc finds
351338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    an empty list in usedpools[], it takes the first pool off of freepools.
352338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    If the size class needed happens to be the same as the size class the pool
353e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters    last had, some pool initialization can be skipped.
354338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters
355338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters
356338e010b45d7bd411e2bbcedcd8ef195be40c2beTim PetersBlock Management
357338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters
358338e010b45d7bd411e2bbcedcd8ef195be40c2beTim PetersBlocks within pools are again carved out as needed.  pool->freeblock points to
359338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Petersthe start of a singly-linked list of free blocks within the pool.  When a
360338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Petersblock is freed, it's inserted at the front of its pool's freeblock list.  Note
361338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Petersthat the available blocks in a pool are *not* linked all together when a pool
362e70ddf3a99e5394faf17d78d0764929ae795b674Tim Petersis initialized.  Instead only "the first two" (lowest addresses) blocks are
363e70ddf3a99e5394faf17d78d0764929ae795b674Tim Petersset up, returning the first such block, and setting pool->freeblock to a
364e70ddf3a99e5394faf17d78d0764929ae795b674Tim Petersone-block list holding the second such block.  This is consistent with that
365e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peterspymalloc strives at all levels (arena, pool, and block) never to touch a piece
366e70ddf3a99e5394faf17d78d0764929ae795b674Tim Petersof memory until it's actually needed.
367e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters
368e70ddf3a99e5394faf17d78d0764929ae795b674Tim PetersSo long as a pool is in the used state, we're certain there *is* a block
36952aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Petersavailable for allocating, and pool->freeblock is not NULL.  If pool->freeblock
37052aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Peterspoints to the end of the free list before we've carved the entire pool into
37152aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Petersblocks, that means we simply haven't yet gotten to one of the higher-address
37252aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Petersblocks.  The offset from the pool_header to the start of "the next" virgin
37352aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Petersblock is stored in the pool_header nextoffset member, and the largest value
37452aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Petersof nextoffset that makes sense is stored in the maxnextoffset member when a
37552aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Peterspool is initialized.  All the blocks in a pool have been passed out at least
37652aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Petersonce when and only when nextoffset > maxnextoffset.
377338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters
3781e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
3791e16db6d3b542b5cc146245055be0a04263c4e5eTim PetersMajor obscurity:  While the usedpools vector is declared to have poolp
3801e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersentries, it doesn't really.  It really contains two pointers per (conceptual)
3811e16db6d3b542b5cc146245055be0a04263c4e5eTim Peterspoolp entry, the nextpool and prevpool members of a pool_header.  The
3821e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersexcruciating initialization code below fools C so that
3831e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
3841e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters    usedpool[i+i]
3851e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
3861e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters"acts like" a genuine poolp, but only so long as you only reference its
3871e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersnextpool and prevpool members.  The "- 2*sizeof(block *)" gibberish is
3881e16db6d3b542b5cc146245055be0a04263c4e5eTim Peterscompensating for that a pool_header's nextpool and prevpool members
3891e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersimmediately follow a pool_header's first two members:
3901e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
3911e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters	union { block *_padding;
3921e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters		uint count; } ref;
3931e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters	block *freeblock;
3941e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
3951e16db6d3b542b5cc146245055be0a04263c4e5eTim Peterseach of which consume sizeof(block *) bytes.  So what usedpools[i+i] really
3961e16db6d3b542b5cc146245055be0a04263c4e5eTim Peterscontains is a fudged-up pointer p such that *if* C believes it's a poolp
3971e16db6d3b542b5cc146245055be0a04263c4e5eTim Peterspointer, then p->nextpool and p->prevpool are both p (meaning that the headed
3981e16db6d3b542b5cc146245055be0a04263c4e5eTim Peterscircular list is empty).
3991e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
4001e16db6d3b542b5cc146245055be0a04263c4e5eTim PetersIt's unclear why the usedpools setup is so convoluted.  It could be to
4011e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersminimize the amount of cache required to hold this heavily-referenced table
4021e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters(which only *needs* the two interpool pointer members of a pool_header). OTOH,
4031e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersreferencing code has to remember to "double the index" and doing so isn't
4041e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersfree, usedpools[0] isn't a strictly legal pointer, and we're crucially relying
4051e16db6d3b542b5cc146245055be0a04263c4e5eTim Peterson that C doesn't insert any padding anywhere in a pool_header at or before
4061e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersthe prevpool member.
4071e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters**************************************************************************** */
4081e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
409a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define PTA(x)	((poolp )((uchar *)&(usedpools[2*(x)]) - 2*sizeof(block *)))
410a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define PT(x)	PTA(x), PTA(x)
411a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
412a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauerstatic poolp usedpools[2 * ((NB_SMALL_SIZE_CLASSES + 7) / 8) * 8] = {
413a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	PT(0), PT(1), PT(2), PT(3), PT(4), PT(5), PT(6), PT(7)
414a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#if NB_SMALL_SIZE_CLASSES > 8
415a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	, PT(8), PT(9), PT(10), PT(11), PT(12), PT(13), PT(14), PT(15)
416a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#if NB_SMALL_SIZE_CLASSES > 16
417a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	, PT(16), PT(17), PT(18), PT(19), PT(20), PT(21), PT(22), PT(23)
418a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#if NB_SMALL_SIZE_CLASSES > 24
419a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	, PT(24), PT(25), PT(26), PT(27), PT(28), PT(29), PT(30), PT(31)
420a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#if NB_SMALL_SIZE_CLASSES > 32
421a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	, PT(32), PT(33), PT(34), PT(35), PT(36), PT(37), PT(38), PT(39)
422a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#if NB_SMALL_SIZE_CLASSES > 40
423a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	, PT(40), PT(41), PT(42), PT(43), PT(44), PT(45), PT(46), PT(47)
424a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#if NB_SMALL_SIZE_CLASSES > 48
425a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	, PT(48), PT(49), PT(50), PT(51), PT(52), PT(53), PT(54), PT(55)
426a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#if NB_SMALL_SIZE_CLASSES > 56
427a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	, PT(56), PT(57), PT(58), PT(59), PT(60), PT(61), PT(62), PT(63)
428a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif /* NB_SMALL_SIZE_CLASSES > 56 */
429a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif /* NB_SMALL_SIZE_CLASSES > 48 */
430a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif /* NB_SMALL_SIZE_CLASSES > 40 */
431a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif /* NB_SMALL_SIZE_CLASSES > 32 */
432a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif /* NB_SMALL_SIZE_CLASSES > 24 */
433a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif /* NB_SMALL_SIZE_CLASSES > 16 */
434a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif /* NB_SMALL_SIZE_CLASSES >  8 */
435a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer};
436a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
437cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters/*==========================================================================
438cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersArena management.
439cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
440cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters`arenas` is a vector of arena_objects.  It contains maxarenas entries, some of
441cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peterswhich may not be currently used (== they're arena_objects that aren't
442cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peterscurrently associated with an allocated arena).  Note that arenas proper are
443cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersseparately malloc'ed.
444cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
445cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersPrior to Python 2.5, arenas were never free()'ed.  Starting with Python 2.5,
446cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peterswe do try to free() arenas, and use some mild heuristic strategies to increase
447cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersthe likelihood that arenas eventually can be freed.
448cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
449cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersunused_arena_objects
450cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
451cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters    This is a singly-linked list of the arena_objects that are currently not
452cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters    being used (no arena is associated with them).  Objects are taken off the
453cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters    head of the list in new_arena(), and are pushed on the head of the list in
454cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters    PyObject_Free() when the arena is empty.  Key invariant:  an arena_object
455cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters    is on this list if and only if its .address member is 0.
456cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
457cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersusable_arenas
458cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
459cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters    This is a doubly-linked list of the arena_objects associated with arenas
460cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters    that have pools available.  These pools are either waiting to be reused,
461cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters    or have not been used before.  The list is sorted to have the most-
462cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters    allocated arenas first (ascending order based on the nfreepools member).
463cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters    This means that the next allocation will come from a heavily used arena,
464cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters    which gives the nearly empty arenas a chance to be returned to the system.
465cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters    In my unscientific tests this dramatically improved the number of arenas
466cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters    that could be freed.
467cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
468cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersNote that an arena_object associated with an arena all of whose pools are
469cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peterscurrently in use isn't on either list.
470cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters*/
471cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
472cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters/* Array of objects used to track chunks of memory (arenas). */
473cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersstatic struct arena_object* arenas = NULL;
474cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters/* Number of slots currently allocated in the `arenas` vector. */
475cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersstatic uint maxarenas = 0;
476cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
477cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters/* The head of the singly-linked, NULL-terminated list of available
478cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters * arena_objects.
479a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
480cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersstatic struct arena_object* unused_arena_objects = NULL;
481a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
482cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters/* The head of the doubly-linked, NULL-terminated at each end, list of
483cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters * arena_objects associated with arenas that have pools available.
484cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters */
485cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersstatic struct arena_object* usable_arenas = NULL;
486d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
487cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters/* How many arena_objects do we initially allocate?
488cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters * 16 = can allocate 16 arenas = 16 * ARENA_SIZE = 4MB before growing the
489cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters * `arenas` vector.
490a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
491cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters#define INITIAL_ARENA_OBJECTS 16
492a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
493cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters/* Number of arenas allocated that haven't been free()'d. */
4949ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Petersstatic size_t narenas_currently_allocated = 0;
495d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
496cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters#ifdef PYMALLOC_DEBUG
497cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters/* Total number of times malloc() called to allocate an arena. */
4989ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Petersstatic size_t ntimes_arena_allocated = 0;
499cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters/* High water mark (max value ever seen) for narenas_currently_allocated. */
5009ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Petersstatic size_t narenas_highwater = 0;
501cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters#endif
502d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
503cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters/* Allocate a new arena.  If we run out of memory, return NULL.  Else
504cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters * allocate a new arena, and return the address of an arena_object
505cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters * describing the new arena.  It's expected that the caller will set
506cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters * `usable_arenas` to the return value.
507d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters */
508cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersstatic struct arena_object*
509d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Petersnew_arena(void)
510d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters{
511cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	struct arena_object* arenaobj;
5123c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters	uint excess;	/* number of bytes above pool alignment */
513d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
5140e871188e8cd9a4e41be7c734e250bfce2d92d56Tim Peters#ifdef PYMALLOC_DEBUG
5150e871188e8cd9a4e41be7c734e250bfce2d92d56Tim Peters	if (Py_GETENV("PYTHONMALLOCSTATS"))
5160e871188e8cd9a4e41be7c734e250bfce2d92d56Tim Peters		_PyObject_DebugMallocStats();
5170e871188e8cd9a4e41be7c734e250bfce2d92d56Tim Peters#endif
518cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	if (unused_arena_objects == NULL) {
519cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		uint i;
5209fa5a2828c8007dfb678b883d65aecac93e995e4Martin v. Löwis		uint numarenas;
521cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		size_t nbytes;
5220e871188e8cd9a4e41be7c734e250bfce2d92d56Tim Peters
523cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		/* Double the number of arena objects on each allocation.
524cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		 * Note that it's possible for `numarenas` to overflow.
525cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		 */
526cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		numarenas = maxarenas ? maxarenas << 1 : INITIAL_ARENA_OBJECTS;
527cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		if (numarenas <= maxarenas)
528cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			return NULL;	/* overflow */
5299fa5a2828c8007dfb678b883d65aecac93e995e4Martin v. Löwis#if SIZEOF_SIZE_T <= SIZEOF_INT
5309d53457e599623fbad90833c3448835b42d7e7f9Gregory P. Smith		if (numarenas > PY_SIZE_MAX / sizeof(*arenas))
531cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			return NULL;	/* overflow */
5329fa5a2828c8007dfb678b883d65aecac93e995e4Martin v. Löwis#endif
5339d53457e599623fbad90833c3448835b42d7e7f9Gregory P. Smith		nbytes = numarenas * sizeof(*arenas);
5349b26122ec0f0b2dd219070b19efd95f54aade034Neal Norwitz		arenaobj = (struct arena_object *)realloc(arenas, nbytes);
535cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		if (arenaobj == NULL)
536cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			return NULL;
537cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		arenas = arenaobj;
538cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
539cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		/* We might need to fix pointers that were copied.  However,
540cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		 * new_arena only gets called when all the pages in the
541cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		 * previous arenas are full.  Thus, there are *no* pointers
542cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		 * into the old array. Thus, we don't have to worry about
543cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		 * invalid pointers.  Just to be sure, some asserts:
544cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		 */
545cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		assert(usable_arenas == NULL);
546cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		assert(unused_arena_objects == NULL);
547cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
548cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		/* Put the new arenas on the unused_arena_objects list. */
549cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		for (i = maxarenas; i < numarenas; ++i) {
550cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			arenas[i].address = 0;	/* mark as unassociated */
551cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			arenas[i].nextarena = i < numarenas - 1 ?
552cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters					       &arenas[i+1] : NULL;
553cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		}
554d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
555cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		/* Update globals. */
556cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		unused_arena_objects = &arenas[maxarenas];
557cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		maxarenas = numarenas;
558d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	}
559cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
560cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	/* Take the next available arena object off the head of the list. */
561cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	assert(unused_arena_objects != NULL);
562cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	arenaobj = unused_arena_objects;
563cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	unused_arena_objects = arenaobj->nextarena;
564cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	assert(arenaobj->address == 0);
565cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	arenaobj->address = (uptr)malloc(ARENA_SIZE);
566cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	if (arenaobj->address == 0) {
567cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		/* The allocation failed: return NULL after putting the
568cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		 * arenaobj back.
569d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 */
570cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		arenaobj->nextarena = unused_arena_objects;
571cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		unused_arena_objects = arenaobj;
572cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		return NULL;
573d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	}
574d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
575cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	++narenas_currently_allocated;
576cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters#ifdef PYMALLOC_DEBUG
577cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	++ntimes_arena_allocated;
578cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	if (narenas_currently_allocated > narenas_highwater)
579cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		narenas_highwater = narenas_currently_allocated;
580cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters#endif
581cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	arenaobj->freepools = NULL;
582cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	/* pool_address <- first pool-aligned address in the arena
583cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	   nfreepools <- number of whole pools that fit after alignment */
584cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	arenaobj->pool_address = (block*)arenaobj->address;
585cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	arenaobj->nfreepools = ARENA_SIZE / POOL_SIZE;
586cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	assert(POOL_SIZE * arenaobj->nfreepools == ARENA_SIZE);
587cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	excess = (uint)(arenaobj->address & POOL_SIZE_MASK);
588cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	if (excess != 0) {
589cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		--arenaobj->nfreepools;
590cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		arenaobj->pool_address += POOL_SIZE - excess;
591cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	}
592cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	arenaobj->ntotalpools = arenaobj->nfreepools;
593d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
594cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	return arenaobj;
595d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters}
596d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
597cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters/*
598cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersPy_ADDRESS_IN_RANGE(P, POOL)
599cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
600cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersReturn true if and only if P is an address that was allocated by pymalloc.
601cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersPOOL must be the pool address associated with P, i.e., POOL = POOL_ADDR(P)
602cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters(the caller is asked to compute this because the macro expands POOL more than
603cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersonce, and for efficiency it's best for the caller to assign POOL_ADDR(P) to a
604cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersvariable and pass the latter to the macro; because Py_ADDRESS_IN_RANGE is
605cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peterscalled on every alloc/realloc/free, micro-efficiency is important here).
606cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
607cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersTricky:  Let B be the arena base address associated with the pool, B =
608cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersarenas[(POOL)->arenaindex].address.  Then P belongs to the arena if and only if
609cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
610cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	B <= P < B + ARENA_SIZE
611cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
612cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersSubtracting B throughout, this is true iff
613cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
614cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	0 <= P-B < ARENA_SIZE
615cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
616cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersBy using unsigned arithmetic, the "0 <=" half of the test can be skipped.
617cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
618cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersObscure:  A PyMem "free memory" function can call the pymalloc free or realloc
619cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersbefore the first arena has been allocated.  `arenas` is still NULL in that
620cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peterscase.  We're relying on that maxarenas is also 0 in that case, so that
621cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters(POOL)->arenaindex < maxarenas  must be false, saving us from trying to index
622cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersinto a NULL arenas.
623cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
624cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersDetails:  given P and POOL, the arena_object corresponding to P is AO =
625cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersarenas[(POOL)->arenaindex].  Suppose obmalloc controls P.  Then (barring wild
626cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersstores, etc), POOL is the correct address of P's pool, AO.address is the
627cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peterscorrect base address of the pool's arena, and P must be within ARENA_SIZE of
628cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersAO.address.  In addition, AO.address is not 0 (no arena can start at address 0
629cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters(NULL)).  Therefore Py_ADDRESS_IN_RANGE correctly reports that obmalloc
630cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peterscontrols P.
631cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
632cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersNow suppose obmalloc does not control P (e.g., P was obtained via a direct
633cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peterscall to the system malloc() or realloc()).  (POOL)->arenaindex may be anything
634cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersin this case -- it may even be uninitialized trash.  If the trash arenaindex
635cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersis >= maxarenas, the macro correctly concludes at once that obmalloc doesn't
636cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peterscontrol P.
637cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
638cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersElse arenaindex is < maxarena, and AO is read up.  If AO corresponds to an
639cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersallocated arena, obmalloc controls all the memory in slice AO.address :
640cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersAO.address+ARENA_SIZE.  By case assumption, P is not controlled by obmalloc,
641cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersso P doesn't lie in that slice, so the macro correctly reports that P is not
642cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peterscontrolled by obmalloc.
643cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
644cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersFinally, if P is not controlled by obmalloc and AO corresponds to an unused
645cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersarena_object (one not currently associated with an allocated arena),
646cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersAO.address is 0, and the second test in the macro reduces to:
647cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
648cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	P < ARENA_SIZE
649cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
650cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersIf P >= ARENA_SIZE (extremely likely), the macro again correctly concludes
651cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersthat P is not controlled by obmalloc.  However, if P < ARENA_SIZE, this part
652cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersof the test still passes, and the third clause (AO.address != 0) is necessary
653cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersto get the correct result:  AO.address is 0 in this case, so the macro
654cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peterscorrectly reports that P is not controlled by obmalloc (despite that P lies in
655cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersslice AO.address : AO.address + ARENA_SIZE).
656cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
657cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersNote:  The third (AO.address != 0) clause was added in Python 2.5.  Before
658cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters2.5, arenas were never free()'ed, and an arenaindex < maxarena always
659cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peterscorresponded to a currently-allocated arena, so the "P is not controlled by
660cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersobmalloc, AO corresponds to an unused arena_object, and P < ARENA_SIZE" case
661cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peterswas impossible.
662cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
663cf79aace07a57d480605f4a5aa8b9ca68567792eTim PetersNote that the logic is excruciating, and reading up possibly uninitialized
664cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersmemory when P is not controlled by obmalloc (to get at (POOL)->arenaindex)
665cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peterscreates problems for some memory debuggers.  The overwhelming advantage is
666cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersthat this test determines whether an arbitrary address is controlled by
667cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersobmalloc in a small constant time, independent of the number of arenas
668cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersobmalloc controls.  Since this test is needed at every entry point, it's
669cf79aace07a57d480605f4a5aa8b9ca68567792eTim Petersextremely desirable that it be this fast.
670cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters*/
671cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters#define Py_ADDRESS_IN_RANGE(P, POOL)			\
672cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	((POOL)->arenaindex < maxarenas &&		\
673cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 (uptr)(P) - arenas[(POOL)->arenaindex].address < (uptr)ARENA_SIZE && \
674cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	 arenas[(POOL)->arenaindex].address != 0)
675cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
6767eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz
6777eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz/* This is only useful when running memory debuggers such as
6787eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz * Purify or Valgrind.  Uncomment to use.
6797eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz *
6806819210b9e4e5719a6f7f9c1725f8fa70a8936f6Martin v. Löwis#define Py_USING_MEMORY_DEBUGGER
681e86b07cc9ad51baa4f5a2854f8a03e7d1b77b817Martin v. Löwis */
6827eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz
6837eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz#ifdef Py_USING_MEMORY_DEBUGGER
6847eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz
6857eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz/* Py_ADDRESS_IN_RANGE may access uninitialized memory by design
6867eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz * This leads to thousands of spurious warnings when using
6877eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz * Purify or Valgrind.  By making a function, we can easily
6887eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz * suppress the uninitialized memory reads in this one function.
6897eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz * So we won't ignore real errors elsewhere.
6907eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz *
6917eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz * Disable the macro and use a function.
6927eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz */
6937eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz
6947eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz#undef Py_ADDRESS_IN_RANGE
6957eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz
696ab772274700baf17e708e8c8d82c78efbaa038cdNeal Norwitz#if defined(__GNUC__) && ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) || \
697ab772274700baf17e708e8c8d82c78efbaa038cdNeal Norwitz			  (__GNUC__ >= 4))
698e5e5aa4ea693d18bfc8a5bb352a75e9154da6af9Neal Norwitz#define Py_NO_INLINE __attribute__((__noinline__))
699e5e5aa4ea693d18bfc8a5bb352a75e9154da6af9Neal Norwitz#else
700e5e5aa4ea693d18bfc8a5bb352a75e9154da6af9Neal Norwitz#define Py_NO_INLINE
701e5e5aa4ea693d18bfc8a5bb352a75e9154da6af9Neal Norwitz#endif
702e5e5aa4ea693d18bfc8a5bb352a75e9154da6af9Neal Norwitz
703e5e5aa4ea693d18bfc8a5bb352a75e9154da6af9Neal Norwitz/* Don't make static, to try to ensure this isn't inlined. */
704e5e5aa4ea693d18bfc8a5bb352a75e9154da6af9Neal Norwitzint Py_ADDRESS_IN_RANGE(void *P, poolp pool) Py_NO_INLINE;
705e5e5aa4ea693d18bfc8a5bb352a75e9154da6af9Neal Norwitz#undef Py_NO_INLINE
7067eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz#endif
707338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters
708a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*==========================================================================*/
709a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
71084c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters/* malloc.  Note that nbytes==0 tries to return a non-NULL pointer, distinct
71184c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters * from all other currently live pointers.  This may not be possible.
71284c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters */
713a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
714a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
715a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * The basic blocks are ordered by decreasing execution frequency,
716a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * which minimizes the number of jumps in the most common cases,
717a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * improves branching prediction and instruction scheduling (small
718a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * block allocations typically result in a couple of instructions).
719a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Unless the optimizer reorders everything, being too smart...
720a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
721a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
722d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil Schemenauer#undef PyObject_Malloc
723a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauervoid *
724d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil SchemenauerPyObject_Malloc(size_t nbytes)
725a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer{
726a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	block *bp;
727a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	poolp pool;
728a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	poolp next;
729a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	uint size;
730a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
731a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	/*
7320470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith	 * Limit ourselves to PY_SSIZE_T_MAX bytes to prevent security holes.
7330470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith	 * Most python internals blindly use a signed Py_ssize_t to track
7340470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith	 * things without checking for overflows or negatives.
7350470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith	 * As size_t is unsigned, checking for nbytes < 0 is not required.
7360470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith	 */
7370470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith	if (nbytes > PY_SSIZE_T_MAX)
7380470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith		return NULL;
7390470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith
7400470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith	/*
74184c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters	 * This implicitly redirects malloc(0).
742a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	 */
743a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	if ((nbytes - 1) < SMALL_REQUEST_THRESHOLD) {
744a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		LOCK();
745a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		/*
746a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		 * Most frequent paths first
747a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		 */
748cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		size = (uint)(nbytes - 1) >> ALIGNMENT_SHIFT;
749a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		pool = usedpools[size + size];
750a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		if (pool != pool->nextpool) {
751a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			/*
752a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 * There is a used pool for this size class.
753a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 * Pick up the head block of its free list.
754a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 */
755a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			++pool->ref.count;
756a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			bp = pool->freeblock;
75752aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Peters			assert(bp != NULL);
758a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			if ((pool->freeblock = *(block **)bp) != NULL) {
759a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				UNLOCK();
760a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				return (void *)bp;
761a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			}
762a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			/*
763cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * Reached the end of the free list, try to extend it.
764a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 */
765e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters			if (pool->nextoffset <= pool->maxnextoffset) {
766cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				/* There is room for another block. */
767cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				pool->freeblock = (block*)pool +
768e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters						  pool->nextoffset;
769e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters				pool->nextoffset += INDEX2SIZE(size);
770a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				*(block **)(pool->freeblock) = NULL;
771a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				UNLOCK();
772a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				return (void *)bp;
773a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			}
774cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			/* Pool is full, unlink from used pools. */
775a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			next = pool->nextpool;
776a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			pool = pool->prevpool;
777a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			next->prevpool = pool;
778a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			pool->nextpool = next;
779a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			UNLOCK();
780a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			return (void *)bp;
781a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		}
782cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
783cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		/* There isn't a pool of the right size class immediately
784cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		 * available:  use a free pool.
785a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		 */
786cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		if (usable_arenas == NULL) {
787cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			/* No arena has a free pool:  allocate a new arena. */
788cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters#ifdef WITH_MEMORY_LIMITS
789cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			if (narenas_currently_allocated >= MAX_ARENAS) {
790cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				UNLOCK();
791cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				goto redirect;
792cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			}
793cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters#endif
794cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			usable_arenas = new_arena();
795cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			if (usable_arenas == NULL) {
796cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				UNLOCK();
797cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				goto redirect;
798cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			}
799cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			usable_arenas->nextarena =
800cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				usable_arenas->prevarena = NULL;
801cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		}
802cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		assert(usable_arenas->address != 0);
803cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
804cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		/* Try to get a cached free pool. */
805cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		pool = usable_arenas->freepools;
806a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		if (pool != NULL) {
807cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			/* Unlink from cached pools. */
808cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			usable_arenas->freepools = pool->nextpool;
809cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
810cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			/* This arena already had the smallest nfreepools
811cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * value, so decreasing nfreepools doesn't change
812cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * that, and we don't need to rearrange the
813cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * usable_arenas list.  However, if the arena has
814cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * become wholly allocated, we need to remove its
815cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * arena_object from usable_arenas.
816a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 */
817cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			--usable_arenas->nfreepools;
818cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			if (usable_arenas->nfreepools == 0) {
819cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				/* Wholly allocated:  remove. */
820cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				assert(usable_arenas->freepools == NULL);
821cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				assert(usable_arenas->nextarena == NULL ||
822cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				       usable_arenas->nextarena->prevarena ==
823cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters					   usable_arenas);
824cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
825cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				usable_arenas = usable_arenas->nextarena;
826cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				if (usable_arenas != NULL) {
827cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters					usable_arenas->prevarena = NULL;
828cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters					assert(usable_arenas->address != 0);
829cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				}
830cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			}
831cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			else {
832cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				/* nfreepools > 0:  it must be that freepools
833cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				 * isn't NULL, or that we haven't yet carved
834cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				 * off all the arena's pools for the first
835cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				 * time.
836cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				 */
837cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				assert(usable_arenas->freepools != NULL ||
838cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				       usable_arenas->pool_address <=
839cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				           (block*)usable_arenas->address +
840cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				               ARENA_SIZE - POOL_SIZE);
841cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			}
842a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		init_pool:
843cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			/* Frontlink to used pools. */
844a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			next = usedpools[size + size]; /* == prev */
845a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			pool->nextpool = next;
846a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			pool->prevpool = next;
847a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			next->nextpool = pool;
848a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			next->prevpool = pool;
849a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			pool->ref.count = 1;
850a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			if (pool->szidx == size) {
851cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				/* Luckily, this pool last contained blocks
852a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				 * of the same size class, so its header
853a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				 * and free list are already initialized.
854a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				 */
855a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				bp = pool->freeblock;
856a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				pool->freeblock = *(block **)bp;
857a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				UNLOCK();
858a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				return (void *)bp;
859a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			}
860a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			/*
861e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters			 * Initialize the pool header, set up the free list to
862e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters			 * contain just the second block, and return the first
863e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters			 * block.
864a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 */
865a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			pool->szidx = size;
866e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters			size = INDEX2SIZE(size);
867a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			bp = (block *)pool + POOL_OVERHEAD;
868e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters			pool->nextoffset = POOL_OVERHEAD + (size << 1);
869e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters			pool->maxnextoffset = POOL_SIZE - size;
870a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			pool->freeblock = bp + size;
871a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			*(block **)(pool->freeblock) = NULL;
872a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			UNLOCK();
873a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			return (void *)bp;
874a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		}
875cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
876cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		/* Carve off a new pool. */
877cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		assert(usable_arenas->nfreepools > 0);
878cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		assert(usable_arenas->freepools == NULL);
879cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		pool = (poolp)usable_arenas->pool_address;
880cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		assert((block*)pool <= (block*)usable_arenas->address +
881cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		                       ARENA_SIZE - POOL_SIZE);
882cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		pool->arenaindex = usable_arenas - arenas;
883cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		assert(&arenas[pool->arenaindex] == usable_arenas);
884cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		pool->szidx = DUMMY_SIZE_IDX;
885cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		usable_arenas->pool_address += POOL_SIZE;
886cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		--usable_arenas->nfreepools;
887cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
888cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		if (usable_arenas->nfreepools == 0) {
889cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			assert(usable_arenas->nextarena == NULL ||
890cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			       usable_arenas->nextarena->prevarena ==
891cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			       	   usable_arenas);
892cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			/* Unlink the arena:  it is completely allocated. */
893cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			usable_arenas = usable_arenas->nextarena;
894cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			if (usable_arenas != NULL) {
895cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				usable_arenas->prevarena = NULL;
896cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				assert(usable_arenas->address != 0);
897cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			}
898a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		}
899cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
900cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		goto init_pool;
901a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	}
902a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
903a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer        /* The small block allocator ends here. */
904a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
905d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Petersredirect:
906cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	/* Redirect the original request to the underlying (libc) allocator.
907a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	 * We jump here on bigger requests, on error in the code above (as a
908a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	 * last chance to serve the request) or when the max memory limit
909a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	 * has been reached.
910a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	 */
91164d80c9f40465f9bed18712bc2b792f28dcac162Tim Peters	if (nbytes == 0)
91264d80c9f40465f9bed18712bc2b792f28dcac162Tim Peters		nbytes = 1;
91364d80c9f40465f9bed18712bc2b792f28dcac162Tim Peters	return (void *)malloc(nbytes);
914a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer}
915a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
916a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/* free */
917a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
918d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil Schemenauer#undef PyObject_Free
919a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauervoid
920d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil SchemenauerPyObject_Free(void *p)
921a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer{
922a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	poolp pool;
9232c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters	block *lastfree;
924a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	poolp next, prev;
925a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	uint size;
926a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
927a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	if (p == NULL)	/* free(NULL) has no effect */
928a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		return;
929a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
930d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	pool = POOL_ADDR(p);
9317eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz	if (Py_ADDRESS_IN_RANGE(p, pool)) {
932d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		/* We allocated this address. */
933d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		LOCK();
934cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		/* Link p to the start of the pool's freeblock list.  Since
9352c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * the pool had at least the p block outstanding, the pool
9362c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * wasn't empty (so it's already in a usedpools[] list, or
9372c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * was full and is in no list -- it's not in the freeblocks
9382c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * list in any case).
939d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 */
94057b17ad6aeb821262aef41ffd31d1302f18e79c5Tim Peters		assert(pool->ref.count > 0);	/* else it was empty */
9412c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		*(block **)p = lastfree = pool->freeblock;
9422c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		pool->freeblock = (block *)p;
9432c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		if (lastfree) {
944cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			struct arena_object* ao;
945cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			uint nf;  /* ao->nfreepools */
946cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
947cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			/* freeblock wasn't NULL, so the pool wasn't full,
9482c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			 * and the pool is in a usedpools[] list.
949d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters			 */
9502c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			if (--pool->ref.count != 0) {
9512c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters				/* pool isn't empty:  leave it in usedpools */
9522c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters				UNLOCK();
9532c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters				return;
9542c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			}
955cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			/* Pool is now empty:  unlink from usedpools, and
956b1da0501317c6e0a6de6d1407ef94dbd936acbbeTim Peters			 * link to the front of freepools.  This ensures that
9572c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			 * previously freed pools will be allocated later
9582c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			 * (being not referenced, they are perhaps paged out).
959d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters			 */
9602c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			next = pool->nextpool;
9612c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			prev = pool->prevpool;
9622c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			next->prevpool = prev;
9632c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			prev->nextpool = next;
964cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
965cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			/* Link the pool to freepools.  This is a singly-linked
966cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * list, and pool->prevpool isn't used there.
967cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 */
968cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			ao = &arenas[pool->arenaindex];
969cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			pool->nextpool = ao->freepools;
970cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			ao->freepools = pool;
971cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			nf = ++ao->nfreepools;
972cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
973cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			/* All the rest is arena management.  We just freed
974cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * a pool, and there are 4 cases for arena mgmt:
975cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * 1. If all the pools are free, return the arena to
976cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 *    the system free().
977cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * 2. If this is the only free pool in the arena,
978cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 *    add the arena back to the `usable_arenas` list.
979cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * 3. If the "next" arena has a smaller count of free
980cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 *    pools, we have to "slide this arena right" to
981cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 *    restore that usable_arenas is sorted in order of
982cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 *    nfreepools.
983cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * 4. Else there's nothing more to do.
984cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 */
985cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			if (nf == ao->ntotalpools) {
986cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				/* Case 1.  First unlink ao from usable_arenas.
987cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				 */
988cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				assert(ao->prevarena == NULL ||
989cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				       ao->prevarena->address != 0);
990cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				assert(ao ->nextarena == NULL ||
991cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				       ao->nextarena->address != 0);
992cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
993cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				/* Fix the pointer in the prevarena, or the
994cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				 * usable_arenas pointer.
995cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				 */
996cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				if (ao->prevarena == NULL) {
997cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters					usable_arenas = ao->nextarena;
998cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters					assert(usable_arenas == NULL ||
999cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters					       usable_arenas->address != 0);
1000cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				}
1001cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				else {
1002cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters					assert(ao->prevarena->nextarena == ao);
1003cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters					ao->prevarena->nextarena =
1004cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters						ao->nextarena;
1005cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				}
1006cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				/* Fix the pointer in the nextarena. */
1007cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				if (ao->nextarena != NULL) {
1008cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters					assert(ao->nextarena->prevarena == ao);
1009cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters					ao->nextarena->prevarena =
1010cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters						ao->prevarena;
1011cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				}
1012cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				/* Record that this arena_object slot is
1013cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				 * available to be reused.
1014cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				 */
1015cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				ao->nextarena = unused_arena_objects;
1016cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				unused_arena_objects = ao;
1017cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
1018cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				/* Free the entire arena. */
1019cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				free((void *)ao->address);
1020cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				ao->address = 0;	/* mark unassociated */
1021cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				--narenas_currently_allocated;
1022cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
1023cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				UNLOCK();
1024cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				return;
1025cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			}
1026cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			if (nf == 1) {
1027cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				/* Case 2.  Put ao at the head of
1028cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				 * usable_arenas.  Note that because
1029cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				 * ao->nfreepools was 0 before, ao isn't
1030cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				 * currently on the usable_arenas list.
1031cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				 */
1032cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				ao->nextarena = usable_arenas;
1033cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				ao->prevarena = NULL;
1034cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				if (usable_arenas)
1035cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters					usable_arenas->prevarena = ao;
1036cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				usable_arenas = ao;
1037cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				assert(usable_arenas->address != 0);
1038cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
1039cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				UNLOCK();
1040cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				return;
1041cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			}
1042cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			/* If this arena is now out of order, we need to keep
1043cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * the list sorted.  The list is kept sorted so that
1044cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * the "most full" arenas are used first, which allows
1045cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * the nearly empty arenas to be completely freed.  In
1046cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * a few un-scientific tests, it seems like this
1047cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * approach allowed a lot more memory to be freed.
1048cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 */
1049cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			if (ao->nextarena == NULL ||
1050cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				     nf <= ao->nextarena->nfreepools) {
1051cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				/* Case 4.  Nothing to do. */
1052cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				UNLOCK();
1053cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				return;
1054cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			}
1055cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			/* Case 3:  We have to move the arena towards the end
1056cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * of the list, because it has more free pools than
1057cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * the arena to its right.
1058cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * First unlink ao from usable_arenas.
10592c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			 */
1060cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			if (ao->prevarena != NULL) {
1061cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				/* ao isn't at the head of the list */
1062cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				assert(ao->prevarena->nextarena == ao);
1063cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				ao->prevarena->nextarena = ao->nextarena;
1064cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			}
1065cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			else {
1066cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				/* ao is at the head of the list */
1067cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				assert(usable_arenas == ao);
1068cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				usable_arenas = ao->nextarena;
1069cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			}
1070cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			ao->nextarena->prevarena = ao->prevarena;
1071cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
1072cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			/* Locate the new insertion point by iterating over
1073cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 * the list, using our nextarena pointer.
1074cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			 */
1075cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			while (ao->nextarena != NULL &&
1076cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters					nf > ao->nextarena->nfreepools) {
1077cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				ao->prevarena = ao->nextarena;
1078cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				ao->nextarena = ao->nextarena->nextarena;
1079cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			}
1080cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
1081cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			/* Insert ao at this point. */
1082cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			assert(ao->nextarena == NULL ||
1083cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				ao->prevarena == ao->nextarena->prevarena);
1084cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			assert(ao->prevarena->nextarena == ao->nextarena);
1085cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
1086cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			ao->prevarena->nextarena = ao;
1087cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			if (ao->nextarena != NULL)
1088cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				ao->nextarena->prevarena = ao;
1089cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
1090cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			/* Verify that the swaps worked. */
1091cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			assert(ao->nextarena == NULL ||
1092cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				  nf <= ao->nextarena->nfreepools);
1093cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			assert(ao->prevarena == NULL ||
1094cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				  nf > ao->prevarena->nfreepools);
1095cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			assert(ao->nextarena == NULL ||
1096cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				ao->nextarena->prevarena == ao);
1097cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			assert((usable_arenas == ao &&
1098cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				ao->prevarena == NULL) ||
1099cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				ao->prevarena->nextarena == ao);
1100cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
1101d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters			UNLOCK();
1102d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters			return;
1103d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		}
1104cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		/* Pool was full, so doesn't currently live in any list:
11052c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * link it to the front of the appropriate usedpools[] list.
11062c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * This mimics LRU pool usage for new allocations and
11072c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * targets optimal filling when several pools contain
11082c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * blocks of the same size class.
1109d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 */
11102c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		--pool->ref.count;
11112c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		assert(pool->ref.count > 0);	/* else the pool is empty */
11122c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		size = pool->szidx;
11132c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		next = usedpools[size + size];
11142c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		prev = next->prevpool;
11152c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		/* insert pool before next:   prev <-> pool <-> next */
11162c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		pool->nextpool = next;
11172c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		pool->prevpool = prev;
11182c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		next->prevpool = pool;
11192c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		prev->nextpool = pool;
1120a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		UNLOCK();
1121a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		return;
1122a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	}
1123d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
11242c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters	/* We didn't allocate this address. */
112584c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters	free(p);
1126a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer}
1127a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
112884c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters/* realloc.  If p is NULL, this acts like malloc(nbytes).  Else if nbytes==0,
112984c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters * then as the Python docs promise, we do not treat this like free(p), and
113084c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters * return a non-NULL result.
113184c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters */
1132a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
1133d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil Schemenauer#undef PyObject_Realloc
1134a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauervoid *
1135d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil SchemenauerPyObject_Realloc(void *p, size_t nbytes)
1136a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer{
113784c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters	void *bp;
1138a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	poolp pool;
113918e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwis	size_t size;
1140a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
1141a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	if (p == NULL)
1142d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil Schemenauer		return PyObject_Malloc(nbytes);
1143a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
11440470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith	/*
11450470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith	 * Limit ourselves to PY_SSIZE_T_MAX bytes to prevent security holes.
11460470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith	 * Most python internals blindly use a signed Py_ssize_t to track
11470470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith	 * things without checking for overflows or negatives.
11480470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith	 * As size_t is unsigned, checking for nbytes < 0 is not required.
11490470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith	 */
11500470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith	if (nbytes > PY_SSIZE_T_MAX)
11510470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith		return NULL;
11520470bab69783c13447cb634fa403ef1067fe56d1Gregory P. Smith
1153d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	pool = POOL_ADDR(p);
11547eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz	if (Py_ADDRESS_IN_RANGE(p, pool)) {
1155a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		/* We're in charge of this block */
1156e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters		size = INDEX2SIZE(pool->szidx);
11574ce71f77c35bafe058196bb9607cb0b1051542d9Tim Peters		if (nbytes <= size) {
11584ce71f77c35bafe058196bb9607cb0b1051542d9Tim Peters			/* The block is staying the same or shrinking.  If
11594ce71f77c35bafe058196bb9607cb0b1051542d9Tim Peters			 * it's shrinking, there's a tradeoff:  it costs
11604ce71f77c35bafe058196bb9607cb0b1051542d9Tim Peters			 * cycles to copy the block to a smaller size class,
11614ce71f77c35bafe058196bb9607cb0b1051542d9Tim Peters			 * but it wastes memory not to copy it.  The
11624ce71f77c35bafe058196bb9607cb0b1051542d9Tim Peters			 * compromise here is to copy on shrink only if at
11634ce71f77c35bafe058196bb9607cb0b1051542d9Tim Peters			 * least 25% of size can be shaved off.
11644ce71f77c35bafe058196bb9607cb0b1051542d9Tim Peters			 */
11654ce71f77c35bafe058196bb9607cb0b1051542d9Tim Peters			if (4 * nbytes > 3 * size) {
11664ce71f77c35bafe058196bb9607cb0b1051542d9Tim Peters				/* It's the same,
11674ce71f77c35bafe058196bb9607cb0b1051542d9Tim Peters				 * or shrinking and new/old > 3/4.
11684ce71f77c35bafe058196bb9607cb0b1051542d9Tim Peters				 */
11694ce71f77c35bafe058196bb9607cb0b1051542d9Tim Peters				return p;
11704ce71f77c35bafe058196bb9607cb0b1051542d9Tim Peters			}
11714ce71f77c35bafe058196bb9607cb0b1051542d9Tim Peters			size = nbytes;
11724ce71f77c35bafe058196bb9607cb0b1051542d9Tim Peters		}
1173d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil Schemenauer		bp = PyObject_Malloc(nbytes);
117484c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters		if (bp != NULL) {
117584c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters			memcpy(bp, p, size);
1176d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil Schemenauer			PyObject_Free(p);
1177a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		}
117884c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters		return bp;
117984c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters	}
1180ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	/* We're not managing this block.  If nbytes <=
1181ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	 * SMALL_REQUEST_THRESHOLD, it's tempting to try to take over this
1182ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	 * block.  However, if we do, we need to copy the valid data from
1183ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	 * the C-managed block to one of our blocks, and there's no portable
1184ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	 * way to know how much of the memory space starting at p is valid.
1185ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	 * As bug 1185883 pointed out the hard way, it's possible that the
1186ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	 * C-managed block is "at the end" of allocated VM space, so that
1187ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	 * a memory fault can occur if we try to copy nbytes bytes starting
1188ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	 * at p.  Instead we punt:  let C continue to manage this block.
1189ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters         */
1190ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	if (nbytes)
1191ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters		return realloc(p, nbytes);
1192ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	/* C doesn't define the result of realloc(p, 0) (it may or may not
1193ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	 * return NULL then), but Python's docs promise that nbytes==0 never
1194ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	 * returns NULL.  We don't pass 0 to realloc(), to avoid that endcase
1195ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	 * to begin with.  Even then, we can't be sure that realloc() won't
1196ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	 * return NULL.
1197ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	 */
1198ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters	bp = realloc(p, 1);
1199ecc6e6a54ed4bb22b8b78dc1eca9183992ac3f40Tim Peters   	return bp ? bp : p;
1200a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer}
1201a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
12021221c0a435135143632d986e861d9243d3d2ad35Tim Peters#else	/* ! WITH_PYMALLOC */
1203ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1204ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters/*==========================================================================*/
1205d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil Schemenauer/* pymalloc not enabled:  Redirect the entry points to malloc.  These will
1206d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil Schemenauer * only be used by extensions that are compiled with pymalloc enabled. */
120762c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters
1208ce7fb9b5151f7238bdbaeb16c3041c9990ca8e9dTim Petersvoid *
1209d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil SchemenauerPyObject_Malloc(size_t n)
12101221c0a435135143632d986e861d9243d3d2ad35Tim Peters{
12111221c0a435135143632d986e861d9243d3d2ad35Tim Peters	return PyMem_MALLOC(n);
12121221c0a435135143632d986e861d9243d3d2ad35Tim Peters}
12131221c0a435135143632d986e861d9243d3d2ad35Tim Peters
1214ce7fb9b5151f7238bdbaeb16c3041c9990ca8e9dTim Petersvoid *
1215d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil SchemenauerPyObject_Realloc(void *p, size_t n)
12161221c0a435135143632d986e861d9243d3d2ad35Tim Peters{
12171221c0a435135143632d986e861d9243d3d2ad35Tim Peters	return PyMem_REALLOC(p, n);
12181221c0a435135143632d986e861d9243d3d2ad35Tim Peters}
12191221c0a435135143632d986e861d9243d3d2ad35Tim Peters
12201221c0a435135143632d986e861d9243d3d2ad35Tim Petersvoid
1221d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil SchemenauerPyObject_Free(void *p)
12221221c0a435135143632d986e861d9243d3d2ad35Tim Peters{
12231221c0a435135143632d986e861d9243d3d2ad35Tim Peters	PyMem_FREE(p);
12241221c0a435135143632d986e861d9243d3d2ad35Tim Peters}
12251221c0a435135143632d986e861d9243d3d2ad35Tim Peters#endif /* WITH_PYMALLOC */
12261221c0a435135143632d986e861d9243d3d2ad35Tim Peters
1227ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters#ifdef PYMALLOC_DEBUG
1228ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters/*==========================================================================*/
122962c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters/* A x-platform debugging allocator.  This doesn't manage memory directly,
123062c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters * it wraps a real allocator, adding extra debugging info to the memory blocks.
123162c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters */
1232ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1233f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters/* Special bytes broadcast into debug memory blocks at appropriate times.
1234f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters * Strings of these are unlikely to be valid addresses, floats, ints or
1235f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters * 7-bit ASCII.
1236f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters */
1237f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters#undef CLEANBYTE
1238f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters#undef DEADBYTE
1239f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters#undef FORBIDDENBYTE
1240f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters#define CLEANBYTE      0xCB    /* clean (newly allocated) memory */
1241889f61dcfbdccf4d1de7da354ee6165e488e4665Tim Peters#define DEADBYTE       0xDB    /* dead (newly freed) memory */
1242f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters#define FORBIDDENBYTE  0xFB    /* untouchable bytes at each end of a block */
1243ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
124402ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson/* We tag each block with an API ID in order to tag API violations */
124502ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson#define _PYMALLOC_MEM_ID 'm'   /* the PyMem_Malloc() API */
124602ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson#define _PYMALLOC_OBJ_ID 'o'   /* The PyObject_Malloc() API */
124702ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson
12489ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Petersstatic size_t serialno = 0;	/* incremented on each debug {m,re}alloc */
1249ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1250e085017ab7121b27be315d36ef0c25ed51484023Tim Peters/* serialno is always incremented via calling this routine.  The point is
12519ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters * to supply a single place to set a breakpoint.
12529ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters */
1253e085017ab7121b27be315d36ef0c25ed51484023Tim Petersstatic void
1254bd02b14255f99feef90121cf654989b9fe827210Neil Schemenauerbumpserialno(void)
1255e085017ab7121b27be315d36ef0c25ed51484023Tim Peters{
1256e085017ab7121b27be315d36ef0c25ed51484023Tim Peters	++serialno;
1257e085017ab7121b27be315d36ef0c25ed51484023Tim Peters}
1258e085017ab7121b27be315d36ef0c25ed51484023Tim Peters
12599ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters#define SST SIZEOF_SIZE_T
1260e085017ab7121b27be315d36ef0c25ed51484023Tim Peters
12619ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters/* Read sizeof(size_t) bytes at p as a big-endian size_t. */
12629ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Petersstatic size_t
12639ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Petersread_size_t(const void *p)
1264ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters{
126562c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters	const uchar *q = (const uchar *)p;
12669ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	size_t result = *q++;
12679ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	int i;
12689ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters
12699ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	for (i = SST; --i > 0; ++q)
12709ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		result = (result << 8) | *q;
12719ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	return result;
1272ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters}
1273ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
12749ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters/* Write n as a big-endian size_t, MSB at address p, LSB at
12759ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters * p + sizeof(size_t) - 1.
12769ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters */
1277ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersstatic void
12789ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peterswrite_size_t(void *p, size_t n)
1279ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters{
12809ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	uchar *q = (uchar *)p + SST - 1;
12819ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	int i;
12829ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters
12839ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	for (i = SST; --i >= 0; --q) {
12849ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		*q = (uchar)(n & 0xff);
12859ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		n >>= 8;
12869ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	}
1287ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters}
1288ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
128908d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters#ifdef Py_DEBUG
129008d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters/* Is target in the list?  The list is traversed via the nextpool pointers.
129108d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters * The list may be NULL-terminated, or circular.  Return 1 if target is in
129208d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters * list, else 0.
129308d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters */
129408d821582faab8f3b6eeab1b1fd7520417b82b80Tim Petersstatic int
129508d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peterspool_is_in_list(const poolp target, poolp list)
129608d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters{
129708d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters	poolp origlist = list;
129808d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters	assert(target != NULL);
129908d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters	if (list == NULL)
130008d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters		return 0;
130108d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters	do {
130208d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters		if (target == list)
130308d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters			return 1;
130408d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters		list = list->nextpool;
130508d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters	} while (list != NULL && list != origlist);
130608d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters	return 0;
130708d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters}
130808d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters
130908d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters#else
131008d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters#define pool_is_in_list(X, Y) 1
131108d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters
131208d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters#endif	/* Py_DEBUG */
131308d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters
13149ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters/* Let S = sizeof(size_t).  The debug malloc asks for 4*S extra bytes and
13159ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters   fills them with useful stuff, here calling the underlying malloc's result p:
1316ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
13179ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Petersp[0: S]
13189ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters    Number of bytes originally asked for.  This is a size_t, big-endian (easier
13199ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters    to read in a memory dump).
13209ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Petersp[S: 2*S]
1321f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters    Copies of FORBIDDENBYTE.  Used to catch under- writes and reads.
13229ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Petersp[2*S: 2*S+n]
1323f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters    The requested memory, filled with copies of CLEANBYTE.
1324ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    Used to catch reference to uninitialized memory.
13259ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters    &p[2*S] is returned.  Note that this is 8-byte aligned if pymalloc
1326ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    handled the request itself.
13279ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Petersp[2*S+n: 2*S+n+S]
1328f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters    Copies of FORBIDDENBYTE.  Used to catch over- writes and reads.
13299ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Petersp[2*S+n+S: 2*S+n+2*S]
1330d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil Schemenauer    A serial number, incremented by 1 on each call to _PyObject_DebugMalloc
1331d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil Schemenauer    and _PyObject_DebugRealloc.
13329ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters    This is a big-endian size_t.
1333ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    If "bad memory" is detected later, the serial number gives an
1334ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    excellent way to set a breakpoint on the next run, to capture the
1335ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    instant at which this block was passed out.
1336ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters*/
1337ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
133802ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson/* debug replacements for the PyMem_* memory API */
133902ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónssonvoid *
134002ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson_PyMem_DebugMalloc(size_t nbytes)
134102ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson{
134202ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	return _PyObject_DebugMallocApi(_PYMALLOC_MEM_ID, nbytes);
134302ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson}
134402ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónssonvoid *
134502ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson_PyMem_DebugRealloc(void *p, size_t nbytes)
134602ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson{
134702ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	return _PyObject_DebugReallocApi(_PYMALLOC_MEM_ID, p, nbytes);
134802ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson}
134902ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónssonvoid
135002ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson_PyMem_DebugFree(void *p)
135102ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson{
135202ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	_PyObject_DebugFreeApi(_PYMALLOC_MEM_ID, p);
135302ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson}
135402ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson
135502ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson/* debug replacements for the PyObject_* memory API */
1356ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersvoid *
1357d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil Schemenauer_PyObject_DebugMalloc(size_t nbytes)
1358ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters{
135902ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	return _PyObject_DebugMallocApi(_PYMALLOC_OBJ_ID, nbytes);
136002ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson}
136102ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónssonvoid *
136202ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson_PyObject_DebugRealloc(void *p, size_t nbytes)
136302ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson{
136402ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	return _PyObject_DebugReallocApi(_PYMALLOC_OBJ_ID, p, nbytes);
136502ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson}
136602ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónssonvoid
136702ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson_PyObject_DebugFree(void *p)
136802ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson{
136902ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	_PyObject_DebugFreeApi(_PYMALLOC_OBJ_ID, p);
137002ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson}
137102ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónssonvoid
1372b331802f976c85954efbeb7a49f2591951460be2Kristján Valur Jónsson_PyObject_DebugCheckAddress(const void *p)
137302ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson{
137402ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	_PyObject_DebugCheckAddressApi(_PYMALLOC_OBJ_ID, p);
137502ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson}
137602ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson
137702ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson
137802ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson/* generic debug memory api, with an "id" to identify the API in use */
137902ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónssonvoid *
138002ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson_PyObject_DebugMallocApi(char id, size_t nbytes)
138102ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson{
1382ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	uchar *p;	/* base address of malloc'ed block */
13839ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	uchar *tail;	/* p + 2*SST + nbytes == pointer to tail pad bytes */
13849ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	size_t total;	/* nbytes + 4*SST */
1385ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1386e085017ab7121b27be315d36ef0c25ed51484023Tim Peters	bumpserialno();
13879ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	total = nbytes + 4*SST;
13889ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	if (total < nbytes)
13899ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		/* overflow:  can't represent total as a size_t */
1390ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		return NULL;
1391ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
13928a8cdfd0f5fac3f340881c9a993d1e2688ef6641Tim Peters	p = (uchar *)PyObject_Malloc(total);
1393ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (p == NULL)
1394ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		return NULL;
1395ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
139602ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	/* at p, write size (SST bytes), id (1 byte), pad (SST-1 bytes) */
13979ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	write_size_t(p, nbytes);
139802ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	p[SST] = (uchar)id;
139902ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	memset(p + SST + 1 , FORBIDDENBYTE, SST-1);
1400ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1401ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (nbytes > 0)
14029ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		memset(p + 2*SST, CLEANBYTE, nbytes);
1403ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
140402ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	/* at tail, write pad (SST bytes) and serialno (SST bytes) */
14059ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	tail = p + 2*SST + nbytes;
14069ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	memset(tail, FORBIDDENBYTE, SST);
14079ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	write_size_t(tail + SST, serialno);
1408ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
14093eeb17346c26bdb100e6c1c1b778b7b5f83acbbaTim Peters	return p + 2*SST;
1410ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters}
1411ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
14129ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters/* The debug free first checks the 2*SST bytes on each end for sanity (in
141302ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson   particular, that the FORBIDDENBYTEs with the api ID are still intact).
1414f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters   Then fills the original bytes with DEADBYTE.
1415ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters   Then calls the underlying free.
1416ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters*/
1417ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersvoid
141802ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson_PyObject_DebugFreeApi(char api, void *p)
1419ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters{
14209ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	uchar *q = (uchar *)p - 2*SST;  /* address returned from malloc */
1421ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	size_t nbytes;
1422ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1423ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (p == NULL)
1424ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		return;
142502ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	_PyObject_DebugCheckAddressApi(api, p);
14269ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	nbytes = read_size_t(q);
142702ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	nbytes += 4*SST;
1428ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (nbytes > 0)
1429f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters		memset(q, DEADBYTE, nbytes);
14309ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	PyObject_Free(q);
1431ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters}
1432ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1433ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersvoid *
143402ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson_PyObject_DebugReallocApi(char api, void *p, size_t nbytes)
1435ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters{
1436ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	uchar *q = (uchar *)p;
143785cc1c43680ac0cf57269cdb594d5325ec07cf32Tim Peters	uchar *tail;
14389ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	size_t total;	/* nbytes + 4*SST */
1439ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	size_t original_nbytes;
14409ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	int i;
1441ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1442ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (p == NULL)
144302ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson		return _PyObject_DebugMallocApi(api, nbytes);
1444ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
144502ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	_PyObject_DebugCheckAddressApi(api, p);
144685cc1c43680ac0cf57269cdb594d5325ec07cf32Tim Peters	bumpserialno();
14479ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	original_nbytes = read_size_t(q - 2*SST);
14489ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	total = nbytes + 4*SST;
14499ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	if (total < nbytes)
14509ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		/* overflow:  can't represent total as a size_t */
145185cc1c43680ac0cf57269cdb594d5325ec07cf32Tim Peters		return NULL;
1452ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1453ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (nbytes < original_nbytes) {
145485cc1c43680ac0cf57269cdb594d5325ec07cf32Tim Peters		/* shrinking:  mark old extra memory dead */
145502ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson		memset(q + nbytes, DEADBYTE, original_nbytes - nbytes + 2*SST);
1456ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	}
1457ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
145802ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	/* Resize and add decorations. We may get a new pointer here, in which
145902ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	 * case we didn't get the chance to mark the old memory with DEADBYTE,
146002ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	 * but we live with that.
146102ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	 */
14629ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	q = (uchar *)PyObject_Realloc(q - 2*SST, total);
146385cc1c43680ac0cf57269cdb594d5325ec07cf32Tim Peters	if (q == NULL)
146485cc1c43680ac0cf57269cdb594d5325ec07cf32Tim Peters		return NULL;
146585cc1c43680ac0cf57269cdb594d5325ec07cf32Tim Peters
14669ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	write_size_t(q, nbytes);
146702ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	assert(q[SST] == (uchar)api);
146802ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	for (i = 1; i < SST; ++i)
14699ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		assert(q[SST + i] == FORBIDDENBYTE);
14709ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	q += 2*SST;
147185cc1c43680ac0cf57269cdb594d5325ec07cf32Tim Peters	tail = q + nbytes;
14729ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	memset(tail, FORBIDDENBYTE, SST);
14739ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	write_size_t(tail + SST, serialno);
147485cc1c43680ac0cf57269cdb594d5325ec07cf32Tim Peters
147585cc1c43680ac0cf57269cdb594d5325ec07cf32Tim Peters	if (nbytes > original_nbytes) {
147685cc1c43680ac0cf57269cdb594d5325ec07cf32Tim Peters		/* growing:  mark new extra memory clean */
147785cc1c43680ac0cf57269cdb594d5325ec07cf32Tim Peters		memset(q + original_nbytes, CLEANBYTE,
147885cc1c43680ac0cf57269cdb594d5325ec07cf32Tim Peters			nbytes - original_nbytes);
147952aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Peters	}
148085cc1c43680ac0cf57269cdb594d5325ec07cf32Tim Peters
148185cc1c43680ac0cf57269cdb594d5325ec07cf32Tim Peters	return q;
1482ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters}
1483ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
14847ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters/* Check the forbidden bytes on both ends of the memory allocated for p.
1485d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil Schemenauer * If anything is wrong, print info to stderr via _PyObject_DebugDumpAddress,
14867ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters * and call Py_FatalError to kill the program.
148702ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson * The API id, is also checked.
14887ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters */
14897ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters void
149002ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson_PyObject_DebugCheckAddressApi(char api, const void *p)
1491ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters{
1492ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	const uchar *q = (const uchar *)p;
149302ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	char msgbuf[64];
1494d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	char *msg;
14959ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	size_t nbytes;
1496449b5a8da19314bdeb77ac3ffaa88fe12beb9c24Tim Peters	const uchar *tail;
1497d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	int i;
149802ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	char id;
1499ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1500d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	if (p == NULL) {
1501ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		msg = "didn't expect a NULL pointer";
1502d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters		goto error;
1503d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	}
1504ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
150502ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	/* Check the API id */
150602ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	id = (char)q[-SST];
150702ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	if (id != api) {
150802ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson		msg = msgbuf;
150902ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson		snprintf(msg, sizeof(msgbuf), "bad ID: Allocated using API '%c', verified using API '%c'", id, api);
151002ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson		msgbuf[sizeof(msgbuf)-1] = 0;
151102ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson		goto error;
151202ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	}
151302ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson
1514449b5a8da19314bdeb77ac3ffaa88fe12beb9c24Tim Peters	/* Check the stuff at the start of p first:  if there's underwrite
1515449b5a8da19314bdeb77ac3ffaa88fe12beb9c24Tim Peters	 * corruption, the number-of-bytes field may be nuts, and checking
1516449b5a8da19314bdeb77ac3ffaa88fe12beb9c24Tim Peters	 * the tail could lead to a segfault then.
1517449b5a8da19314bdeb77ac3ffaa88fe12beb9c24Tim Peters	 */
151802ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	for (i = SST-1; i >= 1; --i) {
1519f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters		if (*(q-i) != FORBIDDENBYTE) {
1520d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters			msg = "bad leading pad byte";
1521d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters			goto error;
1522d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters		}
1523d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	}
1524ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
15259ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	nbytes = read_size_t(q - 2*SST);
1526449b5a8da19314bdeb77ac3ffaa88fe12beb9c24Tim Peters	tail = q + nbytes;
15279ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	for (i = 0; i < SST; ++i) {
1528449b5a8da19314bdeb77ac3ffaa88fe12beb9c24Tim Peters		if (tail[i] != FORBIDDENBYTE) {
1529449b5a8da19314bdeb77ac3ffaa88fe12beb9c24Tim Peters			msg = "bad trailing pad byte";
1530449b5a8da19314bdeb77ac3ffaa88fe12beb9c24Tim Peters			goto error;
1531ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		}
1532ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	}
1533ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1534d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	return;
1535d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters
1536d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peterserror:
1537d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil Schemenauer	_PyObject_DebugDumpAddress(p);
1538d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	Py_FatalError(msg);
1539ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters}
1540ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
15417ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters/* Display info to stderr about the memory block at p. */
1542ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersvoid
1543d2560cd37c8d38c9eb79bcfce9d780b0753a3cb5Neil Schemenauer_PyObject_DebugDumpAddress(const void *p)
1544ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters{
1545ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	const uchar *q = (const uchar *)p;
1546ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	const uchar *tail;
15479ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	size_t nbytes, serial;
1548d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	int i;
15499ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	int ok;
155002ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	char id;
1551ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
155202ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	fprintf(stderr, "Debug memory block at address p=%p:", p);
155302ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	if (p == NULL) {
155402ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson		fprintf(stderr, "\n");
1555ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		return;
155602ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	}
155702ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	id = (char)q[-SST];
155802ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	fprintf(stderr, " API '%c'\n", id);
1559ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
15609ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	nbytes = read_size_t(q - 2*SST);
15619ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	fprintf(stderr, "    %" PY_FORMAT_SIZE_T "u bytes originally "
15629ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	                "requested\n", nbytes);
1563ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1564449b5a8da19314bdeb77ac3ffaa88fe12beb9c24Tim Peters	/* In case this is nuts, check the leading pad bytes first. */
156502ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	fprintf(stderr, "    The %d pad bytes at p-%d are ", SST-1, SST-1);
15669ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	ok = 1;
156702ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson	for (i = 1; i <= SST-1; ++i) {
15689ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		if (*(q-i) != FORBIDDENBYTE) {
15699ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters			ok = 0;
15709ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters			break;
15719ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		}
1572ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	}
15739ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	if (ok)
15749ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		fputs("FORBIDDENBYTE, as expected.\n", stderr);
1575ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	else {
1576f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters		fprintf(stderr, "not all FORBIDDENBYTE (0x%02x):\n",
1577f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters			FORBIDDENBYTE);
157802ca57ce4c728c4a18d31a6a3f2681bcd1aea2daKristján Valur Jónsson		for (i = SST-1; i >= 1; --i) {
1579ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			const uchar byte = *(q-i);
1580ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			fprintf(stderr, "        at p-%d: 0x%02x", i, byte);
1581f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters			if (byte != FORBIDDENBYTE)
1582ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters				fputs(" *** OUCH", stderr);
1583ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			fputc('\n', stderr);
1584ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		}
1585449b5a8da19314bdeb77ac3ffaa88fe12beb9c24Tim Peters
1586449b5a8da19314bdeb77ac3ffaa88fe12beb9c24Tim Peters		fputs("    Because memory is corrupted at the start, the "
1587449b5a8da19314bdeb77ac3ffaa88fe12beb9c24Tim Peters		      "count of bytes requested\n"
1588449b5a8da19314bdeb77ac3ffaa88fe12beb9c24Tim Peters		      "       may be bogus, and checking the trailing pad "
1589449b5a8da19314bdeb77ac3ffaa88fe12beb9c24Tim Peters		      "bytes may segfault.\n", stderr);
1590ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	}
1591ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1592ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	tail = q + nbytes;
15939ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	fprintf(stderr, "    The %d pad bytes at tail=%p are ", SST, tail);
15949ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	ok = 1;
15959ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	for (i = 0; i < SST; ++i) {
15969ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		if (tail[i] != FORBIDDENBYTE) {
15979ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters			ok = 0;
15989ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters			break;
15999ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		}
1600ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	}
16019ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	if (ok)
16029ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		fputs("FORBIDDENBYTE, as expected.\n", stderr);
1603ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	else {
1604f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters		fprintf(stderr, "not all FORBIDDENBYTE (0x%02x):\n",
1605f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters			FORBIDDENBYTE);
16069ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		for (i = 0; i < SST; ++i) {
1607ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			const uchar byte = tail[i];
1608ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			fprintf(stderr, "        at tail+%d: 0x%02x",
1609ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters				i, byte);
1610f6fb501c577ede5c3681a703925abf36e69bc5b9Tim Peters			if (byte != FORBIDDENBYTE)
1611ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters				fputs(" *** OUCH", stderr);
1612ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			fputc('\n', stderr);
1613ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		}
1614ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	}
1615ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
16169ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	serial = read_size_t(tail + SST);
16179ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	fprintf(stderr, "    The block was made by call #%" PY_FORMAT_SIZE_T
16189ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters			"u to debug malloc/realloc.\n", serial);
1619ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1620ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (nbytes > 0) {
16219ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		i = 0;
1622449b5a8da19314bdeb77ac3ffaa88fe12beb9c24Tim Peters		fputs("    Data at p:", stderr);
1623ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		/* print up to 8 bytes at the start */
1624ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		while (q < tail && i < 8) {
1625ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			fprintf(stderr, " %02x", *q);
1626ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			++i;
1627ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			++q;
1628ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		}
1629ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		/* and up to 8 at the end */
1630ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		if (q < tail) {
1631ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			if (tail - q > 8) {
163262c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters				fputs(" ...", stderr);
1633ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters				q = tail - 8;
1634ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			}
1635ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			while (q < tail) {
1636ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters				fprintf(stderr, " %02x", *q);
1637ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters				++q;
1638ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			}
1639ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		}
164062c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters		fputc('\n', stderr);
1641ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	}
1642ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters}
1643ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
16449ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Petersstatic size_t
16459ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Petersprintone(const char* msg, size_t value)
164616bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters{
164749f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	int i, k;
164849f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	char buf[100];
16499ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	size_t origvalue = value;
165016bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters
165116bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	fputs(msg, stderr);
165249f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	for (i = (int)strlen(msg); i < 35; ++i)
165316bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters		fputc(' ', stderr);
165449f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	fputc('=', stderr);
165549f26817eb31d39339fbbf73c707b0e685ae649aTim Peters
165649f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	/* Write the value with commas. */
165749f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	i = 22;
165849f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	buf[i--] = '\0';
165949f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	buf[i--] = '\n';
166049f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	k = 3;
166149f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	do {
16629ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		size_t nextvalue = value / 10;
16639ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		uint digit = (uint)(value - nextvalue * 10);
166449f26817eb31d39339fbbf73c707b0e685ae649aTim Peters		value = nextvalue;
166549f26817eb31d39339fbbf73c707b0e685ae649aTim Peters		buf[i--] = (char)(digit + '0');
166649f26817eb31d39339fbbf73c707b0e685ae649aTim Peters		--k;
166749f26817eb31d39339fbbf73c707b0e685ae649aTim Peters		if (k == 0 && value && i >= 0) {
166849f26817eb31d39339fbbf73c707b0e685ae649aTim Peters			k = 3;
166949f26817eb31d39339fbbf73c707b0e685ae649aTim Peters			buf[i--] = ',';
167049f26817eb31d39339fbbf73c707b0e685ae649aTim Peters		}
167149f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	} while (value && i >= 0);
167249f26817eb31d39339fbbf73c707b0e685ae649aTim Peters
167349f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	while (i >= 0)
167449f26817eb31d39339fbbf73c707b0e685ae649aTim Peters		buf[i--] = ' ';
167549f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	fputs(buf, stderr);
167649f26817eb31d39339fbbf73c707b0e685ae649aTim Peters
167749f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	return origvalue;
167816bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters}
167916bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters
168008d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters/* Print summary info to stderr about the state of pymalloc's structures.
168108d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters * In Py_DEBUG mode, also perform some expensive internal consistency
168208d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters * checks.
168308d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters */
16847ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Petersvoid
16850e871188e8cd9a4e41be7c734e250bfce2d92d56Tim Peters_PyObject_DebugMallocStats(void)
16867ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters{
16877ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	uint i;
16887ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	const uint numclasses = SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT;
168916bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	/* # of pools, allocated blocks, and free blocks per class index */
16909ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	size_t numpools[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
16919ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	size_t numblocks[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
16929ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	size_t numfreeblocks[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
169316bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	/* total # of allocated bytes in used and full pools */
16949ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	size_t allocated_bytes = 0;
169516bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	/* total # of available bytes in used pools */
16969ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	size_t available_bytes = 0;
169716bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	/* # of free pools + pools not yet carved out of current arena */
169816bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	uint numfreepools = 0;
169916bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	/* # of bytes for arena alignment padding */
17009ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	size_t arena_alignment = 0;
170116bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	/* # of bytes in used and full pools used for pool_headers */
17029ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	size_t pool_header_bytes = 0;
170316bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	/* # of bytes in used and full pools wasted due to quantization,
170416bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	 * i.e. the necessarily leftover space at the ends of used and
170516bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	 * full pools.
170616bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	 */
17079ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	size_t quantization = 0;
1708cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	/* # of arenas actually allocated. */
17099ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	size_t narenas = 0;
171016bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	/* running total -- should equal narenas * ARENA_SIZE */
17119ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	size_t total;
171216bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	char buf[128];
17137ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
17147ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	fprintf(stderr, "Small block threshold = %d, in %u size classes.\n",
17157ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		SMALL_REQUEST_THRESHOLD, numclasses);
17167ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
17177ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	for (i = 0; i < numclasses; ++i)
17187ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		numpools[i] = numblocks[i] = numfreeblocks[i] = 0;
17197ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
17206169f09d64caf4c36936bc8caeaeb5448f72afacTim Peters	/* Because full pools aren't linked to from anything, it's easiest
17216169f09d64caf4c36936bc8caeaeb5448f72afacTim Peters	 * to march over all the arenas.  If we're lucky, most of the memory
17226169f09d64caf4c36936bc8caeaeb5448f72afacTim Peters	 * will be living in full pools -- would be a shame to miss them.
17237ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	 */
1724cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	for (i = 0; i < maxarenas; ++i) {
17257ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		uint poolsinarena;
17267ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		uint j;
1727cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		uptr base = arenas[i].address;
1728cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
1729cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		/* Skip arenas which are not allocated. */
1730cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		if (arenas[i].address == (uptr)NULL)
1731cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			continue;
1732cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		narenas += 1;
1733cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
1734cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		poolsinarena = arenas[i].ntotalpools;
1735cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		numfreepools += arenas[i].nfreepools;
17367ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
17377ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		/* round up to pool alignment */
17387ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		if (base & (uptr)POOL_SIZE_MASK) {
173916bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters			arena_alignment += POOL_SIZE;
17407ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			base &= ~(uptr)POOL_SIZE_MASK;
17417ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			base += POOL_SIZE;
17427ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		}
17437ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
17447ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		/* visit every pool in the arena */
1745cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		assert(base <= (uptr) arenas[i].pool_address);
1746cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters		for (j = 0;
1747cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			    base < (uptr) arenas[i].pool_address;
1748cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters			    ++j, base += POOL_SIZE) {
17497ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			poolp p = (poolp)base;
175008d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters			const uint sz = p->szidx;
175108d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters			uint freeblocks;
175208d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters
17537ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			if (p->ref.count == 0) {
17547ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters				/* currently unused */
1755cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters				assert(pool_is_in_list(p, arenas[i].freepools));
17567ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters				continue;
17577ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			}
175808d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters			++numpools[sz];
175908d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters			numblocks[sz] += p->ref.count;
176008d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters			freeblocks = NUMBLOCKS(sz) - p->ref.count;
176108d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters			numfreeblocks[sz] += freeblocks;
176208d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters#ifdef Py_DEBUG
176308d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters			if (freeblocks > 0)
176408d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters				assert(pool_is_in_list(p, usedpools[sz + sz]));
176508d821582faab8f3b6eeab1b1fd7520417b82b80Tim Peters#endif
17667ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		}
17677ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	}
1768cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	assert(narenas == narenas_currently_allocated);
17697ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
17707ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	fputc('\n', stderr);
177149f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	fputs("class   size   num pools   blocks in use  avail blocks\n"
177249f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	      "-----   ----   ---------   -------------  ------------\n",
17737ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		stderr);
17747ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
17757ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	for (i = 0; i < numclasses; ++i) {
17769ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		size_t p = numpools[i];
17779ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		size_t b = numblocks[i];
17789ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		size_t f = numfreeblocks[i];
1779e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters		uint size = INDEX2SIZE(i);
17807ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		if (p == 0) {
17817ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			assert(b == 0 && f == 0);
17827ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			continue;
17837ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		}
17849ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		fprintf(stderr, "%5u %6u "
17859ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters				"%11" PY_FORMAT_SIZE_T "u "
17869ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters				"%15" PY_FORMAT_SIZE_T "u "
17879ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters				"%13" PY_FORMAT_SIZE_T "u\n",
17887ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			i, size, p, b, f);
178916bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters		allocated_bytes += b * size;
179016bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters		available_bytes += f * size;
179116bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters		pool_header_bytes += p * POOL_OVERHEAD;
179216bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters		quantization += p * ((POOL_SIZE - POOL_OVERHEAD) % size);
17937ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	}
17947ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	fputc('\n', stderr);
17950e871188e8cd9a4e41be7c734e250bfce2d92d56Tim Peters	(void)printone("# times object malloc called", serialno);
179616bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters
1797cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	(void)printone("# arenas allocated total", ntimes_arena_allocated);
1798cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	(void)printone("# arenas reclaimed", ntimes_arena_allocated - narenas);
1799cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	(void)printone("# arenas highwater mark", narenas_highwater);
1800cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	(void)printone("# arenas allocated current", narenas);
1801cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters
180216bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	PyOS_snprintf(buf, sizeof(buf),
18039ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		"%" PY_FORMAT_SIZE_T "u arenas * %d bytes/arena",
18049ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters		narenas, ARENA_SIZE);
1805cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	(void)printone(buf, narenas * ARENA_SIZE);
180616bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters
180716bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	fputc('\n', stderr);
180816bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters
180949f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	total = printone("# bytes in allocated blocks", allocated_bytes);
18100e871188e8cd9a4e41be7c734e250bfce2d92d56Tim Peters	total += printone("# bytes in available blocks", available_bytes);
181149f26817eb31d39339fbbf73c707b0e685ae649aTim Peters
181216bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	PyOS_snprintf(buf, sizeof(buf),
181316bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters		"%u unused pools * %d bytes", numfreepools, POOL_SIZE);
18149ea89d2a1972a527bee508c3fb8cd42a86908da1Tim Peters	total += printone(buf, (size_t)numfreepools * POOL_SIZE);
181516bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters
181616bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	total += printone("# bytes lost to pool headers", pool_header_bytes);
181716bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	total += printone("# bytes lost to quantization", quantization);
181816bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	total += printone("# bytes lost to arena alignment", arena_alignment);
181916bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	(void)printone("Total", total);
18207ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters}
18217ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
1822ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters#endif	/* PYMALLOC_DEBUG */
18237eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz
18247eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz#ifdef Py_USING_MEMORY_DEBUGGER
1825cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters/* Make this function last so gcc won't inline it since the definition is
1826cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters * after the reference.
1827cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters */
18287eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitzint
18297eb3c9196da5be52a670d6d8dd24939a3c27b594Neal NorwitzPy_ADDRESS_IN_RANGE(void *P, poolp pool)
18307eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz{
1831cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	return pool->arenaindex < maxarenas &&
1832cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	       (uptr)P - arenas[pool->arenaindex].address < (uptr)ARENA_SIZE &&
1833cf79aace07a57d480605f4a5aa8b9ca68567792eTim Peters	       arenas[pool->arenaindex].address != 0;
18347eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz}
18357eb3c9196da5be52a670d6d8dd24939a3c27b594Neal Norwitz#endif
1836