Remove the rarely-used size field, move its computation to the users. Move the sha1 hash to the front of the structure to eliminate an offset computation per glyph lookup. Shrink the hash itself to 16 bytes. This does raise the collision probability from 1 in 2^160 to 1 in 2^128, but that's still quite rare enough. More importantly it gets us down to nicely aligned sizes for hash matching - one instruction if you have oword compares! - and makes sure that the Picture pointers after the GlyphRec are qword-aligned on LP64.
GlyphRec ILP32 LP64 before 44 56 after 36 40 Signed-off-by: Adam Jackson <[email protected]> --- exa/exa_priv.h | 2 +- hw/dmx/dmxextension.c | 9 ++++++--- render/glyph.c | 13 +++++++------ render/glyphstr.h | 13 ++++++------- render/render.c | 4 ++-- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/exa/exa_priv.h b/exa/exa_priv.h index e5d90d4..8b3a4c5 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -106,7 +106,7 @@ enum ExaMigrationHeuristic { }; typedef struct { - unsigned char sha1[20]; + unsigned char sha1[16]; } ExaCachedGlyphRec, *ExaCachedGlyphPtr; typedef struct { diff --git a/hw/dmx/dmxextension.c b/hw/dmx/dmxextension.c index 0092835..4497b15 100644 --- a/hw/dmx/dmxextension.c +++ b/hw/dmx/dmxextension.c @@ -1092,6 +1092,9 @@ static void dmxBERestoreRenderGlyph(pointer value, XID id, pointer n) int len_images = 0; int i; int ctr; + int glyph_size = sizeof(GlyphRec) + + screenInfo.numScreens * sizeof (PicturePtr) + + dixPrivatesSize(PRIVATE_GLYPH); if (glyphPriv->glyphSets[scrnNum]) { /* Only restore glyphs on the screen we are attaching */ @@ -1114,7 +1117,7 @@ static void dmxBERestoreRenderGlyph(pointer value, XID id, pointer n) GlyphPtr gl = gr->glyph; if (!gl || gl == DeletedGlyph) continue; - len_images += gl->size - sizeof(gl->info); + len_images += glyph_size - sizeof(gl->info); } /* Now allocate the memory we need */ @@ -1144,8 +1147,8 @@ static void dmxBERestoreRenderGlyph(pointer value, XID id, pointer n) glyphs[ctr].yOff = gl->info.yOff; /* Copy the images from the DIX's data into the buffer */ - memcpy(pos, gl+1, gl->size - sizeof(gl->info)); - pos += gl->size - sizeof(gl->info); + memcpy(pos, gl+1, glyph_size - sizeof(gl->info)); + pos += glyph_size - sizeof(gl->info); ctr++; } diff --git a/render/glyph.c b/render/glyph.c index 7193d47..4556046 100644 --- a/render/glyph.c +++ b/render/glyph.c @@ -128,7 +128,7 @@ GlyphRefPtr FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, - unsigned char sha1[20]) + unsigned char sha1[16]) { CARD32 elt, step, s; GlyphPtr glyph; @@ -159,7 +159,7 @@ FindGlyphRef (GlyphHashPtr hash, } else if (s == signature && (!match || - memcmp (glyph->sha1, sha1, 20) == 0)) + memcmp (glyph->sha1, sha1, 16) == 0)) { break; } @@ -180,10 +180,11 @@ int HashGlyph (xGlyphInfo *gi, CARD8 *bits, unsigned long size, - unsigned char sha1[20]) + unsigned char sha1[16]) { void *ctx = x_sha1_init(); int success; + unsigned char digest[20]; if (!ctx) return BadAlloc; @@ -194,14 +195,15 @@ HashGlyph (xGlyphInfo *gi, success = x_sha1_update(ctx, bits, size); if (!success) return BadAlloc; - success = x_sha1_final(ctx, sha1); + success = x_sha1_final(ctx, digest); if (!success) return BadAlloc; + memcpy(sha1, digest, 16); return Success; } GlyphPtr -FindGlyphByHash (unsigned char sha1[20], int format) +FindGlyphByHash (unsigned char sha1[16], int format) { GlyphRefPtr gr; CARD32 signature = *(CARD32 *) sha1; @@ -383,7 +385,6 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth) if (!glyph) return 0; glyph->refcnt = 0; - glyph->size = size + sizeof (xGlyphInfo); glyph->info = *gi; dixInitPrivates(glyph, (char *) glyph + head_size, PRIVATE_GLYPH); diff --git a/render/glyphstr.h b/render/glyphstr.h index 6c1a837..fb66b61 100644 --- a/render/glyphstr.h +++ b/render/glyphstr.h @@ -40,11 +40,10 @@ #define GlyphFormatNum 5 typedef struct _Glyph { - CARD32 refcnt; - PrivateRec *devPrivates; - unsigned char sha1[20]; - CARD32 size; /* info + bitmap */ + unsigned char sha1[16]; + PrivateRec *devPrivates; xGlyphInfo info; + CARD32 refcnt; /* per-screen pixmaps follow */ } GlyphRec, *GlyphPtr; @@ -104,16 +103,16 @@ extern _X_EXPORT GlyphRefPtr FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, - unsigned char sha1[20]); + unsigned char sha1[16]); extern _X_EXPORT GlyphPtr -FindGlyphByHash (unsigned char sha1[20], int format); +FindGlyphByHash (unsigned char sha1[16], int format); extern _X_EXPORT int HashGlyph (xGlyphInfo *gi, CARD8 *bits, unsigned long size, - unsigned char sha1[20]); + unsigned char sha1[16]); extern _X_EXPORT void FreeGlyph (GlyphPtr glyph, int format); diff --git a/render/render.c b/render/render.c index 00241f9..ea059eb 100644 --- a/render/render.c +++ b/render/render.c @@ -1019,7 +1019,7 @@ typedef struct _GlyphNew { Glyph id; GlyphPtr glyph; Bool found; - unsigned char sha1[20]; + unsigned char sha1[16]; } GlyphNewRec, *GlyphNewPtr; #define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) @@ -1197,7 +1197,7 @@ ProcRenderAddGlyphs (ClientPtr client) pSrcPix = NULL; } - memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20); + memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 16); } glyph_new->id = gids[i]; -- 1.7.3.1 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
