From 82f35f8bb4fe58ebc839531f4a63544dc07f0f5d Mon Sep 17 00:00:00 2001 From: Patrick Lam Date: Fri, 4 Nov 2005 19:31:26 +0000 Subject: [PATCH] Fix bug 2878 (excessive relocations at startup for charsets, reported by Ross Burton): fc-lang/fc-lang now creates the static form of the langset, not the dynamic form, so that the charsets should now be in .rodata. --- ChangeLog | 11 +++++++++ fc-lang/fc-lang.c | 59 ++++++++++++++++++++++++++++++++++------------- src/fccharset.c | 18 +++++++++++++++ src/fcint.h | 5 ++++ src/fclang.c | 16 ++++++++++++- 5 files changed, 92 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2d26433..e1e33ef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2005-11-04 Patrick Lam + * fc-lang/fc-lang.c: + * src/fccharset.c: + * src/fcint.h: + * src/fclang.c: + + Fix bug 2878 (excessive relocations at startup for charsets, + reported by Ross Burton): fc-lang/fc-lang now creates the + static form of the langset, not the dynamic form, so that + the charsets should now be in .rodata. + 2005-11-04 Patrick Lam * src/fcdir.c (FcDirScanConfig): diff --git a/fc-lang/fc-lang.c b/fc-lang/fc-lang.c index 2d7aa4e..8d71cf8 100644 --- a/fc-lang/fc-lang.c +++ b/fc-lang/fc-lang.c @@ -37,6 +37,10 @@ * functions are also needed in slightly modified form */ +const FcChar16 *langBankNumbers = 0; +const FcCharLeaf *langBankLeaves = 0; +const int *langBankLeafIdx = 0; + void FcMemAlloc (int kind, int size) { @@ -232,6 +236,7 @@ main (int argc, char **argv) int argi; FcCharLeaf **leaves; int total_leaves = 0; + int leafidx_count = 0, numbers_count = 0, numbers_ptr = 0; int l, sl, tl; int c; char line[1024]; @@ -306,7 +311,7 @@ main (int argc, char **argv) /* * Dump leaves */ - printf ("static const FcCharLeaf leaves[%d] = {\n", tl); + printf ("const FcCharLeaf langBankLeaves[%d] = {\n", tl); for (l = 0; l < tl; l++) { printf (" { { /* %d */", l); @@ -319,7 +324,6 @@ main (int argc, char **argv) printf ("\n } },\n"); } printf ("};\n\n"); - printf ("#define L(n) ((FcCharLeaf *) &leaves[n])\n\n"); /* * Find duplicate charsets @@ -362,8 +366,27 @@ main (int argc, char **argv) if (duplicate[i] >= 0) continue; - printf ("static const FcCharLeaf *leaves_%s[%d] = {\n", - names[i], sets[i]->num); + + for (n = 0; n < sets[i]->num; n++) + { + for (l = 0; l < tl; l++) + if (leaves[l] == FcCharSetGetLeaf(sets[i], n)) + break; + if (l == tl) + fatal (names[i], 0, "can't find leaf"); + leafidx_count++; + numbers_count += sets[i]->num; + } + } + + printf ("const int langBankLeafIdx[%d] = {\n", + leafidx_count); + for (i = 0; sets[i]; i++) + { + int n; + + if (duplicate[i] >= 0) + continue; for (n = 0; n < sets[i]->num; n++) { if (n % 8 == 0) @@ -373,17 +396,21 @@ main (int argc, char **argv) break; if (l == tl) fatal (names[i], 0, "can't find leaf"); - printf (" L(%3d),", l); + printf (" %3d,", l); if (n % 8 == 7) printf ("\n"); } if (n % 8 != 0) printf ("\n"); - printf ("};\n\n"); - + } + printf ("};\n\n"); - printf ("static const FcChar16 numbers_%s[%d] = {\n", - names[i], sets[i]->num); + printf ("const FcChar16 langBankNumbers[%d] = {\n", + numbers_count); + + for (i = 0; sets[i]; i++) + { + int n; for (n = 0; n < sets[i]->num; n++) { if (n % 8 == 0) @@ -394,27 +421,27 @@ main (int argc, char **argv) } if (n % 8 != 0) printf ("\n"); - printf ("};\n\n"); } - printf ("#undef L\n\n"); + printf ("};\n\n"); /* * Dump sets */ - printf ("static const FcLangCharSet fcLangCharSets[] = {\n"); + printf ("const FcLangCharSet fcLangCharSets[] = {\n"); for (i = 0; sets[i]; i++) { int j = duplicate[i]; if (j < 0) j = i; + printf (" { (FcChar8 *) \"%s\",\n" - " { FC_REF_CONSTANT, %d, FC_BANK_DYNAMIC, " - "{ { (FcCharLeaf **) leaves_%s, " - "(FcChar16 *) numbers_%s } } } },\n", + " { FC_REF_CONSTANT, %d, FC_BANK_LANGS, " + "{ .stat = { %d, %d } } } },\n", langs[i], - sets[j]->num, names[j], names[j]); + sets[j]->num, j, numbers_ptr); + numbers_ptr += sets[i]->num; } printf ("};\n\n"); printf ("#define NUM_LANG_CHAR_SET %d\n", i); diff --git a/src/fccharset.c b/src/fccharset.c index 6b3aa5e..9fa0e6b 100644 --- a/src/fccharset.c +++ b/src/fccharset.c @@ -38,6 +38,24 @@ static int charset_leaf_ptr, charset_leaf_count; static int ** leaf_idx = 0; static int charset_leaf_idx_ptr, charset_leaf_idx_count; +extern const FcChar16 *langBankNumbers; +extern const FcCharLeaf *langBankLeaves; +extern const int *langBankLeafIdx; + +static FcBool +FcCharSetEnsureBank (int bi); + +void +FcLangCharSetPopulate (void) +{ + int bi = FcCacheBankToIndex (FC_BANK_LANGS); + FcCharSetEnsureBank (bi); + charsets[bi] = 0; + numbers[bi] = (FcChar16 *)&langBankNumbers; + leaves[bi] = (FcCharLeaf *)&langBankLeaves; + leaf_idx[bi] = (int *)&langBankLeafIdx; +} + FcCharSet * FcCharSetCreate (void) { diff --git a/src/fcint.h b/src/fcint.h index be43e38..00ded26 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -99,6 +99,8 @@ #define FC_MEM_NUM 30 +#define FC_BANK_LANGS 0xfcfcfcfc + typedef enum _FcValueBinding { FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame } FcValueBinding; @@ -524,6 +526,9 @@ FcFileTime FcConfigModifiedTime (FcConfig *config); /* fccharset.c */ +void +FcLangCharSetPopulate (void); + FcCharSet * FcCharSetFreeze (FcCharSet *cs); diff --git a/src/fclang.c b/src/fclang.c index a10641e..b1c7c3f 100644 --- a/src/fclang.c +++ b/src/fclang.c @@ -44,6 +44,8 @@ struct _FcLangSet { #define FcLangSetBitSet(ls, id) ((ls)->map[(id)>>5] |= ((FcChar32) 1 << ((id) & 0x1f))) #define FcLangSetBitGet(ls, id) (((ls)->map[(id)>>5] >> ((id) & 0x1f)) & 1) +static FcBool langsets_populated = FcFalse; + FcLangSet * FcFreeTypeLangSet (const FcCharSet *charset, const FcChar8 *exclusiveLang) @@ -52,7 +54,12 @@ FcFreeTypeLangSet (const FcCharSet *charset, FcChar32 missing; const FcCharSet *exclusiveCharset = 0; FcLangSet *ls; - + + if (!langsets_populated) + { + FcLangCharSetPopulate (); + langsets_populated = FcTrue; + } if (exclusiveLang) exclusiveCharset = FcCharSetForLang (exclusiveLang); @@ -188,6 +195,13 @@ FcCharSetForLang (const FcChar8 *lang) { int i; int country = -1; + + if (!langsets_populated) + { + FcLangCharSetPopulate (); + langsets_populated = FcTrue; + } + for (i = 0; i < NUM_LANG_CHAR_SET; i++) { switch (FcLangCompare (lang, fcLangCharSets[i].lang)) { -- 2.39.2