1 /* Shared pool of memory blocks for pool allocators. 2 Copyright (C) 2015-2021 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 * allocate()56memory_block_pool::allocate () 57 { 58 if (instance.m_blocks == NULL) 59 return XNEWVEC (char, block_size); 60 61 void *result = instance.m_blocks; 62 instance.m_blocks = instance.m_blocks->m_next; 63 VALGRIND_DISCARD (VALGRIND_MAKE_MEM_UNDEFINED (result, block_size)); 64 return result; 65 } 66 67 /* Return UNCAST_BLOCK to the pool. */ 68 inline void release(void * uncast_block)69memory_block_pool::release (void *uncast_block) 70 { 71 block_list *block = new (uncast_block) block_list; 72 block->m_next = instance.m_blocks; 73 instance.m_blocks = block; 74 75 VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS ((char *)uncast_block 76 + sizeof (block_list), 77 block_size 78 - sizeof (block_list))); 79 } 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 */ 85