aboutsummaryrefslogtreecommitdiff
path: root/libgcc/libgcov.h
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2021-01-13 11:17:03 +0100
committerMartin Liska <mliska@suse.cz>2021-03-03 14:21:45 +0100
commit00d79dc4be0b86ec564cfa2b32c47de6c07449e6 (patch)
treee8a0decbad8ba16951cd9f0861e09b67063d8f1c /libgcc/libgcov.h
parent8cfa06570dd5eae2f074e1a1388004a60edfd01f (diff)
downloadgcc-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.h42
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;
}