From e66e3563dd0f9370b298c35a0aefda2d8ed70691 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 29 Mar 2003 00:58:07 +0000 Subject: New option for position-independent code. --- ChangeLog | 17 +++++++++++++++++ NEWS | 4 +++- doc/gperf.texi | 7 +++++++ src/options.cc | 14 ++++++++++++-- src/options.h | 5 ++++- src/output.cc | 13 ++++++++++--- tests/test-6.exp | 3 +++ 7 files changed, 56 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index e2fbf38..ae96aae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2002-12-10 Bruno Haible + + * src/options.h (SHAREDLIB): New enum value. + * src/options.cc (Options::short_usage): Mention option -P. + (Options::long_usage): Document option -P. + (long_options): Add option --pic. + (Options::parse_options): Handle option -P/--pic. + * src/output.cc (output_keyword_blank_entries): When SHAREDLIB is + specified, emit NULL pointers instead of "". + (Output::output_lookup_function_body): When SHAREDLIB is specified + and SWITCH and DUP and not specified, test the table entry against + NULL before the string comparison. + * tests/test-6.exp: Update. + * doc/gperf.texi (Output Details): Document option -P. + * NEWS: Update. + Suggested by Ulrich Drepper. + 2002-12-08 Bruno Haible * tests/permut2.gperf, tests/permut2.exp: New files. diff --git a/NEWS b/NEWS index ae74ffb..2926113 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -New in 2.96: +New in 2.97: * Added option --output that allows to specify the output file name. * Some options have been renamed: @@ -40,6 +40,8 @@ New in 2.96: the table's size will grow as needed. Earlier versions of gperf bailed out with an "Internal error, duplicate hash code value". * The options -f/--fast and -o/--occurrence-sort have no effect any more. +* Added option -P/--pic that optimizes the generated code for use in shared + libraries. * Bug fixes. New in 2.7.2: diff --git a/doc/gperf.texi b/doc/gperf.texi index dd4df04..b9ce792 100644 --- a/doc/gperf.texi +++ b/doc/gperf.texi @@ -931,6 +931,13 @@ Generate the static table of keywords as a static global variable, rather than hiding it inside of the lookup function (which is the default behavior). +@item -P +@itemx --pic +Optimize the generated table for inclusion in shared libraries. This +reduces the startup time of programs using a shared library containing +the generated code, at the expense of one more test-and-branch instruction +at run time. + @item -W @var{hash-table-array-name} @itemx --word-array-name=@var{hash-table-array-name} @cindex Array name diff --git a/src/options.cc b/src/options.cc index 88dacf2..29d0b7b 100644 --- a/src/options.cc +++ b/src/options.cc @@ -66,7 +66,7 @@ static const char *const DEFAULT_DELIMITERS = ","; void Options::short_usage (FILE * stream) const { - fprintf (stream, "Usage: %s [-cCdDef[num]FGhHiIjkKlLmnNorsStTvWZ7] [input-file]\n" + fprintf (stream, "Usage: %s [-cCdDef[num]FGhHiIjkKlLmnNoPrsStTvWZ7] [input-file]\n" "Try '%s --help' for more information.\n", program_name, program_name); } @@ -158,6 +158,10 @@ Options::long_usage (FILE * stream) const " -G, --global-table Generate the static table of keywords as a static\n" " global variable, rather than hiding it inside of the\n" " lookup function (which is the default behavior).\n"); + fprintf (stream, + " -P, --pic Optimize the generated table for inclusion in shared\n" + " libraries. This reduces the startup time of programs\n" + " using a shared library containing the generated code.\n"); fprintf (stream, " -W, --word-array-name=NAME\n" " Specify name of word list array. Default name is\n" @@ -631,6 +635,7 @@ static const struct option long_options[] = { "no-strlen", no_argument, NULL, 'n' }, { "occurrence-sort", no_argument, NULL, 'o' }, { "optimized-collision-resolution", no_argument, NULL, 'O' }, + { "pic", no_argument, NULL, 'P' }, { "random", no_argument, NULL, 'r' }, { "size-multiple", required_argument, NULL, 's' }, { "help", no_argument, NULL, 'h' }, @@ -650,7 +655,7 @@ Options::parse_options (int argc, char *argv[]) while ((option_char = getopt_long (_argument_count, _argument_vector, - "acCdDe:Ef:F:gGhH:i:Ij:k:K:lL:m:nN:oOprs:S:tTvW:Z:7", + "acCdDe:Ef:F:gGhH:i:Ij:k:K:lL:m:nN:oOpPrs:S:tTvW:Z:7", long_options, NULL)) != -1) { @@ -838,6 +843,11 @@ Options::parse_options (int argc, char *argv[]) break; /* Not needed any more. */ case 'p': /* Generated lookup function a pointer instead of int. */ break; /* This is now the default. */ + case 'P': /* Optimize for position-independent code. */ + { + _option_word |= SHAREDLIB; + break; + } case 'r': /* Utilize randomness to initialize the associated values table. */ { _option_word |= RANDOM; diff --git a/src/options.h b/src/options.h index 9d37201..2a9567b 100644 --- a/src/options.h +++ b/src/options.h @@ -95,7 +95,10 @@ enum Option_Type INCLUDE = 1 << 18, /* Assume 7-bit, not 8-bit, characters. */ - SEVENBIT = 1 << 19 + SEVENBIT = 1 << 19, + + /* Optimize for position-independent code. */ + SHAREDLIB = 1 << 20 }; /* Class manager for gperf program Options. */ diff --git a/src/output.cc b/src/output.cc index 20ca0bf..e898254 100644 --- a/src/output.cc +++ b/src/output.cc @@ -726,13 +726,14 @@ output_keyword_blank_entries (int count, const char *indent) int columns; if (option[TYPE]) { - columns = 58 / (6 + strlen (option.get_initializer_suffix())); + columns = 58 / (4 + (option[SHAREDLIB] ? 8 : 2) + + strlen (option.get_initializer_suffix())); if (columns == 0) columns = 1; } else { - columns = 9; + columns = (option[SHAREDLIB] ? 4 : 9); } int column = 0; for (int i = 0; i < count; i++) @@ -749,9 +750,13 @@ output_keyword_blank_entries (int count, const char *indent) printf (", "); } if (option[TYPE]) - printf ("{\"\"%s}", option.get_initializer_suffix()); + printf ("{"); + if (option[SHAREDLIB]) + printf ("(char*)0"); else printf ("\"\""); + if (option[TYPE]) + printf ("%s}", option.get_initializer_suffix()); column++; } } @@ -1362,6 +1367,8 @@ Output::output_lookup_function_body (const Output_Compare& comparison) const printf (";\n\n" "%*s if (", indent, ""); + if (option[SHAREDLIB]) + printf ("s && "); comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s")); printf (")\n" "%*s return ", diff --git a/tests/test-6.exp b/tests/test-6.exp index a6180e6..14cd1d7 100644 --- a/tests/test-6.exp +++ b/tests/test-6.exp @@ -57,6 +57,9 @@ Details in the output code: -G, --global-table Generate the static table of keywords as a static global variable, rather than hiding it inside of the lookup function (which is the default behavior). + -P, --pic Optimize the generated table for inclusion in shared + libraries. This reduces the startup time of programs + using a shared library containing the generated code. -W, --word-array-name=NAME Specify name of word list array. Default name is 'wordlist'. -- cgit v1.2.1