Merge branch 'mini-table-1' into minitable-api

pull/13171/head
Joshua Haberman 3 years ago
commit c3a4f5b79e
  1. 4
      benchmarks/compare.py
  2. 73
      cmake/google/protobuf/descriptor.upb.c
  3. 10
      upb/decode.c
  4. 12
      upb/def.c
  5. 8
      upb/encode.c
  6. 153
      upb/mini_table.c
  7. 16
      upb/mini_table.h
  8. 99
      upb/mini_table.hpp
  9. 18
      upb/mini_table_test.cc
  10. 6
      upb/msg.c
  11. 27
      upb/msg_internal.h
  12. 25
      upb/upb.h
  13. 14
      upbc/protoc-gen-upb.cc

@ -81,8 +81,8 @@ def Benchmark(outbase, bench_cpu=True, runs=12, fasttable=False):
print("{} {} {} ns/op".format(*values), file=f)
Run("sort {} -o {} ".format(txt_filename, txt_filename))
Run("CC=clang bazel build -c opt --copt=-g --copt=-march=native tests:conformance_upb" + extra_args)
Run("cp -f bazel-bin/tests/conformance_upb {}.bin".format(outbase))
Run("CC=clang bazel build -c opt --copt=-g --copt=-march=native :conformance_upb" + extra_args)
Run("cp -f bazel-bin/conformance_upb {}.bin".format(outbase))
baseline = "main"

