From: Keith Packard Date: Tue, 7 Dec 2004 01:36:26 +0000 (+0000) Subject: Reviewed by: Keith Packard X-Git-Tag: fc-2_2_98~8 X-Git-Url: https://git.wh0rd.org/?a=commitdiff_plain;h=1c52c0f0600b4c61fb3b16d2d7b5fa35c3e1b7f0;p=fontconfig.git Reviewed by: Keith Packard memoize strings and share a single copy for all uses. Note that this could be improved further by using statically allocated blocks and gluing multiple strings together, but I'm basically lazy. In my environment with 800 font files, I get a savings of about 90KB. --- diff --git a/ChangeLog b/ChangeLog index 5425d7a..bdb5a60 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2004-12-06 michael meeks + + Reviewed by: Keith Packard + + * src/fcinit.c: (FcMemReport): + * src/fcint.h: + * src/fclist.c: (FcObjectSetAdd): + * src/fcpat.c: (FcValueListEntCreate), (FcPatternBaseFreeze), + (FcPatternInsertElt), (FcPatternEqual), (FcObjectStaticName): + * src/fcxml.c: (FcParsePatelt): + memoize strings and share a single copy for all uses. Note that + this could be improved further by using statically allocated blocks + and gluing multiple strings together, but I'm basically lazy. + In my environment with 800 font files, I get a savings of about 90KB. + 2004-12-06 Keith Packard * COPYING: diff --git a/src/fcinit.c b/src/fcinit.c index d3e927f..c3f497b 100644 --- a/src/fcinit.c +++ b/src/fcinit.c @@ -196,6 +196,7 @@ static struct { { "vstack" }, { "attr" }, { "pstack" }, + { "staticstr" }, }; static int FcAllocCount, FcAllocMem; @@ -216,13 +217,13 @@ FcMemReport (void) printf ("\t Which Alloc Free Active\n"); printf ("\t count bytes count bytes count bytes\n"); for (i = 0; i < FC_MEM_NUM; i++) - printf ("\t%8.8s%8d%8d%8d%8d%8d%8d\n", + printf ("%16.16s%8d%8d%8d%8d%8d%8d\n", FcInUse[i].name, FcInUse[i].alloc_count, FcInUse[i].alloc_mem, FcInUse[i].free_count, FcInUse[i].free_mem, FcInUse[i].alloc_count - FcInUse[i].free_count, FcInUse[i].alloc_mem - FcInUse[i].free_mem); - printf ("\t%8.8s%8d%8d%8d%8d%8d%8d\n", + printf ("%16.16s%8d%8d%8d%8d%8d%8d\n", "Total", FcAllocCount, FcAllocMem, FcFreeCount, FcFreeMem, diff --git a/src/fcint.h b/src/fcint.h index e077f40..106a38b 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -100,8 +100,9 @@ typedef struct _FcSymbolic { #define FC_MEM_VSTACK 26 #define FC_MEM_ATTR 27 #define FC_MEM_PSTACK 28 +#define FC_MEM_STATICSTR 29 -#define FC_MEM_NUM 29 +#define FC_MEM_NUM 30 typedef enum _FcValueBinding { FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame diff --git a/src/fclist.c b/src/fclist.c index 18d7e71..6730f20 100644 --- a/src/fclist.c +++ b/src/fclist.c @@ -82,7 +82,7 @@ FcObjectSetAdd (FcObjectSet *os, const char *object) mid++; memmove (os->objects + mid + 1, os->objects + mid, (os->nobject - mid) * sizeof (const char *)); - os->objects[mid] = object; + os->objects[mid] = FcObjectStaticName (object); os->nobject++; return FcTrue; } diff --git a/src/fcpat.c b/src/fcpat.c index 8e4157a..2fea173 100644 --- a/src/fcpat.c +++ b/src/fcpat.c @@ -321,18 +321,12 @@ FcValueListEntCreate (FcValueList *h) FcValueListEnt *e; FcValueList *l, *new; int n; - int string_size = 0; - FcChar8 *strs; int size; n = 0; for (l = h; l; l = l->next) - { - if (l->value.type == FcTypeString) - string_size += strlen ((char *) l->value.u.s) + 1; n++; - } - size = sizeof (FcValueListAlign) + n * sizeof (FcValueList) + string_size; + size = sizeof (FcValueListAlign) + n * sizeof (FcValueList); FcValueListFrozenCount[h->value.type]++; FcValueListFrozenBytes[h->value.type] += size; ea = malloc (size); @@ -341,21 +335,17 @@ FcValueListEntCreate (FcValueList *h) FcMemAlloc (FC_MEM_VALLIST, size); e = &ea->ent; e->list = (FcValueList *) (ea + 1); - strs = (FcChar8 *) (e->list + n); new = e->list; for (l = h; l; l = l->next, new++) { if (l->value.type == FcTypeString) { new->value.type = FcTypeString; - new->value.u.s = strs; - strcpy ((char *) strs, (char *) l->value.u.s); - strs += strlen ((char *) strs) + 1; + new->value.u.s = FcObjectStaticName (l->value.u.s); } else { - new->value = l->value; - new->value = FcValueSave (new->value); + new->value = FcValueSave (l->value); } new->binding = l->binding; if (l->next) @@ -474,8 +464,6 @@ FcPatternBaseFreeze (FcPattern *b) FcPatternEnt **bucket = &FcPatternHashTable[hash % FC_VALUE_LIST_HASH_SIZE]; FcPatternEnt *ent; int i; - char *objects; - int size_objects; int size; FcPatternTotal++; @@ -485,7 +473,7 @@ FcPatternBaseFreeze (FcPattern *b) { for (i = 0; i < b->num; i++) { - if (strcmp (b->elts[i].object, ent->pattern.elts[i].object)) + if (b->elts[i].object != ent->pattern.elts[i].object) break; if (b->elts[i].values != ent->pattern.elts[i].values) break; @@ -496,13 +484,9 @@ FcPatternBaseFreeze (FcPattern *b) } /* - * Compute size of pattern + elts + object names + * Compute size of pattern + elts */ - size_objects = 0; - for (i = 0; i < b->num; i++) - size_objects += strlen (b->elts[i].object) + 1; - - size = sizeof (FcPatternEnt) + b->num*sizeof (FcPatternElt) + size_objects; + size = sizeof (FcPatternEnt) + b->num*sizeof (FcPatternElt); ent = malloc (size); if (!ent) return 0; @@ -515,13 +499,10 @@ FcPatternBaseFreeze (FcPattern *b) ent->pattern.size = b->num; ent->pattern.ref = FC_REF_CONSTANT; - objects = (char *) (ent->pattern.elts + b->num); for (i = 0; i < b->num; i++) { ent->pattern.elts[i].values = b->elts[i].values; - strcpy (objects, b->elts[i].object); - ent->pattern.elts[i].object = objects; - objects += strlen (objects) + 1; + ent->pattern.elts[i].object = b->elts[i].object; } ent->hash = hash; @@ -678,7 +659,7 @@ FcPatternInsertElt (FcPattern *p, const char *object) /* bump count */ p->num++; - p->elts[i].object = object; + p->elts[i].object = FcObjectStaticName (object); p->elts[i].values = 0; } @@ -697,7 +678,7 @@ FcPatternEqual (const FcPattern *pa, const FcPattern *pb) return FcFalse; for (i = 0; i < pa->num; i++) { - if (strcmp (pa->elts[i].object, pb->elts[i].object) != 0) + if (pa->elts[i].object != pb->elts[i].object) return FcFalse; if (!FcValueListEqual (pa->elts[i].values, pb->elts[i].values)) return FcFalse; @@ -1199,11 +1180,14 @@ FcObjectStaticName (const char *name) FcChar32 hash = FcStringHash ((const FcChar8 *) name); struct objectBucket **p; struct objectBucket *b; + int size; for (p = &buckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) if (b->hash == hash && !strcmp (name, (char *) (b + 1))) return (char *) (b + 1); - b = malloc (sizeof (struct objectBucket) + strlen (name) + 1); + size = sizeof (struct objectBucket) + strlen (name) + 1; + b = malloc (size); + FcMemAlloc (FC_MEM_STATICSTR, size); if (!b) return NULL; b->next = 0; diff --git a/src/fcxml.c b/src/fcxml.c index 19ec419..f5cbdf4 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -1786,12 +1786,6 @@ FcParsePatelt (FcConfigParse *parse) FcConfigMessage (parse, FcSevereWarning, "missing pattern element name"); return; } - name = FcObjectStaticName (name); - if (!name) - { - FcConfigMessage (parse, FcSevereError, "out of memory"); - return; - } for (;;) {