Skip to content

Commit 00d79dc

Browse files
committed
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.
1 parent 8cfa065 commit 00d79dc

File tree

6 files changed

+46
-19
lines changed

6 files changed

+46
-19
lines changed

gcc/gcov-io.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,6 @@ GCOV_COUNTERS
292292
/* Maximum number of tracked TOP N value profiles. */
293293
#define GCOV_TOPN_MAXIMUM_TRACKED_VALUES 32
294294

295-
/* Number of pre-allocated gcov_kvp structures. */
296-
#define GCOV_PREALLOCATED_KVP 64
297-
298295
/* Convert a counter index to a tag. */
299296
#define GCOV_TAG_FOR_COUNTER(COUNT) \
300297
(GCOV_TAG_COUNTER_BASE + ((gcov_unsigned_t)(COUNT) << 17))

libgcc/config.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
/* Define to 1 if you have the <sys/auxv.h> header file. */
5050
#undef HAVE_SYS_AUXV_H
5151

52+
/* Define to 1 if you have the <sys/mman.h> header file. */
53+
#undef HAVE_SYS_MMAN_H
54+
5255
/* Define to 1 if you have the <sys/stat.h> header file. */
5356
#undef HAVE_SYS_STAT_H
5457

libgcc/configure

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4458,7 +4458,7 @@ as_fn_arith $ac_cv_sizeof_long_double \* 8 && long_double_type_size=$as_val
44584458
44594459
for ac_header in inttypes.h stdint.h stdlib.h ftw.h \
44604460
unistd.h sys/stat.h sys/types.h \
4461-
string.h strings.h memory.h sys/auxv.h
4461+
string.h strings.h memory.h sys/auxv.h sys/mman.h
44624462
do :
44634463
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
44644464
ac_fn_c_check_header_preproc "$LINENO" "$ac_header" "$as_ac_Header"
@@ -4913,7 +4913,7 @@ case "$host" in
49134913
case "$enable_cet" in
49144914
auto)
49154915
# Check if target supports multi-byte NOPs
4916-
# and if assembler supports CET insn.
4916+
# and if compiler and assembler support CET insn.
49174917
cet_save_CFLAGS="$CFLAGS"
49184918
CFLAGS="$CFLAGS -fcf-protection"
49194919
cat confdefs.h - <<_ACEOF >conftest.$ac_ext

libgcc/configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ AC_SUBST(long_double_type_size)
224224

225225
AC_CHECK_HEADERS(inttypes.h stdint.h stdlib.h ftw.h \
226226
unistd.h sys/stat.h sys/types.h \
227-
string.h strings.h memory.h sys/auxv.h)
227+
string.h strings.h memory.h sys/auxv.h sys/mman.h)
228228
AC_HEADER_STDC
229229

230230
# Check for decimal float support.

libgcc/libgcov-driver.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -588,11 +588,14 @@ struct gcov_root __gcov_root;
588588
struct gcov_master __gcov_master =
589589
{GCOV_VERSION, 0};
590590

591-
/* Pool of pre-allocated gcov_kvp strutures. */
592-
struct gcov_kvp __gcov_kvp_pool[GCOV_PREALLOCATED_KVP];
591+
/* Dynamic pool for gcov_kvp structures. */
592+
struct gcov_kvp *__gcov_kvp_dynamic_pool;
593593

594-
/* Index to first free gcov_kvp in the pool. */
595-
unsigned __gcov_kvp_pool_index;
594+
/* Index into __gcov_kvp_dynamic_pool array. */
595+
unsigned __gcov_kvp_dynamic_pool_index;
596+
597+
/* Size of _gcov_kvp_dynamic_pool array. */
598+
unsigned __gcov_kvp_dynamic_pool_size;
596599

597600
void
598601
__gcov_exit (void)

libgcc/libgcov.h

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@
4545
#include "libgcc_tm.h"
4646
#include "gcov.h"
4747

48+
#if HAVE_SYS_MMAN_H
49+
#include <sys/mman.h>
50+
#endif
51+
4852
#if __CHAR_BIT__ == 8
4953
typedef unsigned gcov_unsigned_t __attribute__ ((mode (SI)));
5054
typedef unsigned gcov_position_t __attribute__ ((mode (SI)));
@@ -250,8 +254,9 @@ struct indirect_call_tuple
250254

251255
/* Exactly one of these will be active in the process. */
252256
extern struct gcov_master __gcov_master;
253-
extern struct gcov_kvp __gcov_kvp_pool[GCOV_PREALLOCATED_KVP];
254-
extern unsigned __gcov_kvp_pool_index;
257+
extern struct gcov_kvp *__gcov_kvp_dynamic_pool;
258+
extern unsigned __gcov_kvp_dynamic_pool_index;
259+
extern unsigned __gcov_kvp_dynamic_pool_size;
255260

256261
/* Dump a set of gcov objects. */
257262
extern void __gcov_dump_one (struct gcov_root *) ATTRIBUTE_HIDDEN;
@@ -410,25 +415,44 @@ gcov_counter_add (gcov_type *counter, gcov_type value,
410415
static inline struct gcov_kvp *
411416
allocate_gcov_kvp (void)
412417
{
418+
#define MMAP_CHUNK_SIZE (128 * 1024)
413419
struct gcov_kvp *new_node = NULL;
420+
unsigned kvp_sizeof = sizeof(struct gcov_kvp);
421+
422+
/* Try mmaped pool if available. */
423+
#if !defined(IN_GCOV_TOOL) && !defined(L_gcov_merge_topn) && HAVE_SYS_MMAN_H
424+
if (__gcov_kvp_dynamic_pool == NULL
425+
|| __gcov_kvp_dynamic_pool_index >= __gcov_kvp_dynamic_pool_size)
426+
{
427+
void *ptr = mmap (NULL, MMAP_CHUNK_SIZE,
428+
PROT_READ | PROT_WRITE,
429+
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
430+
if (ptr != MAP_FAILED)
431+
{
432+
__gcov_kvp_dynamic_pool = ptr;
433+
__gcov_kvp_dynamic_pool_size = MMAP_CHUNK_SIZE / kvp_sizeof;
434+
__gcov_kvp_dynamic_pool_index = 0;
435+
}
436+
}
414437

415-
#if !defined(IN_GCOV_TOOL) && !defined(L_gcov_merge_topn)
416-
if (__gcov_kvp_pool_index < GCOV_PREALLOCATED_KVP)
438+
if (__gcov_kvp_dynamic_pool != NULL)
417439
{
418440
unsigned index;
419441
#if GCOV_SUPPORTS_ATOMIC
420442
index
421-
= __atomic_fetch_add (&__gcov_kvp_pool_index, 1, __ATOMIC_RELAXED);
443+
= __atomic_fetch_add (&__gcov_kvp_dynamic_pool_index, 1,
444+
__ATOMIC_RELAXED);
422445
#else
423-
index = __gcov_kvp_pool_index++;
446+
index = __gcov_kvp_dynamic_pool_index++;
424447
#endif
425-
if (index < GCOV_PREALLOCATED_KVP)
426-
new_node = &__gcov_kvp_pool[index];
448+
if (index < __gcov_kvp_dynamic_pool_size)
449+
new_node = __gcov_kvp_dynamic_pool + index;
427450
}
428451
#endif
429452

453+
/* Fallback to malloc. */
430454
if (new_node == NULL)
431-
new_node = (struct gcov_kvp *)xcalloc (1, sizeof (struct gcov_kvp));
455+
new_node = (struct gcov_kvp *)xcalloc (1, kvp_sizeof);
432456

433457
return new_node;
434458
}

0 commit comments

Comments
 (0)