diff options
| author | Ulrich Drepper <drepper@redhat.com> | 2009-03-13 23:53:18 +0000 |
|---|---|---|
| committer | Ulrich Drepper <drepper@redhat.com> | 2009-03-13 23:53:18 +0000 |
| commit | 425ce2edb9d11cc1ff650fac16dfbc450241896a (patch) | |
| tree | b3bd9971ea82766a895ab549ff194d97bcc9d51e | |
| parent | e7f110cdbd6e9c5a48b378ba7b30a3ad1dc04314 (diff) | |
| download | glibc-425ce2edb9d11cc1ff650fac16dfbc450241896a.tar.xz glibc-425ce2edb9d11cc1ff650fac16dfbc450241896a.zip | |
* config.h.in (USE_MULTIARCH): Define.
* configure.in: Handle --enable-multi-arch.
* elf/dl-runtime.c (_dl_fixup): Handle STT_GNU_IFUNC.
(_dl_fixup_profile): Likewise.
* elf/do-lookup.c (dl_lookup_x): Likewise.
* sysdeps/x86_64/dl-machine.h: Handle STT_GNU_IFUNC.
* elf/elf.h (STT_GNU_IFUNC): Define.
* include/libc-symbols.h (libc_ifunc): Define.
* sysdeps/x86_64/cacheinfo.c: If USE_MULTIARCH is defined, use the
framework in init-arch.h to get CPUID values.
* sysdeps/x86_64/multiarch/Makefile: New file.
* sysdeps/x86_64/multiarch/init-arch.c: New file.
* sysdeps/x86_64/multiarch/init-arch.h: New file.
* sysdeps/x86_64/multiarch/sched_cpucount.c: New file.
* config.make.in (experimental-malloc): Define.
* configure.in: Handle --enable-experimental-malloc.
* malloc/Makefile: Handle experimental-malloc flag.
* malloc/malloc.c: Implement PER_THREAD and ATOMIC_FASTBINS features.
* malloc/arena.c: Likewise.
* malloc/hooks.c: Likewise.
* malloc/malloc.h: Define M_ARENA_TEST and M_ARENA_MAX.
| -rw-r--r-- | ChangeLog | 25 | ||||
| -rw-r--r-- | NEWS | 4 | ||||
| -rw-r--r-- | config.h.in | 3 | ||||
| -rw-r--r-- | config.make.in | 3 | ||||
| -rwxr-xr-x | configure | 70 | ||||
| -rw-r--r-- | configure.in | 43 | ||||
| -rw-r--r-- | elf/dl-runtime.c | 14 | ||||
| -rw-r--r-- | elf/do-lookup.h | 12 | ||||
| -rw-r--r-- | elf/elf.h | 1 | ||||
| -rw-r--r-- | include/libc-symbols.h | 14 | ||||
| -rw-r--r-- | malloc/Makefile | 5 | ||||
| -rw-r--r-- | malloc/arena.c | 203 | ||||
| -rw-r--r-- | malloc/hooks.c | 15 | ||||
| -rw-r--r-- | malloc/malloc.c | 260 | ||||
| -rw-r--r-- | malloc/malloc.h | 4 | ||||
| -rw-r--r-- | sysdeps/x86_64/cacheinfo.c | 32 | ||||
| -rw-r--r-- | sysdeps/x86_64/multiarch/Makefile | 3 | ||||
| -rw-r--r-- | sysdeps/x86_64/multiarch/init-arch.c | 65 | ||||
| -rw-r--r-- | sysdeps/x86_64/multiarch/init-arch.h | 70 | ||||
| -rw-r--r-- | sysdeps/x86_64/multiarch/sched_cpucount.c | 42 |
20 files changed, 813 insertions, 75 deletions
@@ -1,3 +1,28 @@ +2009-03-13 Ulrich Drepper <drepper@redhat.com> + + * config.h.in (USE_MULTIARCH): Define. + * configure.in: Handle --enable-multi-arch. + * elf/dl-runtime.c (_dl_fixup): Handle STT_GNU_IFUNC. + (_dl_fixup_profile): Likewise. + * elf/do-lookup.c (dl_lookup_x): Likewise. + * sysdeps/x86_64/dl-machine.h: Handle STT_GNU_IFUNC. + * elf/elf.h (STT_GNU_IFUNC): Define. + * include/libc-symbols.h (libc_ifunc): Define. + * sysdeps/x86_64/cacheinfo.c: If USE_MULTIARCH is defined, use the + framework in init-arch.h to get CPUID values. + * sysdeps/x86_64/multiarch/Makefile: New file. + * sysdeps/x86_64/multiarch/init-arch.c: New file. + * sysdeps/x86_64/multiarch/init-arch.h: New file. + * sysdeps/x86_64/multiarch/sched_cpucount.c: New file. + + * config.make.in (experimental-malloc): Define. + * configure.in: Handle --enable-experimental-malloc. + * malloc/Makefile: Handle experimental-malloc flag. + * malloc/malloc.c: Implement PER_THREAD and ATOMIC_FASTBINS features. + * malloc/arena.c: Likewise. + * malloc/hooks.c: Likewise. + * malloc/malloc.h: Define M_ARENA_TEST and M_ARENA_MAX. + 2009-03-11 Ulrich Drepper <drepper@redhat.com> * sysdeps/x86_64/dl-machine.h (elf_machine_rela): Add branch @@ -1,4 +1,4 @@ -GNU C Library NEWS -- history of user-visible changes. 2009-3-8 +GNU C Library NEWS -- history of user-visible changes. 2009-3-12 Copyright (C) 1992-2008, 2009 Free Software Foundation, Inc. See the end for copying conditions. @@ -7,7 +7,7 @@ using `glibc' in the "product" field. Version 2.10 -* New Linux interface: accept4 +* New Linux interfaces: accept4, fallocate, fallocate64. * Correct declarations of string function when used in C++ code. This could lead to compile error for invalid C++ code. diff --git a/config.h.in b/config.h.in index b5abb10187..8dbc224a7d 100644 --- a/config.h.in +++ b/config.h.in @@ -189,6 +189,9 @@ /* Define if __stack_chk_guard canary should be randomized at program startup. */ #undef ENABLE_STACKGUARD_RANDOMIZE +/* Define if multi-arch DSOs should be generated. */ +#undef USE_MULTIARCH + /* */ diff --git a/config.make.in b/config.make.in index aa73466713..6da6362f24 100644 --- a/config.make.in +++ b/config.make.in @@ -70,6 +70,7 @@ versioning = @VERSIONING@ oldest-abi = @oldest_abi@ no-whole-archive = @no_whole_archive@ exceptions = @exceptions@ +multi-arch = @multi_arch@ mach-interface-list = @mach_interface_list@ @@ -78,6 +79,8 @@ have-ksh = @libc_cv_have_ksh@ sizeof-long-double = @sizeof_long_double@ +experimental-malloc = @experimental_malloc@ + # Configuration options. build-static = @static@ build-shared = @shared@ @@ -660,6 +660,8 @@ oldest_abi bindnow force_install all_warnings +multi_arch +experimental_malloc build build_cpu build_vendor @@ -1380,6 +1382,10 @@ Optional Features: --enable-kernel=VERSION compile for compatibility with kernel not older than VERSION --enable-all-warnings enable all useful warnings gcc can issue + --enable-multi-arch enable single DSO with optimizations for multiple + architectures + --enable-experimental-malloc + enable experimental malloc features Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -2173,6 +2179,29 @@ fi +# Check whether --enable-multi-arch was given. +if test "${enable_multi_arch+set}" = set; then + enableval=$enable_multi_arch; multi_arch=$enableval +else + multi_arch=no +fi + +if test x"$multi_arch" = xyes; then + cat >>confdefs.h <<\_ACEOF +#define USE_MULTIARCH 1 +_ACEOF + + multi_arch_d=/multiarch +fi + + +# Check whether --enable-experimental-malloc was given. +if test "${enable_experimental_malloc+set}" = set; then + enableval=$enable_experimental_malloc; experimental_malloc=$enableval +fi + + + # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 @@ -2627,7 +2656,7 @@ for b in $base ''; do test "$v" = / && continue for o in /$ostry ''; do test "$o" = / && continue - for m in $mach ''; do + for m in $multi_arch_d $mach ''; do for d in $add_ons_pfx ''; do for a in $add_ons_sfx ''; do if test -n "$m0$m0sub$b$v$o$m$msub"; then @@ -5684,6 +5713,37 @@ _ACEOF fi +# For the multi-arch option we need support in the assembler. +if test "$multi_arch" = yes; then + if test "x$libc_cv_asm_type_prefix" != xno; then +{ echo "$as_me:$LINENO: checking for assembler gnu_indirect_function symbol type support" >&5 +echo $ECHO_N "checking for assembler gnu_indirect_function symbol type support... $ECHO_C" >&6; } +if test "${libc_cv_asm_gnu_indirect_function+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.s <<EOF +.type foo,%gnu_indirect_function +EOF +if ${CC-cc} -c $ASFLAGS conftest.s 1>&5 2>&5; +then + libc_cv_asm_gnu_indirect_function=yes +else + libc_cv_asm_gnu_indirect_function=no +fi +rm -f conftest* +fi +{ echo "$as_me:$LINENO: result: $libc_cv_asm_gnu_indirect_function" >&5 +echo "${ECHO_T}$libc_cv_asm_gnu_indirect_function" >&6; } + else + libc_cv_asm_gnu_indirect_function=no + fi + if test x"$libc_cv_asm_gnu_indirect_function" != xyes; then + { { echo "$as_me:$LINENO: error: --enable-multi-arch support requires assembler and linker support" >&5 +echo "$as_me: error: --enable-multi-arch support requires assembler and linker support" >&2;} + { (exit 1); exit 1; }; } + fi +fi + { echo "$as_me:$LINENO: checking for .symver assembler directive" >&5 echo $ECHO_N "checking for .symver assembler directive... $ECHO_C" >&6; } if test "${libc_cv_asm_symver_directive+set}" = set; then @@ -9184,6 +9244,8 @@ oldest_abi!$oldest_abi$ac_delim bindnow!$bindnow$ac_delim force_install!$force_install$ac_delim all_warnings!$all_warnings$ac_delim +multi_arch!$multi_arch$ac_delim +experimental_malloc!$experimental_malloc$ac_delim build!$build$ac_delim build_cpu!$build_cpu$ac_delim build_vendor!$build_vendor$ac_delim @@ -9235,8 +9297,6 @@ libc_cv_have_bash2!$libc_cv_have_bash2$ac_delim KSH!$KSH$ac_delim libc_cv_have_ksh!$libc_cv_have_ksh$ac_delim AWK!$AWK$ac_delim -PERL!$PERL$ac_delim -INSTALL_INFO!$INSTALL_INFO$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -9278,6 +9338,8 @@ _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +PERL!$PERL$ac_delim +INSTALL_INFO!$INSTALL_INFO$ac_delim BISON!$BISON$ac_delim VERSIONING!$VERSIONING$ac_delim libc_cv_cc_with_libunwind!$libc_cv_cc_with_libunwind$ac_delim @@ -9334,7 +9396,7 @@ LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 54; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 56; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 diff --git a/configure.in b/configure.in index d7b22f3a3b..4015722d5a 100644 --- a/configure.in +++ b/configure.in @@ -254,6 +254,24 @@ AC_ARG_ENABLE([all-warnings], []) AC_SUBST(all_warnings) +AC_ARG_ENABLE([multi-arch], + AC_HELP_STRING([--enable-multi-arch], + [enable single DSO with optimizations for multiple architectures]), + [multi_arch=$enableval], + [multi_arch=no]) +if test x"$multi_arch" = xyes; then + AC_DEFINE(USE_MULTIARCH) + multi_arch_d=/multiarch +fi +AC_SUBST(multi_arch) + +AC_ARG_ENABLE([experimental-malloc], + AC_HELP_STRING([--enable-experimental-malloc], + [enable experimental malloc features]), + [experimental_malloc=$enableval], + []) +AC_SUBST(experimental_malloc) + AC_CANONICAL_HOST # The way shlib-versions is used to generate soversions.mk uses a @@ -608,7 +626,7 @@ for b in $base ''; do test "$v" = / && continue for o in /$ostry ''; do test "$o" = / && continue - for m in $mach ''; do + for m in $multi_arch_d $mach ''; do for d in $add_ons_pfx ''; do for a in $add_ons_sfx ''; do if test -n "$m0$m0sub$b$v$o$m$msub"; then @@ -1157,6 +1175,29 @@ if test "x$libc_cv_asm_type_prefix" != xno; then AC_DEFINE_UNQUOTED(ASM_TYPE_DIRECTIVE_PREFIX, ${libc_cv_asm_type_prefix}) fi +# For the multi-arch option we need support in the assembler. +if test "$multi_arch" = yes; then + if test "x$libc_cv_asm_type_prefix" != xno; then +AC_CACHE_CHECK([for assembler gnu_indirect_function symbol type support], + libc_cv_asm_gnu_indirect_function, [dnl +cat > conftest.s <<EOF +.type foo,%gnu_indirect_function +EOF +if ${CC-cc} -c $ASFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; +then + libc_cv_asm_gnu_indirect_function=yes +else + libc_cv_asm_gnu_indirect_function=no +fi +rm -f conftest*]) + else + libc_cv_asm_gnu_indirect_function=no + fi + if test x"$libc_cv_asm_gnu_indirect_function" != xyes; then + AC_MSG_ERROR([--enable-multi-arch support requires assembler and linker support]) + fi +fi + AC_CACHE_CHECK(for .symver assembler directive, libc_cv_asm_symver_directive, [cat > conftest.s <<EOF ${libc_cv_dot_text} diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index 968e293409..962f47de64 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -1,5 +1,5 @@ /* On-demand PLT fixup for shared objects. - Copyright (C) 1995-2006, 2007 Free Software Foundation, Inc. + Copyright (C) 1995-2006, 2007, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -130,6 +130,9 @@ _dl_fixup ( /* And now perhaps the relocation addend. */ value = elf_machine_plt_value (l, reloc, value); + if (__builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)) + value = ((DL_FIXUP_VALUE_TYPE (*) (void)) value) (); + /* Finally, fix up the plt itself. */ if (__builtin_expect (GLRO(dl_bind_not), 0)) return value; @@ -215,12 +218,21 @@ _dl_profile_fixup ( defsym != NULL ? LOOKUP_VALUE_ADDRESS (result) + defsym->st_value : 0); + + if (__builtin_expect (ELFW(ST_TYPE) (defsym->st_info) + == STT_GNU_IFUNC, 0)) + value = ((DL_FIXUP_VALUE_TYPE (*) (void)) value) (); } else { /* We already found the symbol. The module (and therefore its load address) is also known. */ value = DL_FIXUP_MAKE_VALUE (l, l->l_addr + refsym->st_value); + + if (__builtin_expect (ELFW(ST_TYPE) (refsym->st_info) + == STT_GNU_IFUNC, 0)) + value = ((DL_FIXUP_VALUE_TYPE (*) (void)) value) (); + result = l; } /* And now perhaps the relocation addend. */ diff --git a/elf/do-lookup.h b/elf/do-lookup.h index ebb9ed5b47..41e5fc137c 100644 --- a/elf/do-lookup.h +++ b/elf/do-lookup.h @@ -1,5 +1,5 @@ /* Look up a symbol in the loaded objects. - Copyright (C) 1995-2004, 2005, 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 1995-2007, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -88,10 +88,12 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash, if (__builtin_expect (ELFW(ST_TYPE) (sym->st_info) > STT_FUNC && ELFW(ST_TYPE) (sym->st_info) != STT_COMMON - && ELFW(ST_TYPE) (sym->st_info) != STT_TLS, 0)) - /* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC, and STT_COMMON - entries (and STT_TLS if TLS is supported) since these - are no code/data definitions. */ + && ELFW(ST_TYPE) (sym->st_info) != STT_TLS + && ELFW(ST_TYPE) (sym->st_info) != STT_GNU_IFUNC, + 0)) + /* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC, STT_COMMON, + STT_TLS, and STT_GNU_IFUNC since these are no code/data + definitions. */ return NULL; if (sym != ref && strcmp (strtab + sym->st_name, undef_name)) @@ -459,6 +459,7 @@ typedef struct #define STT_TLS 6 /* Symbol is thread-local data object*/ #define STT_NUM 7 /* Number of defined types. */ #define STT_LOOS 10 /* Start of OS-specific */ +#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */ #define STT_HIOS 12 /* End of OS-specific */ #define STT_LOPROC 13 /* Start of processor-specific */ #define STT_HIPROC 15 /* End of processor-specific */ diff --git a/include/libc-symbols.h b/include/libc-symbols.h index a2faeafb32..d53bcb9b77 100644 --- a/include/libc-symbols.h +++ b/include/libc-symbols.h @@ -1,7 +1,6 @@ /* Support macros for making weak and strong aliases for symbols, and for using symbol sets and linker warnings with GNU ld. - Copyright (C) 1995-1998,2000-2003,2004,2005,2006 - Free Software Foundation, Inc. + Copyright (C) 1995-1998, 2000-2006, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -835,4 +834,15 @@ for linking") # define compat_data_section .section ".data.compat", "aw"; #endif +/* Marker used for indirection function symbols. */ +#define libc_ifunc(name, expr) \ + extern void *name##_ifunc (void) __asm__ (#name); \ + void *name##_ifunc (void) \ + { \ + INIT_ARCH (); \ + __typeof (name) *res = expr; \ + return res; \ + } \ + __asm__ (".type " #name ", %gnu_indirect_function"); + #endif /* libc-symbols.h */ diff --git a/malloc/Makefile b/malloc/Makefile index 22b14eac77..1099335fff 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991-1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007 +# Copyright (C) 1991-1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009 # Free Software Foundation, Inc. # This file is part of the GNU C Library. @@ -124,6 +124,9 @@ endif tst-mcheck-ENV = MALLOC_CHECK_=3 +ifeq ($(experimental-malloc),yes) +CPPFLAGS-malloc.c += -DPER_THREAD -DATOMIC_FASTBINS +endif # Uncomment this for test releases. For public releases it is too expensive. #CPPFLAGS-malloc.o += -DMALLOC_DEBUG=1 diff --git a/malloc/arena.c b/malloc/arena.c index cc03dc4a5b..f280d38811 100644 --- a/malloc/arena.c +++ b/malloc/arena.c @@ -1,5 +1,5 @@ /* Malloc implementation for multiple threads without lock contention. - Copyright (C) 2001,2002,2003,2004,2005,2006,2007 + Copyright (C) 2001,2002,2003,2004,2005,2006,2007,2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Wolfram Gloger <wg@malloc.de>, 2001. @@ -78,6 +78,10 @@ extern int sanity_check_heap_info_alignment[(sizeof (heap_info) static tsd_key_t arena_key; static mutex_t list_lock; +#ifdef PER_THREAD +static size_t narenas; +static mstate free_list; +#endif #if THREAD_STATS static int stat_n_heaps; @@ -105,13 +109,30 @@ int __malloc_initialized = -1; in the new arena. */ #define arena_get(ptr, size) do { \ + arena_lookup(ptr); \ + arena_lock(ptr, size); \ +} while(0) + +#define arena_lookup(ptr) do { \ Void_t *vptr = NULL; \ ptr = (mstate)tsd_getspecific(arena_key, vptr); \ +} while(0) + +#ifdef PER_THREAD +#define arena_lock(ptr, size) do { \ + if(ptr) \ + (void)mutex_lock(&ptr->mutex); \ + else \ + ptr = arena_get2(ptr, (size)); \ +} while(0) +#else +#define arena_lock(ptr, size) do { \ if(ptr && !mutex_trylock(&ptr->mutex)) { \ THREAD_STAT(++(ptr->stat_lock_direct)); \ } else \ ptr = arena_get2(ptr, (size)); \ } while(0) +#endif /* find the heap and corresponding arena for a given ptr */ @@ -219,6 +240,11 @@ free_atfork(Void_t* mem, const Void_t *caller) } #endif +#ifdef ATOMIC_FASTBINS + ar_ptr = arena_for_chunk(p); + tsd_getspecific(arena_key, vptr); + _int_free(ar_ptr, p, vptr == ATFORK_ARENA_PTR); +#else ar_ptr = arena_for_chunk(p); tsd_getspecific(arena_key, vptr); if(vptr != ATFORK_ARENA_PTR) @@ -226,6 +252,7 @@ free_atfork(Void_t* mem, const Void_t *caller) _int_free(ar_ptr, p); if(vptr != ATFORK_ARENA_PTR) (void)mutex_unlock(&ar_ptr->mutex); +#endif } @@ -312,8 +339,17 @@ ptmalloc_unlock_all2 (void) __malloc_hook = save_malloc_hook; __free_hook = save_free_hook; #endif +#ifdef PER_THREAD + free_list = NULL; +#endif for(ar_ptr = &main_arena;;) { mutex_init(&ar_ptr->mutex); +#ifdef PER_THREAD + if (ar_ptr != save_arena) { + ar_ptr->next_free = free_list; + free_list = ar_ptr; + } +#endif ar_ptr = ar_ptr->next; if(ar_ptr == &main_arena) break; } @@ -377,6 +413,11 @@ ptmalloc_init_minimal (void) mp_.mmap_threshold = DEFAULT_MMAP_THRESHOLD; mp_.trim_threshold = DEFAULT_TRIM_THRESHOLD; mp_.pagesize = malloc_getpagesize; +#ifdef PER_THREAD +# define NARENAS_FROM_NCORES(n) ((n) * (sizeof(long) == 4 ? 2 : 8)) + mp_.arena_test = NARENAS_FROM_NCORES (1); + narenas = 1; +#endif } @@ -529,9 +570,25 @@ ptmalloc_init (void) } break; case 9: - if (! secure &&am |
