summaryrefslogtreecommitdiff
path: root/upb/handlers.h
diff options
context:
space:
mode:
authorJoshua Haberman <jhaberman@gmail.com>2011-08-20 18:43:11 -0700
committerJoshua Haberman <jhaberman@gmail.com>2011-08-20 18:43:11 -0700
commitadb6580d9728c3533faf779812bd7f4c9b27170d (patch)
tree2aa721539ed7f067e26c2d6b16c657307700150b /upb/handlers.h
parenta5e6a7b029850f77059800d6611f406b91f87dfe (diff)
Let the JIT emit hasbit-setting code in addition to calling a callback.
This leads to a major (20-40%) improvement in the parsetoproto2 benchmark with small messages. We now are faster than proto2 in all apples-to-apples comparisons, at least given the (admittedly limited) set of benchmarks in this source tree.
Diffstat (limited to 'upb/handlers.h')
-rw-r--r--upb/handlers.h12
1 files changed, 12 insertions, 0 deletions
diff --git a/upb/handlers.h b/upb/handlers.h
index db28705..3a9509a 100644
--- a/upb/handlers.h
+++ b/upb/handlers.h
@@ -141,6 +141,7 @@ typedef struct _upb_fieldent {
bool is_repeated_primitive;
upb_atomic_t refcount;
uint32_t number;
+ int32_t valuehasbit;
struct _upb_mhandlers *msg;
struct _upb_mhandlers *submsg; // Set iff upb_issubmsgtype(type) == true.
upb_value fval;
@@ -174,6 +175,11 @@ UPB_FHANDLERS_ACCESSORS(startseq, upb_startfield_handler*)
UPB_FHANDLERS_ACCESSORS(endseq, upb_endfield_handler*)
UPB_FHANDLERS_ACCESSORS(msg, struct _upb_mhandlers*)
UPB_FHANDLERS_ACCESSORS(submsg, struct _upb_mhandlers*)
+// If set to >= 0, the hasbit will automatically be set after the corresponding
+// callback is called (when a JIT is enabled, this can be significantly more
+// efficient than setting the hasbit yourself inside the callback). Could add
+// this for seq and submsg also, but doesn't look like a win at the moment.
+UPB_FHANDLERS_ACCESSORS(valuehasbit, int32_t)
/* upb_mhandlers **************************************************************/
@@ -357,11 +363,17 @@ INLINE upb_fhandlers *upb_dispatcher_lookup(upb_dispatcher *d, uint32_t n) {
void _upb_dispatcher_unwind(upb_dispatcher *d, upb_flow_t flow);
+INLINE void _upb_dispatcher_sethas(void *_p, int32_t hasbit) {
+ char *p = (char*)_p;
+ if (hasbit >= 0) p[hasbit / 8] |= (1 << (hasbit % 8));
+}
+
// Dispatch functions -- call the user handler and handle errors.
INLINE void upb_dispatch_value(upb_dispatcher *d, upb_fhandlers *f,
upb_value val) {
upb_flow_t flow = UPB_CONTINUE;
if (f->value) flow = f->value(d->top->closure, f->fval, val);
+ _upb_dispatcher_sethas(d->top->closure, f->valuehasbit);
if (flow != UPB_CONTINUE) _upb_dispatcher_unwind(d, flow);
}
void upb_dispatch_startmsg(upb_dispatcher *d);
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback