Stored mask in the table pointer.

pull/13171/head
Joshua Haberman 4 years ago
parent a6dc88556d
commit 8ed6b2fe85
  1. 7
      upb/decode.c
  2. 2
      upb/decode.int.h
  3. 32
      upb/decode_fast.c
  4. 8
      upb/decode_fast.h
  5. 5
      upb/msg.h

@ -613,13 +613,13 @@ static decode_parseret decode_field(upb_decstate *d, const char *ptr,
UPB_NOINLINE
const char *fastdecode_generic(upb_decstate *d, const char *ptr, upb_msg *msg,
const upb_msglayout *table, uint64_t hasbits,
intptr_t table, uint64_t hasbits,
uint64_t data) {
decode_parseret ret;
*(uint32_t*)msg |= hasbits >> 16; /* Sync hasbits. */
(void)data;
if (ptr == d->limit) return ptr;
ret = decode_field(d, ptr, msg, table);
ret = decode_field(d, ptr, msg, (const upb_msglayout *)(table >> 8));
if (ret.group_end) return ptr;
return fastdecode_dispatch(d, ret.ptr, msg, table, hasbits);
}
@ -628,7 +628,8 @@ UPB_NOINLINE
static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
const upb_msglayout *layout) {
if (msg) {
ptr = fastdecode_dispatch(d, ptr, msg, layout, 0);
ptr = fastdecode_dispatch(d, ptr, msg,
((intptr_t)layout << 8) | layout->table_mask, 0);
} else {
while (ptr < d->limit) {
decode_parseret ret = decode_field(d, ptr, msg, layout);

@ -18,7 +18,7 @@ typedef struct upb_decstate {
} upb_decstate;
const char *fastdecode_dispatch(upb_decstate *d, const char *ptr, upb_msg *msg,
const upb_msglayout *table, uint64_t hasbits);
intptr_t table, uint64_t hasbits);
const char *fastdecode_err(upb_decstate *d);

@ -8,7 +8,7 @@
#include "upb/port_def.inc"
#define UPB_PARSE_PARAMS \
upb_decstate *d, const char *ptr, upb_msg *msg, const upb_msglayout *table, \
upb_decstate *d, const char *ptr, upb_msg *msg, intptr_t table, \
uint64_t hasbits, uint64_t data
#define UPB_PARSE_ARGS d, ptr, msg, table, hasbits, data
@ -24,15 +24,17 @@ typedef enum {
} upb_card;
UPB_FORCEINLINE
const char *fastdecode_tag_dispatch(upb_decstate *d, const char *ptr, upb_msg *msg,
const upb_msglayout *table, uint64_t hasbits, uint32_t tag) {
const char *fastdecode_tag_dispatch(upb_decstate *d, const char *ptr,
upb_msg *msg, intptr_t table,
uint64_t hasbits, uint32_t tag) {
const upb_msglayout *table_p = (void*)(table >> 8);
uint8_t mask = table;
uint64_t data;
size_t idx;
idx = (tag & table->table_mask);
size_t idx = tag & mask;
__builtin_assume((idx & 7) == 0);
idx >>= 3;
data = table->fasttable[idx].field_data ^ tag;
return table->fasttable[idx].field_parser(UPB_PARSE_ARGS);
data = table_p->fasttable[idx].field_data ^ tag;
return table_p->fasttable[idx].field_parser(UPB_PARSE_ARGS);
}
UPB_FORCEINLINE
@ -42,9 +44,9 @@ uint32_t fastdecode_load_tag(const char* ptr) {
return tag;
}
UPB_NOINLINE
UPB_FORCEINLINE
const char *fastdecode_dispatch(upb_decstate *d, const char *ptr, upb_msg *msg,
const upb_msglayout *table, uint64_t hasbits) {
intptr_t table, uint64_t hasbits) {
if (UPB_UNLIKELY(ptr >= d->fastlimit)) {
if (UPB_LIKELY(ptr == d->limit)) {
*(uint32_t*)msg |= hasbits >> 16; /* Sync hasbits. */
@ -265,9 +267,9 @@ const char *upb_pos_2bt(UPB_PARSE_PARAMS) {
/* message fields *************************************************************/
UPB_NOINLINE static
const char *fastdecode_lendelim_submsg(upb_decstate *d, const char *ptr, upb_msg *msg,
const upb_msglayout *table, uint64_t hasbits, const char* saved_limit) {
UPB_NOINLINE static const char *fastdecode_lendelim_submsg(
upb_decstate *d, const char *ptr, upb_msg *msg, intptr_t table,
uint64_t hasbits, const char *saved_limit) {
size_t len = (uint8_t)ptr[-1];
if (UPB_UNLIKELY(len & 0x80)) {
int i;
@ -308,7 +310,9 @@ static const char *fastdecode_submsg(UPB_PARSE_PARAMS, int tagbytes,
void *end;
uint32_t submsg_idx = data;
submsg_idx >>= 16;
const upb_msglayout *subl = table->submsgs[submsg_idx];
const upb_msglayout *table_p = (void*)(table >> 8);
const upb_msglayout *subl = table_p->submsgs[submsg_idx];
intptr_t subt = (intptr_t)subl << 8 | subl->table_mask;
submsg = fastdecode_getfield_ofs(d, ptr, msg, &data, &hasbits, &arr, &end,
sizeof(upb_msg *), card, true);
@ -344,7 +348,7 @@ again:
ptr += tagbytes + 1;
ptr = fastdecode_lendelim_submsg(d, ptr, child, subl, 0, saved_limit);
ptr = fastdecode_lendelim_submsg(d, ptr, child, subt, 0, saved_limit);
if (UPB_UNLIKELY(ptr != d->limit || d->end_group != 0)) {
return fastdecode_err(d);

@ -7,12 +7,12 @@
struct upb_decstate;
const char *fastdecode_generic(struct upb_decstate *d, const char *ptr,
upb_msg *msg, const upb_msglayout *table,
uint64_t hasbits, uint64_t data);
upb_msg *msg, intptr_t table, uint64_t hasbits,
uint64_t data);
#define UPB_PARSE_PARAMS \
struct upb_decstate *d, const char *ptr, upb_msg *msg, \
const upb_msglayout *table, uint64_t hasbits, uint64_t data
struct upb_decstate *d, const char *ptr, upb_msg *msg, intptr_t table, \
uint64_t hasbits, uint64_t data
#define F(card, type, valbytes, tagbytes) \
const char *upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS);

@ -50,8 +50,7 @@ struct upb_msglayout;
struct upb_decstate;
typedef const char *_upb_field_parser(struct upb_decstate *d, const char *ptr,
upb_msg *msg,
const struct upb_msglayout *table,
upb_msg *msg, intptr_t table,
uint64_t hasbits, uint64_t data);
typedef struct {
@ -62,7 +61,7 @@ typedef struct {
typedef struct upb_msglayout {
const struct upb_msglayout *const* submsgs;
const upb_msglayout_field *fields;
uint32_t table_mask;
uint8_t table_mask;
/* Must be aligned to sizeof(void*). Doesn't include internal members like
* unknown fields, extension dict, pointer to msglayout, etc. */
uint16_t size;

Loading…
Cancel
Save