]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gcov: use mmap pools for KVP.
authorMartin Liska <mliska@suse.cz>
Wed, 13 Jan 2021 10:17:03 +0000 (11:17 +0100)
committerMartin Liska <mliska@suse.cz>
Wed, 3 Mar 2021 13:21:45 +0000 (14:21 +0100)
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.

gcc/gcov-io.h
libgcc/config.in
libgcc/configure
libgcc/configure.ac
libgcc/libgcov-driver.c
libgcc/libgcov.h

index baed67609e246e582ea323c124c731fa12451162..75f16a274c72835bd18ef5bb70e67eca62534935 100644 (file)
@@ -292,9 +292,6 @@ GCOV_COUNTERS
 /* Maximum number of tracked TOP N value profiles.  */
 #define GCOV_TOPN_MAXIMUM_TRACKED_VALUES 32
 
-/* Number of pre-allocated gcov_kvp structures.  */
-#define GCOV_PREALLOCATED_KVP 64
-
 /* Convert a counter index to a tag.  */
 #define GCOV_TAG_FOR_COUNTER(COUNT)                            \
        (GCOV_TAG_COUNTER_BASE + ((gcov_unsigned_t)(COUNT) << 17))
index 5be5321d2584392bac1ec3af779cd96823212902..f93c64a00c3663ceee1fb67391a2819a801e503f 100644 (file)
@@ -49,6 +49,9 @@
 /* Define to 1 if you have the <sys/auxv.h> header file. */
 #undef HAVE_SYS_AUXV_H
 
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
 /* Define to 1 if you have the <sys/stat.h> header file. */
 #undef HAVE_SYS_STAT_H
 
index 78fc22a5784e7c64980e46b7d586139e4317275f..dd3afb2c95761f53dfa5bc71434e944369ef8a98 100755 (executable)
@@ -4458,7 +4458,7 @@ as_fn_arith $ac_cv_sizeof_long_double \* 8 && long_double_type_size=$as_val
 
 for ac_header in inttypes.h stdint.h stdlib.h ftw.h \
        unistd.h sys/stat.h sys/types.h \
-       string.h strings.h memory.h sys/auxv.h
+       string.h strings.h memory.h sys/auxv.h sys/mman.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_preproc "$LINENO" "$ac_header" "$as_ac_Header"
@@ -4913,7 +4913,7 @@ case "$host" in
     case "$enable_cet" in
       auto)
        # Check if target supports multi-byte NOPs
-       # and if assembler supports CET insn.
+       # and if compiler and assembler support CET insn.
        cet_save_CFLAGS="$CFLAGS"
        CFLAGS="$CFLAGS -fcf-protection"
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
index ed50c0e9b494672babaad7129218b2b8dd82d711..10ffb0464156cded1b2c386ff61d198216e2e399 100644 (file)
@@ -224,7 +224,7 @@ AC_SUBST(long_double_type_size)
 
 AC_CHECK_HEADERS(inttypes.h stdint.h stdlib.h ftw.h \
        unistd.h sys/stat.h sys/types.h \
-       string.h strings.h memory.h sys/auxv.h)
+       string.h strings.h memory.h sys/auxv.h sys/mman.h)
 AC_HEADER_STDC
 
 # Check for decimal float support.
index e474e032b541f67cc7b405619046fd77d6c2390a..914623501329420efaea9e0f475601a66c1c90e1 100644 (file)
@@ -588,11 +588,14 @@ struct gcov_root __gcov_root;
 struct gcov_master __gcov_master = 
   {GCOV_VERSION, 0};
 
-/* Pool of pre-allocated gcov_kvp strutures.  */
-struct gcov_kvp __gcov_kvp_pool[GCOV_PREALLOCATED_KVP];
+/* Dynamic pool for gcov_kvp structures.  */
+struct gcov_kvp *__gcov_kvp_dynamic_pool;
 
-/* Index to first free gcov_kvp in the pool.  */
-unsigned __gcov_kvp_pool_index;
+/* Index into __gcov_kvp_dynamic_pool array.  */
+unsigned __gcov_kvp_dynamic_pool_index;
+
+/* Size of _gcov_kvp_dynamic_pool array.  */
+unsigned __gcov_kvp_dynamic_pool_size;
 
 void
 __gcov_exit (void)
index ddc688509bd9c0b180bb627918a3c440a77a25bf..9c5fcfba4ade8579816abb90badc417bbbc02a8f 100644 (file)
 #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;
 }