From c8692b7483e92dc20352367f8ac236d3f2912a43 Mon Sep 17 00:00:00 2001 From: Matthew Fernandez Date: Sun, 28 Mar 2021 19:51:51 -0700 Subject: [PATCH] use a bitfield instead of shifting and masking for reference count in refstr.c This performs the same operations, but asks the compiler to generate the required shifts and masks instead of relying on the error prone process of doing them manually. --- lib/cgraph/refstr.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/cgraph/refstr.c b/lib/cgraph/refstr.c index e632278ca..e7fbfc992 100644 --- a/lib/cgraph/refstr.c +++ b/lib/cgraph/refstr.c @@ -15,12 +15,10 @@ * reference counted strings. */ -enum { HTML_BIT = (uint64_t)(UINT64_C(1) << (sizeof(uint64_t) * 8 - 1)) }; -enum { CNT_BITS = ~(uint64_t)HTML_BIT }; - typedef struct refstr_t { Dtlink_t link; - uint64_t refcnt; + uint64_t refcnt: sizeof(uint64_t) * 8 - 1; + uint64_t is_html: 1; char *s; char store[1]; /* this is actually a dynamic array */ } refstr_t; @@ -105,6 +103,7 @@ char *agstrdup(Agraph_t * g, char *s) else r = malloc(sz); r->refcnt = 1; + r->is_html = 0; strcpy(r->store, s); r->s = r->store; dtinsert(strdict, r); @@ -130,7 +129,8 @@ char *agstrdup_html(Agraph_t * g, char *s) r = (refstr_t *) agalloc(g, sz); else r = malloc(sz); - r->refcnt = 1 | HTML_BIT; + r->refcnt = 1; + r->is_html = 1; strcpy(r->store, s); r->s = r->store; dtinsert(strdict, r); @@ -150,7 +150,7 @@ int agstrfree(Agraph_t * g, char *s) r = refsymbind(strdict, s); if (r && (r->s == s)) { r->refcnt--; - if ((r->refcnt & CNT_BITS) == 0) { + if (r->refcnt == 0) { agdtdelete(g, strdict, r); } } @@ -170,7 +170,7 @@ int aghtmlstr(char *s) if (s == NULL) return 0; key = (refstr_t *) (s - offsetof(refstr_t, store[0])); - return (key->refcnt & HTML_BIT) != 0; + return key->is_html; } void agmarkhtmlstr(char *s) @@ -180,7 +180,7 @@ void agmarkhtmlstr(char *s) if (s == NULL) return; key = (refstr_t *) (s - offsetof(refstr_t, store[0])); - key->refcnt |= HTML_BIT; + key->is_html = 1; } #ifdef DEBUG -- 2.40.0