We have a properly structured algorithm, but perf regresses by 20%.

pull/13171/head
Joshua Haberman 4 years ago
parent 438ecaeb5a
commit 3937874a85
  1. 21
      upb/decode.c
  2. 1
      upb/decode.h

@ -275,7 +275,6 @@ static upb_msg *decode_newsubmsg(upb_decstate *d, const upb_msglayout *layout,
return _upb_msg_new(subl, d->arena);
}
UPB_FORCEINLINE
static void decode_tosubmsg(upb_decstate *d, upb_msg *submsg,
const upb_msglayout *layout,
const upb_msglayout_field *field, upb_strview val) {
@ -283,13 +282,14 @@ static void decode_tosubmsg(upb_decstate *d, upb_msg *submsg,
const char *saved_limit = d->limit;
if (--d->depth < 0) decode_err(d);
d->limit = val.data + val.size;
d->fastlimit = UPB_MIN(d->limit, d->fastend);
decode_msg(d, val.data, submsg, subl);
d->limit = saved_limit;
d->fastlimit = UPB_MIN(d->limit, d->fastend);
if (d->end_group != 0) decode_err(d);
d->depth++;
}
UPB_FORCEINLINE
static const char *decode_group(upb_decstate *d, const char *ptr,
upb_msg *submsg, const upb_msglayout *subl,
uint32_t number) {
@ -301,7 +301,6 @@ static const char *decode_group(upb_decstate *d, const char *ptr,
return ptr;
}
UPB_FORCEINLINE
static const char *decode_togroup(upb_decstate *d, const char *ptr,
upb_msg *submsg, const upb_msglayout *layout,
const upb_msglayout_field *field) {
@ -402,7 +401,6 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
}
}
UPB_FORCEINLINE
static void decode_tomap(upb_decstate *d, upb_msg *msg,
const upb_msglayout *layout,
const upb_msglayout_field *field, wireval val) {
@ -594,19 +592,23 @@ static const char *decode_field(upb_decstate *d, const char *ptr, upb_msg *msg,
return ptr;
}
UPB_NOINLINE
const char *fastdecode_generic(upb_decstate *d, const char *ptr, upb_msg *msg,
const upb_msglayout *table, uint64_t hasbits,
uint64_t data) {
*(uint32_t*)msg |= hasbits; /* Sync hasbits. */
if (hasbits) *(uint32_t*)msg |= hasbits; /* Sync hasbits. */
(void)data;
return decode_field(d, ptr, msg, table);
ptr = decode_field(d, ptr, msg, table);
return fastdecode_dispatch(d, ptr, msg, table, hasbits);
}
UPB_NOINLINE
static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
const upb_msglayout *layout) {
while (ptr < d->limit) {
while (1) {
ptr = fastdecode_dispatch(d, ptr, msg, layout, 0);
if (ptr < d->limit) ptr = decode_field(d, ptr, msg, layout);
if (ptr == d->limit) break;
ptr = decode_field(d, ptr, msg, layout);
}
if (ptr != d->limit) decode_err(d);
@ -617,7 +619,8 @@ bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l,
upb_arena *arena) {
upb_decstate state;
state.limit = buf + size;
state.fastlimit = buf + size - 16;
state.fastend = buf + size - 16;
state.fastlimit = state.fastend;
state.arena = arena;
state.depth = 64;
state.end_group = 0;

@ -22,6 +22,7 @@ typedef struct upb_decstate {
const void *rep_end;
const char *limit; /* End of delimited region or end of buffer. */
const char *fastlimit; /* End of delimited region or end of buffer. */
const char *fastend;
upb_array *arr;
_upb_field_parser *resume;
upb_arena *arena;

Loading…
Cancel
Save