diff options
author | Martin Liska <mliska@suse.cz> | 2021-01-13 11:17:03 +0100 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2021-03-03 14:21:45 +0100 |
commit | 00d79dc4be0b86ec564cfa2b32c47de6c07449e6 (patch) | |
tree | e8a0decbad8ba16951cd9f0861e09b67063d8f1c /libgcc/libgcov.h | |
parent | 8cfa06570dd5eae2f074e1a1388004a60edfd01f (diff) | |
download | gcc-00d79dc4be0b86ec564cfa2b32c47de6c07449e6.zip gcc-00d79dc4be0b86ec564cfa2b32c47de6c07449e6.tar.gz gcc-00d79dc4be0b86ec564cfa2b32c47de6c07449e6.tar.bz2 |
gcov: use mmap pools for KVP.
gcc/ChangeLog:
PR gcov-profile/97461
* gcov-io.h (GCOV_PREALLOCATED_KVP): Remove.
libgcc/ChangeLog:
PR gcov-profile/97461
* config.in: Regenerate.
* configure: Likewise.
* configure.ac: Check sys/mman.h header file
* libgcov-driver.c (struct gcov_kvp): Remove static
pre-allocated pool and use a dynamic one.
* libgcov.h (MMAP_CHUNK_SIZE): New.
(gcov_counter_add): Use mmap to allocate pool for struct
gcov_kvp.
Diffstat (limited to 'libgcc/libgcov.h')
-rw-r--r-- | libgcc/libgcov.h | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h index ddc6885..9c5fcfb 100644 --- a/libgcc/libgcov.h +++ b/libgcc/libgcov.h @@ -45,6 +45,10 @@ #include "libgcc_tm.h" #include "gcov.h" +#if HAVE_SYS_MMAN_H +#include <sys/mman.h> +#endif + #if __CHAR_BIT__ == 8 typedef unsigned gcov_unsigned_t __attribute__ ((mode (SI))); typedef unsigned gcov_position_t __attribute__ ((mode (SI))); @@ -250,8 +254,9 @@ struct indirect_call_tuple /* Exactly one of these will be active in the process. */ extern struct gcov_master __gcov_master; -extern struct gcov_kvp __gcov_kvp_pool[GCOV_PREALLOCATED_KVP]; -extern unsigned __gcov_kvp_pool_index; +extern struct gcov_kvp *__gcov_kvp_dynamic_pool; +extern unsigned __gcov_kvp_dynamic_pool_index; +extern unsigned __gcov_kvp_dynamic_pool_size; /* Dump a set of gcov objects. */ extern void __gcov_dump_one (struct gcov_root *) ATTRIBUTE_HIDDEN; @@ -410,25 +415,44 @@ gcov_counter_add (gcov_type *counter, gcov_type value, static inline struct gcov_kvp * allocate_gcov_kvp (void) { +#define MMAP_CHUNK_SIZE (128 * 1024) struct gcov_kvp *new_node = NULL; + unsigned kvp_sizeof = sizeof(struct gcov_kvp); + + /* Try mmaped pool if available. */ +#if !defined(IN_GCOV_TOOL) && !defined(L_gcov_merge_topn) && HAVE_SYS_MMAN_H + if (__gcov_kvp_dynamic_pool == NULL + || __gcov_kvp_dynamic_pool_index >= __gcov_kvp_dynamic_pool_size) + { + void *ptr = mmap (NULL, MMAP_CHUNK_SIZE, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); + if (ptr != MAP_FAILED) + { + __gcov_kvp_dynamic_pool = ptr; + __gcov_kvp_dynamic_pool_size = MMAP_CHUNK_SIZE / kvp_sizeof; + __gcov_kvp_dynamic_pool_index = 0; + } + } -#if !defined(IN_GCOV_TOOL) && !defined(L_gcov_merge_topn) - if (__gcov_kvp_pool_index < GCOV_PREALLOCATED_KVP) + if (__gcov_kvp_dynamic_pool != NULL) { unsigned index; #if GCOV_SUPPORTS_ATOMIC index - = __atomic_fetch_add (&__gcov_kvp_pool_index, 1, __ATOMIC_RELAXED); + = __atomic_fetch_add (&__gcov_kvp_dynamic_pool_index, 1, + __ATOMIC_RELAXED); #else - index = __gcov_kvp_pool_index++; + index = __gcov_kvp_dynamic_pool_index++; #endif - if (index < GCOV_PREALLOCATED_KVP) - new_node = &__gcov_kvp_pool[index]; + if (index < __gcov_kvp_dynamic_pool_size) + new_node = __gcov_kvp_dynamic_pool + index; } #endif + /* Fallback to malloc. */ if (new_node == NULL) - new_node = (struct gcov_kvp *)xcalloc (1, sizeof (struct gcov_kvp)); + new_node = (struct gcov_kvp *)xcalloc (1, kvp_sizeof); return new_node; } |