diff --git a/gcc/Makefile.in b/gcc/Makefile.in index c1cb4ce..1b4198d 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1516,7 +1516,7 @@ OBJS = \ # Objects in libcommon.a, potentially used by all host binaries and with # no target dependencies. OBJS-libcommon = diagnostic.o diagnostic-color.o pretty-print.o intl.o \ - vec.o input.o version.o hash-table.o ggc-none.o + vec.o input.o version.o hash-table.o ggc-none.o virtual-memory.o # Objects in libcommon-target.a, used by drivers and by the core # compiler and containing target-dependent code. diff --git a/gcc/alloc-pool.c b/gcc/alloc-pool.c index f8c1351..7e25915 100644 --- a/gcc/alloc-pool.c +++ b/gcc/alloc-pool.c @@ -35,25 +35,3 @@ dump_alloc_pool_statistics (void) pool_allocator_usage.dump (ALLOC_POOL_ORIGIN); } - -/* Global singleton-like instance. */ -memory_block_pool memory_block_pool::instance; - -memory_block_pool::memory_block_pool () : m_blocks (NULL) {} - -memory_block_pool::~memory_block_pool () -{ - release (); -} - -/* Free all memory allocated by memory_block_pool. */ -void -memory_block_pool::release () -{ - while (m_blocks) - { - block_list *next = m_blocks->m_next; - XDELETEVEC (m_blocks); - m_blocks = next; - } -} diff --git a/gcc/alloc-pool.h b/gcc/alloc-pool.h index dccc41a..eccdf0d 100644 --- a/gcc/alloc-pool.h +++ b/gcc/alloc-pool.h @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see #ifndef ALLOC_POOL_H #define ALLOC_POOL_H +#include "virtual-memory.h" extern void dump_alloc_pool_statistics (void); @@ -95,55 +96,6 @@ struct pool_usage: public mem_usage extern mem_alloc_description pool_allocator_usage; -/* Shared pool which allows other memory pools to reuse each others' allocated - memory blocks instead of calling free/malloc again. */ -class memory_block_pool -{ -public: - /* Blocks have fixed size. This is necessary for sharing. */ - static const size_t block_size = 64 * 1024; - - memory_block_pool (); - ~memory_block_pool (); - - static inline void *allocate () ATTRIBUTE_MALLOC; - static inline void remove (void *); - void release (); - -private: - /* memory_block_pool singleton instance, defined in alloc-pool.c. */ - static memory_block_pool instance; - - struct block_list - { - block_list *m_next; - }; - - /* Free list. */ - block_list *m_blocks; -}; - -/* Allocate single block. Reuse previously returned block, if possible. */ -inline void * -memory_block_pool::allocate () -{ - if (instance.m_blocks == NULL) - return XNEWVEC (char, block_size); - - void *result = instance.m_blocks; - instance.m_blocks = instance.m_blocks->m_next; - return result; -} - -/* Return UNCAST_BLOCK to pool. */ -inline void -memory_block_pool::remove (void *uncast_block) -{ - block_list *block = reinterpret_cast (uncast_block); - block->m_next = instance.m_blocks; - instance.m_blocks = block; -} - #if 0 /* If a pool with custom block size is needed, one might use the following template. An instance of this template can be used as a parameter for diff --git a/gcc/coretypes.h b/gcc/coretypes.h index 17e2b40..b7b7402 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -225,12 +225,19 @@ struct basic_block_def; typedef struct basic_block_def *basic_block; typedef const struct basic_block_def *const_basic_block; -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free -#define OBSTACK_CHUNK_SIZE 0 +#if !defined (GENERATOR_FILE) +# define OBSTACK_CHUNK_SIZE memory_block_pool::block_size +# define obstack_chunk_alloc mempool_obstack_chunk_alloc +# define obstack_chunk_free mempool_obstack_chunk_free +#else +# define OBSTACK_CHUNK_SIZE 0 +# define obstack_chunk_alloc xmalloc +# define obstack_chunk_free free +#endif + #define gcc_obstack_init(OBSTACK) \ obstack_specify_allocation ((OBSTACK), OBSTACK_CHUNK_SIZE, 0, \ - obstack_chunk_alloc, \ + obstack_chunk_alloc, \ obstack_chunk_free) /* enum reg_class is target specific, so it should not appear in @@ -328,6 +335,7 @@ typedef unsigned char uchar; #include "hash-set.h" #include "input.h" #include "is-a.h" +#include "virtual-memory.h" #endif /* GENERATOR_FILE && !USED_FOR_TARGET */ #endif /* coretypes.h */ diff --git a/gcc/virtual-memory.cc b/gcc/virtual-memory.cc new file mode 100644 index 0000000..69bda37 --- /dev/null +++ b/gcc/virtual-memory.cc @@ -0,0 +1,66 @@ +/* + Copyright (C) 2015 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "virtual-memory.h" +#include "obstack.h" + +/* Global singleton-like instance. */ +memory_block_pool memory_block_pool::instance; + +memory_block_pool::memory_block_pool () : m_blocks (NULL) {} + +memory_block_pool::~memory_block_pool () +{ + release (); +} + +/* Free all memory allocated by memory_block_pool. */ +void +memory_block_pool::release () +{ + while (m_blocks) + { + block_list *next = m_blocks->m_next; + XDELETEVEC (m_blocks); + m_blocks = next; + } +} + +void * +mempool_obstack_chunk_alloc (size_t size) +{ + if (size == memory_block_pool::block_size) + return memory_block_pool::allocate (); + else + return XNEWVEC (char, size); +} + +void +mempool_obstack_chunk_free (void *chunk) +{ + size_t size = reinterpret_cast<_obstack_chunk *> (chunk)->limit - + reinterpret_cast(chunk); + if (size == memory_block_pool::block_size) + memory_block_pool::remove (chunk); + else + XDELETEVEC (chunk); +} diff --git a/gcc/virtual-memory.h b/gcc/virtual-memory.h new file mode 100644 index 0000000..1d8f0bd --- /dev/null +++ b/gcc/virtual-memory.h @@ -0,0 +1,76 @@ +/* + Copyright (C) 2015 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + + +#ifndef VIRTUAL_MEMORY_H +#define VIRTUAL_MEMORY_H + +/* Shared pool which allows other memory pools to reuse each others' allocated + memory blocks instead of calling free/malloc again. */ +class memory_block_pool +{ +public: + /* Blocks have fixed size. This is necessary for sharing. */ + static const size_t block_size = 8 * 1024; + + memory_block_pool (); + ~memory_block_pool (); + + static inline void *allocate () ATTRIBUTE_MALLOC; + static inline void remove (void *); + void release (); + +private: + /* memory_block_pool singleton instance, defined in virtual-memory.cc. */ + static memory_block_pool instance; + + struct block_list + { + block_list *m_next; + }; + + /* Free list. */ + block_list *m_blocks; +}; + +/* Allocate single block. Reuse previously returned block, if possible. */ +inline void * +memory_block_pool::allocate () +{ + if (instance.m_blocks == NULL) + return XNEWVEC (char, block_size); + + void *result = instance.m_blocks; + instance.m_blocks = instance.m_blocks->m_next; + return result; +} + +/* Return UNCAST_BLOCK to pool. */ +inline void +memory_block_pool::remove (void *uncast_block) +{ + block_list *block = reinterpret_cast (uncast_block); + block->m_next = instance.m_blocks; + instance.m_blocks = block; +} + +extern void *mempool_obstack_chunk_alloc(size_t) ATTRIBUTE_MALLOC; +extern void mempool_obstack_chunk_free(void *); + +#endif /* VIRTUAL_MEMORY_H */