diff --git a/ChangeLog b/ChangeLog index 153fb9f..d18f210 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-04-27 Keith Packard + + * src/fcinit.c: (FcMemReport): + * src/fcint.h: + * src/fcpat.c: (FcPatternFini): + * src/fcxml.c: (FcParsePatelt): + Eliminate pattern freezing + 2006-04-27 Keith Packard reviewed by: Patrick Lam diff --git a/src/fcinit.c b/src/fcinit.c index 9ce7952..ac6dad7 100644 --- a/src/fcinit.c +++ b/src/fcinit.c @@ -208,9 +208,6 @@ static int FcMemNotice = 1*1024*1024; static int FcAllocNotify, FcFreeNotify; -void -FcValueListReport (void); - void FcMemReport (void) { @@ -233,7 +230,6 @@ FcMemReport (void) FcAllocMem - FcFreeMem); FcAllocNotify = 0; FcFreeNotify = 0; - FcValueListReport (); } void diff --git a/src/fcint.h b/src/fcint.h index ae348b8..6d8ae5d 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -862,9 +862,6 @@ FcPatternAddWithBinding (FcPattern *p, FcValueBinding binding, FcBool append); -FcPattern * -FcPatternFreeze (FcPattern *p); - void FcPatternFini (void); diff --git a/src/fcpat.c b/src/fcpat.c index c78e670..da1d490 100644 --- a/src/fcpat.c +++ b/src/fcpat.c @@ -316,374 +316,6 @@ FcPatternDestroy (FcPattern *p) free (p); } -#define FC_VALUE_LIST_HASH_SIZE 257 -#define FC_PATTERN_HASH_SIZE 67 - -typedef struct _FcValueListEnt FcValueListEnt; - -struct _FcValueListEnt { - FcValueListEnt *next; - FcValueListPtr list; - FcChar32 hash, pad; -}; - -typedef union _FcValueListAlign { - FcValueListEnt ent; - FcValueList list; -} FcValueListAlign; - -static int FcValueListFrozenCount[FcTypeLangSet + 1]; -static int FcValueListFrozenBytes[FcTypeLangSet + 1]; -static const char FcValueListFrozenName[][8] = { - "Void", - "Integer", - "Double", - "String", - "Bool", - "Matrix", - "CharSet", - "FTFace", - "LangSet" -}; - -void -FcValueListReport (void); - -void -FcValueListReport (void) -{ - FcType t; - - printf ("Fc Frozen Values:\n"); - printf ("\t%8s %9s %9s\n", "Type", "Count", "Bytes"); - for (t = FcTypeVoid; t <= FcTypeLangSet; t++) - printf ("\t%8s %9d %9d\n", FcValueListFrozenName[t], - FcValueListFrozenCount[t], FcValueListFrozenBytes[t]); -} - -static FcValueListEnt * -FcValueListEntCreate (FcValueListPtr h) -{ - FcValueListAlign *ea; - FcValueListEnt *e; - FcValueListPtr l; - FcValueList *new; - int n; - int size; - - n = 0; - for (l = h; FcValueListPtrU(l); l = FcValueListPtrU(l)->next) - n++; - size = sizeof (FcValueListAlign) + n * sizeof (FcValueList); - FcValueListFrozenCount[FcValueListPtrU(h)->value.type]++; - FcValueListFrozenBytes[FcValueListPtrU(h)->value.type] += size; - /* this leaks for some reason */ - ea = malloc (sizeof (FcValueListAlign)); - if (!ea) - return 0; - new = malloc (n * sizeof (FcValueList)); - if (!new) - { - free (ea); - return 0; - } - memset(new, 0, n * sizeof (FcValueList)); - FcMemAlloc (FC_MEM_VALLIST, size); - e = &ea->ent; - e->list = FcValueListPtrCreateDynamic(new); - for (l = h; FcValueListPtrU(l); - l = FcValueListPtrU(l)->next, new++) - { - if ((FcValueListPtrU(l)->value.type & ~FC_STORAGE_STATIC) == FcTypeString) - { - new->value.type = FcTypeString; - new->value.u.s = FcStrStaticName - (fc_value_string(&FcValueListPtrU(l)->value)); - } - else - { - new->value = FcValueSave (FcValueCanonicalize - (&FcValueListPtrU(l)->value)); - } - new->binding = FcValueListPtrU(l)->binding; - if (FcValueListPtrU(FcValueListPtrU(l)->next)) - { - new->next = FcValueListPtrCreateDynamic(new + 1); - } - else - { - new->next = FcValueListPtrCreateDynamic(0); - } - } - return e; -} - -static void -FcValueListEntDestroy (FcValueListEnt *e) -{ - FcValueListPtr l; - - FcValueListFrozenCount[FcValueListPtrU(e->list)->value.type]--; - - /* XXX: We should perform these two operations with "size" as - computed in FcValueListEntCreate, but we don't have access to - that value here. Without this, the FcValueListFrozenBytes - values will be wrong as will the FcMemFree counts. - - FcValueListFrozenBytes[e->list->value.type] -= size; - FcMemFree (FC_MEM_VALLIST, size); - */ - - for (l = e->list; FcValueListPtrU(l); - l = FcValueListPtrU(l)->next) - { - if (FcValueListPtrU(l)->value.type != FcTypeString) - FcValueDestroy (FcValueListPtrU(l)->value); - } - /* XXX: Are we being too chummy with the implementation here to - free(e) when it was actually the enclosing FcValueListAlign - that was allocated? */ - free (e); -} - -static int FcValueListTotal; -static int FcValueListUsed; - -static FcValueListEnt *FcValueListHashTable[FC_VALUE_LIST_HASH_SIZE]; - -static FcValueListPtr -FcValueListFreeze (FcValueListPtr l) -{ - FcChar32 hash = FcValueListHash (l); - FcValueListEnt **bucket = &FcValueListHashTable[hash % FC_VALUE_LIST_HASH_SIZE]; - FcValueListEnt *ent; - - FcValueListTotal++; - for (ent = *bucket; ent; ent = ent->next) - { - if (ent->hash == hash && FcValueListEqual (ent->list, l)) - return ent->list; - } - - ent = FcValueListEntCreate (l); - if (!ent) - return FcValueListPtrCreateDynamic(0); - - FcValueListUsed++; - ent->hash = hash; - ent->next = *bucket; - *bucket = ent; - return ent->list; -} - -static void -FcValueListThawAll (void) -{ - int i; - FcValueListEnt *ent, *next; - - for (i = 0; i < FC_VALUE_LIST_HASH_SIZE; i++) - { - for (ent = FcValueListHashTable[i]; ent; ent = next) - { - next = ent->next; - FcValueListEntDestroy (ent); - } - FcValueListHashTable[i] = 0; - } - - FcValueListTotal = 0; - FcValueListUsed = 0; -} - -static FcChar32 -FcPatternBaseHash (FcPattern *b) -{ - FcChar32 hash = b->num; - int i; - - for (i = 0; i < b->num; i++) - hash = ((hash << 1) | (hash >> 31)) ^ - (long) (FcValueListPtrU((FcPatternEltU(b->elts)+i)->values)); - return hash; -} - -typedef struct _FcPatternEnt FcPatternEnt; - -struct _FcPatternEnt { - FcPatternEnt *next; - FcChar32 hash; - FcPattern *pattern; -}; - -static int FcPatternTotal; -static int FcPatternUsed; - -static FcPatternEnt *FcPatternHashTable[FC_VALUE_LIST_HASH_SIZE]; - -static FcPattern * -FcPatternBaseFreeze (FcPattern *b) -{ - FcPattern *ep; - FcPatternElt *epp; - FcChar32 hash = FcPatternBaseHash (b); - FcPatternEnt **bucket = &FcPatternHashTable[hash % FC_VALUE_LIST_HASH_SIZE]; - FcPatternEnt *ent; - int i; - - FcPatternTotal++; - for (ent = *bucket; ent; ent = ent->next) - { - if (ent->hash == hash && b->num == ent->pattern->num) - { - for (i = 0; i < b->num; i++) - { - if (FcObjectPtrCompare((FcPatternEltU(b->elts)+i)->object, - (FcPatternEltU(ent->pattern->elts)+i)->object) != 0) - break; - if (FcValueListPtrU((FcPatternEltU(b->elts)+i)->values) != - FcValueListPtrU((FcPatternEltU(ent->pattern->elts)+i)->values)) - break; - } - if (i == b->num) - return ent->pattern; - } - } - - /* - * Compute size of pattern + elts - */ - ent = malloc (sizeof (FcPatternEnt)); - if (!ent) - return 0; - - FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPatternEnt)); - FcPatternUsed++; - - ep = FcPatternCreate(); - if (!ep) - goto bail; - ent->pattern = ep; - epp = malloc(b->num * sizeof (FcPatternElt)); - if (!epp) - { - FcPatternDestroy (ep); - goto bail; - } - ep->elts = FcPatternEltPtrCreateDynamic(epp); - - FcMemAlloc (FC_MEM_PATELT, sizeof (FcPatternElt)*(b->num)); - - ep->num = b->num; - ep->size = b->num; - ep->ref = FC_REF_CONSTANT; - - for (i = 0; i < b->num; i++) - { - (FcPatternEltU(ep->elts)+i)->values = - (FcPatternEltU(b->elts)+i)->values; - (FcPatternEltU(ep->elts)+i)->object = - (FcPatternEltU(b->elts)+i)->object; - } - - ent->hash = hash; - ent->next = *bucket; - *bucket = ent; - return ent->pattern; - bail: - free(ent); - FcMemFree (FC_MEM_PATTERN, sizeof (FcPatternEnt)); - FcPatternUsed--; - return 0; -} - -static void -FcPatternBaseThawAll (void) -{ - int i; - FcPatternEnt *ent, *next; - - for (i = 0; i < FC_VALUE_LIST_HASH_SIZE; i++) - { - for (ent = FcPatternHashTable[i]; ent; ent = next) - { - next = ent->next; - free (ent); - } - FcPatternHashTable[i] = 0; - } - - FcPatternTotal = 0; - FcPatternUsed = 0; -} - -FcPattern * -FcPatternFreeze (FcPattern *p) -{ - FcPattern *b, *n = 0, *freeme = 0; - FcPatternElt *e; - int i; - - if (p->ref == FC_REF_CONSTANT) - return p; - - b = FcPatternCreate(); - if (!b) - return 0; - - b->num = p->num; - b->size = b->num; - b->ref = 1; - - e = malloc(b->num * sizeof (FcPatternElt)); - if (!e) - { - FcPatternDestroy (b); - return 0; - } - b->elts = FcPatternEltPtrCreateDynamic(e); - FcMemAlloc (FC_MEM_PATELT, sizeof (FcPatternElt)*(b->num)); - - /* - * Freeze object lists - */ - for (i = 0; i < p->num; i++) - { - (FcPatternEltU(b->elts)+i)->object = - (FcPatternEltU(p->elts)+i)->object; - (FcPatternEltU(b->elts)+i)->values = - FcValueListFreeze((FcPatternEltU(p->elts)+i)->values); - if (!FcValueListPtrU((FcPatternEltU(p->elts)+i)->values)) - { - freeme = b; - goto bail; - } - } - - /* - * Freeze base - */ - n = FcPatternBaseFreeze (b); -#ifdef CHATTY - if (FcDebug() & FC_DBG_MEMORY) - { - printf ("ValueLists: total %9d used %9d\n", FcValueListTotal, FcValueListUsed); - printf ("Patterns: total %9d used %9d\n", FcPatternTotal, FcPatternUsed); - } -#endif - bail: - free(FcPatternEltU(b->elts)); - b->elts = FcPatternEltPtrCreateDynamic(0); - FcMemFree (FC_MEM_PATELT, sizeof (FcPatternElt)*(b->num)); - b->num = -1; - if (freeme) - FcPatternDestroy (freeme); -#ifdef DEBUG - assert (FcPatternEqual (n, p)); -#endif - return n; -} - static int FcPatternPosition (const FcPattern *p, const char *object) { @@ -1399,8 +1031,6 @@ FcStrStaticNameFini (void) void FcPatternFini (void) { - FcPatternBaseThawAll (); - FcValueListThawAll (); FcStrStaticNameFini (); FcObjectStaticNameFini (); } diff --git a/src/fcxml.c b/src/fcxml.c index f92bf56..2438193 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -1966,8 +1966,7 @@ FcParsePatelt (FcConfigParse *parse) } } - FcVStackPushPattern (parse, FcPatternFreeze(pattern)); - FcPatternDestroy (pattern); + FcVStackPushPattern (parse, pattern); } static void