Tables are compressed, but perf goes down to 2.44GB/s.

pull/13171/head
Joshua Haberman 4 years ago
parent 91eb09b1bc
commit a6dc88556d
  1. 1
      BUILD
  2. 2129
      generated_for_cmake/google/protobuf/descriptor.upb.c
  3. 10
      upb/decode_fast.c
  4. 12
      upb/def.c
  5. 9
      upb/msg.h
  6. 26
      upbc/generator.cc

@ -42,6 +42,7 @@ COPTS = CPPOPTS + [
# copybara:strip_for_google3_begin
#"-pedantic",
#"-Werror=pedantic",
"-std=gnu11",
"-Wstrict-prototypes",
# copybara:strip_end
]

File diff suppressed because it is too large Load Diff

@ -28,9 +28,11 @@ const char *fastdecode_tag_dispatch(upb_decstate *d, const char *ptr, upb_msg *m
const upb_msglayout *table, uint64_t hasbits, uint32_t tag) {
uint64_t data;
size_t idx;
idx = (tag & 0xf8) >> 3;
data = table->field_data[idx] ^ tag;
return table->field_parser[idx](UPB_PARSE_ARGS);
idx = (tag & table->table_mask);
__builtin_assume((idx & 7) == 0);
idx >>= 3;
data = table->fasttable[idx].field_data ^ tag;
return table->fasttable[idx].field_parser(UPB_PARSE_ARGS);
}
UPB_FORCEINLINE
@ -40,7 +42,7 @@ uint32_t fastdecode_load_tag(const char* ptr) {
return tag;
}
UPB_FORCEINLINE
UPB_NOINLINE
const char *fastdecode_dispatch(upb_decstate *d, const char *ptr, upb_msg *msg,
const upb_msglayout *table, uint64_t hasbits) {
if (UPB_UNLIKELY(ptr >= d->fastlimit)) {

@ -940,9 +940,8 @@ static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) {
const upb_msglayout **submsgs;
upb_msglayout_field *fields;
upb_alloc *alloc = upb_arena_alloc(symtab->arena);
size_t i;
memset(l, 0, sizeof(*l));
memset(l, 0, sizeof(*l) + sizeof(_upb_fasttable_entry));
fields = upb_malloc(alloc, upb_msgdef_numfields(m) * sizeof(*fields));
submsgs = upb_malloc(alloc, submsg_count * sizeof(*submsgs));
@ -956,10 +955,10 @@ static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) {
l->field_count = upb_msgdef_numfields(m);
l->fields = fields;
l->submsgs = submsgs;
l->table_mask = 0;
for (i = 0; i < 32; i++) {
l->field_parser[i] = &fastdecode_generic;
}
l->fasttable[0].field_parser = &fastdecode_generic;
l->fasttable[0].field_data = 0;
if (upb_msgdef_mapentry(m)) {
/* TODO(haberman): refactor this method so this special case is more
@ -1722,7 +1721,8 @@ static bool create_msgdef(symtab_addctx *ctx, const char *prefix,
ctx->layouts++;
} else {
/* Allocate now (to allow cross-linking), populate later. */
m->layout = upb_malloc(ctx->alloc, sizeof(*m->layout));
m->layout = upb_malloc(ctx->alloc,
sizeof(*m->layout) + sizeof(_upb_fasttable_entry));
}
oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n);

@ -54,16 +54,21 @@ typedef const char *_upb_field_parser(struct upb_decstate *d, const char *ptr,
const struct upb_msglayout *table,
uint64_t hasbits, uint64_t data);
typedef struct {
_upb_field_parser *field_parser;
uint64_t field_data;
} _upb_fasttable_entry;
typedef struct upb_msglayout {
_upb_field_parser *field_parser[32];
uint64_t field_data[32];
const struct upb_msglayout *const* submsgs;
const upb_msglayout_field *fields;
uint32_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;
uint16_t field_count;
bool extendable;
_upb_fasttable_entry fasttable[];
} upb_msglayout;
/** upb_msg *******************************************************************/

@ -857,11 +857,19 @@ void TryFillTableEntry(const protobuf::Descriptor* message,
std::vector<TableEntry> FastDecodeTable(const protobuf::Descriptor* message,
const MessageLayout& layout) {
int table_size = 1;
for (int i = 0; i < message->field_count(); i++) {
int num = message->field(i)->number();
while (num >= table_size && num < 32) {
table_size *= 2;
}
}
std::vector<TableEntry> table;
MessageLayout::Size empty_size;
empty_size.size32 = 0;
empty_size.size64 = 0;
for (int i = 0; i < 32; i++) {
for (int i = 0; i < table_size; i++) {
table.emplace_back(TableEntry{"fastdecode_generic", empty_size});
TryFillTableEntry(message, layout, i, table.back());
}
@ -963,22 +971,18 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output) {
std::vector<TableEntry> table = FastDecodeTable(message, layout);
output("const upb_msglayout $0 = {\n", MessageInit(message));
output(" {\n");
for (const auto& ent : table) {
output(" &$0,\n", ent.first);
}
output(" },\n");
output(" {\n");
for (const auto& ent : table) {
output(" $0,\n", GetSizeInit(ent.second));
}
output(" },\n");
output(" $0,\n", submsgs_array_ref);
output(" $0,\n", fields_array_ref);
output(" $0,\n", (table.size() - 1) << 3);
output(" $0, $1, $2,\n", GetSizeInit(layout.message_size()),
field_number_order.size(),
"false" // TODO: extendable
);
output(" {\n");
for (const auto& ent : table) {
output(" {&$0, $1},\n", ent.first, GetSizeInit(ent.second));
}
output(" },\n");
output("};\n\n");
}

Loading…
Cancel
Save