More optimization, back up to 2.56GB/s.

pull/13171/head
Joshua Haberman 4 years ago
parent 199c914295
commit f3a2a79349
  1. 13
      upb/decode.c
  2. 23
      upb/decode.int.h
  3. 66
      upb/decode_fast.c

@ -234,19 +234,6 @@ static const char *decode_varint64(upb_decstate *d, const char *ptr,
}
}
static int decode_pushlimit(upb_decstate *d, const char *ptr, int size) {
int limit = size + (int)(ptr - d->end);
int delta = d->limit - limit;
d->limit = limit;
d->limit_ptr = d->end + UPB_MIN(0, limit);
return delta;
}
static void decode_poplimit(upb_decstate *d, int saved_delta) {
d->limit += saved_delta;
d->limit_ptr = d->end + UPB_MIN(0, d->limit);
}
UPB_FORCEINLINE
static const char *decode_varint32(upb_decstate *d, const char *ptr,
uint32_t *val) {

@ -46,6 +46,7 @@ const char *decode_isdonefallback_inl(upb_decstate *d, const char *ptr,
int overrun) {
if (overrun < d->limit) {
/* Need to copy remaining data into patch buffer. */
UPB_ASSERT(overrun >= 0);
UPB_ASSERT(overrun < 16);
memset(d->patch + 16, 0, 16);
memcpy(d->patch, d->end, 16);
@ -62,7 +63,8 @@ const char *decode_isdonefallback_inl(upb_decstate *d, const char *ptr,
}
UPB_INLINE
bool decode_isdone(upb_decstate *d, const char **ptr) {
bool decode_isdone_limit(upb_decstate *d, const char **ptr,
const char *limit_ptr) {
int overrun = *ptr - d->end;
if (UPB_LIKELY(*ptr < d->limit_ptr)) {
return false;
@ -74,6 +76,25 @@ bool decode_isdone(upb_decstate *d, const char **ptr) {
}
}
UPB_INLINE
bool decode_isdone(upb_decstate *d, const char **ptr) {
return decode_isdone_limit(d, ptr, d->limit_ptr);
}
UPB_INLINE int decode_pushlimit(upb_decstate *d, const char *ptr, int size) {
int limit = size + (int)(ptr - d->end);
int delta = d->limit - limit;
d->limit = limit;
d->limit_ptr = d->end + UPB_MIN(0, limit);
return delta;
}
UPB_INLINE void decode_poplimit(upb_decstate *d, int saved_delta) {
d->limit += saved_delta;
d->limit_ptr = d->end + UPB_MIN(0, d->limit);
UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
}
#include "upb/port_undef.inc"
#endif /* UPB_DECODE_INT_H_ */

@ -53,32 +53,6 @@ typedef struct {
int val; /* If <=0, the old limit, else a delta */
} fastdecode_savedlimit;
static fastdecode_savedlimit fastdecode_pushlimit(upb_decstate *d,
const char *ptr, int size) {
fastdecode_savedlimit saved;
int limit = size + (int)(ptr - d->end);
if (UPB_LIKELY(limit <= 0)) {
saved.limit_ptr = d->limit_ptr;
saved.val = d->limit;
d->limit_ptr = ptr + size;
} else {
saved.limit_ptr = NULL;
saved.val = d->limit - limit;
}
d->limit = limit;
return saved;
}
static void fastdecode_poplimit(upb_decstate *d, fastdecode_savedlimit saved) {
if (UPB_LIKELY(saved.limit_ptr != NULL)) {
d->limit_ptr = saved.limit_ptr;
d->limit = saved.val;
} else {
d->limit += saved.val;
d->limit_ptr = d->end + UPB_MIN(0, d->limit);
}
}
UPB_FORCEINLINE
static const char *fastdecode_tagdispatch(upb_decstate *d, const char *ptr,
upb_msg *msg,
@ -382,6 +356,23 @@ const char *upb_pos_2bt(UPB_PARSE_PARAMS) {
/* message fields *************************************************************/
UPB_NOINLINE
static const char *fastdecode_longsubmsg(upb_decstate *d, const char *ptr,
upb_msg *msg,
const upb_msglayout *table,
size_t len) {
return ptr;
}
UPB_FORCEINLINE
static bool fastdecode_boundscheck2(const char *ptr, size_t len,
const char *end) {
uintptr_t uptr = (uintptr_t)ptr;
uintptr_t uend = (uintptr_t)end;
uintptr_t res = uptr + len;
return res < uptr || res > uend;
}
UPB_FORCEINLINE
static const char *fastdecode_submsg(UPB_PARSE_PARAMS, int tagbytes,
int msg_ceil_bytes, upb_card card) {
@ -429,8 +420,10 @@ again:
}
ptr += tagbytes + 1;
size_t len = (uint8_t)ptr[-1];
int64_t len = (int8_t)ptr[-1];
if (fastdecode_boundscheck2(ptr, len, d->limit_ptr)) {
if (UPB_UNLIKELY(len & 0x80)) {
len &= 0xff;
int i;
for (i = 0; i < 3; i++) {
ptr++;
@ -445,13 +438,26 @@ again:
if (UPB_UNLIKELY(byte >= 8)) return fastdecode_err(d);
len += (byte - 1) << 28;
}
done:
done:
if (ptr - d->end + (int)len > d->limit) {
return fastdecode_err(d);
}
fastdecode_savedlimit saved = fastdecode_pushlimit(d, ptr, len);
int delta = decode_pushlimit(d, ptr, len);
ptr = fastdecode_dispatch(d, ptr, child, subl, 0);
fastdecode_poplimit(d, saved);
decode_poplimit(d, delta);
} else {
UPB_ASSERT(d->limit_ptr - ptr >= len);
UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
const char *saved_limit_ptr = d->limit_ptr;
int saved_limit = d->limit;
d->limit_ptr = ptr + len;
d->limit = d->limit_ptr - d->end;
UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
ptr = fastdecode_dispatch(d, ptr, child, subl, 0);
d->limit_ptr = saved_limit_ptr;
d->limit = saved_limit;
UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
}
if (UPB_UNLIKELY(d->end_group != 0)) {
return fastdecode_err(d);
}

Loading…
Cancel
Save