obmalloc.c revision 52aefc8a7b9e9ebda6c1b98a831a273e0b07bf96
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
142a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * have to be.
143a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
144a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define SYSTEM_PAGE_SIZE	(4 * 1024)
145a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define SYSTEM_PAGE_SIZE_MASK	(SYSTEM_PAGE_SIZE - 1)
146a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
147a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
148a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Maximum amount of memory managed by the allocator for small requests.
149a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
150a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#ifdef WITH_MEMORY_LIMITS
151a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#ifndef SMALL_MEMORY_LIMIT
152a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define SMALL_MEMORY_LIMIT	(64 * 1024 * 1024)	/* 64 MB -- more? */
153a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif
154a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif
155a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
156a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
157a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * The allocator sub-allocates <Big> blocks of memory (called arenas) aligned
158a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * on a page boundary. This is a reserved virtual address space for the
159a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * current process (obtained through a malloc call). In no way this means
160a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * that the memory arenas will be used entirely. A malloc(<Big>) is usually
161a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * an address range reservation for <Big> bytes, unless all pages within this
162a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * space are referenced subsequently. So malloc'ing big blocks and not using
163a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * them does not mean "wasting memory". It's an addressable range wastage...
164a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *
165a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Therefore, allocating arenas with malloc is not optimal, because there is
166a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * some address space wastage, but this is the most portable way to request
167d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters * memory from the system across various platforms.
168a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
1693c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters#define ARENA_SIZE		(256 << 10)	/* 256KB */
170a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
171a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#ifdef WITH_MEMORY_LIMITS
172a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define MAX_ARENAS		(SMALL_MEMORY_LIMIT / ARENA_SIZE)
173a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif
174a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
175a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
176a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Size of the pools used for small blocks. Should be a power of 2,
177c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters * between 1K and SYSTEM_PAGE_SIZE, that is: 1k, 2k, 4k.
178a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
179a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define POOL_SIZE		SYSTEM_PAGE_SIZE	/* must be 2^N */
180a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define POOL_SIZE_MASK		SYSTEM_PAGE_SIZE_MASK
181a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
182a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
183a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * -- End of tunable settings section --
184a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
185a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
186a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*==========================================================================*/
187a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
188a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
189a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Locking
190a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *
191a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * To reduce lock contention, it would probably be better to refine the
192a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * crude function locking with per size class locking. I'm not positive
193a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * however, whether it's worth switching to such locking policy because
194a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * of the performance penalty it might introduce.
195a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer *
196a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * The following macros describe the simplest (should also be the fastest)
197a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * lock object on a particular platform and the init/fini/lock/unlock
198a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * operations on it. The locks defined here are not expected to be recursive
199a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * because it is assumed that they will always be called in the order:
200a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * INIT, [LOCK, UNLOCK]*, FINI.
201a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
202a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
203a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
204a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Python's threads are serialized, so object malloc locking is disabled.
205a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
206a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define SIMPLELOCK_DECL(lock)	/* simple lock declaration		*/
207a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define SIMPLELOCK_INIT(lock)	/* allocate (if needed) and initialize	*/
208a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define SIMPLELOCK_FINI(lock)	/* free/destroy an existing lock 	*/
209a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define SIMPLELOCK_LOCK(lock)	/* acquire released lock */
210a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define SIMPLELOCK_UNLOCK(lock)	/* release acquired lock */
211a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
212a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
213a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Basic types
214a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * I don't care if these are defined in <sys/types.h> or elsewhere. Axiom.
215a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
216a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#undef  uchar
217a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define uchar			unsigned char	/* assuming == 8 bits  */
218a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
219a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#undef  uint
220a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define uint			unsigned int	/* assuming >= 16 bits */
221a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
222a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#undef  ulong
223a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define ulong			unsigned long	/* assuming >= 32 bits */
224a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
225d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters#undef uptr
226d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters#define uptr			Py_uintptr_t
227d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
228a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/* When you say memory, my mind reasons in terms of (pointers to) blocks */
229a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauertypedef uchar block;
230a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
231e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters/* Pool for small blocks. */
232a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauerstruct pool_header {
233b2336529ef548181d53af151cf3fc116274846d6Tim Peters	union { block *_padding;
234a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		uint count; } ref;	/* number of allocated blocks    */
235a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	block *freeblock;		/* pool's free list head         */
236a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	struct pool_header *nextpool;	/* next pool of this size class  */
237a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	struct pool_header *prevpool;	/* previous pool       ""        */
2381d99af8d6960a3b6adc5ed25a8b27e59e21970d3Tim Peters	uint arenaindex;		/* index into arenas of base adr */
239a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	uint szidx;			/* block size class index	 */
240e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters	uint nextoffset;		/* bytes to virgin block	 */
241e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters	uint maxnextoffset;		/* largest valid nextoffset	 */
242a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer};
243a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
244a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauertypedef struct pool_header *poolp;
245a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
246a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#undef  ROUNDUP
247a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define ROUNDUP(x)		(((x) + ALIGNMENT_MASK) & ~ALIGNMENT_MASK)
248a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define POOL_OVERHEAD		ROUNDUP(sizeof(struct pool_header))
249a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
250a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define DUMMY_SIZE_IDX		0xffff	/* size class of newly cached pools */
251a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
252d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters/* Round pointer P down to the closest pool-aligned address <= P, as a poolp */
253e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters#define POOL_ADDR(P) ((poolp)((uptr)(P) & ~(uptr)POOL_SIZE_MASK))
254e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters
25516bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters/* Return total number of blocks in pool of size index I, as a uint. */
25616bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters#define NUMBLOCKS(I) ((uint)(POOL_SIZE - POOL_OVERHEAD) / INDEX2SIZE(I))
257d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
258a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*==========================================================================*/
259a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
260a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
261a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * This malloc lock
262a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
263b2336529ef548181d53af151cf3fc116274846d6Tim PetersSIMPLELOCK_DECL(_malloc_lock);
264b2336529ef548181d53af151cf3fc116274846d6Tim Peters#define LOCK()		SIMPLELOCK_LOCK(_malloc_lock)
265b2336529ef548181d53af151cf3fc116274846d6Tim Peters#define UNLOCK()	SIMPLELOCK_UNLOCK(_malloc_lock)
266b2336529ef548181d53af151cf3fc116274846d6Tim Peters#define LOCK_INIT()	SIMPLELOCK_INIT(_malloc_lock)
267b2336529ef548181d53af151cf3fc116274846d6Tim Peters#define LOCK_FINI()	SIMPLELOCK_FINI(_malloc_lock)
268a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
269a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
2701e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters * Pool table -- headed, circular, doubly-linked lists of partially used pools.
2711e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
2721e16db6d3b542b5cc146245055be0a04263c4e5eTim PetersThis is involved.  For an index i, usedpools[i+i] is the header for a list of
2731e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersall partially used pools holding small blocks with "size class idx" i. So
2741e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersusedpools[0] corresponds to blocks of size 8, usedpools[2] to blocks of size
2751e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters16, and so on:  index 2*i <-> blocks of size (i+1)<<ALIGNMENT_SHIFT.
2761e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
277338e010b45d7bd411e2bbcedcd8ef195be40c2beTim PetersPools are carved off the current arena highwater mark (file static arenabase)
278338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Petersas needed.  Once carved off, a pool is in one of three states forever after:
279338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters
280338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Petersused == partially used, neither empty nor full
281338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    At least one block in the pool is currently allocated, and at least one
282338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    block in the pool is not currently allocated (note this implies a pool
283338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    has room for at least two blocks).
284338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    This is a pool's initial state, as a pool is created only when malloc
285338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    needs space.
286338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    The pool holds blocks of a fixed size, and is in the circular list headed
287338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    at usedpools[i] (see above).  It's linked to the other used pools of the
288338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    same size class via the pool_header's nextpool and prevpool members.
289338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    If all but one block is currently allocated, a malloc can cause a
290338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    transition to the full state.  If all but one block is not currently
291338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    allocated, a free can cause a transition to the empty state.
292338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters
293338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Petersfull == all the pool's blocks are currently allocated
294338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    On transition to full, a pool is unlinked from its usedpools[] list.
295338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    It's not linked to from anything then anymore, and its nextpool and
296338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    prevpool members are meaningless until it transitions back to used.
297338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    A free of a block in a full pool puts the pool back in the used state.
298338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    Then it's linked in at the front of the appropriate usedpools[] list, so
299338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    that the next allocation for its size class will reuse the freed block.
300338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters
301338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Petersempty == all the pool's blocks are currently available for allocation
302338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    On transition to empty, a pool is unlinked from its usedpools[] list,
303338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    and linked to the front of the (file static) singly-linked freepools list,
304338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    via its nextpool member.  The prevpool member has no meaning in this case.
305338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    Empty pools have no inherent size class:  the next time a malloc finds
306338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    an empty list in usedpools[], it takes the first pool off of freepools.
307338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters    If the size class needed happens to be the same as the size class the pool
308e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters    last had, some pool initialization can be skipped.
309338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters
310338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters
311338e010b45d7bd411e2bbcedcd8ef195be40c2beTim PetersBlock Management
312338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters
313338e010b45d7bd411e2bbcedcd8ef195be40c2beTim PetersBlocks within pools are again carved out as needed.  pool->freeblock points to
314338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Petersthe start of a singly-linked list of free blocks within the pool.  When a
315338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Petersblock is freed, it's inserted at the front of its pool's freeblock list.  Note
316338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Petersthat the available blocks in a pool are *not* linked all together when a pool
317e70ddf3a99e5394faf17d78d0764929ae795b674Tim Petersis initialized.  Instead only "the first two" (lowest addresses) blocks are
318e70ddf3a99e5394faf17d78d0764929ae795b674Tim Petersset up, returning the first such block, and setting pool->freeblock to a
319e70ddf3a99e5394faf17d78d0764929ae795b674Tim Petersone-block list holding the second such block.  This is consistent with that
320e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peterspymalloc strives at all levels (arena, pool, and block) never to touch a piece
321e70ddf3a99e5394faf17d78d0764929ae795b674Tim Petersof memory until it's actually needed.
322e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters
323e70ddf3a99e5394faf17d78d0764929ae795b674Tim PetersSo long as a pool is in the used state, we're certain there *is* a block
32452aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Petersavailable for allocating, and pool->freeblock is not NULL.  If pool->freeblock
32552aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Peterspoints to the end of the free list before we've carved the entire pool into
32652aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Petersblocks, that means we simply haven't yet gotten to one of the higher-address
32752aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Petersblocks.  The offset from the pool_header to the start of "the next" virgin
32852aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Petersblock is stored in the pool_header nextoffset member, and the largest value
32952aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Petersof nextoffset that makes sense is stored in the maxnextoffset member when a
33052aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Peterspool is initialized.  All the blocks in a pool have been passed out at least
33152aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Petersonce when and only when nextoffset > maxnextoffset.
332338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters
3331e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
3341e16db6d3b542b5cc146245055be0a04263c4e5eTim PetersMajor obscurity:  While the usedpools vector is declared to have poolp
3351e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersentries, it doesn't really.  It really contains two pointers per (conceptual)
3361e16db6d3b542b5cc146245055be0a04263c4e5eTim Peterspoolp entry, the nextpool and prevpool members of a pool_header.  The
3371e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersexcruciating initialization code below fools C so that
3381e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
3391e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters    usedpool[i+i]
3401e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
3411e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters"acts like" a genuine poolp, but only so long as you only reference its
3421e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersnextpool and prevpool members.  The "- 2*sizeof(block *)" gibberish is
3431e16db6d3b542b5cc146245055be0a04263c4e5eTim Peterscompensating for that a pool_header's nextpool and prevpool members
3441e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersimmediately follow a pool_header's first two members:
3451e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
3461e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters	union { block *_padding;
3471e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters		uint count; } ref;
3481e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters	block *freeblock;
3491e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
3501e16db6d3b542b5cc146245055be0a04263c4e5eTim Peterseach of which consume sizeof(block *) bytes.  So what usedpools[i+i] really
3511e16db6d3b542b5cc146245055be0a04263c4e5eTim Peterscontains is a fudged-up pointer p such that *if* C believes it's a poolp
3521e16db6d3b542b5cc146245055be0a04263c4e5eTim Peterspointer, then p->nextpool and p->prevpool are both p (meaning that the headed
3531e16db6d3b542b5cc146245055be0a04263c4e5eTim Peterscircular list is empty).
3541e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
3551e16db6d3b542b5cc146245055be0a04263c4e5eTim PetersIt's unclear why the usedpools setup is so convoluted.  It could be to
3561e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersminimize the amount of cache required to hold this heavily-referenced table
3571e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters(which only *needs* the two interpool pointer members of a pool_header). OTOH,
3581e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersreferencing code has to remember to "double the index" and doing so isn't
3591e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersfree, usedpools[0] isn't a strictly legal pointer, and we're crucially relying
3601e16db6d3b542b5cc146245055be0a04263c4e5eTim Peterson that C doesn't insert any padding anywhere in a pool_header at or before
3611e16db6d3b542b5cc146245055be0a04263c4e5eTim Petersthe prevpool member.
3621e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters**************************************************************************** */
3631e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters
364a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define PTA(x)	((poolp )((uchar *)&(usedpools[2*(x)]) - 2*sizeof(block *)))
365a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#define PT(x)	PTA(x), PTA(x)
366a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
367a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauerstatic poolp usedpools[2 * ((NB_SMALL_SIZE_CLASSES + 7) / 8) * 8] = {
368a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	PT(0), PT(1), PT(2), PT(3), PT(4), PT(5), PT(6), PT(7)
369a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#if NB_SMALL_SIZE_CLASSES > 8
370a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	, PT(8), PT(9), PT(10), PT(11), PT(12), PT(13), PT(14), PT(15)
371a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#if NB_SMALL_SIZE_CLASSES > 16
372a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	, PT(16), PT(17), PT(18), PT(19), PT(20), PT(21), PT(22), PT(23)
373a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#if NB_SMALL_SIZE_CLASSES > 24
374a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	, PT(24), PT(25), PT(26), PT(27), PT(28), PT(29), PT(30), PT(31)
375a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#if NB_SMALL_SIZE_CLASSES > 32
376a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	, PT(32), PT(33), PT(34), PT(35), PT(36), PT(37), PT(38), PT(39)
377a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#if NB_SMALL_SIZE_CLASSES > 40
378a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	, PT(40), PT(41), PT(42), PT(43), PT(44), PT(45), PT(46), PT(47)
379a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#if NB_SMALL_SIZE_CLASSES > 48
380a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	, PT(48), PT(49), PT(50), PT(51), PT(52), PT(53), PT(54), PT(55)
381a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#if NB_SMALL_SIZE_CLASSES > 56
382a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	, PT(56), PT(57), PT(58), PT(59), PT(60), PT(61), PT(62), PT(63)
383a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif /* NB_SMALL_SIZE_CLASSES > 56 */
384a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif /* NB_SMALL_SIZE_CLASSES > 48 */
385a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif /* NB_SMALL_SIZE_CLASSES > 40 */
386a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif /* NB_SMALL_SIZE_CLASSES > 32 */
387a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif /* NB_SMALL_SIZE_CLASSES > 24 */
388a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif /* NB_SMALL_SIZE_CLASSES > 16 */
389a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif /* NB_SMALL_SIZE_CLASSES >  8 */
390a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer};
391a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
392a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
393a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Free (cached) pools
394a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
395a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauerstatic poolp freepools = NULL;		/* free list for cached pools */
396a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
397d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters/*==========================================================================*/
398d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters/* Arena management. */
399d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
400d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters/* arenas is a vector of arena base addresses, in order of allocation time.
401d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters * arenas currently contains narenas entries, and has space allocated
402d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters * for at most maxarenas entries.
403d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters *
404d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters * CAUTION:  See the long comment block about thread safety in new_arena():
405d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters * the code currently relies in deep ways on that this vector only grows,
406d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters * and only grows by appending at the end.  For now we never return an arena
407d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters * to the OS.
408a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
409c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Petersstatic uptr *volatile arenas = NULL;	/* the pointer itself is volatile */
410c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Petersstatic volatile uint narenas = 0;
4111d99af8d6960a3b6adc5ed25a8b27e59e21970d3Tim Petersstatic uint maxarenas = 0;
412a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
4133c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters/* Number of pools still available to be allocated in the current arena. */
4143c83df2047b865dde2b400fee2dea336dbbaf99dTim Petersstatic uint nfreepools = 0;
415d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
4163c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters/* Free space start address in current arena.  This is pool-aligned. */
417d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Petersstatic block *arenabase = NULL;
418d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
419d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters#if 0
420d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Petersstatic ulong wasmine = 0;
421d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Petersstatic ulong wasntmine = 0;
422d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
423d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Petersstatic void
424d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Petersdumpem(void *ptr)
425d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters{
426d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	if (ptr)
427d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		printf("inserted new arena at %08x\n", ptr);
4281d99af8d6960a3b6adc5ed25a8b27e59e21970d3Tim Peters	printf("# arenas %u\n", narenas);
429d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	printf("was mine %lu wasn't mine %lu\n", wasmine, wasntmine);
430d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters}
431d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters#define INCMINE ++wasmine
432d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters#define INCTHEIRS ++wasntmine
433d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
434d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters#else
435d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters#define dumpem(ptr)
436d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters#define INCMINE
437d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters#define INCTHEIRS
438d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters#endif
439d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
440d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters/* Allocate a new arena and return its base address.  If we run out of
441d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters * memory, return NULL.
442d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters */
443d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Petersstatic block *
444d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Petersnew_arena(void)
445d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters{
4463c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters	uint excess;	/* number of bytes above pool alignment */
44784c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters	block *bp = (block *)malloc(ARENA_SIZE);
448d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	if (bp == NULL)
449d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		return NULL;
450d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
4513c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters	/* arenabase <- first pool-aligned address in the arena
4523c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters	   nfreepools <- number of whole pools that fit after alignment */
4533c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters	arenabase = bp;
4543c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters	nfreepools = ARENA_SIZE / POOL_SIZE;
455c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters	assert(POOL_SIZE * nfreepools == ARENA_SIZE);
4563c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters	excess = (uint)bp & POOL_SIZE_MASK;
4573c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters	if (excess != 0) {
4583c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters		--nfreepools;
4593c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters		arenabase += POOL_SIZE - excess;
4603c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters	}
461d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
462d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	/* Make room for a new entry in the arenas vector. */
463d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	if (arenas == NULL) {
464c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters		assert(narenas == 0 && maxarenas == 0);
46584c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters		arenas = (uptr *)malloc(16 * sizeof(*arenas));
466d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		if (arenas == NULL)
467d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters			goto error;
468d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		maxarenas = 16;
469d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	}
470d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	else if (narenas == maxarenas) {
47152aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Peters		/* Grow arenas.
472c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters		 *
473d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * Exceedingly subtle:  Someone may be calling the pymalloc
474d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * free via PyMem_{DEL, Del, FREE, Free} without holding the
475d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 *.GIL.  Someone else may simultaneously be calling the
476d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * pymalloc malloc while holding the GIL via, e.g.,
477d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * PyObject_New.  Now the pymalloc free may index into arenas
478d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * for an address check, while the pymalloc malloc calls
479d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * new_arena and we end up here to grow a new arena *and*
480d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * grow the arenas vector.  If the value for arenas pymalloc
481d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * free picks up "vanishes" during this resize, anything may
482d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * happen, and it would be an incredibly rare bug.  Therefore
483d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * the code here takes great pains to make sure that, at every
484d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * moment, arenas always points to an intact vector of
485d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * addresses.  It doesn't matter whether arenas points to a
486d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * wholly up-to-date vector when pymalloc free checks it in
487d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * this case, because the only legal (and that even this is
488d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * legal is debatable) way to call PyMem_{Del, etc} while not
489d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * holding the GIL is if the memory being released is not
490d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * object memory, i.e. if the address check in pymalloc free
491d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * is supposed to fail.  Having an incomplete vector can't
492d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * make a supposed-to-fail case succeed by mistake (it could
493d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * only make a supposed-to-succeed case fail by mistake).
494c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters		 *
495c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters		 * In addition, without a lock we can't know for sure when
496c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters		 * an old vector is no longer referenced, so we simply let
497c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters		 * old vectors leak.
498c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters		 *
499c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters		 * And on top of that, since narenas and arenas can't be
500c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters		 * changed as-a-pair atomically without a lock, we're also
501c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters		 * careful to declare them volatile and ensure that we change
502c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters		 * arenas first.  This prevents another thread from picking
503c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters		 * up an narenas value too large for the arenas value it
504c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters		 * reads up (arenas never shrinks).
505c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters		 *
506d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * Read the above 50 times before changing anything in this
507d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 * block.
508d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 */
5091d99af8d6960a3b6adc5ed25a8b27e59e21970d3Tim Peters		uptr *p;
510c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters		uint newmax = maxarenas << 1;
5111d99af8d6960a3b6adc5ed25a8b27e59e21970d3Tim Peters		if (newmax <= maxarenas)	/* overflow */
5121d99af8d6960a3b6adc5ed25a8b27e59e21970d3Tim Peters			goto error;
51384c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters		p = (uptr *)malloc(newmax * sizeof(*arenas));
514d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		if (p == NULL)
515d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters			goto error;
516d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		memcpy(p, arenas, narenas * sizeof(*arenas));
517c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters		arenas = p;	/* old arenas deliberately leaked */
518d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		maxarenas = newmax;
519d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	}
520d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
521d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	/* Append the new arena address to arenas. */
522d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	assert(narenas < maxarenas);
523d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	arenas[narenas] = (uptr)bp;
5241d99af8d6960a3b6adc5ed25a8b27e59e21970d3Tim Peters	++narenas;	/* can't overflow, since narenas < maxarenas before */
525d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	dumpem(bp);
526d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	return bp;
527d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
528d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peterserror:
52984c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters	free(bp);
5307b85b4aa7fa4e1535dc3eda7d2387a6ea7c29012Tim Peters	nfreepools = 0;
531d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	return NULL;
532d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters}
533d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
534d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters/* Return true if and only if P is an address that was allocated by
535d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters * pymalloc.  I must be the index into arenas that the address claims
536d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters * to come from.
537c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters *
538d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters * Tricky:  Letting B be the arena base address in arenas[I], P belongs to the
539d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters * arena if and only if
5403c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters *	B <= P < B + ARENA_SIZE
541d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters * Subtracting B throughout, this is true iff
5423c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters *	0 <= P-B < ARENA_SIZE
543d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters * By using unsigned arithmetic, the "0 <=" half of the test can be skipped.
544c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters *
545c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters * Obscure:  A PyMem "free memory" function can call the pymalloc free or
546c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters * realloc before the first arena has been allocated.  arenas is still
547c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters * NULL in that case.  We're relying on that narenas is also 0 in that case,
548c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters * so the (I) < narenas must be false, saving us from trying to index into
549c2ce91af5fbe71c5e12d78b0021701233aacde31Tim Peters * a NULL arenas.
550d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters */
551d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters#define ADDRESS_IN_RANGE(P, I) \
5523c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters	((I) < narenas && (uptr)(P) - arenas[I] < (uptr)ARENA_SIZE)
553338e010b45d7bd411e2bbcedcd8ef195be40c2beTim Peters
554a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*==========================================================================*/
555a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
55684c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters/* malloc.  Note that nbytes==0 tries to return a non-NULL pointer, distinct
55784c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters * from all other currently live pointers.  This may not be possible.
55884c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters */
559a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
560a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/*
561a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * The basic blocks are ordered by decreasing execution frequency,
562a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * which minimizes the number of jumps in the most common cases,
563a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * improves branching prediction and instruction scheduling (small
564a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * block allocations typically result in a couple of instructions).
565a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer * Unless the optimizer reorders everything, being too smart...
566a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer */
567a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
568a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauervoid *
56925f3dc21b5a5e59a517b4d175173fd1f399b0e62Neil Schemenauer_PyMalloc_Malloc(size_t nbytes)
570a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer{
571a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	block *bp;
572a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	poolp pool;
573a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	poolp next;
574a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	uint size;
575a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
576a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	/*
57784c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters	 * This implicitly redirects malloc(0).
578a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	 */
579a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	if ((nbytes - 1) < SMALL_REQUEST_THRESHOLD) {
580a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		LOCK();
581a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		/*
582a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		 * Most frequent paths first
583a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		 */
584a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		size = (uint )(nbytes - 1) >> ALIGNMENT_SHIFT;
585a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		pool = usedpools[size + size];
586a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		if (pool != pool->nextpool) {
587a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			/*
588a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 * There is a used pool for this size class.
589a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 * Pick up the head block of its free list.
590a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 */
591a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			++pool->ref.count;
592a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			bp = pool->freeblock;
59352aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Peters			assert(bp != NULL);
594a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			if ((pool->freeblock = *(block **)bp) != NULL) {
595a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				UNLOCK();
596a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				return (void *)bp;
597a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			}
598a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			/*
599a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 * Reached the end of the free list, try to extend it
600a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 */
601e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters			if (pool->nextoffset <= pool->maxnextoffset) {
602a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				/*
603a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				 * There is room for another block
604a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				 */
605e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters				pool->freeblock = (block *)pool +
606e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters						  pool->nextoffset;
607e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters				pool->nextoffset += INDEX2SIZE(size);
608a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				*(block **)(pool->freeblock) = NULL;
609a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				UNLOCK();
610a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				return (void *)bp;
611a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			}
612a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			/*
613a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 * Pool is full, unlink from used pools
614a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 */
615a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			next = pool->nextpool;
616a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			pool = pool->prevpool;
617a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			next->prevpool = pool;
618a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			pool->nextpool = next;
619a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			UNLOCK();
620a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			return (void *)bp;
621a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		}
622a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		/*
623a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		 * Try to get a cached free pool
624a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		 */
625a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		pool = freepools;
626a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		if (pool != NULL) {
627a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			/*
628a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 * Unlink from cached pools
629a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 */
630a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			freepools = pool->nextpool;
631a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		init_pool:
632a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			/*
633a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 * Frontlink to used pools
634a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 */
635a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			next = usedpools[size + size]; /* == prev */
636a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			pool->nextpool = next;
637a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			pool->prevpool = next;
638a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			next->nextpool = pool;
639a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			next->prevpool = pool;
640a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			pool->ref.count = 1;
641a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			if (pool->szidx == size) {
642a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				/*
643a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				 * Luckily, this pool last contained blocks
644a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				 * of the same size class, so its header
645a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				 * and free list are already initialized.
646a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				 */
647a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				bp = pool->freeblock;
648a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				pool->freeblock = *(block **)bp;
649a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				UNLOCK();
650a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer				return (void *)bp;
651a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			}
652a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			/*
653e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters			 * Initialize the pool header, set up the free list to
654e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters			 * contain just the second block, and return the first
655e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters			 * block.
656a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			 */
657a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			pool->szidx = size;
658e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters			size = INDEX2SIZE(size);
659a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			bp = (block *)pool + POOL_OVERHEAD;
660e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters			pool->nextoffset = POOL_OVERHEAD + (size << 1);
661e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters			pool->maxnextoffset = POOL_SIZE - size;
662a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			pool->freeblock = bp + size;
663a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			*(block **)(pool->freeblock) = NULL;
664a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			UNLOCK();
665a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			return (void *)bp;
666a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		}
667a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer                /*
668a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer                 * Allocate new pool
669a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer                 */
6703c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters		if (nfreepools) {
671a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		commit_pool:
6723c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters			--nfreepools;
6733c83df2047b865dde2b400fee2dea336dbbaf99dTim Peters			pool = (poolp)arenabase;
674a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			arenabase += POOL_SIZE;
675d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters			pool->arenaindex = narenas - 1;
676a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			pool->szidx = DUMMY_SIZE_IDX;
677a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			goto init_pool;
678a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		}
679a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer                /*
680a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer                 * Allocate new arena
681a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer                 */
682a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#ifdef WITH_MEMORY_LIMITS
683d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		if (!(narenas < MAX_ARENAS)) {
684a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			UNLOCK();
685a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer			goto redirect;
686a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		}
687a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer#endif
688d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		bp = new_arena();
689d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		if (bp != NULL)
690d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters			goto commit_pool;
691d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		UNLOCK();
692d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		goto redirect;
693a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	}
694a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
695a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer        /* The small block allocator ends here. */
696a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
697d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Petersredirect:
698a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	/*
699a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	 * Redirect the original request to the underlying (libc) allocator.
700a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	 * We jump here on bigger requests, on error in the code above (as a
701a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	 * last chance to serve the request) or when the max memory limit
702a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	 * has been reached.
703a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	 */
70484c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters	return (void *)malloc(nbytes ? nbytes : 1);
705a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer}
706a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
707a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer/* free */
708a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
709a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauervoid
71025f3dc21b5a5e59a517b4d175173fd1f399b0e62Neil Schemenauer_PyMalloc_Free(void *p)
711a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer{
712a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	poolp pool;
7132c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters	block *lastfree;
714a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	poolp next, prev;
715a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	uint size;
716a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
717a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	if (p == NULL)	/* free(NULL) has no effect */
718a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		return;
719a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
720d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	pool = POOL_ADDR(p);
721d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	if (ADDRESS_IN_RANGE(p, pool->arenaindex)) {
722d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		/* We allocated this address. */
723d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		LOCK();
7241e16db6d3b542b5cc146245055be0a04263c4e5eTim Peters		INCMINE;
725a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		/*
7262c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * Link p to the start of the pool's freeblock list.  Since
7272c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * the pool had at least the p block outstanding, the pool
7282c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * wasn't empty (so it's already in a usedpools[] list, or
7292c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * was full and is in no list -- it's not in the freeblocks
7302c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * list in any case).
731d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 */
73257b17ad6aeb821262aef41ffd31d1302f18e79c5Tim Peters		assert(pool->ref.count > 0);	/* else it was empty */
7332c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		*(block **)p = lastfree = pool->freeblock;
7342c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		pool->freeblock = (block *)p;
7352c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		if (lastfree) {
736d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters			/*
7372c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			 * freeblock wasn't NULL, so the pool wasn't full,
7382c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			 * and the pool is in a usedpools[] list.
739d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters			 */
7402c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			if (--pool->ref.count != 0) {
7412c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters				/* pool isn't empty:  leave it in usedpools */
7422c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters				UNLOCK();
7432c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters				return;
7442c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			}
745d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters			/*
7462c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			 * Pool is now empty:  unlink from usedpools, and
747b1da0501317c6e0a6de6d1407ef94dbd936acbbeTim Peters			 * link to the front of freepools.  This ensures that
7482c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			 * previously freed pools will be allocated later
7492c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			 * (being not referenced, they are perhaps paged out).
750d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters			 */
7512c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			next = pool->nextpool;
7522c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			prev = pool->prevpool;
7532c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			next->prevpool = prev;
7542c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			prev->nextpool = next;
7552c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			/* Link to freepools.  This is a singly-linked list,
7562c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			 * and pool->prevpool isn't used there.
7572c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			 */
7582c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			pool->nextpool = freepools;
7592c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters			freepools = pool;
760d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters			UNLOCK();
761d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters			return;
762d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		}
763a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		/*
7642c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * Pool was full, so doesn't currently live in any list:
7652c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * link it to the front of the appropriate usedpools[] list.
7662c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * This mimics LRU pool usage for new allocations and
7672c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * targets optimal filling when several pools contain
7682c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		 * blocks of the same size class.
769d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		 */
7702c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		--pool->ref.count;
7712c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		assert(pool->ref.count > 0);	/* else the pool is empty */
7722c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		size = pool->szidx;
7732c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		next = usedpools[size + size];
7742c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		prev = next->prevpool;
7752c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		/* insert pool before next:   prev <-> pool <-> next */
7762c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		pool->nextpool = next;
7772c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		pool->prevpool = prev;
7782c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		next->prevpool = pool;
7792c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters		prev->nextpool = pool;
780a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		UNLOCK();
781a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		return;
782a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	}
783d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters
7842c95c99a644a62cd2544dd37be6e04b849b07416Tim Peters	/* We didn't allocate this address. */
785d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	INCTHEIRS;
78684c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters	free(p);
787a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer}
788a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
78984c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters/* realloc.  If p is NULL, this acts like malloc(nbytes).  Else if nbytes==0,
79084c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters * then as the Python docs promise, we do not treat this like free(p), and
79184c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters * return a non-NULL result.
79284c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters */
793a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
794a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauervoid *
79525f3dc21b5a5e59a517b4d175173fd1f399b0e62Neil Schemenauer_PyMalloc_Realloc(void *p, size_t nbytes)
796a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer{
79784c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters	void *bp;
798a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	poolp pool;
799a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	uint size;
800a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
801a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	if (p == NULL)
80225f3dc21b5a5e59a517b4d175173fd1f399b0e62Neil Schemenauer		return _PyMalloc_Malloc(nbytes);
803a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
804d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	pool = POOL_ADDR(p);
805d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	if (ADDRESS_IN_RANGE(p, pool->arenaindex)) {
806a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		/* We're in charge of this block */
807d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters		INCMINE;
808e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters		size = INDEX2SIZE(pool->szidx);
80984c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters		if (size >= nbytes)
81084c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters			/* Don't bother if a smaller size was requested. */
81184c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters			return p;
81284c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters		/* We need more memory. */
81384c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters		assert(nbytes != 0);
814b7265dbe3ee954b5ebca795adc6b90b609a0bb23Tim Peters		bp = _PyMalloc_Malloc(nbytes);
81584c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters		if (bp != NULL) {
81684c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters			memcpy(bp, p, size);
81784c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters			_PyMalloc_Free(p);
818a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		}
81984c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters		return bp;
82084c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters	}
82184c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters	/* We're not managing this block. */
82284c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters	INCTHEIRS;
82384c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters	if (nbytes <= SMALL_REQUEST_THRESHOLD) {
82484c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters		/* Take over this block. */
82584c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters		bp = _PyMalloc_Malloc(nbytes ? nbytes : 1);
82684c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters		if (bp != NULL) {
82784c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters			memcpy(bp, p, nbytes);
82884c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters			free(p);
82984c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters		}
83084c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters		else if (nbytes == 0) {
83184c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters			/* Meet the doc's promise that nbytes==0 will
83284c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters			 * never return a NULL pointer when p isn't NULL.
83384c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters			 */
83484c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters			bp = p;
835a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer		}
83684c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters
837a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer	}
838d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	else {
83984c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters		assert(nbytes != 0);
84084c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters		bp = realloc(p, nbytes);
841d97a1c008c4a7ae04c55c8de2cdb71a9ea43656aTim Peters	}
84284c1b974675b9252e1f5764a399ff9455fbf73e0Tim Peters	return bp;
843a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer}
844a35c688055c72e9442f6a82c3ec0e09654077975Neil Schemenauer
8451221c0a435135143632d986e861d9243d3d2ad35Tim Peters#else	/* ! WITH_PYMALLOC */
846ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
847ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters/*==========================================================================*/
848ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters/* pymalloc not enabled:  Redirect the entry points to the PyMem family. */
84962c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters
850ce7fb9b5151f7238bdbaeb16c3041c9990ca8e9dTim Petersvoid *
851ce7fb9b5151f7238bdbaeb16c3041c9990ca8e9dTim Peters_PyMalloc_Malloc(size_t n)
8521221c0a435135143632d986e861d9243d3d2ad35Tim Peters{
8531221c0a435135143632d986e861d9243d3d2ad35Tim Peters	return PyMem_MALLOC(n);
8541221c0a435135143632d986e861d9243d3d2ad35Tim Peters}
8551221c0a435135143632d986e861d9243d3d2ad35Tim Peters
856ce7fb9b5151f7238bdbaeb16c3041c9990ca8e9dTim Petersvoid *
857ce7fb9b5151f7238bdbaeb16c3041c9990ca8e9dTim Peters_PyMalloc_Realloc(void *p, size_t n)
8581221c0a435135143632d986e861d9243d3d2ad35Tim Peters{
8591221c0a435135143632d986e861d9243d3d2ad35Tim Peters	return PyMem_REALLOC(p, n);
8601221c0a435135143632d986e861d9243d3d2ad35Tim Peters}
8611221c0a435135143632d986e861d9243d3d2ad35Tim Peters
8621221c0a435135143632d986e861d9243d3d2ad35Tim Petersvoid
8631221c0a435135143632d986e861d9243d3d2ad35Tim Peters_PyMalloc_Free(void *p)
8641221c0a435135143632d986e861d9243d3d2ad35Tim Peters{
8651221c0a435135143632d986e861d9243d3d2ad35Tim Peters	PyMem_FREE(p);
8661221c0a435135143632d986e861d9243d3d2ad35Tim Peters}
8671221c0a435135143632d986e861d9243d3d2ad35Tim Peters#endif /* WITH_PYMALLOC */
8681221c0a435135143632d986e861d9243d3d2ad35Tim Peters
86962c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters/*==========================================================================*/
87062c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters/* Regardless of whether pymalloc is enabled, export entry points for
87162c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters * the object-oriented pymalloc functions.
87262c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters */
87362c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters
874ce7fb9b5151f7238bdbaeb16c3041c9990ca8e9dTim PetersPyObject *
875ce7fb9b5151f7238bdbaeb16c3041c9990ca8e9dTim Peters_PyMalloc_New(PyTypeObject *tp)
8761221c0a435135143632d986e861d9243d3d2ad35Tim Peters{
8771221c0a435135143632d986e861d9243d3d2ad35Tim Peters	PyObject *op;
8781221c0a435135143632d986e861d9243d3d2ad35Tim Peters	op = (PyObject *) _PyMalloc_MALLOC(_PyObject_SIZE(tp));
8791221c0a435135143632d986e861d9243d3d2ad35Tim Peters	if (op == NULL)
8801221c0a435135143632d986e861d9243d3d2ad35Tim Peters		return PyErr_NoMemory();
8811221c0a435135143632d986e861d9243d3d2ad35Tim Peters	return PyObject_INIT(op, tp);
8821221c0a435135143632d986e861d9243d3d2ad35Tim Peters}
8831221c0a435135143632d986e861d9243d3d2ad35Tim Peters
8841221c0a435135143632d986e861d9243d3d2ad35Tim PetersPyVarObject *
8851221c0a435135143632d986e861d9243d3d2ad35Tim Peters_PyMalloc_NewVar(PyTypeObject *tp, int nitems)
8861221c0a435135143632d986e861d9243d3d2ad35Tim Peters{
8871221c0a435135143632d986e861d9243d3d2ad35Tim Peters	PyVarObject *op;
8881221c0a435135143632d986e861d9243d3d2ad35Tim Peters	const size_t size = _PyObject_VAR_SIZE(tp, nitems);
8891221c0a435135143632d986e861d9243d3d2ad35Tim Peters	op = (PyVarObject *) _PyMalloc_MALLOC(size);
8901221c0a435135143632d986e861d9243d3d2ad35Tim Peters	if (op == NULL)
8911221c0a435135143632d986e861d9243d3d2ad35Tim Peters		return (PyVarObject *)PyErr_NoMemory();
8921221c0a435135143632d986e861d9243d3d2ad35Tim Peters	return PyObject_INIT_VAR(op, tp, nitems);
8931221c0a435135143632d986e861d9243d3d2ad35Tim Peters}
8941221c0a435135143632d986e861d9243d3d2ad35Tim Peters
8951221c0a435135143632d986e861d9243d3d2ad35Tim Petersvoid
8961221c0a435135143632d986e861d9243d3d2ad35Tim Peters_PyMalloc_Del(PyObject *op)
8971221c0a435135143632d986e861d9243d3d2ad35Tim Peters{
8981221c0a435135143632d986e861d9243d3d2ad35Tim Peters	_PyMalloc_FREE(op);
8991221c0a435135143632d986e861d9243d3d2ad35Tim Peters}
900ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
901ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters#ifdef PYMALLOC_DEBUG
902ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters/*==========================================================================*/
90362c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters/* A x-platform debugging allocator.  This doesn't manage memory directly,
90462c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters * it wraps a real allocator, adding extra debugging info to the memory blocks.
90562c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters */
906ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
907ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters#define PYMALLOC_CLEANBYTE      0xCB    /* uninitialized memory */
908ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters#define PYMALLOC_DEADBYTE       0xDB    /* free()ed memory */
909ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters#define PYMALLOC_FORBIDDENBYTE  0xFB    /* unusable memory */
910ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
911ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersstatic ulong serialno = 0;	/* incremented on each debug {m,re}alloc */
912ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
913e085017ab7121b27be315d36ef0c25ed51484023Tim Peters/* serialno is always incremented via calling this routine.  The point is
914e085017ab7121b27be315d36ef0c25ed51484023Tim Peters   to supply a single place to set a breakpoint.
915e085017ab7121b27be315d36ef0c25ed51484023Tim Peters*/
916e085017ab7121b27be315d36ef0c25ed51484023Tim Petersstatic void
917bd02b14255f99feef90121cf654989b9fe827210Neil Schemenauerbumpserialno(void)
918e085017ab7121b27be315d36ef0c25ed51484023Tim Peters{
919e085017ab7121b27be315d36ef0c25ed51484023Tim Peters	++serialno;
920e085017ab7121b27be315d36ef0c25ed51484023Tim Peters}
921e085017ab7121b27be315d36ef0c25ed51484023Tim Peters
922e085017ab7121b27be315d36ef0c25ed51484023Tim Peters
923ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters/* Read 4 bytes at p as a big-endian ulong. */
924ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersstatic ulong
925ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersread4(const void *p)
926ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters{
92762c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters	const uchar *q = (const uchar *)p;
928ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	return ((ulong)q[0] << 24) |
929ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	       ((ulong)q[1] << 16) |
930ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	       ((ulong)q[2] <<  8) |
931ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	        (ulong)q[3];
932ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters}
933ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
934ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters/* Write the 4 least-significant bytes of n as a big-endian unsigned int,
935ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters   MSB at address p, LSB at p+3. */
936ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersstatic void
937ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peterswrite4(void *p, ulong n)
938ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters{
93962c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters	uchar *q = (uchar *)p;
94062c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters	q[0] = (uchar)((n >> 24) & 0xff);
94162c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters	q[1] = (uchar)((n >> 16) & 0xff);
94262c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters	q[2] = (uchar)((n >>  8) & 0xff);
94362c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters	q[3] = (uchar)( n        & 0xff);
944ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters}
945ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
946ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters/* The debug malloc asks for 16 extra bytes and fills them with useful stuff,
947ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters   here calling the underlying malloc's result p:
948ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
949ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersp[0:4]
950ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    Number of bytes originally asked for.  4-byte unsigned integer,
951ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    big-endian (easier to read in a memory dump).
952d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Petersp[4:8]
953ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    Copies of PYMALLOC_FORBIDDENBYTE.  Used to catch under- writes
954ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    and reads.
955ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersp[8:8+n]
956ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    The requested memory, filled with copies of PYMALLOC_CLEANBYTE.
957ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    Used to catch reference to uninitialized memory.
958ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    &p[8] is returned.  Note that this is 8-byte aligned if PyMalloc
959ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    handled the request itself.
960ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersp[8+n:8+n+4]
961ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    Copies of PYMALLOC_FORBIDDENBYTE.  Used to catch over- writes
962ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    and reads.
963ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersp[8+n+4:8+n+8]
964ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    A serial number, incremented by 1 on each call to _PyMalloc_DebugMalloc
965ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    and _PyMalloc_DebugRealloc.
966ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    4-byte unsigned integer, big-endian.
967ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    If "bad memory" is detected later, the serial number gives an
968ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    excellent way to set a breakpoint on the next run, to capture the
969ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters    instant at which this block was passed out.
970ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters*/
971ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
972ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersvoid *
973d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters_PyMalloc_DebugMalloc(size_t nbytes)
974ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters{
975ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	uchar *p;	/* base address of malloc'ed block */
97662c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters	uchar *tail;	/* p + 8 + nbytes == pointer to tail pad bytes */
977ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	size_t total;	/* nbytes + 16 */
978ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
979e085017ab7121b27be315d36ef0c25ed51484023Tim Peters	bumpserialno();
980ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	total = nbytes + 16;
981ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (total < nbytes || (total >> 31) > 1) {
982ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		/* overflow, or we can't represent it in 4 bytes */
983ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		/* Obscure:  can't do (total >> 32) != 0 instead, because
984ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		   C doesn't define what happens for a right-shift of 32
985ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		   when size_t is a 32-bit type.  At least C guarantees
986ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		   size_t is an unsigned type. */
987ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		return NULL;
988ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	}
989ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
990d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	p = _PyMalloc_Malloc(total);
991ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (p == NULL)
992ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		return NULL;
993ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
994ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	write4(p, nbytes);
995d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	p[4] = p[5] = p[6] = p[7] = PYMALLOC_FORBIDDENBYTE;
996ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
997ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (nbytes > 0)
998ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		memset(p+8, PYMALLOC_CLEANBYTE, nbytes);
999ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
100062c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters	tail = p + 8 + nbytes;
100162c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters	tail[0] = tail[1] = tail[2] = tail[3] = PYMALLOC_FORBIDDENBYTE;
100262c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters	write4(tail + 4, serialno);
1003ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1004ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	return p+8;
1005ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters}
1006ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
100762c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters/* The debug free first checks the 8 bytes on each end for sanity (in
100862c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters   particular, that the PYMALLOC_FORBIDDENBYTEs are still intact).
1009ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters   Then fills the original bytes with PYMALLOC_DEADBYTE.
1010ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters   Then calls the underlying free.
1011ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters*/
1012ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersvoid
1013d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters_PyMalloc_DebugFree(void *p)
1014ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters{
101562c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters	uchar *q = (uchar *)p;
1016ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	size_t nbytes;
1017ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1018ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (p == NULL)
1019ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		return;
1020ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	_PyMalloc_DebugCheckAddress(p);
1021ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	nbytes = read4(q-8);
1022ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (nbytes > 0)
1023ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		memset(q, PYMALLOC_DEADBYTE, nbytes);
1024d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	_PyMalloc_Free(q-8);
1025ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters}
1026ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1027ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersvoid *
1028d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters_PyMalloc_DebugRealloc(void *p, size_t nbytes)
1029ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters{
1030ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	uchar *q = (uchar *)p;
1031ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	size_t original_nbytes;
1032e085017ab7121b27be315d36ef0c25ed51484023Tim Peters	void *fresh;	/* new memory block, if needed */
1033ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1034ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (p == NULL)
1035d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters		return _PyMalloc_DebugMalloc(nbytes);
1036ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1037ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	_PyMalloc_DebugCheckAddress(p);
1038ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	original_nbytes = read4(q-8);
1039ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (nbytes == original_nbytes) {
1040ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		/* note that this case is likely to be common due to the
1041ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		   way Python appends to lists */
1042e085017ab7121b27be315d36ef0c25ed51484023Tim Peters		bumpserialno();
1043ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		write4(q + nbytes + 4, serialno);
1044ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		return p;
1045ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	}
1046ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1047ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (nbytes < original_nbytes) {
1048ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		/* shrinking -- leave the guts alone, except to
1049ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		   fill the excess with DEADBYTE */
1050ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		const size_t excess = original_nbytes - nbytes;
1051e085017ab7121b27be315d36ef0c25ed51484023Tim Peters		bumpserialno();
1052ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		write4(q-8, nbytes);
1053ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		/* kill the excess bytes plus the trailing 8 pad bytes */
1054ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		q += nbytes;
1055ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		q[0] = q[1] = q[2] = q[3] = PYMALLOC_FORBIDDENBYTE;
1056ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		write4(q+4, serialno);
1057d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters		memset(q+8, PYMALLOC_DEADBYTE, excess);
1058ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		return p;
1059ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	}
1060ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
106152aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Peters	assert(nbytes != 0);
1062ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	/* More memory is needed:  get it, copy over the first original_nbytes
1063ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	   of the original data, and free the original memory. */
1064d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	fresh = _PyMalloc_DebugMalloc(nbytes);
106552aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Peters	if (fresh != NULL) {
106652aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Peters		if (original_nbytes > 0)
106752aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Peters			memcpy(fresh, p, original_nbytes);
106852aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Peters		_PyMalloc_DebugFree(p);
106952aefc8a7b9e9ebda6c1b98a831a273e0b07bf96Tim Peters	}
1070ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	return fresh;
1071ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters}
1072ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
10737ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters/* Check the forbidden bytes on both ends of the memory allocated for p.
10747ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters * If anything is wrong, print info to stderr via _PyMalloc_DebugDumpAddress,
10757ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters * and call Py_FatalError to kill the program.
10767ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters */
10777ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters void
1078ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters_PyMalloc_DebugCheckAddress(const void *p)
1079ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters{
1080ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	const uchar *q = (const uchar *)p;
1081d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	char *msg;
1082d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	int i;
1083ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1084d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	if (p == NULL) {
1085ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		msg = "didn't expect a NULL pointer";
1086d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters		goto error;
1087d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	}
1088ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1089d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	for (i = 4; i >= 1; --i) {
1090d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters		if (*(q-i) != PYMALLOC_FORBIDDENBYTE) {
1091d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters			msg = "bad leading pad byte";
1092d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters			goto error;
1093d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters		}
1094d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	}
1095ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1096d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	{
1097ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		const ulong nbytes = read4(q-8);
1098ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		const uchar *tail = q + nbytes;
1099ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		for (i = 0; i < 4; ++i) {
1100ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			if (tail[i] != PYMALLOC_FORBIDDENBYTE) {
1101ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters				msg = "bad trailing pad byte";
1102d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters				goto error;
1103ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			}
1104ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		}
1105ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	}
1106ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1107d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	return;
1108d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters
1109d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peterserror:
1110d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	_PyMalloc_DebugDumpAddress(p);
1111d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	Py_FatalError(msg);
1112ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters}
1113ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
11147ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters/* Display info to stderr about the memory block at p. */
1115ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Petersvoid
1116ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters_PyMalloc_DebugDumpAddress(const void *p)
1117ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters{
1118ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	const uchar *q = (const uchar *)p;
1119ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	const uchar *tail;
1120ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	ulong nbytes, serial;
1121d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	int i;
1122ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1123ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	fprintf(stderr, "Debug memory block at address p=%p:\n", p);
1124ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (p == NULL)
1125ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		return;
1126ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1127ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	nbytes = read4(q-8);
1128ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	fprintf(stderr, "    %lu bytes originally allocated\n", nbytes);
1129ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1130ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	/* In case this is nuts, check the pad bytes before trying to read up
1131ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	   the serial number (the address deref could blow up). */
1132ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1133d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	fputs("    the 4 pad bytes at p-4 are ", stderr);
1134d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	if (*(q-4) == PYMALLOC_FORBIDDENBYTE &&
1135d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters	    *(q-3) == PYMALLOC_FORBIDDENBYTE &&
1136ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	    *(q-2) == PYMALLOC_FORBIDDENBYTE &&
1137ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	    *(q-1) == PYMALLOC_FORBIDDENBYTE) {
113862c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters		fputs("PYMALLOC_FORBIDDENBYTE, as expected\n", stderr);
1139ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	}
1140ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	else {
1141ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		fprintf(stderr, "not all PYMALLOC_FORBIDDENBYTE (0x%02x):\n",
1142ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			PYMALLOC_FORBIDDENBYTE);
1143d1139e043c74fd2495ded3cb534c7e0a339532e2Tim Peters		for (i = 4; i >= 1; --i) {
1144ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			const uchar byte = *(q-i);
1145ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			fprintf(stderr, "        at p-%d: 0x%02x", i, byte);
1146ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			if (byte != PYMALLOC_FORBIDDENBYTE)
1147ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters				fputs(" *** OUCH", stderr);
1148ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			fputc('\n', stderr);
1149ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		}
1150ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	}
1151ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1152ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	tail = q + nbytes;
1153ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	fprintf(stderr, "    the 4 pad bytes at tail=%p are ", tail);
1154ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (tail[0] == PYMALLOC_FORBIDDENBYTE &&
1155ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	    tail[1] == PYMALLOC_FORBIDDENBYTE &&
1156ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	    tail[2] == PYMALLOC_FORBIDDENBYTE &&
1157ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	    tail[3] == PYMALLOC_FORBIDDENBYTE) {
115862c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters		fputs("PYMALLOC_FORBIDDENBYTE, as expected\n", stderr);
1159ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	}
1160ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	else {
1161ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		fprintf(stderr, "not all PYMALLOC_FORBIDDENBYTE (0x%02x):\n",
1162ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			PYMALLOC_FORBIDDENBYTE);
1163ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		for (i = 0; i < 4; ++i) {
1164ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			const uchar byte = tail[i];
1165ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			fprintf(stderr, "        at tail+%d: 0x%02x",
1166ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters				i, byte);
1167ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			if (byte != PYMALLOC_FORBIDDENBYTE)
1168ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters				fputs(" *** OUCH", stderr);
1169ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			fputc('\n', stderr);
1170ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		}
1171ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	}
1172ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1173ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	serial = read4(tail+4);
1174ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	fprintf(stderr, "    the block was made by call #%lu to "
1175ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	                "debug malloc/realloc\n", serial);
1176ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
1177ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	if (nbytes > 0) {
1178ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		int i = 0;
117962c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters		fputs("    data at p:", stderr);
1180ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		/* print up to 8 bytes at the start */
1181ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		while (q < tail && i < 8) {
1182ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			fprintf(stderr, " %02x", *q);
1183ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			++i;
1184ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			++q;
1185ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		}
1186ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		/* and up to 8 at the end */
1187ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		if (q < tail) {
1188ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			if (tail - q > 8) {
118962c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters				fputs(" ...", stderr);
1190ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters				q = tail - 8;
1191ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			}
1192ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			while (q < tail) {
1193ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters				fprintf(stderr, " %02x", *q);
1194ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters				++q;
1195ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters			}
1196ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters		}
119762c06ba6a9aa388555d826b4adb5d8981d74f4b2Tim Peters		fputc('\n', stderr);
1198ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters	}
1199ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters}
1200ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters
120116bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Petersstatic ulong
120216bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Petersprintone(const char* msg, ulong value)
120316bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters{
120449f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	int i, k;
120549f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	char buf[100];
120649f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	ulong origvalue = value;
120716bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters
120816bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	fputs(msg, stderr);
120949f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	for (i = (int)strlen(msg); i < 35; ++i)
121016bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters		fputc(' ', stderr);
121149f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	fputc('=', stderr);
121249f26817eb31d39339fbbf73c707b0e685ae649aTim Peters
121349f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	/* Write the value with commas. */
121449f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	i = 22;
121549f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	buf[i--] = '\0';
121649f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	buf[i--] = '\n';
121749f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	k = 3;
121849f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	do {
121949f26817eb31d39339fbbf73c707b0e685ae649aTim Peters		ulong nextvalue = value / 10UL;
122049f26817eb31d39339fbbf73c707b0e685ae649aTim Peters		uint digit = value - nextvalue * 10UL;
122149f26817eb31d39339fbbf73c707b0e685ae649aTim Peters		value = nextvalue;
122249f26817eb31d39339fbbf73c707b0e685ae649aTim Peters		buf[i--] = (char)(digit + '0');
122349f26817eb31d39339fbbf73c707b0e685ae649aTim Peters		--k;
122449f26817eb31d39339fbbf73c707b0e685ae649aTim Peters		if (k == 0 && value && i >= 0) {
122549f26817eb31d39339fbbf73c707b0e685ae649aTim Peters			k = 3;
122649f26817eb31d39339fbbf73c707b0e685ae649aTim Peters			buf[i--] = ',';
122749f26817eb31d39339fbbf73c707b0e685ae649aTim Peters		}
122849f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	} while (value && i >= 0);
122949f26817eb31d39339fbbf73c707b0e685ae649aTim Peters
123049f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	while (i >= 0)
123149f26817eb31d39339fbbf73c707b0e685ae649aTim Peters		buf[i--] = ' ';
123249f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	fputs(buf, stderr);
123349f26817eb31d39339fbbf73c707b0e685ae649aTim Peters
123449f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	return origvalue;
123516bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters}
123616bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters
12377ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters/* Print summary info to stderr about the state of pymalloc's structures. */
12387ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Petersvoid
12397ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters_PyMalloc_DebugDumpStats(void)
12407ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters{
12417ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	uint i;
12427ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	const uint numclasses = SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT;
124316bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	/* # of pools, allocated blocks, and free blocks per class index */
12447ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	ulong numpools[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
12457ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	ulong numblocks[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
12467ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	ulong numfreeblocks[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
124716bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	/* total # of allocated bytes in used and full pools */
124816bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	ulong allocated_bytes = 0;
124916bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	/* total # of available bytes in used pools */
125016bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	ulong available_bytes = 0;
125116bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	/* # of free pools + pools not yet carved out of current arena */
125216bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	uint numfreepools = 0;
125316bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	/* # of bytes for arena alignment padding */
125416bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	uint arena_alignment = 0;
125516bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	/* # of bytes in used and full pools used for pool_headers */
125616bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	ulong pool_header_bytes = 0;
125716bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	/* # of bytes in used and full pools wasted due to quantization,
125816bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	 * i.e. the necessarily leftover space at the ends of used and
125916bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	 * full pools.
126016bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	 */
126116bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	ulong quantization = 0;
126216bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	/* running total -- should equal narenas * ARENA_SIZE */
126316bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	ulong total;
126416bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	char buf[128];
12657ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
12667ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	fprintf(stderr, "Small block threshold = %d, in %u size classes.\n",
12677ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		SMALL_REQUEST_THRESHOLD, numclasses);
12687ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	fprintf(stderr, "pymalloc malloc+realloc called %lu times.\n",
12697ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		serialno);
12707ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
12717ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	for (i = 0; i < numclasses; ++i)
12727ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		numpools[i] = numblocks[i] = numfreeblocks[i] = 0;
12737ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
12746169f09d64caf4c36936bc8caeaeb5448f72afacTim Peters	/* Because full pools aren't linked to from anything, it's easiest
12756169f09d64caf4c36936bc8caeaeb5448f72afacTim Peters	 * to march over all the arenas.  If we're lucky, most of the memory
12766169f09d64caf4c36936bc8caeaeb5448f72afacTim Peters	 * will be living in full pools -- would be a shame to miss them.
12777ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	 */
12787ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	for (i = 0; i < narenas; ++i) {
12797ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		uint poolsinarena;
12807ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		uint j;
12817ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		uptr base = arenas[i];
12827ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
12837ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		/* round up to pool alignment */
12847ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		poolsinarena = ARENA_SIZE / POOL_SIZE;
12857ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		if (base & (uptr)POOL_SIZE_MASK) {
12867ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			--poolsinarena;
128716bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters			arena_alignment += POOL_SIZE;
12887ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			base &= ~(uptr)POOL_SIZE_MASK;
12897ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			base += POOL_SIZE;
12907ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		}
12917ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
12927ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		if (i == narenas - 1) {
12937ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			/* current arena may have raw memory at the end */
12947ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			numfreepools += nfreepools;
12957ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			poolsinarena -= nfreepools;
12967ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		}
12977ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
12987ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		/* visit every pool in the arena */
12997ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		for (j = 0; j < poolsinarena; ++j, base += POOL_SIZE) {
13007ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			poolp p = (poolp)base;
13017ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			if (p->ref.count == 0) {
13027ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters				/* currently unused */
13037ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters				++numfreepools;
13047ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters				continue;
13057ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			}
13067ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			++numpools[p->szidx];
13077ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			numblocks[p->szidx] += p->ref.count;
130816bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters			numfreeblocks[p->szidx] += NUMBLOCKS(p->szidx) -
130916bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters						   p->ref.count;
13107ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		}
13117ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	}
13127ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
13137ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	fputc('\n', stderr);
131449f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	fputs("class   size   num pools   blocks in use  avail blocks\n"
131549f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	      "-----   ----   ---------   -------------  ------------\n",
13167ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		stderr);
13177ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
13187ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	for (i = 0; i < numclasses; ++i) {
13197ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		ulong p = numpools[i];
13207ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		ulong b = numblocks[i];
13217ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		ulong f = numfreeblocks[i];
1322e70ddf3a99e5394faf17d78d0764929ae795b674Tim Peters		uint size = INDEX2SIZE(i);
13237ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		if (p == 0) {
13247ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			assert(b == 0 && f == 0);
13257ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			continue;
13267ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters		}
132749f26817eb31d39339fbbf73c707b0e685ae649aTim Peters		fprintf(stderr, "%5u %6u %11lu %15lu %13lu\n",
13287ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters			i, size, p, b, f);
132916bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters		allocated_bytes += b * size;
133016bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters		available_bytes += f * size;
133116bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters		pool_header_bytes += p * POOL_OVERHEAD;
133216bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters		quantization += p * ((POOL_SIZE - POOL_OVERHEAD) % size);
13337ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	}
13347ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters	fputc('\n', stderr);
133516bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters
133616bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	PyOS_snprintf(buf, sizeof(buf),
133716bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters		"%u arenas * %d bytes/arena", narenas, ARENA_SIZE);
133816bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	(void)printone(buf, (ulong)narenas * ARENA_SIZE);
133916bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters
134016bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	fputc('\n', stderr);
134116bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters
134249f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	total = printone("# bytes in allocated blocks", allocated_bytes);
134349f26817eb31d39339fbbf73c707b0e685ae649aTim Peters
134416bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	PyOS_snprintf(buf, sizeof(buf),
134516bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters		"%u unused pools * %d bytes", numfreepools, POOL_SIZE);
134649f26817eb31d39339fbbf73c707b0e685ae649aTim Peters	total += printone(buf, (ulong)numfreepools * POOL_SIZE);
134716bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters
134816bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	total += printone("# bytes in available blocks", available_bytes);
134916bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	total += printone("# bytes lost to pool headers", pool_header_bytes);
135016bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	total += printone("# bytes lost to quantization", quantization);
135116bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	total += printone("# bytes lost to arena alignment", arena_alignment);
135216bcb6b1afc46f2f73e207bc0484f016c51f0fd9Tim Peters	(void)printone("Total", total);
13537ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters}
13547ccfadf3a88fb83ffa9cee2a3ff41910aa5a00ecTim Peters
1355ddea208be9e2a8fa281e25ebbc890378dd2aa286Tim Peters#endif	/* PYMALLOC_DEBUG */
1356