@ -23,7 +23,7 @@ static const upb_MiniTable_Field google_protobuf_FileDescriptorSet__fields[1] =
const upb_MiniTable google_protobuf_FileDescriptorSet_msginit = {
&google_protobuf_FileDescriptorSet_submsgs[0],
&google_protobuf_FileDescriptorSet__fields[0],
UPB_SIZE(8, 8), 1, upb_ExtMode_NonExtendable, 1, 255, 0,
UPB_SIZE(8, 8), 1, kUpb_ExtMode_NonExtendable, 1, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_FileDescriptorProto_submsgs[6] = {
@ -53,7 +53,7 @@ static const upb_MiniTable_Field google_protobuf_FileDescriptorProto__fields[12]
const upb_MiniTable google_protobuf_FileDescriptorProto_msginit = {
&google_protobuf_FileDescriptorProto_submsgs[0],
&google_protobuf_FileDescriptorProto__fields[0],
UPB_SIZE(64, 128), 12, upb_ExtMode_NonExtendable, 12, 255, 0,
UPB_SIZE(64, 128), 12, kUpb_ExtMode_NonExtendable, 12, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_DescriptorProto_submsgs[7] = {
@ -82,7 +82,7 @@ static const upb_MiniTable_Field google_protobuf_DescriptorProto__fields[10] = {
const upb_MiniTable google_protobuf_DescriptorProto_msginit = {
&google_protobuf_DescriptorProto_submsgs[0],
&google_protobuf_DescriptorProto__fields[0],
UPB_SIZE(48, 96), 10, upb_ExtMode_NonExtendable, 10, 255, 0,
UPB_SIZE(48, 96), 10, kUpb_ExtMode_NonExtendable, 10, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = {
@ -98,7 +98,7 @@ static const upb_MiniTable_Field google_protobuf_DescriptorProto_ExtensionRange_
const upb_MiniTable google_protobuf_DescriptorProto_ExtensionRange_msginit = {
&google_protobuf_DescriptorProto_ExtensionRange_submsgs[0],
&google_protobuf_DescriptorProto_ExtensionRange__fields[0],
UPB_SIZE(16, 24), 3, upb_ExtMode_NonExtendable, 3, 255, 0,
UPB_SIZE(16, 24), 3, kUpb_ExtMode_NonExtendable, 3, 255, 0,
};
static const upb_MiniTable_Field google_protobuf_DescriptorProto_ReservedRange__fields[2] = {
@ -109,7 +109,7 @@ static const upb_MiniTable_Field google_protobuf_DescriptorProto_ReservedRange__
const upb_MiniTable google_protobuf_DescriptorProto_ReservedRange_msginit = {
NULL,
&google_protobuf_DescriptorProto_ReservedRange__fields[0],
UPB_SIZE(16, 16), 2, upb_ExtMode_NonExtendable, 2, 255, 0,
UPB_SIZE(16, 16), 2, kUpb_ExtMode_NonExtendable, 2, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_ExtensionRangeOptions_submsgs[1] = {
@ -123,7 +123,7 @@ static const upb_MiniTable_Field google_protobuf_ExtensionRangeOptions__fields[1
const upb_MiniTable google_protobuf_ExtensionRangeOptions_msginit = {
&google_protobuf_ExtensionRangeOptions_submsgs[0],
&google_protobuf_ExtensionRangeOptions__fields[0],
UPB_SIZE(8, 8), 1, upb_ExtMode_Extendable, 0, 255, 0,
UPB_SIZE(8, 8), 1, kUpb_ExtMode_Extendable, 0, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_FieldDescriptorProto_submsgs[3] = {
@ -149,7 +149,7 @@ static const upb_MiniTable_Field google_protobuf_FieldDescriptorProto__fields[11
const upb_MiniTable google_protobuf_FieldDescriptorProto_msginit = {
&google_protobuf_FieldDescriptorProto_submsgs[0],
&google_protobuf_FieldDescriptorProto__fields[0],
UPB_SIZE(72, 112), 11, upb_ExtMode_NonExtendable, 10, 255, 0,
UPB_SIZE(72, 112), 11, kUpb_ExtMode_NonExtendable, 10, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_OneofDescriptorProto_submsgs[1] = {
@ -164,7 +164,7 @@ static const upb_MiniTable_Field google_protobuf_OneofDescriptorProto__fields[2]
const upb_MiniTable google_protobuf_OneofDescriptorProto_msginit = {
&google_protobuf_OneofDescriptorProto_submsgs[0],
&google_protobuf_OneofDescriptorProto__fields[0],
UPB_SIZE(16, 32), 2, upb_ExtMode_NonExtendable, 2, 255, 0,
UPB_SIZE(16, 32), 2, kUpb_ExtMode_NonExtendable, 2, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_EnumDescriptorProto_submsgs[3] = {
@ -184,7 +184,11 @@ static const upb_MiniTable_Field google_protobuf_EnumDescriptorProto__fields[5]
const upb_MiniTable google_protobuf_EnumDescriptorProto_msginit = {
&google_protobuf_EnumDescriptorProto_submsgs[0],
&google_protobuf_EnumDescriptorProto__fields[0],
<<<<<<< HEAD
UPB_SIZE(32, 56), 5, upb_ExtMode_NonExtendable, 5, 255, 0,
=======
UPB_SIZE(32, 64), 5, kUpb_ExtMode_NonExtendable, 5, 255, 0,
>>>>>>> mini-table-1
};
static const upb_MiniTable_Field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = {
@ -195,7 +199,7 @@ static const upb_MiniTable_Field google_protobuf_EnumDescriptorProto_EnumReserve
const upb_MiniTable google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = {
NULL,
&google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0],
UPB_SIZE(16, 16), 2, upb_ExtMode_NonExtendable, 2, 255, 0,
UPB_SIZE(16, 16), 2, kUpb_ExtMode_NonExtendable, 2, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_EnumValueDescriptorProto_submsgs[1] = {
@ -211,7 +215,7 @@ static const upb_MiniTable_Field google_protobuf_EnumValueDescriptorProto__field
const upb_MiniTable google_protobuf_EnumValueDescriptorProto_msginit = {
&google_protobuf_EnumValueDescriptorProto_submsgs[0],
&google_protobuf_EnumValueDescriptorProto__fields[0],
UPB_SIZE(24, 32), 3, upb_ExtMode_NonExtendable, 3, 255, 0,
UPB_SIZE(24, 32), 3, kUpb_ExtMode_NonExtendable, 3, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_ServiceDescriptorProto_submsgs[2] = {
@ -228,7 +232,11 @@ static const upb_MiniTable_Field google_protobuf_ServiceDescriptorProto__fields[
const upb_MiniTable google_protobuf_ServiceDescriptorProto_msginit = {
&google_protobuf_ServiceDescriptorProto_submsgs[0],
&google_protobuf_ServiceDescriptorProto__fields[0],
<<<<<<< HEAD
UPB_SIZE(24, 40), 3, upb_ExtMode_NonExtendable, 3, 255, 0,
=======
UPB_SIZE(24, 48), 3, kUpb_ExtMode_NonExtendable, 3, 255, 0,
>>>>>>> mini-table-1
};
static const upb_MiniTable_Sub google_protobuf_MethodDescriptorProto_submsgs[1] = {
@ -247,7 +255,7 @@ static const upb_MiniTable_Field google_protobuf_MethodDescriptorProto__fields[6
const upb_MiniTable google_protobuf_MethodDescriptorProto_msginit = {
&google_protobuf_MethodDescriptorProto_submsgs[0],
&google_protobuf_MethodDescriptorProto__fields[0],
UPB_SIZE(32, 64), 6, upb_ExtMode_NonExtendable, 6, 255, 0,
UPB_SIZE(32, 64), 6, kUpb_ExtMode_NonExtendable, 6, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_FileOptions_submsgs[2] = {
@ -282,7 +290,7 @@ static const upb_MiniTable_Field google_protobuf_FileOptions__fields[21] = {
const upb_MiniTable google_protobuf_FileOptions_msginit = {
&google_protobuf_FileOptions_submsgs[0],
&google_protobuf_FileOptions__fields[0],
UPB_SIZE(104, 192), 21, upb_ExtMode_Extendable, 1, 255, 0,
UPB_SIZE(104, 192), 21, kUpb_ExtMode_Extendable, 1, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_MessageOptions_submsgs[1] = {
@ -300,7 +308,7 @@ static const upb_MiniTable_Field google_protobuf_MessageOptions__fields[5] = {
const upb_MiniTable google_protobuf_MessageOptions_msginit = {
&google_protobuf_MessageOptions_submsgs[0],
&google_protobuf_MessageOptions__fields[0],
UPB_SIZE(16, 16), 5, upb_ExtMode_Extendable, 3, 255, 0,
UPB_SIZE(16, 16), 5, kUpb_ExtMode_Extendable, 3, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_FieldOptions_submsgs[3] = {
@ -323,7 +331,7 @@ static const upb_MiniTable_Field google_protobuf_FieldOptions__fields[8] = {
const upb_MiniTable google_protobuf_FieldOptions_msginit = {
&google_protobuf_FieldOptions_submsgs[0],
&google_protobuf_FieldOptions__fields[0],
UPB_SIZE(24, 32), 8, upb_ExtMode_Extendable, 3, 255, 0,
UPB_SIZE(24, 32), 8, kUpb_ExtMode_Extendable, 3, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_OneofOptions_submsgs[1] = {
@ -337,7 +345,7 @@ static const upb_MiniTable_Field google_protobuf_OneofOptions__fields[1] = {
const upb_MiniTable google_protobuf_OneofOptions_msginit = {
&google_protobuf_OneofOptions_submsgs[0],
&google_protobuf_OneofOptions__fields[0],
UPB_SIZE(8, 8), 1, upb_ExtMode_Extendable, 0, 255, 0,
UPB_SIZE(8, 8), 1, kUpb_ExtMode_Extendable, 0, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_EnumOptions_submsgs[1] = {
@ -353,7 +361,7 @@ static const upb_MiniTable_Field google_protobuf_EnumOptions__fields[3] = {
const upb_MiniTable google_protobuf_EnumOptions_msginit = {
&google_protobuf_EnumOptions_submsgs[0],
&google_protobuf_EnumOptions__fields[0],
UPB_SIZE(8, 16), 3, upb_ExtMode_Extendable, 0, 255, 0,
UPB_SIZE(8, 16), 3, kUpb_ExtMode_Extendable, 0, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_EnumValueOptions_submsgs[1] = {
@ -368,7 +376,7 @@ static const upb_MiniTable_Field google_protobuf_EnumValueOptions__fields[2] = {
const upb_MiniTable google_protobuf_EnumValueOptions_msginit = {
&google_protobuf_EnumValueOptions_submsgs[0],
&google_protobuf_EnumValueOptions__fields[0],
UPB_SIZE(8, 16), 2, upb_ExtMode_Extendable, 1, 255, 0,
UPB_SIZE(8, 16), 2, kUpb_ExtMode_Extendable, 1, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_ServiceOptions_submsgs[1] = {
@ -383,7 +391,7 @@ static const upb_MiniTable_Field google_protobuf_ServiceOptions__fields[2] = {
const upb_MiniTable google_protobuf_ServiceOptions_msginit = {
&google_protobuf_ServiceOptions_submsgs[0],
&google_protobuf_ServiceOptions__fields[0],
UPB_SIZE(8, 16), 2, upb_ExtMode_Extendable, 0, 255, 0,
UPB_SIZE(8, 16), 2, kUpb_ExtMode_Extendable, 0, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_MethodOptions_submsgs[2] = {
@ -400,7 +408,7 @@ static const upb_MiniTable_Field google_protobuf_MethodOptions__fields[3] = {
const upb_MiniTable google_protobuf_MethodOptions_msginit = {
&google_protobuf_MethodOptions_submsgs[0],
&google_protobuf_MethodOptions__fields[0],
UPB_SIZE(16, 24), 3, upb_ExtMode_Extendable, 0, 255, 0,
UPB_SIZE(16, 24), 3, kUpb_ExtMode_Extendable, 0, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_UninterpretedOption_submsgs[1] = {
@ -420,7 +428,11 @@ static const upb_MiniTable_Field google_protobuf_UninterpretedOption__fields[7]
const upb_MiniTable google_protobuf_UninterpretedOption_msginit = {
&google_protobuf_UninterpretedOption_submsgs[0],
&google_protobuf_UninterpretedOption__fields[0],
<<<<<<< HEAD
UPB_SIZE(64, 88), 7, upb_ExtMode_NonExtendable, 0, 255, 0,
=======
UPB_SIZE(64, 96), 7, kUpb_ExtMode_NonExtendable, 0, 255, 0,
>>>>>>> mini-table-1
};
static const upb_MiniTable_Field google_protobuf_UninterpretedOption_NamePart__fields[2] = {
@ -431,7 +443,11 @@ static const upb_MiniTable_Field google_protobuf_UninterpretedOption_NamePart__f
const upb_MiniTable google_protobuf_UninterpretedOption_NamePart_msginit = {
NULL,
&google_protobuf_UninterpretedOption_NamePart__fields[0],
<<<<<<< HEAD
UPB_SIZE(16, 24), 2, upb_ExtMode_NonExtendable, 2, 255, 2,
=======
UPB_SIZE(16, 32), 2, kUpb_ExtMode_NonExtendable, 2, 255, 2,
>>>>>>> mini-table-1
};
static const upb_MiniTable_Sub google_protobuf_SourceCodeInfo_submsgs[1] = {
@ -445,12 +461,17 @@ static const upb_MiniTable_Field google_protobuf_SourceCodeInfo__fields[1] = {
const upb_MiniTable google_protobuf_SourceCodeInfo_msginit = {
&google_protobuf_SourceCodeInfo_submsgs[0],
&google_protobuf_SourceCodeInfo__fields[0],
UPB_SIZE(8, 8), 1, upb_ExtMode_NonExtendable, 1, 255, 0,
UPB_SIZE(8, 8), 1, kUpb_ExtMode_NonExtendable, 1, 255, 0,
};
static const upb_MiniTable_Field google_protobuf_SourceCodeInfo_Location__fields[5] = {
<<<<<<< HEAD
{1, UPB_SIZE(20, 40), 0, 0, 5, kUpb_FieldMode_Array | upb_LabelFlags_IsPacked | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
{2, UPB_SIZE(24, 48), 0, 0, 5, kUpb_FieldMode_Array | upb_LabelFlags_IsPacked | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
=======
{1, UPB_SIZE(20, 40), 0, 0, 5, kUpb_FieldMode_Array | kUpb_LabelFlags_IsPacked | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
{2, UPB_SIZE(24, 48), 0, 0, 5, kUpb_FieldMode_Array | kUpb_LabelFlags_IsPacked | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
>>>>>>> mini-table-1
{3, UPB_SIZE(4, 8), 1, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{4, UPB_SIZE(12, 24), 2, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{6, UPB_SIZE(28, 56), 0, 0, 12, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
@ -459,7 +480,7 @@ static const upb_MiniTable_Field google_protobuf_SourceCodeInfo_Location__fields
const upb_MiniTable google_protobuf_SourceCodeInfo_Location_msginit = {
NULL,
&google_protobuf_SourceCodeInfo_Location__fields[0],
UPB_SIZE(32, 64), 5, upb_ExtMode_NonExtendable, 4, 255, 0,
UPB_SIZE(32, 64), 5, kUpb_ExtMode_NonExtendable, 4, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_GeneratedCodeInfo_submsgs[1] = {
@ -473,11 +494,15 @@ static const upb_MiniTable_Field google_protobuf_GeneratedCodeInfo__fields[1] =
const upb_MiniTable google_protobuf_GeneratedCodeInfo_msginit = {
&google_protobuf_GeneratedCodeInfo_submsgs[0],
&google_protobuf_GeneratedCodeInfo__fields[0],
UPB_SIZE(8, 8), 1, upb_ExtMode_NonExtendable, 1, 255, 0,
UPB_SIZE(8, 8), 1, kUpb_ExtMode_NonExtendable, 1, 255, 0,
};
static const upb_MiniTable_Field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = {
<<<<<<< HEAD
{1, UPB_SIZE(20, 32), 0, 0, 5, kUpb_FieldMode_Array | upb_LabelFlags_IsPacked | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
=======
{1, UPB_SIZE(20, 32), 0, 0, 5, kUpb_FieldMode_Array | kUpb_LabelFlags_IsPacked | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
>>>>>>> mini-table-1
{2, UPB_SIZE(12, 16), 1, 0, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{3, UPB_SIZE(4, 4), 2, 0, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{4, UPB_SIZE(8, 8), 3, 0, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
@ -486,7 +511,11 @@ static const upb_MiniTable_Field google_protobuf_GeneratedCodeInfo_Annotation__f
const upb_MiniTable google_protobuf_GeneratedCodeInfo_Annotation_msginit = {
NULL,
&google_protobuf_GeneratedCodeInfo_Annotation__fields[0],
<<<<<<< HEAD
UPB_SIZE(24, 40), 4, upb_ExtMode_NonExtendable, 4, 255, 0,
=======
UPB_SIZE(24, 48), 4, kUpb_ExtMode_NonExtendable, 4, 255, 0,
>>>>>>> mini-table-1
};
static const upb_MiniTable *messages_layout[27] = {

@ -742,7 +742,7 @@ static const char* decode_msgset(upb_Decoder* d, const char* ptr,
.fields = NULL,
.size = 0,
.field_count = 0,
.ext = upb_ExtMode_IsMessageSet_ITEM,
.ext = kUpb_ExtMode_IsMessageSet_ITEM,
.dense_below = 0,
.table_mask = -1};
return decode_group(d, ptr, msg, &item_layout, 1);
@ -780,19 +780,19 @@ static const upb_MiniTable_Field* decode_findfield(upb_Decoder* d,
if (d->extreg) {
switch (l->ext) {
case upb_ExtMode_Extendable: {
case kUpb_ExtMode_Extendable: {
const upb_MiniTable_Extension* ext =
_upb_extreg_get(d->extreg, l, field_number);
if (ext) return &ext->field;
break;
}
case upb_ExtMode_IsMessageSet:
case kUpb_ExtMode_IsMessageSet:
if (field_number == _UPB_MSGSET_ITEM) {
static upb_MiniTable_Field item = {0, 0, 0, 0, TYPE_MSGSET_ITEM, 0};
return &item;
}
break;
case upb_ExtMode_IsMessageSet_ITEM:
case kUpb_ExtMode_IsMessageSet_ITEM:
switch (field_number) {
case _UPB_MSGSET_TYPEID: {
static upb_MiniTable_Field type_id = {
@ -885,7 +885,7 @@ static const char* decode_known(upb_Decoder* d, const char* ptr,
const upb_MiniTable_Sub* subs = layout->subs;
uint8_t mode = field->mode;
if (UPB_UNLIKELY(mode & upb_LabelFlags_IsExtension)) {
if (UPB_UNLIKELY(mode & kUpb_LabelFlags_IsExtension)) {
const upb_MiniTable_Extension* ext_layout =
(const upb_MiniTable_Extension*)field;
upb_Message_Extension* ext =

@ -1433,7 +1433,7 @@ static void fill_fieldlayout(upb_MiniTable_Field* field,
} else {
/* Maps descriptor type -> elem_size_lg2. */
static const uint8_t sizes[] = {
-1, /* invalid descriptor type */
-1, /* invalid descriptor type */
kUpb_FieldRep_8Byte, /* DOUBLE */
kUpb_FieldRep_4Byte, /* FLOAT */
kUpb_FieldRep_8Byte, /* INT64 */
@ -1458,11 +1458,11 @@ static void fill_fieldlayout(upb_MiniTable_Field* field,
}
if (upb_FieldDef_IsPacked(f)) {
field->mode |= upb_LabelFlags_IsPacked;
field->mode |= kUpb_LabelFlags_IsPacked;
}
if (upb_FieldDef_IsExtension(f)) {
field->mode |= upb_LabelFlags_IsExtension;
field->mode |= kUpb_LabelFlags_IsExtension;
}
}
@ -1500,12 +1500,12 @@ static void make_layout(symtab_addctx* ctx, const upb_MessageDef* m) {
if (upb_MessageDef_ExtensionRangeCount(m) > 0) {
if (google_protobuf_MessageOptions_message_set_wire_format(m->opts)) {
l->ext = upb_ExtMode_IsMessageSet;
l->ext = kUpb_ExtMode_IsMessageSet;
} else {
l->ext = upb_ExtMode_Extendable;
l->ext = kUpb_ExtMode_Extendable;
}
} else {
l->ext = upb_ExtMode_NonExtendable;
l->ext = kUpb_ExtMode_NonExtendable;
}
/* TODO(haberman): initialize fast tables so that reflection-based parsing

@ -288,7 +288,7 @@ static void encode_array(upb_encstate* e, const upb_Message* msg,
const upb_MiniTable_Sub* subs,
const upb_MiniTable_Field* f) {
const upb_Array* arr = *UPB_PTR_AT(msg, f->offset, upb_Array*);
bool packed = f->mode & upb_LabelFlags_IsPacked;
bool packed = f->mode & kUpb_LabelFlags_IsPacked;
size_t pre_len = e->limit - e->ptr;
if (arr == NULL || arr->len == 0) {
@ -449,7 +449,7 @@ static bool encode_shouldencode(upb_encstate* e, const upb_Message* msg,
return ch != 0;
}
#if UINTPTR_MAX == 0xffffffff
case upb_FieldRep_Pointer:
case kUpb_FieldRep_Pointer:
#endif
case kUpb_FieldRep_4Byte: {
uint32_t u32;
@ -538,7 +538,7 @@ static void encode_message(upb_encstate* e, const upb_Message* msg,
}
}
if (m->ext != upb_ExtMode_NonExtendable) {
if (m->ext != kUpb_ExtMode_NonExtendable) {
/* Encode all extensions together. Unlike C++, we do not attempt to keep
* these in field number order relative to normal fields or even to each
* other. */
@ -547,7 +547,7 @@ static void encode_message(upb_encstate* e, const upb_Message* msg,
if (ext_count) {
const upb_Message_Extension* end = ext + ext_count;
for (; ext != end; ext++) {
if (UPB_UNLIKELY(m->ext == upb_ExtMode_IsMessageSet)) {
if (UPB_UNLIKELY(m->ext == kUpb_ExtMode_IsMessageSet)) {
encode_msgset_item(e, ext);
} else {
encode_field(e, &ext->data, &ext->ext->sub, &ext->ext->field);

@ -60,11 +60,11 @@ typedef enum {
} upb_EncodedType;
typedef enum {
kUpb_EncodedFieldModifier_IsUnpacked = 1,
kUpb_EncodedFieldModifier_JspbString = 2,
kUpb_EncodedFieldModifier_IsUnpacked = 1 << 0,
kUpb_EncodedFieldModifier_JspbString = 1 << 1,
// upb only.
kUpb_EncodedFieldModifier_IsProto3Singular = 4,
kUpb_EncodedFieldModifier_IsRequired = 8,
kUpb_EncodedFieldModifier_IsProto3Singular = 1 << 2,
kUpb_EncodedFieldModifier_IsRequired = 1 << 3,
} upb_EncodedFieldModifier;
enum {
@ -77,6 +77,8 @@ enum {
kUpb_EncodedValue_MaxSkip = '~',
kUpb_EncodedValue_OneofSeparator = '~',
kUpb_EncodedValue_FieldSeparator = '|',
kUpb_EncodedValue_MinOneofField = ' ',
kUpb_EncodedValue_MaxOneofField = 'b',
};
char upb_ToBase92(int8_t ch) {
@ -90,7 +92,7 @@ char upb_ToBase92(int8_t ch) {
'w', 'x', 'y', 'z', '{', '|', '}', '~',
};
assert(0 <= ch && ch < 92);
UPB_ASSERT(0 <= ch && ch < 92);
return kUpb_ToBase92[ch];
}
@ -139,6 +141,7 @@ static char* upb_MtDataEncoder_Put(upb_MtDataEncoder* e, char* ptr, char ch) {
static char* upb_MtDataEncoder_PutBase92Varint(upb_MtDataEncoder* e, char* ptr,
uint32_t val, int min, int max) {
int shift = _upb_Log2Ceiling(upb_FromBase92(max) - upb_FromBase92(min) + 1);
UPB_ASSERT(shift <= 6);
uint32_t mask = (1 << shift) - 1;
do {
uint32_t bits = val & mask;
@ -186,7 +189,7 @@ char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr,
if (field_num <= in->last_field_num) return NULL;
if (in->last_field_num + 1 != field_num) {
// Put skip.
assert(field_num > in->last_field_num);
UPB_ASSERT(field_num > in->last_field_num);
uint32_t skip = field_num - in->last_field_num;
ptr = upb_MtDataEncoder_PutBase92Varint(
e, ptr, skip, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip);
@ -197,6 +200,8 @@ char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr,
// Put field type.
int encoded_type = kUpb_TypeToEncoded[type];
if (modifiers & kUpb_FieldModifier_IsRepeated) {
// Repeated fields shift the type number up (unlike other modifiers which
// are bit flags).
encoded_type += kUpb_EncodedType_RepeatedBase;
}
ptr = upb_MtDataEncoder_Put(e, ptr, encoded_type);
@ -260,10 +265,13 @@ const upb_MiniTable_Field* upb_MiniTable_FindFieldByNumber(
/** Data decoder **************************************************************/
// Note: we sort by this number when calculating layout order.
typedef enum {
kUpb_LayoutItemType_Field, // Non-oneof field data.
kUpb_LayoutItemType_OneofField, // Oneof field data.
kUpb_LayoutItemType_OneofCase, // Oneof case.
kUpb_LayoutItemType_OneofField, // Oneof field data.
kUpb_LayoutItemType_Field, // Non-oneof field data.
kUpb_LayoutItemType_Max = kUpb_LayoutItemType_Field,
} upb_LayoutItemType;
#define kUpb_LayoutItem_IndexSentinel ((uint16_t)-1)
@ -272,11 +280,9 @@ typedef struct {
// Index of the corresponding field. When this is a oneof field, the field's
// offset will be the index of the next field in a linked list.
uint16_t field_index;
uint16_t offset;
upb_FieldRep rep;
upb_LayoutItemType type;
// Used for temporary storage while assigning offsets (internal only).
uint16_t offset;
} upb_LayoutItem;
typedef struct {
@ -329,16 +335,19 @@ static const char* upb_MiniTable_DecodeBase92Varint(upb_MtDecoder* d,
uint32_t* out_val) {
uint32_t val = 0;
uint32_t shift = 0;
const int bits_per_char =
_upb_Log2Ceiling(upb_FromBase92(max) - upb_FromBase92(min));
char ch = first_ch;
while (1) {
uint32_t bits = upb_FromBase92(ch) - upb_FromBase92(min);
UPB_ASSERT(shift < 32 - bits_per_char);
val |= bits << shift;
if (ptr == d->end || *ptr < min || max < *ptr) {
*out_val = val;
return ptr;
}
ch = *ptr++;
shift += _upb_Log2Ceiling(upb_FromBase92(max) - upb_FromBase92(min));
shift += bits_per_char;
}
}
@ -418,9 +427,9 @@ static void upb_MiniTable_SetField(upb_MtDecoder* d, uint8_t ch,
static void upb_MtDecoder_ModifyField(upb_MtDecoder* d, uint32_t mod,
upb_MiniTable_Field* field) {
if (mod & kUpb_EncodedFieldModifier_IsUnpacked) {
field->mode &= ~upb_LabelFlags_IsPacked;
field->mode &= ~kUpb_LabelFlags_IsPacked;
} else {
field->mode |= upb_LabelFlags_IsPacked;
field->mode |= kUpb_LabelFlags_IsPacked;
}
bool singular = mod & kUpb_EncodedFieldModifier_IsProto3Singular;
@ -475,8 +484,9 @@ static const char* upb_MtDecoder_DecodeOneofField(upb_MtDecoder* d,
char first_ch,
upb_LayoutItem* item) {
uint32_t field_num;
ptr = upb_MiniTable_DecodeBase92Varint(d, ptr, first_ch, upb_ToBase92(0),
upb_ToBase92(63), &field_num);
ptr = upb_MiniTable_DecodeBase92Varint(
d, ptr, first_ch, kUpb_EncodedValue_MinOneofField,
kUpb_EncodedValue_MaxOneofField, &field_num);
upb_MiniTable_Field* f =
(void*)upb_MiniTable_FindFieldByNumber(d->table, field_num);
@ -561,7 +571,7 @@ static void upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, size_t len,
uint32_t last_field_number = 0;
bool need_dense_below = d->table != NULL;
d->end = ptr + len;
d->end = UPB_PTRADD(ptr, len);
while (ptr < d->end) {
char ch = *ptr++;
@ -573,7 +583,8 @@ static void upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, size_t len,
upb_MiniTable_SetField(d, ch, field, msg_modifiers, sub_count);
} else if (kUpb_EncodedValue_MinModifier <= ch &&
ch <= kUpb_EncodedValue_MaxModifier) {
ptr = upb_MtDecoder_ParseModifier(d, ptr, ch, *field_count, &msg_modifiers);
ptr =
upb_MtDecoder_ParseModifier(d, ptr, ch, *field_count, &msg_modifiers);
} else if (ch == kUpb_EncodedValue_End) {
if (!d->table) {
upb_MtDecoder_ErrorFormat(d, "Extensions cannot have oneofs.");
@ -613,30 +624,34 @@ static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data,
upb_MtDecoder_Parse(d, data, len, d->fields, sizeof(*d->fields),
&d->table->field_count, &sub_count);
// Return unused memory from fields array.
assert(d->table->field_count <= len);
d->fields = upb_Arena_Realloc(d->arena, d->fields, sizeof(*d->fields) * len,
sizeof(*d->fields) * d->table->field_count);
upb_Arena_ShrinkLast(d->arena, d->fields, sizeof(*d->fields) * len,
sizeof(*d->fields) * d->table->field_count);
d->table->fields = d->fields;
upb_MtDecoder_AllocateSubs(d, sub_count);
}
#define UPB_COMPARE_INTEGERS(a, b) ((a) < (b) ? -1 : ((a) == (b) ? 0 : 1))
#define UPB_COMBINE(rep, ty, idx) (((rep << type_bits) | ty) << idx_bits) | idx
int upb_MtDecoder_CompareFields(const void* _a, const void* _b) {
const upb_LayoutItem* a = _a;
const upb_LayoutItem* b = _b;
// Currently we just sort by:
// 1. rep (descending, so largest fields are first)
// 2. is_case (descending, so oneof cases are first)
// 2. field_number (ascending, so smallest numbers are first)
//
// 1. rep (smallest fields first)
// 2. type (oneof cases first)
// 2. field_number (smallest numbers first)
// The main goal of this is to reduce space lost to padding.
if (a->rep != b->rep) return UPB_COMPARE_INTEGERS(a->rep, b->rep);
if (a->type != b->type) return UPB_COMPARE_INTEGERS(a->type, b->type);
return UPB_COMPARE_INTEGERS(b->field_index, a->field_index);
// Later we may have more subtle reasons to prefer a different ordering.
const int rep_bits = _upb_Log2Ceiling(kUpb_FieldRep_Max);
const int type_bits = _upb_Log2Ceiling(kUpb_LayoutItemType_Max);
const int idx_bits = (sizeof(a->field_index) * 8);
UPB_ASSERT(idx_bits + rep_bits + type_bits < 32);
uint32_t a_packed = UPB_COMBINE(a->rep, a->type, a->field_index);
uint32_t b_packed = UPB_COMBINE(b->rep, b->type, b->field_index);
return UPB_COMPARE_INTEGERS(a_packed, b_packed);
}
#undef UPB_COMBINE
#undef UPB_COMPARE_INTEGERS
static bool upb_MtDecoder_SortLayoutItems(upb_MtDecoder* d) {
@ -646,12 +661,15 @@ static bool upb_MtDecoder_SortLayoutItems(upb_MtDecoder* d) {
upb_MiniTable_Field* f = &d->fields[i];
if (f->offset >= kOneofBase) continue;
upb_LayoutItem item = {.field_index = i,
.rep = f->mode >> kUpb_FieldRep_Shift};
.rep = f->mode >> kUpb_FieldRep_Shift,
.type = kUpb_LayoutItemType_Field};
upb_MtDecoder_PushItem(d, item);
}
qsort(d->vec.data, d->vec.size, sizeof(*d->vec.data),
upb_MtDecoder_CompareFields);
if (d->vec.size) {
qsort(d->vec.data, d->vec.size, sizeof(*d->vec.data),
upb_MtDecoder_CompareFields);
}
return true;
}
@ -684,44 +702,38 @@ static void upb_MtDecoder_AssignHasbits(upb_MiniTable* ret) {
ret->size = upb_MiniTable_DivideRoundUp(last_hasbit, 8);
}
size_t upb_MtDecoder_SizeOfRep(upb_FieldRep rep, upb_MiniTablePlatform platform) {
size_t upb_MtDecoder_SizeOfRep(upb_FieldRep rep,
upb_MiniTablePlatform platform) {
static const uint8_t kRepToSize32[] = {
[kUpb_FieldRep_1Byte] = 1,
[kUpb_FieldRep_4Byte] = 4,
[kUpb_FieldRep_Pointer] = 4,
[kUpb_FieldRep_StringView] = 8,
[kUpb_FieldRep_1Byte] = 1, [kUpb_FieldRep_4Byte] = 4,
[kUpb_FieldRep_Pointer] = 4, [kUpb_FieldRep_StringView] = 8,
[kUpb_FieldRep_8Byte] = 8,
};
static const uint8_t kRepToSize64[] = {
[kUpb_FieldRep_1Byte] = 1,
[kUpb_FieldRep_4Byte] = 4,
[kUpb_FieldRep_Pointer] = 8,
[kUpb_FieldRep_StringView] = 16,
[kUpb_FieldRep_1Byte] = 1, [kUpb_FieldRep_4Byte] = 4,
[kUpb_FieldRep_Pointer] = 8, [kUpb_FieldRep_StringView] = 16,
[kUpb_FieldRep_8Byte] = 8,
};
assert(sizeof(upb_StringView) ==
UPB_SIZE(kRepToSize32, kRepToSize64)[kUpb_FieldRep_StringView]);
UPB_ASSERT(sizeof(upb_StringView) ==
UPB_SIZE(kRepToSize32, kRepToSize64)[kUpb_FieldRep_StringView]);
return platform == kUpb_MiniTablePlatform_32Bit ? kRepToSize32[rep]
: kRepToSize64[rep];
}
size_t upb_MtDecoder_AlignOfRep(upb_FieldRep rep, upb_MiniTablePlatform platform) {
size_t upb_MtDecoder_AlignOfRep(upb_FieldRep rep,
upb_MiniTablePlatform platform) {
static const uint8_t kRepToAlign32[] = {
[kUpb_FieldRep_1Byte] = 1,
[kUpb_FieldRep_4Byte] = 4,
[kUpb_FieldRep_Pointer] = 4,
[kUpb_FieldRep_StringView] = 4,
[kUpb_FieldRep_1Byte] = 1, [kUpb_FieldRep_4Byte] = 4,
[kUpb_FieldRep_Pointer] = 4, [kUpb_FieldRep_StringView] = 4,
[kUpb_FieldRep_8Byte] = 8,
};
static const uint8_t kRepToAlign64[] = {
[kUpb_FieldRep_1Byte] = 1,
[kUpb_FieldRep_4Byte] = 4,
[kUpb_FieldRep_Pointer] = 8,
[kUpb_FieldRep_StringView] = 8,
[kUpb_FieldRep_1Byte] = 1, [kUpb_FieldRep_4Byte] = 4,
[kUpb_FieldRep_Pointer] = 8, [kUpb_FieldRep_StringView] = 8,
[kUpb_FieldRep_8Byte] = 8,
};
assert(UPB_ALIGN_OF(upb_StringView) ==
UPB_SIZE(kRepToAlign32, kRepToAlign64)[kUpb_FieldRep_StringView]);
UPB_ASSERT(UPB_ALIGN_OF(upb_StringView) ==
UPB_SIZE(kRepToAlign32, kRepToAlign64)[kUpb_FieldRep_StringView]);
return platform == kUpb_MiniTablePlatform_32Bit ? kRepToAlign32[rep]
: kRepToAlign64[rep];
}
@ -735,7 +747,7 @@ size_t upb_MtDecoder_Place(upb_MtDecoder* d, upb_FieldRep rep) {
}
static bool upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) {
upb_LayoutItem* end = d->vec.data + d->vec.size;
upb_LayoutItem* end = UPB_PTRADD(d->vec.data, d->vec.size);
// Compute offsets.
for (upb_LayoutItem* item = d->vec.data; item < end; item++) {
@ -750,6 +762,7 @@ static bool upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) {
while (true) {
f->presence = ~item->offset;
if (f->offset == kUpb_LayoutItem_IndexSentinel) break;
UPB_ASSERT(f->offset - kOneofBase < d->table->field_count);
f = &d->fields[f->offset - kOneofBase];
}
}
@ -779,7 +792,8 @@ static bool upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) {
upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len,
upb_MiniTablePlatform platform,
upb_Arena* arena, void** buf,
size_t* buf_size, upb_Status* status) {
size_t* buf_size,
upb_Status* status) {
upb_MtDecoder decoder = {
.platform = platform,
.vec =
@ -802,7 +816,7 @@ upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len,
decoder.table->size = 0;
decoder.table->field_count = 0;
decoder.table->ext = upb_ExtMode_NonExtendable;
decoder.table->ext = kUpb_ExtMode_NonExtendable;
decoder.table->dense_below = 0;
decoder.table->table_mask = 0;
decoder.table->required_count = 0;
@ -825,7 +839,7 @@ upb_MiniTable* upb_MiniTable_BuildMessageSet(upb_MiniTablePlatform platform,
ret->size = 0;
ret->field_count = 0;
ret->ext = upb_ExtMode_IsMessageSet;
ret->ext = kUpb_ExtMode_IsMessageSet;
ret->dense_below = 0;
ret->table_mask = 0;
ret->required_count = 0;
@ -841,7 +855,8 @@ upb_MiniTable* upb_MiniTable_BuildMapEntry(upb_FieldType key_type,
if (!ret || !fields) return NULL;
upb_MiniTable_Sub* subs = NULL;
if (value_type == kUpb_FieldType_Message || value_type == kUpb_FieldType_Group) {
if (value_type == kUpb_FieldType_Message ||
value_type == kUpb_FieldType_Group) {
subs = upb_Arena_Malloc(arena, sizeof(*subs));
if (!subs) return NULL;
}
@ -863,7 +878,7 @@ upb_MiniTable* upb_MiniTable_BuildMapEntry(upb_FieldType key_type,
ret->size = UPB_ALIGN_UP(2 * field_size, 8);
ret->field_count = 2;
ret->ext = upb_ExtMode_NonExtendable | upb_ExtMode_IsMapEntry;
ret->ext = kUpb_ExtMode_NonExtendable | kUpb_ExtMode_IsMapEntry;
ret->dense_below = 2;
ret->table_mask = 0;
ret->required_count = 0;
@ -895,8 +910,7 @@ upb_MiniTable_Extension* upb_MiniTable_BuildExtensions(const char* data,
exts = upb_Arena_Malloc(arena, len);
upb_MtDecoder_CheckOutOfMemory(&decoder, exts);
upb_MtDecoder_Parse(&decoder, data, len, exts, sizeof(*exts), &count, NULL);
exts = upb_Arena_Realloc(arena, exts, sizeof(*exts) * len,
sizeof(*exts) * count);
upb_Arena_ShrinkLast(arena, exts, sizeof(*exts) * len, sizeof(*exts) * count);
done:
*ext_count = count;
@ -917,9 +931,10 @@ upb_MiniTable* upb_MiniTable_Build(const char* data, size_t len,
void upb_MiniTable_SetSubMessage(upb_MiniTable* table,
upb_MiniTable_Field* field,
const upb_MiniTable* sub) {
assert((uintptr_t)table->fields <= (uintptr_t)field &&
(uintptr_t)field < (uintptr_t)(table->fields + table->field_count));
if (sub->ext & upb_ExtMode_IsMapEntry) {
UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field &&
(uintptr_t)field <
(uintptr_t)(table->fields + table->field_count));
if (sub->ext & kUpb_ExtMode_IsMapEntry) {
field->mode =
(kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift) | kUpb_FieldMode_Map;
}
@ -927,11 +942,11 @@ void upb_MiniTable_SetSubMessage(upb_MiniTable* table,
table_sub->submsg = sub;
}
void upb_MiniTable_SetSubEnum(upb_MiniTable* table,
upb_MiniTable_Field* field,
void upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTable_Field* field,
const upb_MiniTable_Enum* sub) {
assert((uintptr_t)table->fields <= (uintptr_t)field &&
(uintptr_t)field < (uintptr_t)(table->fields + table->field_count));
UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field &&
(uintptr_t)field <
(uintptr_t)(table->fields + table->field_count));
upb_MiniTable_Sub* table_sub = (void*)&table->subs[field->submsg_index];
table_sub->subenum = sub;
}

@ -1,5 +1,9 @@
/*
<<<<<<< HEAD
* Copyright (c) 2009-2021, Google LLC
=======
* Copyright (c) 2009-2022, Google LLC
>>>>>>> mini-table-1
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -101,7 +105,6 @@ char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* buf);
char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* buf,
uint32_t field_num);
/** upb_MiniTable *************************************************************/
typedef enum {
@ -121,8 +124,7 @@ upb_MiniTable* upb_MiniTable_Build(const char* data, size_t len,
void upb_MiniTable_SetSubMessage(upb_MiniTable* table,
upb_MiniTable_Field* field,
const upb_MiniTable* sub);
void upb_MiniTable_SetSubEnum(upb_MiniTable* table,
upb_MiniTable_Field* field,
void upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTable_Field* field,
const upb_MiniTable_Enum* sub);
upb_MiniTable_Extension* upb_MiniTable_BuildExtensions(const char* data,
@ -153,10 +155,14 @@ upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len,
upb_Arena* arena, void** buf,
size_t* buf_size, upb_Status* status);
// For testing only.
char upb_ToBase92(int8_t ch);
char upb_FromBase92(uint8_t ch);
#ifdef __cplusplus
} /* extern "C" */
} /* extern "C" */
#endif
#include "upb/port_undef.inc"
#endif /* UPB_MINI_TABLE_H_ */
#endif /* UPB_MINI_TABLE_H_ */

@ -0,0 +1,99 @@
/*
* Copyright (c) 2009-2021, Google LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Google LLC nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UPB_MINI_TABLE_HPP_
#define UPB_MINI_TABLE_HPP_
#include <assert.h>
#include <string>
#include "upb/mini_table.h"
namespace upb {
class MtDataEncoder {
public:
MtDataEncoder() : appender_(&encoder_) {}
bool StartMessage(uint64_t msg_mod) {
return appender_([=](char* buf) {
return upb_MtDataEncoder_StartMessage(&encoder_, buf, msg_mod);
});
}
bool PutField(upb_FieldType type, uint32_t field_num, uint64_t field_mod) {
return appender_([=](char* buf) {
return upb_MtDataEncoder_PutField(&encoder_, buf, type, field_num,
field_mod);
});
}
bool StartOneof() {
return appender_([=](char* buf) {
return upb_MtDataEncoder_StartOneof(&encoder_, buf);
});
}
bool PutOneofField(uint32_t field_num) {
return appender_([=](char* buf) {
return upb_MtDataEncoder_PutOneofField(&encoder_, buf, field_num);
});
}
const std::string& data() const { return appender_.data(); }
private:
class StringAppender {
public:
StringAppender(upb_MtDataEncoder* e) { e->end = buf_ + sizeof(buf_); }
template <class T>
bool operator()(T&& func) {
char* end = func(buf_);
if (!end) return false;
// C++ does not guarantee that string has doubling growth behavior, but
// we need it to avoid O(n^2).
str_.reserve(_upb_Log2CeilingSize(str_.size() + (end - buf_)));
str_.append(buf_, end - buf_);
return true;
}
const std::string& data() const { return str_; }
private:
char buf_[kUpb_MtDataEncoder_MinSize];
std::string str_;
};
upb_MtDataEncoder encoder_;
StringAppender appender_;
};
} // namespace upb
#endif /* UPB_MINI_TABLE_HPP_ */

@ -50,11 +50,10 @@ TEST_P(MiniTableTest, AllScalarTypes) {
upb::MtDataEncoder e;
ASSERT_TRUE(e.StartMessage(0));
int count = 0;
for (int i = kUpb_FieldType_Double ; i < kUpb_FieldType_SInt64; i++) {
for (int i = kUpb_FieldType_Double; i < kUpb_FieldType_SInt64; i++) {
ASSERT_TRUE(e.PutField(static_cast<upb_FieldType>(i), i, 0));
count++;
}
fprintf(stderr, "YO: %s\n", e.data().c_str());
upb::Status status;
upb_MiniTable* table = upb_MiniTable_Build(
e.data().data(), e.data().size(), GetParam(), arena.ptr(), status.ptr());
@ -77,12 +76,11 @@ TEST_P(MiniTableTest, AllRepeatedTypes) {
upb::MtDataEncoder e;
ASSERT_TRUE(e.StartMessage(0));
int count = 0;
for (int i = kUpb_FieldType_Double ; i < kUpb_FieldType_SInt64; i++) {
for (int i = kUpb_FieldType_Double; i < kUpb_FieldType_SInt64; i++) {
ASSERT_TRUE(e.PutField(static_cast<upb_FieldType>(i), i,
kUpb_FieldModifier_IsRepeated));
count++;
}
fprintf(stderr, "YO: %s\n", e.data().c_str());
upb::Status status;
upb_MiniTable* table = upb_MiniTable_Build(
e.data().data(), e.data().size(), GetParam(), arena.ptr(), status.ptr());
@ -112,7 +110,6 @@ TEST_P(MiniTableTest, Skips) {
ASSERT_TRUE(e.PutField(kUpb_FieldType_Float, field_number, 0));
count++;
}
fprintf(stderr, "YO: %s, %zu\n", e.data().c_str(), e.data().size());
upb::Status status;
upb_MiniTable* table = upb_MiniTable_Build(
e.data().data(), e.data().size(), GetParam(), arena.ptr(), status.ptr());
@ -135,15 +132,14 @@ TEST_P(MiniTableTest, AllScalarTypesOneof) {
upb::MtDataEncoder e;
ASSERT_TRUE(e.StartMessage(0));
int count = 0;
for (int i = kUpb_FieldType_Double ; i < kUpb_FieldType_SInt64; i++) {
for (int i = kUpb_FieldType_Double; i < kUpb_FieldType_SInt64; i++) {
ASSERT_TRUE(e.PutField(static_cast<upb_FieldType>(i), i, 0));
count++;
}
ASSERT_TRUE(e.StartOneof());
for (int i = kUpb_FieldType_Double ; i < kUpb_FieldType_SInt64; i++) {
for (int i = kUpb_FieldType_Double; i < kUpb_FieldType_SInt64; i++) {
ASSERT_TRUE(e.PutOneofField(i));
}
fprintf(stderr, "YO: %s\n", e.data().c_str());
upb::Status status;
upb_MiniTable* table = upb_MiniTable_Build(
e.data().data(), e.data().size(), GetParam(), arena.ptr(), status.ptr());
@ -170,3 +166,9 @@ TEST_P(MiniTableTest, AllScalarTypesOneof) {
INSTANTIATE_TEST_SUITE_P(Platforms, MiniTableTest,
testing::Values(kUpb_MiniTablePlatform_32Bit,
kUpb_MiniTablePlatform_64Bit));
TEST(MiniTablePlatformIndependentTest, Base92Roundtrip) {
for (char i = 0; i < 92; i++) {
EXPECT_EQ(i, upb_FromBase92(upb_ToBase92(i)));
}
}

@ -54,7 +54,7 @@ static bool realloc_internal(upb_Message* msg, size_t need, upb_Arena* arena) {
upb_Message_Internal* in = upb_Message_Getinternal(msg);
if (!in->internal) {
/* No internal data, allocate from scratch. */
size_t size = UPB_MAX(128, _upb_Log2Ceilingsize(need + overhead));
size_t size = UPB_MAX(128, _upb_Log2CeilingSize(need + overhead));
upb_Message_InternalData* internal = upb_Arena_Malloc(arena, size);
if (!internal) return false;
internal->size = size;
@ -63,7 +63,7 @@ static bool realloc_internal(upb_Message* msg, size_t need, upb_Arena* arena) {
in->internal = internal;
} else if (in->internal->ext_begin - in->internal->unknown_end < need) {
/* Internal data is too small, reallocate. */
size_t new_size = _upb_Log2Ceilingsize(in->internal->size + need);
size_t new_size = _upb_Log2CeilingSize(in->internal->size + need);
size_t ext_bytes = in->internal->size - in->internal->ext_begin;
size_t new_ext_begin = new_size - ext_bytes;
upb_Message_InternalData* internal =
@ -309,7 +309,7 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type,
/* Grow s->entries if necessary. */
if (sorted->end > s->cap) {
s->cap = _upb_Log2Ceilingsize(sorted->end);
s->cap = _upb_Log2CeilingSize(sorted->end);
s->entries = realloc(s->entries, s->cap * sizeof(*s->entries));
if (!s->entries) return false;
}

@ -87,20 +87,21 @@ typedef enum {
} upb_FieldMode;
/* Extra flags on the mode field. */
enum upb_LabelFlags {
upb_LabelFlags_IsPacked = 4,
upb_LabelFlags_IsExtension = 8,
};
typedef enum {
kUpb_LabelFlags_IsPacked = 4,
kUpb_LabelFlags_IsExtension = 8,
} upb_LabelFlags;
/* Representation in the message. Derivable from descriptortype and mode, but
* fast access helps the serializer. */
// Note: we sort by this number when calculating layout order.
typedef enum {
kUpb_FieldRep_1Byte = 0,
kUpb_FieldRep_4Byte = 1,
kUpb_FieldRep_Pointer = 2,
kUpb_FieldRep_StringView = 3,
kUpb_FieldRep_StringView = 2,
kUpb_FieldRep_Pointer = 3,
kUpb_FieldRep_8Byte = 4,
kUpb_FieldRep_Shift = 5, // Bit offset of the rep in upb_MiniTable_Field.mode
kUpb_FieldRep_Max = kUpb_FieldRep_8Byte,
} upb_FieldRep;
UPB_INLINE upb_FieldMode upb_FieldMode_Get(const upb_MiniTable_Field* field) {
@ -153,15 +154,15 @@ typedef union {
} upb_MiniTable_Sub;
typedef enum {
upb_ExtMode_NonExtendable = 0, // Non-extendable message.
upb_ExtMode_Extendable = 1, // Normal extendable message.
upb_ExtMode_IsMessageSet = 2, // MessageSet message.
upb_ExtMode_IsMessageSet_ITEM =
kUpb_ExtMode_NonExtendable = 0, // Non-extendable message.
kUpb_ExtMode_Extendable = 1, // Normal extendable message.
kUpb_ExtMode_IsMessageSet = 2, // MessageSet message.
kUpb_ExtMode_IsMessageSet_ITEM =
3, // MessageSet item (temporary only, see decode.c)
// During table building we steal a bit to indicate that the message is a map
// entry. *Only* used during table building!
upb_ExtMode_IsMapEntry = 4,
kUpb_ExtMode_IsMapEntry = 4,
} upb_ExtMode;
/* MessageSet wire format is:

@ -223,17 +223,30 @@ UPB_INLINE void* upb_Arena_Malloc(upb_Arena* a, size_t size) {
return ret;
}
// Call to shrink the last alloc from this arena.
// REQUIRES: (ptr, oldsize) was the last malloc/realloc from this arena.
// We could also add a upb_Arena_TryShrinkLast() which is simply a no-op if
// this was not the last alloc.
UPB_INLINE void upb_Arena_ShrinkLast(upb_Arena* a, void* ptr, size_t oldsize,
size_t size) {
_upb_ArenaHead* h = (_upb_ArenaHead*)a;
oldsize = UPB_ALIGN_MALLOC(oldsize);
size = UPB_ALIGN_MALLOC(size);
UPB_ASSERT((char*)ptr + oldsize == h->ptr); // Must be the last alloc.
UPB_ASSERT(size <= oldsize);
h->ptr = (char*)ptr + size;
}
UPB_INLINE void* upb_Arena_Realloc(upb_Arena* a, void* ptr, size_t oldsize,
size_t size) {
_upb_ArenaHead* h = (_upb_ArenaHead*)a;
char* ch_ptr = (char*)ptr;
oldsize = UPB_ALIGN_MALLOC(oldsize);
size = UPB_ALIGN_MALLOC(size);
if (ch_ptr + oldsize == h->ptr) {
if ((size_t)(h->end - ch_ptr) >= size) {
h->ptr = ch_ptr + size;
return ptr;
if (size <= oldsize) {
if ((char*)ptr + oldsize == h->ptr) {
upb_Arena_ShrinkLast(a, ptr, oldsize, size);
}
return ptr;
}
void* ret = upb_Arena_Malloc(a, size);
@ -343,7 +356,7 @@ UPB_INLINE int _upb_Log2Ceiling(int x) {
#endif
}
UPB_INLINE int _upb_Log2Ceilingsize(int x) { return 1 << _upb_Log2Ceiling(x); }
UPB_INLINE int _upb_Log2CeilingSize(int x) { return 1 << _upb_Log2Ceiling(x); }
#include "upb/port_undef.inc"

@ -1385,12 +1385,12 @@ std::string GetModeInit(uint8_t mode) {
break;
}
if (mode & upb_LabelFlags_IsPacked) {
absl::StrAppend(&ret, " | upb_LabelFlags_IsPacked");
if (mode & kUpb_LabelFlags_IsPacked) {
absl::StrAppend(&ret, " | kUpb_LabelFlags_IsPacked");
}
if (mode & upb_LabelFlags_IsExtension) {
absl::StrAppend(&ret, " | upb_LabelFlags_IsExtension");
if (mode & kUpb_LabelFlags_IsExtension) {
absl::StrAppend(&ret, " | kUpb_LabelFlags_IsExtension");
}
std::string rep;
@ -1485,13 +1485,13 @@ void WriteMessage(const protobuf::Descriptor* message, const FileLayout& layout,
table_mask = (table.size() - 1) << 3;
}
std::string msgext = "upb_ExtMode_NonExtendable";
std::string msgext = "kUpb_ExtMode_NonExtendable";
if (message->extension_range_count()) {
if (message->options().message_set_wire_format()) {
msgext = "upb_ExtMode_IsMessageSet";
msgext = "kUpb_ExtMode_IsMessageSet";
} else {
msgext = "upb_ExtMode_Extendable";
msgext = "kUpb_ExtMode_Extendable";
}
}

Loading…
Cancel
Save