summaryrefslogtreecommitdiff
path: root/upb/handlers.c
diff options
context:
space:
mode:
authorJoshua Haberman <jhaberman@gmail.com>2012-03-24 11:24:16 -0700
committerJoshua Haberman <jhaberman@gmail.com>2012-03-24 11:24:16 -0700
commit86bad61b76a260ffc442acffbe58feee67df45e5 (patch)
treee375e62ff6d7fea9fb810830e66118e67b4ec2c8 /upb/handlers.c
parentdb59a5198f890ecdcac1227b0bb998160acac5c6 (diff)
Sync from internal Google development.
Many improvements, too many to mention. One significant perf regression warrants investigation: omitfp.parsetoproto2_googlemessage1.upb_jit: 343 -> 252 (-26.53) plain.parsetoproto2_googlemessage1.upb_jit: 334 -> 251 (-24.85) 25% regression for this benchmark is bad, but since I don't think there's any fundamental design issue that caused it I'm going to go ahead with the commit anyway. Can investigate and fix later. Other benchmarks were neutral or showed slight improvement.
Diffstat (limited to 'upb/handlers.c')
-rw-r--r--upb/handlers.c64
1 files changed, 33 insertions, 31 deletions
diff --git a/upb/handlers.c b/upb/handlers.c
index 1ccaf8d..ea5a054 100644
--- a/upb/handlers.c
+++ b/upb/handlers.c
@@ -13,7 +13,7 @@
static upb_mhandlers *upb_mhandlers_new() {
upb_mhandlers *m = malloc(sizeof(*m));
- upb_inttable_init(&m->fieldtab, 8, sizeof(upb_itofhandlers_ent));
+ upb_inttable_init(&m->fieldtab);
m->startmsg = NULL;
m->endmsg = NULL;
m->is_group = false;
@@ -26,20 +26,19 @@ static upb_mhandlers *upb_mhandlers_new() {
static upb_fhandlers *_upb_mhandlers_newfhandlers(upb_mhandlers *m, uint32_t n,
upb_fieldtype_t type,
bool repeated) {
- upb_itofhandlers_ent *e = upb_inttable_lookup(&m->fieldtab, n);
+ const upb_value *v = upb_inttable_lookup(&m->fieldtab, n);
// TODO: design/refine the API for changing the set of fields or modifying
// existing handlers.
- if (e) return NULL;
- upb_fhandlers new_f = {type, repeated, UPB_ATOMIC_INIT(0),
+ if (v) return NULL;
+ upb_fhandlers new_f = {type, repeated, 0,
n, -1, m, NULL, UPB_NO_VALUE, NULL, NULL, NULL, NULL, NULL,
#ifdef UPB_USE_JIT_X64
0, 0, 0,
#endif
- NULL};
+ };
upb_fhandlers *ptr = malloc(sizeof(*ptr));
memcpy(ptr, &new_f, sizeof(upb_fhandlers));
- upb_itofhandlers_ent ent = {false, ptr};
- upb_inttable_insert(&m->fieldtab, n, &ent);
+ upb_inttable_insert(&m->fieldtab, n, upb_value_ptr(ptr));
return ptr;
}
@@ -64,12 +63,17 @@ upb_fhandlers *upb_mhandlers_newfhandlers_subm(upb_mhandlers *m, uint32_t n,
return f;
}
+upb_fhandlers *upb_mhandlers_lookup(const upb_mhandlers *m, uint32_t n) {
+ const upb_value *v = upb_inttable_lookup(&m->fieldtab, n);
+ return v ? upb_value_getptr(*v) : NULL;
+}
+
/* upb_handlers ***************************************************************/
upb_handlers *upb_handlers_new() {
upb_handlers *h = malloc(sizeof(*h));
- upb_atomic_init(&h->refcount, 1);
+ h->refcount = 1;
h->msgs_len = 0;
h->msgs_size = 4;
h->msgs = malloc(h->msgs_size * sizeof(*h->msgs));
@@ -77,19 +81,18 @@ upb_handlers *upb_handlers_new() {
return h;
}
-void upb_handlers_ref(upb_handlers *h) { upb_atomic_ref(&h->refcount); }
+void upb_handlers_ref(upb_handlers *h) { h->refcount++; }
void upb_handlers_unref(upb_handlers *h) {
- if (upb_atomic_unref(&h->refcount)) {
+ if (--h->refcount == 0) {
for (int i = 0; i < h->msgs_len; i++) {
upb_mhandlers *mh = h->msgs[i];
- for(upb_inttable_iter j = upb_inttable_begin(&mh->fieldtab);
- !upb_inttable_done(j);
- j = upb_inttable_next(&mh->fieldtab, j)) {
- upb_itofhandlers_ent *e = upb_inttable_iter_value(j);
- free(e->f);
+ upb_inttable_iter j;
+ upb_inttable_begin(&j, &mh->fieldtab);
+ for(; !upb_inttable_done(&j); upb_inttable_next(&j)) {
+ free(upb_value_getptr(upb_inttable_iter_value(&j)));
}
- upb_inttable_free(&mh->fieldtab);
+ upb_inttable_uninit(&mh->fieldtab);
#ifdef UPB_USE_JIT_X64
free(mh->tablearray);
#endif
@@ -110,31 +113,28 @@ upb_mhandlers *upb_handlers_newmhandlers(upb_handlers *h) {
return mh;
}
-typedef struct {
- upb_mhandlers *mh;
-} upb_mtab_ent;
-
static upb_mhandlers *upb_regmsg_dfs(upb_handlers *h, const upb_msgdef *m,
upb_onmsgreg *msgreg_cb,
upb_onfieldreg *fieldreg_cb,
void *closure, upb_strtable *mtab) {
upb_mhandlers *mh = upb_handlers_newmhandlers(h);
- upb_mtab_ent e = {mh};
- upb_strtable_insert(mtab, m->base.fqname, &e);
+ upb_strtable_insert(mtab, upb_def_fullname(UPB_UPCAST(m)), upb_value_ptr(mh));
if (msgreg_cb) msgreg_cb(closure, mh, m);
upb_msg_iter i;
- for(i = upb_msg_begin(m); !upb_msg_done(i); i = upb_msg_next(m, i)) {
- upb_fielddef *f = upb_msg_iter_field(i);
+ for(upb_msg_begin(&i, m); !upb_msg_done(&i); upb_msg_next(&i)) {
+ upb_fielddef *f = upb_msg_iter_field(&i);
upb_fhandlers *fh;
if (upb_issubmsg(f)) {
upb_mhandlers *sub_mh;
- upb_mtab_ent *subm_ent;
+ const upb_value *subm_ent;
// The table lookup is necessary to break the DFS for type cycles.
- if ((subm_ent = upb_strtable_lookup(mtab, f->def->fqname)) != NULL) {
- sub_mh = subm_ent->mh;
+ const char *subname = upb_def_fullname(upb_fielddef_subdef(f));
+ if ((subm_ent = upb_strtable_lookup(mtab, subname)) != NULL) {
+ sub_mh = upb_value_getptr(*subm_ent);
} else {
- sub_mh = upb_regmsg_dfs(h, upb_downcast_msgdef(f->def), msgreg_cb,
- fieldreg_cb, closure, mtab);
+ sub_mh = upb_regmsg_dfs(
+ h, upb_downcast_msgdef_const(upb_fielddef_subdef(f)),
+ msgreg_cb, fieldreg_cb, closure, mtab);
}
fh = upb_mhandlers_newfhandlers_subm(
mh, f->number, f->type, upb_isseq(f), sub_mh);
@@ -151,10 +151,10 @@ upb_mhandlers *upb_handlers_regmsgdef(upb_handlers *h, const upb_msgdef *m,
upb_onfieldreg *fieldreg_cb,
void *closure) {
upb_strtable mtab;
- upb_strtable_init(&mtab, 8, sizeof(upb_mtab_ent));
+ upb_strtable_init(&mtab);
upb_mhandlers *ret =
upb_regmsg_dfs(h, m, msgreg_cb, fieldreg_cb, closure, &mtab);
- upb_strtable_free(&mtab);
+ upb_strtable_uninit(&mtab);
return ret;
}
@@ -212,6 +212,7 @@ upb_dispatcher_frame *upb_dispatch_startseq(upb_dispatcher *d,
upb_sflow_t sflow = UPB_CONTINUE_WITH(d->top->closure);
if (f->startseq) sflow = f->startseq(d->top->closure, f->fval);
+ _upb_dispatcher_sethas(d->top->closure, f->hasbit);
if (sflow.flow != UPB_CONTINUE) {
_upb_dispatcher_abortjmp(d);
}
@@ -247,6 +248,7 @@ upb_dispatcher_frame *upb_dispatch_startsubmsg(upb_dispatcher *d,
upb_sflow_t sflow = UPB_CONTINUE_WITH(d->top->closure);
if (f->startsubmsg) sflow = f->startsubmsg(d->top->closure, f->fval);
+ _upb_dispatcher_sethas(d->top->closure, f->hasbit);
if (sflow.flow != UPB_CONTINUE) {
_upb_dispatcher_abortjmp(d);
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback