Matthias Clasen wrote: > Another interesting bug in this area is 2878, which complains that > all the FcCharSets in fcLangCharSets are stored in .data and cause > relocations, although they are not modified at runtime. It seems to me > that it should be possible to fix this by generating the charsets > in the form in which fc-cache stores them in the mmap cache, but I have > not been able to work out the details. I've committed the attached patch to the branch subsequent to tagging 2.3.92 (release announcement for that will follow once I get home and type in my gpg password). However, I'm also sending it to the list for comments: I'm not entirely sure that this patch is correct, as I don't know how to test it. Keith and Matthias, can you take a look? It does seem to work, for what that's worth. pat -------------- next part -------------- ? blacklisting.patch ? charset-diffs ? fc-list-patch ? fclang-static.diff ? plam-blacklist-patch.diff Index: fc-lang/fc-lang.c =================================================================== RCS file: /cvs/fontconfig/fontconfig/fc-lang/fc-lang.c,v retrieving revision 1.11.4.6 diff -u -r1.11.4.6 fc-lang.c --- fc-lang/fc-lang.c 23 Sep 2005 01:48:33 -0000 1.11.4.6 +++ fc-lang/fc-lang.c 4 Nov 2005 06:00:40 -0000 @@ -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 @@ 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 @@ /* * 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 @@ printf ("\n } },\n"); } printf ("};\n\n"); - printf ("#define L(n) ((FcCharLeaf *) &leaves[n])\n\n"); /* * Find duplicate charsets @@ -362,8 +366,27 @@ 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 @@ 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 @@ } 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); Index: src/fccharset.c =================================================================== RCS file: /cvs/fontconfig/fontconfig/src/fccharset.c,v retrieving revision 1.25.4.4 diff -u -r1.25.4.4 fccharset.c --- src/fccharset.c 22 Sep 2005 23:45:53 -0000 1.25.4.4 +++ src/fccharset.c 4 Nov 2005 06:00:40 -0000 @@ -38,6 +38,24 @@ 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) { Index: src/fcint.h =================================================================== RCS file: /cvs/fontconfig/fontconfig/src/fcint.h,v retrieving revision 1.47.4.18 diff -u -r1.47.4.18 fcint.h --- src/fcint.h 2 Nov 2005 06:29:14 -0000 1.47.4.18 +++ src/fcint.h 4 Nov 2005 06:00:40 -0000 @@ -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 @@ FcConfigModifiedTime (FcConfig *config); /* fccharset.c */ +void +FcLangCharSetPopulate (void); + FcCharSet * FcCharSetFreeze (FcCharSet *cs); Index: src/fclang.c =================================================================== RCS file: /cvs/fontconfig/fontconfig/src/fclang.c,v retrieving revision 1.14.4.4 diff -u -r1.14.4.4 fclang.c --- src/fclang.c 14 Oct 2005 21:02:31 -0000 1.14.4.4 +++ src/fclang.c 4 Nov 2005 06:00:40 -0000 @@ -44,6 +44,8 @@ #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 @@ FcChar32 missing; const FcCharSet *exclusiveCharset = 0; FcLangSet *ls; - + + if (!langsets_populated) + { + FcLangCharSetPopulate (); + langsets_populated = FcTrue; + } if (exclusiveLang) exclusiveCharset = FcCharSetForLang (exclusiveLang); @@ -188,6 +195,13 @@ { 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)) {