Optimized memset() with cutoff and fixed group & unknown message bugs.

pull/13171/head
Joshua Haberman 4 years ago
parent 8dd7b5a2ca
commit 9e5c5ce089
  1. 132
      generated_for_cmake/google/protobuf/descriptor.upb.c
  2. 2
      tests/benchmark.cc
  3. 34
      upb/decode.c
  4. 12
      upb/decode.h
  5. 29
      upb/decode_fast.c
  6. 2
      upbc/generator.cc

@ -23,7 +23,7 @@ static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] =
const upb_msglayout google_protobuf_FileDescriptorSet_msginit = {
{
&fastdecode_generic,
&fastdecode_generic,
&upb_prm_1bt,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
@ -57,7 +57,7 @@ const upb_msglayout google_protobuf_FileDescriptorSet_msginit = {
},
{
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(10, 10),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
@ -124,12 +124,12 @@ const upb_msglayout google_protobuf_FileDescriptorProto_msginit = {
&upb_pss_1bt,
&upb_pss_1bt,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
&upb_prm_1bt,
&upb_prm_1bt,
&upb_prm_1bt,
&upb_prm_1bt,
&upb_psm_1bt,
&upb_psm_1bt,
&fastdecode_generic,
&fastdecode_generic,
&upb_pss_1bt,
@ -158,12 +158,12 @@ const upb_msglayout google_protobuf_FileDescriptorProto_msginit = {
UPB_SIZE(1125899906973706, 2251799813816330),
UPB_SIZE(3377699720790034, 6755399441317906),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(844424930132002, 844424930132002),
UPB_SIZE(1125899906842666, 1125899906842666),
UPB_SIZE(1407374883553330, 1407374883553330),
UPB_SIZE(1688849860263994, 1688849860263994),
UPB_SIZE(1970324838023234, 1970324838023234),
UPB_SIZE(2251799815782474, 2251799815782474),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(5629499534737506, 11258999068950626),
@ -219,14 +219,14 @@ const upb_msglayout google_protobuf_DescriptorProto_msginit = {
{
&fastdecode_generic,
&upb_pss_1bt,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
&upb_prm_1bt,
&upb_prm_1bt,
&upb_prm_1bt,
&upb_prm_1bt,
&upb_prm_1bt,
&upb_psm_1bt,
&upb_prm_1bt,
&upb_prm_1bt,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
@ -253,14 +253,14 @@ const upb_msglayout google_protobuf_DescriptorProto_msginit = {
{
UPB_SIZE(0, 0),
UPB_SIZE(1125899906973706, 2251799813816330),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(281474976710674, 281474976710674),
UPB_SIZE(562949953421338, 562949953421338),
UPB_SIZE(844424930132002, 844424930132002),
UPB_SIZE(1125899906842666, 1125899906842666),
UPB_SIZE(1407374883553330, 1407374883553330),
UPB_SIZE(1688849860526138, 1688849860526138),
UPB_SIZE(1970324836974658, 1970324836974658),
UPB_SIZE(2251799813685322, 2251799813685322),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
@ -304,7 +304,7 @@ const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = {
&fastdecode_generic,
&upb_psv4_1bt,
&upb_psv4_1bt,
&fastdecode_generic,
&upb_psm_1bt,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
@ -338,7 +338,7 @@ const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = {
UPB_SIZE(0, 0),
UPB_SIZE(1125899906973704, 1125899906973704),
UPB_SIZE(2251799813947408, 2251799813947408),
UPB_SIZE(0, 0),
UPB_SIZE(562949953945626, 562949953945626),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
@ -562,7 +562,7 @@ const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = {
&upb_psv4_1bt,
&upb_pss_1bt,
&upb_pss_1bt,
&fastdecode_generic,
&upb_psm_1bt,
&upb_psv4_1bt,
&upb_pss_1bt,
&fastdecode_generic,
@ -596,7 +596,7 @@ const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = {
UPB_SIZE(4503599627632680, 4503599627632680),
UPB_SIZE(14636698805731378, 20266198339944498),
UPB_SIZE(16888498636193850, 24769797984092218),
UPB_SIZE(0, 0),
UPB_SIZE(1970324971192386, 1970324971192386),
UPB_SIZE(7881299348947016, 7881299348947016),
UPB_SIZE(19140298483433554, 29273397645017170),
UPB_SIZE(0, 0),
@ -605,7 +605,7 @@ const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = {
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(9007199256838280, 9007199256838280),
UPB_SIZE(9007199256838536, 9007199256838536),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
@ -639,7 +639,7 @@ const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = {
{
&fastdecode_generic,
&upb_pss_1bt,
&fastdecode_generic,
&upb_psm_1bt,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
@ -673,7 +673,7 @@ const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = {
{
UPB_SIZE(0, 0),
UPB_SIZE(1125899906973706, 2251799813816330),
UPB_SIZE(0, 0),
UPB_SIZE(281474976972818, 281474976972818),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
@ -727,9 +727,9 @@ const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = {
{
&fastdecode_generic,
&upb_pss_1bt,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
&upb_prm_1bt,
&upb_psm_1bt,
&upb_prm_1bt,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
@ -761,9 +761,9 @@ const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = {
{
UPB_SIZE(0, 0),
UPB_SIZE(1125899906973706, 2251799813816330),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(281474976710674, 281474976710674),
UPB_SIZE(562949953683482, 562949953683482),
UPB_SIZE(844424930132002, 844424930132002),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
@ -891,7 +891,7 @@ const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = {
&fastdecode_generic,
&upb_pss_1bt,
&upb_psv4_1bt,
&fastdecode_generic,
&upb_psm_1bt,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
@ -925,7 +925,7 @@ const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = {
UPB_SIZE(0, 0),
UPB_SIZE(2251799813947402, 2251799813947402),
UPB_SIZE(1125899906973712, 1125899906973712),
UPB_SIZE(0, 0),
UPB_SIZE(562949953945626, 562949953945626),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
@ -975,8 +975,8 @@ const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = {
{
&fastdecode_generic,
&upb_pss_1bt,
&fastdecode_generic,
&fastdecode_generic,
&upb_prm_1bt,
&upb_psm_1bt,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
@ -1009,8 +1009,8 @@ const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = {
{
UPB_SIZE(0, 0),
UPB_SIZE(1125899906973706, 2251799813816330),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(281474976710674, 281474976710674),
UPB_SIZE(562949953683482, 562949953683482),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
@ -1064,7 +1064,7 @@ const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = {
&upb_pss_1bt,
&upb_pss_1bt,
&upb_pss_1bt,
&fastdecode_generic,
&upb_psm_1bt,
&upb_psb1_1bt,
&upb_psb1_1bt,
&fastdecode_generic,
@ -1098,7 +1098,7 @@ const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = {
UPB_SIZE(1125899907366922, 2251799814209546),
UPB_SIZE(3377699721576466, 6755399442104338),
UPB_SIZE(5629499536310298, 11258999070523418),
UPB_SIZE(0, 0),
UPB_SIZE(844424934326306, 844424934326306),
UPB_SIZE(281474976841768, 281474976841768),
UPB_SIZE(562949953683504, 562949953683504),
UPB_SIZE(0, 0),
@ -1212,22 +1212,22 @@ const upb_msglayout google_protobuf_FileOptions_msginit = {
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(4785074604605568, 4785074604605568),
UPB_SIZE(5066549581840520, 5066549581840520),
UPB_SIZE(5348024559599760, 5348024559599760),
UPB_SIZE(4785074604605824, 4785074604605824),
UPB_SIZE(5066549581840776, 5066549581840776),
UPB_SIZE(5348024559600016, 5348024559600016),
UPB_SIZE(0, 0),
UPB_SIZE(5629499538407584, 5629499538407584),
UPB_SIZE(5629499538407840, 5629499538407840),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(5910974519312568, 5910974519312568),
UPB_SIZE(5910974519312824, 5910974519312824),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(6192449504411864, 6192449504411864),
UPB_SIZE(6192449504412120, 6192449504412120),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(6473924497899768, 6473924497899768),
UPB_SIZE(6473924497900024, 6473924497900024),
},
&google_protobuf_FileOptions_submsgs[0],
&google_protobuf_FileOptions__fields[0],
@ -1842,12 +1842,12 @@ const upb_msglayout google_protobuf_UninterpretedOption_msginit = {
{
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
&upb_prm_1bt,
&upb_pss_1bt,
&upb_psv8_1bt,
&upb_psv8_1bt,
&fastdecode_generic,
&upb_pss_1bt,
&fastdecode_generic,
&upb_pss_1bt,
&fastdecode_generic,
&fastdecode_generic,
@ -1876,12 +1876,12 @@ const upb_msglayout google_protobuf_UninterpretedOption_msginit = {
{
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(18, 18),
UPB_SIZE(9007199255789594, 9007199255789594),
UPB_SIZE(2251799813816352, 2251799813816352),
UPB_SIZE(4503599627632680, 4503599627632680),
UPB_SIZE(0, 0),
UPB_SIZE(11258999070523450, 13510798884208698),
UPB_SIZE(0, 0),
UPB_SIZE(13510798886305858, 18014398513676354),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
@ -2002,7 +2002,7 @@ static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = {
const upb_msglayout google_protobuf_SourceCodeInfo_msginit = {
{
&fastdecode_generic,
&fastdecode_generic,
&upb_prm_1bt,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
@ -2036,7 +2036,7 @@ const upb_msglayout google_protobuf_SourceCodeInfo_msginit = {
},
{
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(10, 10),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
@ -2166,7 +2166,7 @@ static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] =
const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = {
{
&fastdecode_generic,
&fastdecode_generic,
&upb_prm_1bt,
&fastdecode_generic,
&fastdecode_generic,
&fastdecode_generic,
@ -2200,7 +2200,7 @@ const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = {
},
{
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(10, 10),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),
UPB_SIZE(0, 0),

@ -41,7 +41,7 @@ static void BM_ParseDescriptorNoHeap(benchmark::State& state) {
}
bytes += descriptor.size;
upb_arena_free(arena);
fprintf(stderr, "+++ finished parse\n");
//fprintf(stderr, "+++ finished parse: %zu\n", descriptor.size);
}
state.SetBytesProcessed(state.iterations() * descriptor.size);
}

@ -565,9 +565,14 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg,
return ptr;
}
typedef struct {
const char *ptr;
bool group_end;
} decode_parseret;
UPB_FORCEINLINE
static const char *decode_field(upb_decstate *d, const char *ptr, upb_msg *msg,
const upb_msglayout *layout) {
static decode_parseret decode_field(upb_decstate *d, const char *ptr,
upb_msg *msg, const upb_msglayout *layout) {
uint32_t tag;
const upb_msglayout_field *field;
int field_number;
@ -575,6 +580,7 @@ static const char *decode_field(upb_decstate *d, const char *ptr, upb_msg *msg,
const char *field_start = ptr;
wireval val;
int op;
decode_parseret ret;
ptr = decode_varint32(d, ptr, d->limit, &tag);
field_number = tag >> 3;
@ -625,7 +631,9 @@ static const char *decode_field(upb_decstate *d, const char *ptr, upb_msg *msg,
break;
case UPB_WIRE_TYPE_END_GROUP:
d->end_group = field_number;
return ptr;
ret.ptr = ptr;
ret.group_end = true;
return ret;
default:
decode_err(d);
}
@ -656,24 +664,36 @@ static const char *decode_field(upb_decstate *d, const char *ptr, upb_msg *msg,
}
}
return ptr;
ret.ptr = ptr;
ret.group_end = false;
return ret;
}
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) {
decode_parseret ret;
*(uint32_t*)msg |= hasbits >> 16; /* Sync hasbits. */
(void)data;
if (ptr == d->limit) return ptr;
ptr = decode_field(d, ptr, msg, table);
return fastdecode_dispatch(d, ptr, msg, table, hasbits);
ret = decode_field(d, ptr, msg, table);
if (ret.group_end) return ptr;
return fastdecode_dispatch(d, ret.ptr, msg, table, hasbits);
}
UPB_NOINLINE
static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
const upb_msglayout *layout) {
ptr = fastdecode_dispatch(d, ptr, msg, layout, 0);
if (msg) {
ptr = fastdecode_dispatch(d, ptr, msg, layout, 0);
} else {
while (ptr < d->limit) {
decode_parseret ret = decode_field(d, ptr, msg, layout);
ptr = ret.ptr;
if (ret.group_end) return ptr;
}
}
if (ptr != d->limit) decode_err(d);
return ptr;
}

@ -54,9 +54,17 @@ static void *decode_malloc(upb_decstate *d, size_t size) {
UPB_INLINE
upb_msg *decode_newmsg(upb_decstate *d, const upb_msglayout *l) {
const size_t cutoff = 192;
size_t size = l->size + sizeof(upb_msg_internal);
char *msg_data = (char*)decode_malloc(d, size);
memset(msg_data, 0, size);
char *msg_data;
if (size <= cutoff && (size_t)(d->arena_end - d->arena_ptr) >= cutoff) {
msg_data = d->arena_ptr;
memset(msg_data, 0, cutoff);
d->arena_ptr += size;
} else {
msg_data = (char*)decode_malloc(d, size);
memset(msg_data, 0, size);
}
return msg_data + sizeof(upb_msg_internal);
}

@ -9,6 +9,10 @@
#define UPB_PARSE_ARGS d, ptr, msg, table, hasbits, data
#define RETURN_GENERIC(msg) \
/* fprintf(stderr, msg); */ \
return fastdecode_generic(UPB_PARSE_ARGS);
typedef enum {
CARD_s = 0,
CARD_o = 1,
@ -24,10 +28,10 @@ const char *fastdecode_dispatch(upb_decstate *d, const char *ptr, upb_msg *msg,
size_t idx;
if (UPB_UNLIKELY(ptr >= d->fastlimit)) {
if (UPB_LIKELY(ptr == d->limit)) {
*(uint32_t*)msg |= hasbits >> 16; /* Sync hasbits. */
return ptr;
}
//fprintf(stderr, "dispatch hit end\n");
return fastdecode_generic(UPB_PARSE_ARGS);
RETURN_GENERIC("dispatch hit end\n");
}
memcpy(&tag, ptr, 2);
idx = (tag & 0xf8) >> 3;
@ -166,8 +170,7 @@ static const char *fastdecode_varint(UPB_PARSE_PARAMS, int tagbytes,
uint64_t val = 0;
void *dst;
if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
//fprintf(stderr, "varint field tag mismatch\n");
return fastdecode_generic(UPB_PARSE_ARGS);;
RETURN_GENERIC("varint field tag mismatch\n");
}
dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, tagbytes, valbytes,
card);
@ -176,8 +179,7 @@ static const char *fastdecode_varint(UPB_PARSE_PARAMS, int tagbytes,
uint32_t byte = (uint8_t)ptr[tagbytes + 1];
val += (byte - 1) << 7;
if (UPB_UNLIKELY(byte & 0x80)) {
//fprintf(stderr, "varint field >2 bytes\n");
return fastdecode_generic(UPB_PARSE_ARGS);
RETURN_GENERIC("varint field >2 bytes\n");
}
ptr++;
}
@ -241,16 +243,14 @@ static const char *fastdecode_string(UPB_PARSE_PARAMS, int tagbytes,
upb_strview *dst;
int64_t len;
if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
//fprintf(stderr, "string field tag mismatch\n");
return fastdecode_generic(UPB_PARSE_ARGS);
RETURN_GENERIC("string field tag mismatch\n");
}
dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, tagbytes,
sizeof(upb_strview), card);
len = ptr[tagbytes];
if (UPB_UNLIKELY(len < 0)) {
//fprintf(stderr, "string field len >1 byte\n");
return fastdecode_generic(UPB_PARSE_ARGS);
RETURN_GENERIC("string field len >1 byte\n");
}
ptr += tagbytes + 1;
dst->data = ptr;
@ -292,8 +292,7 @@ static const char *fastdecode_submsg(UPB_PARSE_PARAMS, int tagbytes,
void *end;
if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
//fprintf(stderr, "submessage field tag mismatch\n");
return fastdecode_generic(UPB_PARSE_ARGS);
RETURN_GENERIC("submessage field tag mismatch\n");
}
submsg = fastdecode_getfield_ofs(d, ptr, msg, ofs, &data, &hasbits, &arr,
@ -302,8 +301,7 @@ static const char *fastdecode_submsg(UPB_PARSE_PARAMS, int tagbytes,
again:
if (card == CARD_r) {
if (UPB_UNLIKELY(submsg == end)) {
//fprintf(stderr, "need array realloc\n");
return fastdecode_generic(UPB_PARSE_ARGS);
RETURN_GENERIC("need array realloc\n");
}
}
@ -313,8 +311,7 @@ again:
uint32_t byte = (uint8_t)ptr[tagbytes + 1];
len += (byte - 1) << 7;
if (UPB_UNLIKELY(byte & 0x80)) {
//fprintf(stderr, "submessage field len >2 bytes\n");
return fastdecode_generic(UPB_PARSE_ARGS);
RETURN_GENERIC("submessage field len >2 bytes\n");
}
ptr++;
}

@ -733,7 +733,7 @@ void TryFillTableEntry(const protobuf::Descriptor* message,
type = "z8";
break;
case protobuf::FieldDescriptor::TYPE_STRING:
case protobuf::FieldDescriptor::TYPE_BYTES:
//case protobuf::FieldDescriptor::TYPE_BYTES:
type = "s";
wire_type = 2;
break;

Loading…
Cancel
Save