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.
This commit is contained in:
parent
50544b13c1
commit
82f35f8bb4
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2005-11-04 Patrick Lam <plam@mit.edu>
|
||||||
|
* 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 <plam@mit.edu>
|
2005-11-04 Patrick Lam <plam@mit.edu>
|
||||||
* src/fcdir.c (FcDirScanConfig):
|
* src/fcdir.c (FcDirScanConfig):
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,10 @@
|
||||||
* functions are also needed in slightly modified form
|
* functions are also needed in slightly modified form
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const FcChar16 *langBankNumbers = 0;
|
||||||
|
const FcCharLeaf *langBankLeaves = 0;
|
||||||
|
const int *langBankLeafIdx = 0;
|
||||||
|
|
||||||
void
|
void
|
||||||
FcMemAlloc (int kind, int size)
|
FcMemAlloc (int kind, int size)
|
||||||
{
|
{
|
||||||
|
@ -232,6 +236,7 @@ main (int argc, char **argv)
|
||||||
int argi;
|
int argi;
|
||||||
FcCharLeaf **leaves;
|
FcCharLeaf **leaves;
|
||||||
int total_leaves = 0;
|
int total_leaves = 0;
|
||||||
|
int leafidx_count = 0, numbers_count = 0, numbers_ptr = 0;
|
||||||
int l, sl, tl;
|
int l, sl, tl;
|
||||||
int c;
|
int c;
|
||||||
char line[1024];
|
char line[1024];
|
||||||
|
@ -306,7 +311,7 @@ main (int argc, char **argv)
|
||||||
/*
|
/*
|
||||||
* Dump leaves
|
* Dump leaves
|
||||||
*/
|
*/
|
||||||
printf ("static const FcCharLeaf leaves[%d] = {\n", tl);
|
printf ("const FcCharLeaf langBankLeaves[%d] = {\n", tl);
|
||||||
for (l = 0; l < tl; l++)
|
for (l = 0; l < tl; l++)
|
||||||
{
|
{
|
||||||
printf (" { { /* %d */", l);
|
printf (" { { /* %d */", l);
|
||||||
|
@ -319,7 +324,6 @@ main (int argc, char **argv)
|
||||||
printf ("\n } },\n");
|
printf ("\n } },\n");
|
||||||
}
|
}
|
||||||
printf ("};\n\n");
|
printf ("};\n\n");
|
||||||
printf ("#define L(n) ((FcCharLeaf *) &leaves[n])\n\n");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find duplicate charsets
|
* Find duplicate charsets
|
||||||
|
@ -362,8 +366,27 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
if (duplicate[i] >= 0)
|
if (duplicate[i] >= 0)
|
||||||
continue;
|
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++)
|
for (n = 0; n < sets[i]->num; n++)
|
||||||
{
|
{
|
||||||
if (n % 8 == 0)
|
if (n % 8 == 0)
|
||||||
|
@ -373,17 +396,21 @@ main (int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
if (l == tl)
|
if (l == tl)
|
||||||
fatal (names[i], 0, "can't find leaf");
|
fatal (names[i], 0, "can't find leaf");
|
||||||
printf (" L(%3d),", l);
|
printf (" %3d,", l);
|
||||||
if (n % 8 == 7)
|
if (n % 8 == 7)
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
if (n % 8 != 0)
|
if (n % 8 != 0)
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf ("};\n\n");
|
}
|
||||||
|
printf ("};\n\n");
|
||||||
|
|
||||||
printf ("static const FcChar16 numbers_%s[%d] = {\n",
|
printf ("const FcChar16 langBankNumbers[%d] = {\n",
|
||||||
names[i], sets[i]->num);
|
numbers_count);
|
||||||
|
|
||||||
|
for (i = 0; sets[i]; i++)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
for (n = 0; n < sets[i]->num; n++)
|
for (n = 0; n < sets[i]->num; n++)
|
||||||
{
|
{
|
||||||
if (n % 8 == 0)
|
if (n % 8 == 0)
|
||||||
|
@ -394,27 +421,27 @@ main (int argc, char **argv)
|
||||||
}
|
}
|
||||||
if (n % 8 != 0)
|
if (n % 8 != 0)
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf ("};\n\n");
|
|
||||||
}
|
}
|
||||||
printf ("#undef L\n\n");
|
printf ("};\n\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dump sets
|
* Dump sets
|
||||||
*/
|
*/
|
||||||
|
|
||||||
printf ("static const FcLangCharSet fcLangCharSets[] = {\n");
|
printf ("const FcLangCharSet fcLangCharSets[] = {\n");
|
||||||
for (i = 0; sets[i]; i++)
|
for (i = 0; sets[i]; i++)
|
||||||
{
|
{
|
||||||
int j = duplicate[i];
|
int j = duplicate[i];
|
||||||
|
|
||||||
if (j < 0)
|
if (j < 0)
|
||||||
j = i;
|
j = i;
|
||||||
|
|
||||||
printf (" { (FcChar8 *) \"%s\",\n"
|
printf (" { (FcChar8 *) \"%s\",\n"
|
||||||
" { FC_REF_CONSTANT, %d, FC_BANK_DYNAMIC, "
|
" { FC_REF_CONSTANT, %d, FC_BANK_LANGS, "
|
||||||
"{ { (FcCharLeaf **) leaves_%s, "
|
"{ .stat = { %d, %d } } } },\n",
|
||||||
"(FcChar16 *) numbers_%s } } } },\n",
|
|
||||||
langs[i],
|
langs[i],
|
||||||
sets[j]->num, names[j], names[j]);
|
sets[j]->num, j, numbers_ptr);
|
||||||
|
numbers_ptr += sets[i]->num;
|
||||||
}
|
}
|
||||||
printf ("};\n\n");
|
printf ("};\n\n");
|
||||||
printf ("#define NUM_LANG_CHAR_SET %d\n", i);
|
printf ("#define NUM_LANG_CHAR_SET %d\n", i);
|
||||||
|
|
|
@ -38,6 +38,24 @@ static int charset_leaf_ptr, charset_leaf_count;
|
||||||
static int ** leaf_idx = 0;
|
static int ** leaf_idx = 0;
|
||||||
static int charset_leaf_idx_ptr, charset_leaf_idx_count;
|
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 *
|
FcCharSet *
|
||||||
FcCharSetCreate (void)
|
FcCharSetCreate (void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -99,6 +99,8 @@
|
||||||
|
|
||||||
#define FC_MEM_NUM 30
|
#define FC_MEM_NUM 30
|
||||||
|
|
||||||
|
#define FC_BANK_LANGS 0xfcfcfcfc
|
||||||
|
|
||||||
typedef enum _FcValueBinding {
|
typedef enum _FcValueBinding {
|
||||||
FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame
|
FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame
|
||||||
} FcValueBinding;
|
} FcValueBinding;
|
||||||
|
@ -524,6 +526,9 @@ FcFileTime
|
||||||
FcConfigModifiedTime (FcConfig *config);
|
FcConfigModifiedTime (FcConfig *config);
|
||||||
|
|
||||||
/* fccharset.c */
|
/* fccharset.c */
|
||||||
|
void
|
||||||
|
FcLangCharSetPopulate (void);
|
||||||
|
|
||||||
FcCharSet *
|
FcCharSet *
|
||||||
FcCharSetFreeze (FcCharSet *cs);
|
FcCharSetFreeze (FcCharSet *cs);
|
||||||
|
|
||||||
|
|
16
src/fclang.c
16
src/fclang.c
|
@ -44,6 +44,8 @@ struct _FcLangSet {
|
||||||
#define FcLangSetBitSet(ls, id) ((ls)->map[(id)>>5] |= ((FcChar32) 1 << ((id) & 0x1f)))
|
#define FcLangSetBitSet(ls, id) ((ls)->map[(id)>>5] |= ((FcChar32) 1 << ((id) & 0x1f)))
|
||||||
#define FcLangSetBitGet(ls, id) (((ls)->map[(id)>>5] >> ((id) & 0x1f)) & 1)
|
#define FcLangSetBitGet(ls, id) (((ls)->map[(id)>>5] >> ((id) & 0x1f)) & 1)
|
||||||
|
|
||||||
|
static FcBool langsets_populated = FcFalse;
|
||||||
|
|
||||||
FcLangSet *
|
FcLangSet *
|
||||||
FcFreeTypeLangSet (const FcCharSet *charset,
|
FcFreeTypeLangSet (const FcCharSet *charset,
|
||||||
const FcChar8 *exclusiveLang)
|
const FcChar8 *exclusiveLang)
|
||||||
|
@ -52,7 +54,12 @@ FcFreeTypeLangSet (const FcCharSet *charset,
|
||||||
FcChar32 missing;
|
FcChar32 missing;
|
||||||
const FcCharSet *exclusiveCharset = 0;
|
const FcCharSet *exclusiveCharset = 0;
|
||||||
FcLangSet *ls;
|
FcLangSet *ls;
|
||||||
|
|
||||||
|
if (!langsets_populated)
|
||||||
|
{
|
||||||
|
FcLangCharSetPopulate ();
|
||||||
|
langsets_populated = FcTrue;
|
||||||
|
}
|
||||||
|
|
||||||
if (exclusiveLang)
|
if (exclusiveLang)
|
||||||
exclusiveCharset = FcCharSetForLang (exclusiveLang);
|
exclusiveCharset = FcCharSetForLang (exclusiveLang);
|
||||||
|
@ -188,6 +195,13 @@ FcCharSetForLang (const FcChar8 *lang)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int country = -1;
|
int country = -1;
|
||||||
|
|
||||||
|
if (!langsets_populated)
|
||||||
|
{
|
||||||
|
FcLangCharSetPopulate ();
|
||||||
|
langsets_populated = FcTrue;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < NUM_LANG_CHAR_SET; i++)
|
for (i = 0; i < NUM_LANG_CHAR_SET; i++)
|
||||||
{
|
{
|
||||||
switch (FcLangCompare (lang, fcLangCharSets[i].lang)) {
|
switch (FcLangCompare (lang, fcLangCharSets[i].lang)) {
|
||||||
|
|
Loading…
Reference in New Issue