Removed kUpb_FieldRep_Pointer as a distinct FieldRep, saving a bit in the MiniTable

We can resolve the difference between these two reps at MiniTable build time.

PiperOrigin-RevId: 479320737
pull/13171/head
Joshua Haberman 2 years ago committed by Copybara-Service
parent aabb2b62ae
commit 30a28f3d3a
  1. 6
      upb/encode.c
  2. 42
      upb/mini_table.c
  3. 5
      upb/msg_internal.h
  4. 24
      upbc/protoc-gen-upb.cc

@ -454,17 +454,11 @@ static bool encode_shouldencode(upb_encstate* e, const upb_Message* msg,
memcpy(&ch, mem, 1);
return ch != 0;
}
#if UINTPTR_MAX == 0xffffffff
case kUpb_FieldRep_Pointer:
#endif
case kUpb_FieldRep_4Byte: {
uint32_t u32;
memcpy(&u32, mem, 4);
return u32 != 0;
}
#if UINTPTR_MAX != 0xffffffff
case kUpb_FieldRep_Pointer:
#endif
case kUpb_FieldRep_8Byte: {
uint64_t u64;
memcpy(&u64, mem, 8);

@ -499,8 +499,6 @@ static void upb_MiniTable_SetField(upb_MtDecoder* d, uint8_t ch,
[kUpb_EncodedType_Fixed32] = kUpb_FieldRep_4Byte,
[kUpb_EncodedType_Bool] = kUpb_FieldRep_1Byte,
[kUpb_EncodedType_String] = kUpb_FieldRep_StringView,
[kUpb_EncodedType_Group] = kUpb_FieldRep_Pointer,
[kUpb_EncodedType_Message] = kUpb_FieldRep_Pointer,
[kUpb_EncodedType_Bytes] = kUpb_FieldRep_StringView,
[kUpb_EncodedType_UInt32] = kUpb_FieldRep_4Byte,
[kUpb_EncodedType_Enum] = kUpb_FieldRep_4Byte,
@ -531,20 +529,27 @@ static void upb_MiniTable_SetField(upb_MtDecoder* d, uint8_t ch,
[kUpb_EncodedType_SInt64] = kUpb_FieldType_SInt64,
};
char pointer_rep = d->platform == kUpb_MiniTablePlatform_32Bit
? kUpb_FieldRep_4Byte
: kUpb_FieldRep_8Byte;
int8_t type = upb_FromBase92(ch);
if (ch >= upb_ToBase92(kUpb_EncodedType_RepeatedBase)) {
type -= kUpb_EncodedType_RepeatedBase;
field->mode = kUpb_FieldMode_Array;
field->mode |= kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift;
field->mode |= pointer_rep << kUpb_FieldRep_Shift;
field->offset = kNoPresence;
} else {
if (type >= sizeof(kUpb_EncodedToFieldRep)) {
field->mode = kUpb_FieldMode_Scalar;
field->offset = kHasbitPresence;
if (type == kUpb_EncodedType_Group || type == kUpb_EncodedType_Message) {
field->mode |= pointer_rep << kUpb_FieldRep_Shift;
} else if (type >= sizeof(kUpb_EncodedToFieldRep)) {
upb_MtDecoder_ErrorFormat(d, "Invalid field type: %d", (int)type);
UPB_UNREACHABLE();
} else {
field->mode |= kUpb_EncodedToFieldRep[type] << kUpb_FieldRep_Shift;
}
field->mode = kUpb_FieldMode_Scalar;
field->mode |= kUpb_EncodedToFieldRep[type] << kUpb_FieldRep_Shift;
field->offset = kHasbitPresence;
}
if (type >= sizeof(kUpb_EncodedToType)) {
upb_MtDecoder_ErrorFormat(d, "Invalid field type: %d", (int)type);
@ -619,13 +624,15 @@ static void upb_MtDecoder_PushOneof(upb_MtDecoder* d, upb_LayoutItem item) {
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_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_StringView] = 16,
[kUpb_FieldRep_8Byte] = 8,
};
UPB_ASSERT(sizeof(upb_StringView) ==
@ -637,13 +644,15 @@ size_t upb_MtDecoder_SizeOfRep(upb_FieldRep rep,
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_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_StringView] = 8,
[kUpb_FieldRep_8Byte] = 8,
};
UPB_ASSERT(UPB_ALIGN_OF(upb_StringView) ==
@ -1197,8 +1206,7 @@ void upb_MiniTable_SetSubMessage(upb_MiniTable* table,
(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;
field->mode = (field->mode & ~kUpb_FieldMode_Mask) | kUpb_FieldMode_Map;
}
upb_MiniTable_Sub* table_sub = (void*)&table->subs[field->submsg_index];
table_sub->submsg = sub;

@ -103,10 +103,9 @@ typedef enum {
kUpb_FieldRep_1Byte = 0,
kUpb_FieldRep_4Byte = 1,
kUpb_FieldRep_StringView = 2,
kUpb_FieldRep_Pointer = 3,
kUpb_FieldRep_8Byte = 4,
kUpb_FieldRep_8Byte = 3,
kUpb_FieldRep_Shift = 5, // Bit offset of the rep in upb_MiniTable_Field.mode
kUpb_FieldRep_Shift = 6, // Bit offset of the rep in upb_MiniTable_Field.mode
kUpb_FieldRep_Max = kUpb_FieldRep_8Byte,
} upb_FieldRep;

@ -32,10 +32,8 @@
#include "google/protobuf/wire_format.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/ascii.h"
#include "absl/strings/substitute.h"
#include "upb/mini_table.hpp"
#include "upb/upb.hpp"
#include "upbc/common.h"
#include "upbc/file_layout.h"
#include "upbc/names.h"
@ -1224,9 +1222,9 @@ std::vector<TableEntry> FastDecodeTable(const protobuf::Descriptor* message,
// We could just emit this as a number (and we may yet go in that direction) but
// for now emitting symbolic constants gives this better readability and
// debuggability.
std::string GetModeInit(uint8_t mode) {
std::string GetModeInit(uint8_t mode32, uint8_t mode64) {
std::string ret;
switch (mode & kUpb_FieldMode_Mask) {
switch (mode32 & kUpb_FieldMode_Mask) {
case kUpb_FieldMode_Map:
ret = "kUpb_FieldMode_Map";
break;
@ -1240,24 +1238,26 @@ std::string GetModeInit(uint8_t mode) {
break;
}
if (mode & kUpb_LabelFlags_IsPacked) {
if (mode32 & kUpb_LabelFlags_IsPacked) {
absl::StrAppend(&ret, " | kUpb_LabelFlags_IsPacked");
}
if (mode & kUpb_LabelFlags_IsExtension) {
if (mode32 & kUpb_LabelFlags_IsExtension) {
absl::StrAppend(&ret, " | kUpb_LabelFlags_IsExtension");
}
std::string rep;
switch (mode >> kUpb_FieldRep_Shift) {
switch (mode32 >> kUpb_FieldRep_Shift) {
case kUpb_FieldRep_1Byte:
rep = "kUpb_FieldRep_1Byte";
break;
case kUpb_FieldRep_4Byte:
rep = "kUpb_FieldRep_4Byte";
break;
case kUpb_FieldRep_Pointer:
rep = "kUpb_FieldRep_Pointer";
if (mode64 >> kUpb_FieldRep_Shift == kUpb_FieldRep_4Byte) {
rep = "kUpb_FieldRep_4Byte";
} else {
assert(mode64 >> kUpb_FieldRep_Shift == kUpb_FieldRep_8Byte);
rep = "UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)";
}
break;
case kUpb_FieldRep_StringView:
rep = "kUpb_FieldRep_StringView";
@ -1279,7 +1279,7 @@ void WriteField(const upb_MiniTable_Field* field64,
field64->submsg_index == kUpb_NoSub
? "kUpb_NoSub"
: absl::StrCat(field64->submsg_index).c_str(),
field64->descriptortype, GetModeInit(field64->mode));
field64->descriptortype, GetModeInit(field32->mode, field64->mode));
}
// Writes a single field into a .upb.c source file.

Loading…
Cancel
Save