Simplify push/pop when msg fits in the current buffer.

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

@ -234,6 +234,19 @@ 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) {

@ -74,21 +74,6 @@ bool decode_isdone(upb_decstate *d, const char **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);
}
#include "upb/port_undef.inc"
#endif /* UPB_DECODE_INT_H_ */

@ -48,6 +48,37 @@ upb_msg *decode_newmsg_ceil(upb_decstate *d, const upb_msglayout *l,
return msg_data + sizeof(upb_msg_internal);
}
typedef struct {
const char *limit_ptr;
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,
@ -399,7 +430,6 @@ again:
ptr += tagbytes + 1;
size_t len = (uint8_t)ptr[-1];
int saved_delta;
if (UPB_UNLIKELY(len & 0x80)) {
int i;
for (i = 0; i < 3; i++) {
@ -419,9 +449,9 @@ done:
if (ptr - d->end + (int)len > d->limit) {
return fastdecode_err(d);
}
saved_delta = decode_pushlimit(d, ptr, len);
fastdecode_savedlimit saved = fastdecode_pushlimit(d, ptr, len);
ptr = fastdecode_dispatch(d, ptr, child, subl, 0);
decode_poplimit(d, saved_delta);
fastdecode_poplimit(d, saved);
if (UPB_UNLIKELY(d->end_group != 0)) {
return fastdecode_err(d);
}

Loading…
Cancel
Save