mirror of git://gcc.gnu.org/git/gcc.git
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.
This commit is contained in:
parent
8cfa06570d
commit
00d79dc4be
|
@ -292,9 +292,6 @@ GCOV_COUNTERS
|
||||||
/* Maximum number of tracked TOP N value profiles. */
|
/* Maximum number of tracked TOP N value profiles. */
|
||||||
#define GCOV_TOPN_MAXIMUM_TRACKED_VALUES 32
|
#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. */
|
/* Convert a counter index to a tag. */
|
||||||
#define GCOV_TAG_FOR_COUNTER(COUNT) \
|
#define GCOV_TAG_FOR_COUNTER(COUNT) \
|
||||||
(GCOV_TAG_COUNTER_BASE + ((gcov_unsigned_t)(COUNT) << 17))
|
(GCOV_TAG_COUNTER_BASE + ((gcov_unsigned_t)(COUNT) << 17))
|
||||||
|
|
|
@ -49,6 +49,9 @@
|
||||||
/* Define to 1 if you have the <sys/auxv.h> header file. */
|
/* Define to 1 if you have the <sys/auxv.h> header file. */
|
||||||
#undef HAVE_SYS_AUXV_H
|
#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. */
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
#undef HAVE_SYS_STAT_H
|
#undef HAVE_SYS_STAT_H
|
||||||
|
|
||||||
|
|
|
@ -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 \
|
for ac_header in inttypes.h stdint.h stdlib.h ftw.h \
|
||||||
unistd.h sys/stat.h sys/types.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 :
|
do :
|
||||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
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"
|
ac_fn_c_check_header_preproc "$LINENO" "$ac_header" "$as_ac_Header"
|
||||||
|
@ -4913,7 +4913,7 @@ case "$host" in
|
||||||
case "$enable_cet" in
|
case "$enable_cet" in
|
||||||
auto)
|
auto)
|
||||||
# Check if target supports multi-byte NOPs
|
# 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"
|
cet_save_CFLAGS="$CFLAGS"
|
||||||
CFLAGS="$CFLAGS -fcf-protection"
|
CFLAGS="$CFLAGS -fcf-protection"
|
||||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
|
|
@ -224,7 +224,7 @@ AC_SUBST(long_double_type_size)
|
||||||
|
|
||||||
AC_CHECK_HEADERS(inttypes.h stdint.h stdlib.h ftw.h \
|
AC_CHECK_HEADERS(inttypes.h stdint.h stdlib.h ftw.h \
|
||||||
unistd.h sys/stat.h sys/types.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
|
AC_HEADER_STDC
|
||||||
|
|
||||||
# Check for decimal float support.
|
# Check for decimal float support.
|
||||||
|
|
|
@ -588,11 +588,14 @@ struct gcov_root __gcov_root;
|
||||||
struct gcov_master __gcov_master =
|
struct gcov_master __gcov_master =
|
||||||
{GCOV_VERSION, 0};
|
{GCOV_VERSION, 0};
|
||||||
|
|
||||||
/* Pool of pre-allocated gcov_kvp strutures. */
|
/* Dynamic pool for gcov_kvp structures. */
|
||||||
struct gcov_kvp __gcov_kvp_pool[GCOV_PREALLOCATED_KVP];
|
struct gcov_kvp *__gcov_kvp_dynamic_pool;
|
||||||
|
|
||||||
/* Index to first free gcov_kvp in the pool. */
|
/* Index into __gcov_kvp_dynamic_pool array. */
|
||||||
unsigned __gcov_kvp_pool_index;
|
unsigned __gcov_kvp_dynamic_pool_index;
|
||||||
|
|
||||||
|
/* Size of _gcov_kvp_dynamic_pool array. */
|
||||||
|
unsigned __gcov_kvp_dynamic_pool_size;
|
||||||
|
|
||||||
void
|
void
|
||||||
__gcov_exit (void)
|
__gcov_exit (void)
|
||||||
|
|
|
@ -45,6 +45,10 @@
|
||||||
#include "libgcc_tm.h"
|
#include "libgcc_tm.h"
|
||||||
#include "gcov.h"
|
#include "gcov.h"
|
||||||
|
|
||||||
|
#if HAVE_SYS_MMAN_H
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if __CHAR_BIT__ == 8
|
#if __CHAR_BIT__ == 8
|
||||||
typedef unsigned gcov_unsigned_t __attribute__ ((mode (SI)));
|
typedef unsigned gcov_unsigned_t __attribute__ ((mode (SI)));
|
||||||
typedef unsigned gcov_position_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. */
|
/* Exactly one of these will be active in the process. */
|
||||||
extern struct gcov_master __gcov_master;
|
extern struct gcov_master __gcov_master;
|
||||||
extern struct gcov_kvp __gcov_kvp_pool[GCOV_PREALLOCATED_KVP];
|
extern struct gcov_kvp *__gcov_kvp_dynamic_pool;
|
||||||
extern unsigned __gcov_kvp_pool_index;
|
extern unsigned __gcov_kvp_dynamic_pool_index;
|
||||||
|
extern unsigned __gcov_kvp_dynamic_pool_size;
|
||||||
|
|
||||||
/* Dump a set of gcov objects. */
|
/* Dump a set of gcov objects. */
|
||||||
extern void __gcov_dump_one (struct gcov_root *) ATTRIBUTE_HIDDEN;
|
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 *
|
static inline struct gcov_kvp *
|
||||||
allocate_gcov_kvp (void)
|
allocate_gcov_kvp (void)
|
||||||
{
|
{
|
||||||
|
#define MMAP_CHUNK_SIZE (128 * 1024)
|
||||||
struct gcov_kvp *new_node = NULL;
|
struct gcov_kvp *new_node = NULL;
|
||||||
|
unsigned kvp_sizeof = sizeof(struct gcov_kvp);
|
||||||
|
|
||||||
#if !defined(IN_GCOV_TOOL) && !defined(L_gcov_merge_topn)
|
/* Try mmaped pool if available. */
|
||||||
if (__gcov_kvp_pool_index < GCOV_PREALLOCATED_KVP)
|
#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 (__gcov_kvp_dynamic_pool != NULL)
|
||||||
{
|
{
|
||||||
unsigned index;
|
unsigned index;
|
||||||
#if GCOV_SUPPORTS_ATOMIC
|
#if GCOV_SUPPORTS_ATOMIC
|
||||||
index
|
index
|
||||||
= __atomic_fetch_add (&__gcov_kvp_pool_index, 1, __ATOMIC_RELAXED);
|
= __atomic_fetch_add (&__gcov_kvp_dynamic_pool_index, 1,
|
||||||
|
__ATOMIC_RELAXED);
|
||||||
#else
|
#else
|
||||||
index = __gcov_kvp_pool_index++;
|
index = __gcov_kvp_dynamic_pool_index++;
|
||||||
#endif
|
#endif
|
||||||
if (index < GCOV_PREALLOCATED_KVP)
|
if (index < __gcov_kvp_dynamic_pool_size)
|
||||||
new_node = &__gcov_kvp_pool[index];
|
new_node = __gcov_kvp_dynamic_pool + index;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Fallback to malloc. */
|
||||||
if (new_node == NULL)
|
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;
|
return new_node;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue