From: Mark Wooding Date: Sat, 3 Aug 2019 18:28:13 +0000 (+0100) Subject: Abandoned atoms work: hardly any performance benefit. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/sod/commitdiff_plain/refs/heads/mdw/atoms-abandoned Abandoned atoms work: hardly any performance benefit. --- diff --git a/lib/keyword.h b/lib/keyword.h index 525b31f..58dd29c 100644 --- a/lib/keyword.h +++ b/lib/keyword.h @@ -113,6 +113,44 @@ typedef void kw_unkhookfn(const char */*set*/, const char */*kw*/); */ extern kw_unkhookfn *kw_unkhook; +/*----- Atoms -------------------------------------------------------------*/ + +#ifdef __arm__ +# define KW__SECTTY "%" +#else +# define KW__SECTTY "@" +#endif + +#if defined(__GNUC__) && defined(__ELF__) && 0 +# define KWATOM_DECL(id, name) \ + __asm__( ".ifndef " #id "\n" \ + ".pushsection .rodata." #id ", " \ + "\"aGS\", " KW__SECTTY "progbits, " \ + ".rodata." #id ", comdat\n" \ + ".globl " #id "\n" \ + #id ": .asciz " #name "\n" \ + ".popsection\n" \ + ".endif"); \ + extern const char id[] +#endif + +#ifdef KWATOM_DECL +# define KW_ATOM(id, name) id +#else +# define KWATOM_DECL(id, name) extern int kw__fake_##id +# define KW_ATOM(id, name) (name + 0*sizeof(kw__fake_##id)) +#endif + +#define KADECL(atom) KWATOM_DECL(kw__atom__##atom, #atom) +#define KA(atom) KW_ATOM(kw__atom__##atom, #atom) +#define KA_TAB KW_ATOM(kw__atom_kw_tab, "kw.tab") +#define KA_UNKNOWN KW_ATOM(kw__atom_kw_unknown, "kw.unknown") +#define KA_VALIST KW_ATOM(kw__atom_kw_valist, "kw.valist") + +KWATOM_DECL(kw__atom_kw_tab, "kw.tab"); +KWATOM_DECL(kw__atom_kw_unknown, "kw.unknown"); +KWATOM_DECL(kw__atom_kw_valist, "kw.valist"); + /*----- Argument list macros ----------------------------------------------*/ /* These macros are intended to be conveniences rather than a proper @@ -172,7 +210,7 @@ extern kw_unkhookfn *kw_unkhook; * Use: Bundles a keyword @kw@ and value @val@ together. */ -#define K(kw, val) #kw, (val), +#define K(kw, val) KA(kw), (val), /* --- @K_VALIST@ --- * * @@ -182,7 +220,7 @@ extern kw_unkhookfn *kw_unkhook; * function. */ -#define K_VALIST(ap) "kw.valist", &(ap), +#define K_VALIST(ap) KA_VALIST, &(ap), /* --- @K_TAB@ --- * * @@ -193,7 +231,7 @@ extern kw_unkhookfn *kw_unkhook; * function. */ -#define K_TAB(v, n) "kw.tab", (v), (size_t)(n), +#define K_TAB(v, n) KA_TAB, (v), (size_t)(n), /*----- Keyword set definitions -------------------------------------------* * @@ -359,6 +397,75 @@ extern kw_unkhookfn *kw_unkhook; kw->name = *(type const *)v->val; \ } else +#define KWSET_PARSEFN_ATOMS(set) \ + void set##_kwparse(struct set##_kwargs *kw, \ + const char *kwfirst, va_list *ap, \ + const struct kwval *v, size_t n) \ + { \ + const char *k, *kk; \ + va_list *aap; \ + const struct kwtab *t; \ + const struct kwval *vv; \ + size_t nn; \ + \ + for (k = kwfirst; k; k = va_arg(*ap, const char *)) { \ + set##_KWSET(KWSET__ARGVA_ATOM) \ + /*else*/ if (k == KA_VALIST) { \ + aap = va_arg(*ap, va_list *); \ + kk = va_arg(*aap, const char *); \ + set##_kwparse(kw, kk, aap, 0, 0); \ + } else if (k == KA_TAB) { \ + vv = va_arg(*ap, const struct kwval *); \ + nn = va_arg(*ap, size_t); \ + set##_kwparse(kw, 0, 0, vv, nn); \ + } else set##_KWSET(KWSET__ARGVA) \ + /*else*/ if (!strcmp(k, KA_VALIST)) { \ + aap = va_arg(*ap, va_list *); \ + kk = va_arg(*aap, const char *); \ + set##_kwparse(kw, kk, aap, 0, 0); \ + } else if (!strcmp(k, KA_TAB)) { \ + vv = va_arg(*ap, const struct kwval *); \ + nn = va_arg(*ap, size_t); \ + set##_kwparse(kw, 0, 0, vv, nn); \ + } else kw_unknown(#set, k); \ + } \ + \ + while (n) { \ + set##_KWSET(KWSET__ARGTAB) \ + /*else*/ if (!strcmp(v->kw, KA_VALIST)) { \ + aap = *(va_list *const *)v->val; \ + kk = va_arg(*aap, const char *); \ + set##_kwparse(kw, kk, aap, 0, 0); \ + } else if (!strcmp(v->kw, KA_TAB)) { \ + t = (const struct kwtab *)v->val; \ + set##_kwparse(kw, 0, 0, t->v, t->n); \ + } else kw_unknown(#set, v->kw); \ + v++; n--; \ + } \ + } + +#define KWSET__ARGVA_ATOM(type, name, dflt) \ + if (k == KA(name)) { \ + kw->name##_suppliedp = 1; \ + kw->name = va_arg(*ap, type); \ + } else +#define KWSET__ARGTAB_ATOM(type, name, dflt) \ + if (v->kw == KA(name)) { \ + kw->name##_suppliedp = 1; \ + kw->name = *(type const *)v->val; \ + } else + +#define KWSET__ARGVA(type, name, dflt) \ + if (!strcmp(k, #name)) { \ + kw->name##_suppliedp = 1; \ + kw->name = va_arg(*ap, type); \ + } else +#define KWSET__ARGTAB(type, name, dflt) \ + if (!strcmp(v->kw, #name)) { \ + kw->name##_suppliedp = 1; \ + kw->name = *(type const *)v->val; \ + } else + /*----- Defining keyword-accepting functions ------------------------------*/ /* --- @KWDECL@ --- * diff --git a/test/Makefile.am b/test/Makefile.am index de5b634..71b3908 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -58,6 +58,9 @@ check-local:: kwtest kwtest.ref ./kwtest >kwtest.out diff -u $(srcdir)/kwtest.ref kwtest.out +check_PROGRAMS += kwbench +kwbench_SOURCES = kwbench-back.c kwbench.c kwbench.h + check_PROGRAMS += rat EXTRA_DIST += rat.sod rat.ref