Branch data Line data Source code
1 : : /* Shared pool of memory blocks for pool allocators.
2 : : Copyright (C) 2015-2025 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
6 : : GCC is free software; you can redistribute it and/or modify
7 : : it under the terms of the GNU General Public License as published by
8 : : the Free Software Foundation; either version 3, or (at your option)
9 : : any later version.
10 : :
11 : : GCC is distributed in the hope that it will be useful,
12 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : : GNU General Public License for more details.
15 : :
16 : : You should have received a copy of the GNU General Public License
17 : : along with GCC; see the file COPYING3. If not see
18 : : <http://www.gnu.org/licenses/>. */
19 : :
20 : :
21 : : #ifndef MEMORY_BLOCK_H
22 : : #define MEMORY_BLOCK_H
23 : :
24 : : /* Shared pool which allows other memory pools to reuse each others' allocated
25 : : memory blocks instead of calling free/malloc again. */
26 : : class memory_block_pool
27 : : {
28 : : public:
29 : : /* Blocks have fixed size. This is necessary for sharing. */
30 : : static const size_t block_size = 64 * 1024;
31 : : /* Number of blocks we keep in the freelists. */
32 : : static const size_t freelist_size = 1024 * 1024 / block_size;
33 : :
34 : : memory_block_pool ();
35 : :
36 : : static inline void *allocate () ATTRIBUTE_MALLOC;
37 : : static inline void release (void *);
38 : : static void trim (int nblocks = freelist_size);
39 : : void reduce_free_list (int);
40 : :
41 : : private:
42 : : /* memory_block_pool singleton instance, defined in memory-block.cc. */
43 : : static memory_block_pool instance;
44 : :
45 : : struct block_list
46 : : {
47 : : block_list *m_next;
48 : : };
49 : :
50 : : /* Free list. */
51 : : block_list *m_blocks;
52 : : };
53 : :
54 : : /* Allocate a single block. Reuse a previously returned block, if possible. */
55 : : inline void *
56 : 914256146 : memory_block_pool::allocate ()
57 : : {
58 : 914256146 : if (instance.m_blocks == NULL)
59 : 12267824 : return XNEWVEC (char, block_size);
60 : :
61 : 901988322 : void *result = instance.m_blocks;
62 : 901988322 : instance.m_blocks = instance.m_blocks->m_next;
63 : 901988322 : VALGRIND_DISCARD (VALGRIND_MAKE_MEM_UNDEFINED (result, block_size));
64 : 901988322 : return result;
65 : : }
66 : :
67 : : /* Return UNCAST_BLOCK to the pool. */
68 : : inline void
69 : 913172838 : memory_block_pool::release (void *uncast_block)
70 : : {
71 : 913172838 : block_list *block = new (uncast_block) block_list;
72 : 913172838 : block->m_next = instance.m_blocks;
73 : 913172838 : instance.m_blocks = block;
74 : :
75 : : VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS ((char *)uncast_block
76 : : + sizeof (block_list),
77 : : block_size
78 : 913172838 : - sizeof (block_list)));
79 : 403927701 : }
80 : :
81 : : extern void *mempool_obstack_chunk_alloc (size_t) ATTRIBUTE_MALLOC;
82 : : extern void mempool_obstack_chunk_free (void *);
83 : :
84 : : #endif /* MEMORY_BLOCK_H */
|