Reduce decoder memory usage.

The "field" entry was only being used to determine
whether we were inside a group, but the "end_offset"
member contains enough information to tell us that.
pull/13171/head
Joshua Haberman 15 years ago
parent c7a95061a7
commit fcfc37e7d4
  1. 2
      Makefile
  2. 12
      stream/upb_decoder.c

@ -54,7 +54,7 @@ OTHERSRC=src/upb_encoder.c src/upb_text.c
# Override the optimization level for upb_def.o, because it is not in the # Override the optimization level for upb_def.o, because it is not in the
# critical path but gets very large when -O3 is used. # critical path but gets very large when -O3 is used.
core/upb_def.o: core/upb_def.c core/upb_def.o: core/upb_def.c
$(CC) $(CFLAGS) $(CPPFLAGS) -O0 -c -o $@ $< $(CC) $(CFLAGS) $(CPPFLAGS) -Os -c -o $@ $<
core/upb_def.lo: core/upb_def.c core/upb_def.lo: core/upb_def.c
$(CC) $(CFLAGS) $(CPPFLAGS) -Os -c -o $@ $< -fPIC $(CC) $(CFLAGS) $(CPPFLAGS) -Os -c -o $@ $< -fPIC

@ -29,8 +29,7 @@ static int64_t upb_zzdec_64(uint64_t n) { return (n >> 1) ^ -(int64_t)(n & 1); }
// upb_decoder_frame is one frame of that stack. // upb_decoder_frame is one frame of that stack.
typedef struct { typedef struct {
upb_msgdef *msgdef; upb_msgdef *msgdef;
upb_fielddef *field; upb_strlen_t end_offset; // For groups, UPB_GROUP_END_OFFSET.
upb_strlen_t end_offset; // For groups, -1.
} upb_decoder_frame; } upb_decoder_frame;
struct upb_decoder { struct upb_decoder {
@ -57,9 +56,6 @@ struct upb_decoder {
// The overall stream offset of the beginning of "buf". // The overall stream offset of the beginning of "buf".
uint32_t buf_stream_offset; uint32_t buf_stream_offset;
// Fielddef for the key we just read.
upb_fielddef *field;
// Wire type of the key we just read. // Wire type of the key we just read.
upb_wire_type_t wire_type; upb_wire_type_t wire_type;
@ -68,6 +64,9 @@ struct upb_decoder {
upb_strlen_t packed_end_offset; upb_strlen_t packed_end_offset;
// Fielddef for the key we just read.
upb_fielddef *field;
// We keep a stack of messages we have recursed into. // We keep a stack of messages we have recursed into.
upb_decoder_frame *top, *limit, stack[UPB_MAX_NESTING]; upb_decoder_frame *top, *limit, stack[UPB_MAX_NESTING];
}; };
@ -455,7 +454,6 @@ bool upb_decoder_getstr(upb_decoder *d, upb_string *str) {
static bool upb_decoder_skipgroup(upb_decoder *d); static bool upb_decoder_skipgroup(upb_decoder *d);
bool upb_decoder_startmsg(upb_decoder *d) { bool upb_decoder_startmsg(upb_decoder *d) {
d->top->field = d->field;
if(++d->top >= d->limit) { if(++d->top >= d->limit) {
upb_seterr(&d->src.status, UPB_ERROR_MAX_NESTING_EXCEEDED, upb_seterr(&d->src.status, UPB_ERROR_MAX_NESTING_EXCEEDED,
"Nesting exceeded maximum (%d levels)\n", "Nesting exceeded maximum (%d levels)\n",
@ -476,7 +474,7 @@ bool upb_decoder_endmsg(upb_decoder *d) {
if(d->top > d->stack) { if(d->top > d->stack) {
--d->top; --d->top;
if(!d->src.eof) { if(!d->src.eof) {
if(d->top->field->type == UPB_TYPE(GROUP)) if(d->top->end_offset == UPB_GROUP_END_OFFSET)
upb_decoder_skipgroup(d); upb_decoder_skipgroup(d);
else else
upb_decoder_skipbytes(d, d->top->end_offset - upb_decoder_offset(d)); upb_decoder_skipbytes(d, d->top->end_offset - upb_decoder_offset(d));

Loading…
Cancel
Save