Home | History | Annotate | Line # | Download | only in gcc
      1 /* Shared pool of memory blocks for pool allocators.
      2    Copyright (C) 2015-2022 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 memory_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
     69 memory_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