* 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:
Ulrich Drepper 1999-07-31 05:15:48 +00:00
parent 94ffedf6e6
commit 3d558f4ec7
5 changed files with 363 additions and 199 deletions

View File

@ -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.

View File

@ -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
/*
*/

478
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -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.

View File

@ -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;