Remove branch prediction hints. They seem to hurt more than help.

pull/13171/head
Joshua Haberman 16 years ago
parent 9c88385ba4
commit d7b666ecf4
  1. 9
      upb.h
  2. 29
      upb_parse.c

@ -18,15 +18,6 @@
extern "C" { extern "C" {
#endif #endif
/* Branch prediction hints for GCC. */
#ifdef __GNUC__
#define likely(x) __builtin_expect((x),1)
#define unlikely(x) __builtin_expect((x),0)
#else
#define likely(x) (x)
#define unlikely(x) (x)
#endif
/* inline if possible, emit standalone code if required. */ /* inline if possible, emit standalone code if required. */
#ifndef INLINE #ifndef INLINE
#define INLINE static inline #define INLINE static inline

@ -38,7 +38,7 @@ static upb_status_t get_v_uint64_t(void *restrict *buf, void *end,
for(int bitpos = 0; b < (uint8_t*)end && (last & 0x80); b++, bitpos += 7) for(int bitpos = 0; b < (uint8_t*)end && (last & 0x80); b++, bitpos += 7)
*val |= ((uint64_t)((last = *b) & 0x7F)) << bitpos; *val |= ((uint64_t)((last = *b) & 0x7F)) << bitpos;
if(unlikely(last & 0x80)) return bound_error; if(last & 0x80) return bound_error;
*buf = b; *buf = b;
return UPB_STATUS_OK; return UPB_STATUS_OK;
} }
@ -52,7 +52,7 @@ static upb_status_t skip_v_uint64_t(void **buf, void *end)
for(; b < (uint8_t*)end && (last & 0x80); b++) for(; b < (uint8_t*)end && (last & 0x80); b++)
last = *b; last = *b;
if(unlikely(last & 0x80)) return bound_error; if(last & 0x80) return bound_error;
*buf = b; *buf = b;
return UPB_STATUS_OK; return UPB_STATUS_OK;
} }
@ -73,7 +73,7 @@ static upb_status_t get_v_uint32_t(void *restrict *buf, void *end,
for(; b < (uint8_t*)end && (last & 0x80); b++) for(; b < (uint8_t*)end && (last & 0x80); b++)
last = *b; last = *b;
if(unlikely(last & 0x80)) if(last & 0x80)
return bound_error; return bound_error;
*buf = b; *buf = b;
return UPB_STATUS_OK; return UPB_STATUS_OK;
@ -84,7 +84,7 @@ static upb_status_t get_f_uint32_t(void *restrict *buf, void *end,
{ {
uint8_t *b = *buf; uint8_t *b = *buf;
void *uint32_end = (uint8_t*)*buf + sizeof(uint32_t); void *uint32_end = (uint8_t*)*buf + sizeof(uint32_t);
if(unlikely(uint32_end > end)) return UPB_STATUS_NEED_MORE_DATA; if(uint32_end > end) return UPB_STATUS_NEED_MORE_DATA;
#if UPB_UNALIGNED_READS_OK #if UPB_UNALIGNED_READS_OK
*val = *(uint32_t*)b; *val = *(uint32_t*)b;
#else #else
@ -100,7 +100,7 @@ static upb_status_t get_f_uint64_t(void *restrict *buf, void *end,
uint64_t *restrict val) uint64_t *restrict val)
{ {
void *uint64_end = (uint8_t*)*buf + sizeof(uint64_t); void *uint64_end = (uint8_t*)*buf + sizeof(uint64_t);
if(unlikely(uint64_end > end)) return UPB_STATUS_NEED_MORE_DATA; if(uint64_end > end) return UPB_STATUS_NEED_MORE_DATA;
#if UPB_UNALIGNED_READS_OK #if UPB_UNALIGNED_READS_OK
*val = *(uint64_t*)*buf; *val = *(uint64_t*)*buf;
*buf = uint64_end; *buf = uint64_end;
@ -116,7 +116,7 @@ static upb_status_t get_f_uint64_t(void *restrict *buf, void *end,
static upb_status_t skip_f_uint32_t(void **buf, void *end) static upb_status_t skip_f_uint32_t(void **buf, void *end)
{ {
void *uint32_end = (uint8_t*)*buf + sizeof(uint32_t); void *uint32_end = (uint8_t*)*buf + sizeof(uint32_t);
if(unlikely(uint32_end > end)) return UPB_STATUS_NEED_MORE_DATA; if(uint32_end > end) return UPB_STATUS_NEED_MORE_DATA;
*buf = uint32_end; *buf = uint32_end;
return UPB_STATUS_OK; return UPB_STATUS_OK;
} }
@ -124,7 +124,7 @@ static upb_status_t skip_f_uint32_t(void **buf, void *end)
static upb_status_t skip_f_uint64_t(void **buf, void *end) static upb_status_t skip_f_uint64_t(void **buf, void *end)
{ {
void *uint64_end = (uint8_t*)*buf + sizeof(uint64_t); void *uint64_end = (uint8_t*)*buf + sizeof(uint64_t);
if(unlikely(uint64_end > end)) return UPB_STATUS_NEED_MORE_DATA; if(uint64_end > end) return UPB_STATUS_NEED_MORE_DATA;
*buf = uint64_end; *buf = uint64_end;
return UPB_STATUS_OK; return UPB_STATUS_OK;
} }
@ -289,7 +289,7 @@ static upb_status_t push_stack_frame(struct upb_parse_state *s, size_t end,
{ {
s->top++; s->top++;
s->top = (struct upb_parse_stack_frame*)((char*)s->top + s->udata_size); s->top = (struct upb_parse_stack_frame*)((char*)s->top + s->udata_size);
if(unlikely(s->top > s->limit)) return UPB_ERROR_STACK_OVERFLOW; if(s->top > s->limit) return UPB_ERROR_STACK_OVERFLOW;
s->top->end_offset = end; s->top->end_offset = end;
if(s->submsg_start_cb) s->submsg_start_cb(s, user_field_desc); if(s->submsg_start_cb) s->submsg_start_cb(s, user_field_desc);
return UPB_STATUS_OK; return UPB_STATUS_OK;
@ -308,9 +308,8 @@ static upb_status_t parse_delimited(struct upb_parse_state *s,
* the length. */ * the length. */
UPB_CHECK(get_INT32(buf, end, &delim_len)); UPB_CHECK(get_INT32(buf, end, &delim_len));
upb_field_type_t ft = s->tag_cb(s, tag, &user_field_desc); upb_field_type_t ft = s->tag_cb(s, tag, &user_field_desc);
if(unlikely(*buf < bufstart)) return UPB_ERROR_OVERFLOW; if(*buf < bufstart) return UPB_ERROR_OVERFLOW;
if(unlikely(*buf > end && if(*buf > end && ft != GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_MESSAGE) {
ft != GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_MESSAGE)) {
/* Streaming submessages is ok, but for other delimited types (string, /* Streaming submessages is ok, but for other delimited types (string,
* bytes, and packed arrays) we require that all the delimited data is * bytes, and packed arrays) we require that all the delimited data is
* available. This could be relaxed if desired. */ * available. This could be relaxed if desired. */
@ -354,8 +353,8 @@ static upb_status_t parse_nondelimited(struct upb_parse_state *s,
return UPB_STATUS_OK; return UPB_STATUS_OK;
} }
upb_status_t upb_parse(struct upb_parse_state *s, void *buf, size_t len, upb_status_t upb_parse(struct upb_parse_state *restrict s, void *buf, size_t len,
size_t *read) size_t *restrict read)
{ {
void *end = (char*)buf + len; void *end = (char*)buf + len;
*read = 0; *read = 0;
@ -368,8 +367,8 @@ upb_status_t upb_parse(struct upb_parse_state *s, void *buf, size_t len,
struct upb_tag tag; struct upb_tag tag;
void *bufstart = buf; void *bufstart = buf;
UPB_CHECK(parse_tag(&buf, end, &tag)); UPB_CHECK(parse_tag(&buf, end, &tag));
if(unlikely(tag.wire_type == UPB_WIRE_TYPE_END_GROUP)) { if(tag.wire_type == UPB_WIRE_TYPE_END_GROUP) {
if(unlikely(s->top->end_offset != UINT32_MAX)) if(s->top->end_offset != UINT32_MAX)
return UPB_ERROR_SPURIOUS_END_GROUP; return UPB_ERROR_SPURIOUS_END_GROUP;
pop_stack_frame(s); pop_stack_frame(s);
} else if(tag.wire_type == UPB_WIRE_TYPE_DELIMITED) { } else if(tag.wire_type == UPB_WIRE_TYPE_DELIMITED) {

Loading…
Cancel
Save