Update.
* configure.in: Add test for local label subtraction. * config.h.in: Ad HAVE_SUBTRACT_LOCAL_LABELS. * stdio-common/vfprintf.c (vfprintf): Use subtraction of local labels to reduce number of runtime relocations and move jump tables in read-only seciton.
This commit is contained in:
parent
94ffedf6e6
commit
3d558f4ec7
@ -1,5 +1,11 @@
|
||||
1999-07-30 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* configure.in: Add test for local label subtraction.
|
||||
* config.h.in: Ad HAVE_SUBTRACT_LOCAL_LABELS.
|
||||
* stdio-common/vfprintf.c (vfprintf): Use subtraction of local
|
||||
labels to reduce number of runtime relocations and move jump
|
||||
tables in read-only seciton.
|
||||
|
||||
* malloc/malloc.c (ptmalloc_init): Correct last patch. The
|
||||
assignment cannot be moved.
|
||||
|
||||
|
@ -80,6 +80,10 @@
|
||||
/* Linux specific: minimum supported kernel version. */
|
||||
#undef __LINUX_KERNEL_VERSION
|
||||
|
||||
/* An extension in gcc 2.96 and up allows to substract the values of two
|
||||
local labels. */
|
||||
#undef HAVE_SUBTRACT_LOCAL_LABELS
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
|
30
configure.in
30
configure.in
@ -1050,6 +1050,36 @@ if test "$libc_cv_gcc_builtin_expect" = yes; then
|
||||
AC_DEFINE(HAVE_BUILTIN_EXPECT)
|
||||
fi
|
||||
|
||||
dnl Check whether the compiler supports subtraction of local labels.
|
||||
AC_CACHE_CHECK(for local label subtraction, libc_cv_gcc_subtract_local_labels,
|
||||
[cat > conftest.c <<EOF
|
||||
changequote(,)dnl
|
||||
#line __oline__ "configure"
|
||||
int foo (int a)
|
||||
{
|
||||
static const int ar[] = { &&l1 - &&l1, &&l2 - &&l1 };
|
||||
void *p = &&l1 + ar[a];
|
||||
goto *p;
|
||||
l1:
|
||||
return 1;
|
||||
l2:
|
||||
return 2;
|
||||
}
|
||||
changequote([,])dnl
|
||||
EOF
|
||||
dnl No \ in command here because it ends up inside ''.
|
||||
if AC_TRY_COMMAND([${CC-cc} $CFLAGS -nostdlib -nostartfiles
|
||||
-o conftest conftest.c -lgcc >&AC_FD_CC]); then
|
||||
libc_cv_gcc_subtract_local_labels=yes
|
||||
else
|
||||
libc_cv_gcc_subtract_local_labels=no
|
||||
fi
|
||||
rm -f conftest*])
|
||||
if test "$libc_cv_gcc_subtract_local_labels" = yes; then
|
||||
AC_DEFINE(HAVE_SUBTRACT_LOCAL_LABELS)
|
||||
fi
|
||||
|
||||
|
||||
### End of automated tests.
|
||||
### Now run sysdeps configure fragments.
|
||||
|
||||
|
@ -271,7 +271,24 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
|
||||
|
||||
#define NOT_IN_JUMP_RANGE(Ch) ((Ch) < L_(' ') || (Ch) > L_('z'))
|
||||
#define CHAR_CLASS(Ch) (jump_table[(INT_T) (Ch) - L_(' ')])
|
||||
#define JUMP(ChExpr, table) \
|
||||
#if defined HAVE_SUBTRACT_LOCAL_LABELS && defined PIC
|
||||
/* 'int' is enough and it saves some space on 64 bit systems. */
|
||||
# define JUMP_TABLE_TYPE const int
|
||||
# define JUMP(ChExpr, table) \
|
||||
do \
|
||||
{ \
|
||||
int offset; \
|
||||
void *ptr; \
|
||||
spec = (ChExpr); \
|
||||
offset = NOT_IN_JUMP_RANGE (spec) ? REF (form_unknown) \
|
||||
: table[CHAR_CLASS (spec)]; \
|
||||
ptr = &&do_form_unknown + offset; \
|
||||
goto *ptr; \
|
||||
} \
|
||||
while (0)
|
||||
#else
|
||||
# define JUMP_TABLE_TYPE const void *const
|
||||
# define JUMP(ChExpr, table) \
|
||||
do \
|
||||
{ \
|
||||
const void *ptr; \
|
||||
@ -281,10 +298,11 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
|
||||
goto *ptr; \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
#define STEP0_3_TABLE \
|
||||
/* Step 0: at the beginning. */ \
|
||||
static const void *step0_jumps[29] = \
|
||||
static JUMP_TABLE_TYPE step0_jumps[29] = \
|
||||
{ \
|
||||
REF (form_unknown), \
|
||||
REF (flag_space), /* for ' ' */ \
|
||||
@ -317,7 +335,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
|
||||
REF (mod_intmax_t), /* for 'j' */ \
|
||||
}; \
|
||||
/* Step 1: after processing width. */ \
|
||||
static const void *step1_jumps[29] = \
|
||||
static JUMP_TABLE_TYPE step1_jumps[29] = \
|
||||
{ \
|
||||
REF (form_unknown), \
|
||||
REF (form_unknown), /* for ' ' */ \
|
||||
@ -350,7 +368,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
|
||||
REF (mod_intmax_t) /* for 'j' */ \
|
||||
}; \
|
||||
/* Step 2: after processing precision. */ \
|
||||
static const void *step2_jumps[29] = \
|
||||
static JUMP_TABLE_TYPE step2_jumps[29] = \
|
||||
{ \
|
||||
REF (form_unknown), \
|
||||
REF (form_unknown), /* for ' ' */ \
|
||||
@ -383,7 +401,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
|
||||
REF (mod_intmax_t) /* for 'j' */ \
|
||||
}; \
|
||||
/* Step 3a: after processing first 'h' modifier. */ \
|
||||
static const void *step3a_jumps[29] = \
|
||||
static JUMP_TABLE_TYPE step3a_jumps[29] = \
|
||||
{ \
|
||||
REF (form_unknown), \
|
||||
REF (form_unknown), /* for ' ' */ \
|
||||
@ -416,7 +434,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
|
||||
REF (form_unknown) /* for 'j' */ \
|
||||
}; \
|
||||
/* Step 3b: after processing first 'l' modifier. */ \
|
||||
static const void *step3b_jumps[29] = \
|
||||
static JUMP_TABLE_TYPE step3b_jumps[29] = \
|
||||
{ \
|
||||
REF (form_unknown), \
|
||||
REF (form_unknown), /* for ' ' */ \
|
||||
@ -451,7 +469,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
|
||||
|
||||
#define STEP4_TABLE \
|
||||
/* Step 4: processing format specifier. */ \
|
||||
static const void *step4_jumps[29] = \
|
||||
static JUMP_TABLE_TYPE step4_jumps[29] = \
|
||||
{ \
|
||||
REF (form_unknown), \
|
||||
REF (form_unknown), /* for ' ' */ \
|
||||
@ -1179,7 +1197,11 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
|
||||
/* Process whole format string. */
|
||||
do
|
||||
{
|
||||
#define REF(Name) &&do_##Name
|
||||
#if defined HAVE_SUBTRACT_LOCAL_LABELS && defined PIC
|
||||
# define REF(Name) &&do_##Name - &&do_form_unknown
|
||||
#else
|
||||
# define REF(Name) &&do_##Name
|
||||
#endif
|
||||
#define LABEL(Name) do_##Name
|
||||
STEP0_3_TABLE;
|
||||
STEP4_TABLE;
|
||||
@ -1560,7 +1582,11 @@ do_positional:
|
||||
for (; (size_t) nspecs_done < nspecs; ++nspecs_done)
|
||||
{
|
||||
#undef REF
|
||||
#define REF(Name) &&do2_##Name
|
||||
#if defined HAVE_SUBTRACT_LOCAL_LABELS && defined PIC
|
||||
# define REF(Name) &&do2_##Name - &&do_form_unknown
|
||||
#else
|
||||
# define REF(Name) &&do2_##Name
|
||||
#endif
|
||||
#undef LABEL
|
||||
#define LABEL(Name) do2_##Name
|
||||
STEP4_TABLE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user