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)) {