Skip to content

Commit

Permalink
Add an indirection to sub-messages pointers to allow for static tree …
Browse files Browse the repository at this point in the history
…shaking.

PiperOrigin-RevId: 640369522
  • Loading branch information
haberman authored and copybara-github committed Jun 5, 2024
1 parent a1e78a5 commit 85c7cc2
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 75 deletions.
9 changes: 7 additions & 2 deletions upb/mini_descriptor/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "upb/mini_table/field.h"
#include "upb/mini_table/internal/field.h"
#include "upb/mini_table/internal/message.h"
#include "upb/mini_table/internal/sub.h"
#include "upb/mini_table/message.h"
#include "upb/mini_table/sub.h"

Expand Down Expand Up @@ -407,11 +408,15 @@ static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d,
upb_SubCounts sub_counts) {
uint32_t total_count = sub_counts.submsg_count + sub_counts.subenum_count;
size_t subs_bytes = sizeof(*d->table->UPB_PRIVATE(subs)) * total_count;
upb_MiniTableSub* subs = upb_Arena_Malloc(d->arena, subs_bytes);
size_t ptrs_bytes = sizeof(upb_MiniTable*) * sub_counts.submsg_count;
upb_MiniTableSubInternal* subs = upb_Arena_Malloc(d->arena, subs_bytes);
const upb_MiniTable** subs_ptrs = upb_Arena_Malloc(d->arena, ptrs_bytes);
upb_MdDecoder_CheckOutOfMemory(&d->base, subs);
upb_MdDecoder_CheckOutOfMemory(&d->base, subs_ptrs);
uint32_t i = 0;
for (; i < sub_counts.submsg_count; i++) {
subs[i].UPB_PRIVATE(submsg) = UPB_PRIVATE(_upb_MiniTable_Empty)();
subs_ptrs[i] = UPB_PRIVATE(_upb_MiniTable_Empty)();
subs[i].UPB_PRIVATE(submsg) = &subs_ptrs[i];
}
if (sub_counts.subenum_count) {
upb_MiniTableField* f = d->fields;
Expand Down
8 changes: 6 additions & 2 deletions upb/mini_descriptor/link.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@

#include <stddef.h>
#include <stdint.h>
#include <string.h>

#include "upb/base/descriptor_constants.h"
#include "upb/mini_table/enum.h"
#include "upb/mini_table/field.h"
#include "upb/mini_table/internal/field.h"
#include "upb/mini_table/internal/message.h"
#include "upb/mini_table/internal/sub.h"
#include "upb/mini_table/message.h"
#include "upb/mini_table/sub.h"

Expand Down Expand Up @@ -51,11 +55,11 @@ bool upb_MiniTable_SetSubMessage(upb_MiniTable* table,
}

int idx = field->UPB_PRIVATE(submsg_index);
upb_MiniTableSub* table_subs = (void*)table->UPB_PRIVATE(subs);
upb_MiniTableSubInternal* table_subs = (void*)table->UPB_PRIVATE(subs);
// TODO: Add this assert back once YouTube is updated to not call
// this function repeatedly.
// UPB_ASSERT(UPB_PRIVATE(_upb_MiniTable_IsEmpty)(table_sub->submsg));
table_subs[idx] = upb_MiniTableSub_FromMessage(sub);
memcpy((void*)table_subs[idx].UPB_PRIVATE(submsg), &sub, sizeof(void*));
return true;
}

Expand Down
12 changes: 7 additions & 5 deletions upb/mini_table/internal/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ typedef enum {

// LINT.IfChange(minitable_struct_definition)
struct upb_MiniTable {
const union upb_MiniTableSub* UPB_PRIVATE(subs);
const upb_MiniTableSubInternal* UPB_PRIVATE(subs);
const struct upb_MiniTableField* UPB_ONLYBITS(fields);

// Must be aligned to sizeof(void*). Doesn't include internal members like
Expand Down Expand Up @@ -99,17 +99,19 @@ UPB_API_INLINE const struct upb_MiniTableField* upb_MiniTable_GetFieldByIndex(
return &m->UPB_ONLYBITS(fields)[i];
}

UPB_INLINE const union upb_MiniTableSub UPB_PRIVATE(
_upb_MiniTable_GetSubByIndex)(const struct upb_MiniTable* m, uint32_t i) {
return m->UPB_PRIVATE(subs)[i];
UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(
_upb_MiniTable_GetSubTableByIndex)(const struct upb_MiniTable* m,
uint32_t i) {
return *m->UPB_PRIVATE(subs)[i].UPB_PRIVATE(submsg);
}

UPB_API_INLINE const struct upb_MiniTable* upb_MiniTable_SubMessage(
const struct upb_MiniTable* m, const struct upb_MiniTableField* f) {
if (upb_MiniTableField_CType(f) != kUpb_CType_Message) {
return NULL;
}
return m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)].UPB_PRIVATE(submsg);
return UPB_PRIVATE(_upb_MiniTable_GetSubTableByIndex)(
m, f->UPB_PRIVATE(submsg_index));
}

UPB_API_INLINE const struct upb_MiniTable* upb_MiniTable_GetSubMessageTable(
Expand Down
5 changes: 5 additions & 0 deletions upb/mini_table/internal/sub.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
// Must be last.
#include "upb/port/def.inc"

typedef union {
const struct upb_MiniTable* const* UPB_PRIVATE(submsg);
const struct upb_MiniTableEnum* UPB_PRIVATE(subenum);
} upb_MiniTableSubInternal;

union upb_MiniTableSub {
const struct upb_MiniTable* UPB_PRIVATE(submsg);
const struct upb_MiniTableEnum* UPB_PRIVATE(subenum);
Expand Down
89 changes: 50 additions & 39 deletions upb/wire/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
#include "upb/mini_table/field.h"
#include "upb/mini_table/internal/field.h"
#include "upb/mini_table/internal/message.h"
#include "upb/mini_table/internal/size_log2.h"
#include "upb/mini_table/internal/sub.h"
#include "upb/mini_table/message.h"
#include "upb/mini_table/sub.h"
#include "upb/port/atomic.h"
Expand Down Expand Up @@ -97,15 +97,15 @@ typedef union {
// Returns the MiniTable corresponding to a given MiniTableField
// from an array of MiniTableSubs.
static const upb_MiniTable* _upb_MiniTableSubs_MessageByField(
const upb_MiniTableSub* subs, const upb_MiniTableField* field) {
return upb_MiniTableSub_Message(subs[field->UPB_PRIVATE(submsg_index)]);
const upb_MiniTableSubInternal* subs, const upb_MiniTableField* field) {
return *subs[field->UPB_PRIVATE(submsg_index)].UPB_PRIVATE(submsg);
}

// Returns the MiniTableEnum corresponding to a given MiniTableField
// from an array of MiniTableSub.
static const upb_MiniTableEnum* _upb_MiniTableSubs_EnumByField(
const upb_MiniTableSub* subs, const upb_MiniTableField* field) {
return upb_MiniTableSub_Enum(subs[field->UPB_PRIVATE(submsg_index)]);
const upb_MiniTableSubInternal* subs, const upb_MiniTableField* field) {
return subs[field->UPB_PRIVATE(submsg_index)].UPB_PRIVATE(subenum);
}

static const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr,
Expand Down Expand Up @@ -240,11 +240,10 @@ static void _upb_Decoder_Munge(int type, wireval* val) {
}
}

static upb_Message* _upb_Decoder_NewSubMessage(upb_Decoder* d,
const upb_MiniTableSub* subs,
const upb_MiniTableField* field,
upb_TaggedMessagePtr* target) {
const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field);
static upb_Message* _upb_Decoder_NewSubMessage2(upb_Decoder* d,
const upb_MiniTable* subl,
const upb_MiniTableField* field,
upb_TaggedMessagePtr* target) {
UPB_ASSERT(subl);
upb_Message* msg = _upb_Message_New(subl, &d->arena);
if (!msg) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
Expand All @@ -265,8 +264,15 @@ static upb_Message* _upb_Decoder_NewSubMessage(upb_Decoder* d,
return msg;
}

static upb_Message* _upb_Decoder_NewSubMessage(
upb_Decoder* d, const upb_MiniTableSubInternal* subs,
const upb_MiniTableField* field, upb_TaggedMessagePtr* target) {
const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field);
return _upb_Decoder_NewSubMessage2(d, subl, field, target);
}

static upb_Message* _upb_Decoder_ReuseSubMessage(
upb_Decoder* d, const upb_MiniTableSub* subs,
upb_Decoder* d, const upb_MiniTableSubInternal* subs,
const upb_MiniTableField* field, upb_TaggedMessagePtr* target) {
upb_TaggedMessagePtr tagged = *target;
const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field);
Expand Down Expand Up @@ -319,7 +325,7 @@ const char* _upb_Decoder_RecurseSubMessage(upb_Decoder* d, const char* ptr,
UPB_FORCEINLINE
const char* _upb_Decoder_DecodeSubMessage(upb_Decoder* d, const char* ptr,
upb_Message* submsg,
const upb_MiniTableSub* subs,
const upb_MiniTableSubInternal* subs,
const upb_MiniTableField* field,
int size) {
int saved_delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, size);
Expand Down Expand Up @@ -352,7 +358,7 @@ const char* _upb_Decoder_DecodeUnknownGroup(upb_Decoder* d, const char* ptr,
UPB_FORCEINLINE
const char* _upb_Decoder_DecodeKnownGroup(upb_Decoder* d, const char* ptr,
upb_Message* submsg,
const upb_MiniTableSub* subs,
const upb_MiniTableSubInternal* subs,
const upb_MiniTableField* field) {
const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field);
UPB_ASSERT(subl);
Expand Down Expand Up @@ -403,12 +409,10 @@ bool _upb_Decoder_CheckEnum(upb_Decoder* d, const char* ptr, upb_Message* msg,
}

UPB_NOINLINE
static const char* _upb_Decoder_DecodeEnumArray(upb_Decoder* d, const char* ptr,
upb_Message* msg,
upb_Array* arr,
const upb_MiniTableSub* subs,
const upb_MiniTableField* field,
wireval* val) {
static const char* _upb_Decoder_DecodeEnumArray(
upb_Decoder* d, const char* ptr, upb_Message* msg, upb_Array* arr,
const upb_MiniTableSubInternal* subs, const upb_MiniTableField* field,
wireval* val) {
const upb_MiniTableEnum* e = _upb_MiniTableSubs_EnumByField(subs, field);
if (!_upb_Decoder_CheckEnum(d, ptr, msg, e, field, val)) return ptr;
void* mem = UPB_PTR_AT(upb_Array_MutableDataPtr(arr),
Expand Down Expand Up @@ -484,7 +488,7 @@ const char* _upb_Decoder_DecodeVarintPacked(upb_Decoder* d, const char* ptr,
UPB_NOINLINE
static const char* _upb_Decoder_DecodeEnumPacked(
upb_Decoder* d, const char* ptr, upb_Message* msg, upb_Array* arr,
const upb_MiniTableSub* subs, const upb_MiniTableField* field,
const upb_MiniTableSubInternal* subs, const upb_MiniTableField* field,
wireval* val) {
const upb_MiniTableEnum* e = _upb_MiniTableSubs_EnumByField(subs, field);
int saved_limit = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, val->size);
Expand Down Expand Up @@ -518,11 +522,10 @@ static upb_Array* _upb_Decoder_CreateArray(upb_Decoder* d,
return ret;
}

static const char* _upb_Decoder_DecodeToArray(upb_Decoder* d, const char* ptr,
upb_Message* msg,
const upb_MiniTableSub* subs,
const upb_MiniTableField* field,
wireval* val, int op) {
static const char* _upb_Decoder_DecodeToArray(
upb_Decoder* d, const char* ptr, upb_Message* msg,
const upb_MiniTableSubInternal* subs, const upb_MiniTableField* field,
wireval* val, int op) {
upb_Array** arrp = UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), void);
upb_Array* arr = *arrp;
void* mem;
Expand Down Expand Up @@ -623,11 +626,10 @@ static upb_Map* _upb_Decoder_CreateMap(upb_Decoder* d,
return ret;
}

static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr,
upb_Message* msg,
const upb_MiniTableSub* subs,
const upb_MiniTableField* field,
wireval* val) {
static const char* _upb_Decoder_DecodeToMap(
upb_Decoder* d, const char* ptr, upb_Message* msg,
const upb_MiniTableSubInternal* subs, const upb_MiniTableField* field,
wireval* val) {
upb_Map** map_p = UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), upb_Map*);
upb_Map* map = *map_p;
upb_MapEntry ent;
Expand Down Expand Up @@ -688,8 +690,8 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr,

static const char* _upb_Decoder_DecodeToSubMessage(
upb_Decoder* d, const char* ptr, upb_Message* msg,
const upb_MiniTableSub* subs, const upb_MiniTableField* field, wireval* val,
int op) {
const upb_MiniTableSubInternal* subs, const upb_MiniTableField* field,
wireval* val, int op) {
void* mem = UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), void);
int type = field->UPB_PRIVATE(descriptortype);

Expand Down Expand Up @@ -819,9 +821,9 @@ static void upb_Decoder_AddKnownMessageSetItem(
if (UPB_UNLIKELY(!ext)) {
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}
upb_Message* submsg = _upb_Decoder_NewSubMessage(
d, &ext->ext->UPB_PRIVATE(sub), &ext->ext->UPB_PRIVATE(field),
(upb_TaggedMessagePtr*)&ext->data);
upb_Message* submsg = _upb_Decoder_NewSubMessage2(
d, ext->ext->UPB_PRIVATE(sub).UPB_PRIVATE(submsg),
&ext->ext->UPB_PRIVATE(field), (upb_TaggedMessagePtr*)&ext->data);
upb_DecodeStatus status = upb_Decode(
data, size, submsg, upb_MiniTableExtension_GetSubMessage(item_mt),
d->extreg, d->options, &d->arena);
Expand Down Expand Up @@ -1022,8 +1024,9 @@ void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt,
// unlinked.
do {
UPB_ASSERT(upb_MiniTableField_CType(oneof) == kUpb_CType_Message);
const upb_MiniTableSub* oneof_sub =
&mt->UPB_PRIVATE(subs)[oneof->UPB_PRIVATE(submsg_index)];
const upb_MiniTable* oneof_sub =
*mt->UPB_PRIVATE(subs)[oneof->UPB_PRIVATE(submsg_index)].UPB_PRIVATE(
submsg);
UPB_ASSERT(!oneof_sub);
} while (upb_MiniTable_NextOneofField(mt, &oneof));
}
Expand Down Expand Up @@ -1161,8 +1164,9 @@ const char* _upb_Decoder_DecodeKnownField(upb_Decoder* d, const char* ptr,
const upb_MiniTable* layout,
const upb_MiniTableField* field,
int op, wireval* val) {
const upb_MiniTableSub* subs = layout->UPB_PRIVATE(subs);
const upb_MiniTableSubInternal* subs = layout->UPB_PRIVATE(subs);
uint8_t mode = field->UPB_PRIVATE(mode);
upb_MiniTableSubInternal ext_sub;

if (UPB_UNLIKELY(mode & kUpb_LabelFlags_IsExtension)) {
const upb_MiniTableExtension* ext_layout =
Expand All @@ -1174,7 +1178,14 @@ const char* _upb_Decoder_DecodeKnownField(upb_Decoder* d, const char* ptr,
}
d->unknown_msg = msg;
msg = (upb_Message*)&ext->data;
subs = &ext->ext->UPB_PRIVATE(sub);
if (upb_MiniTableField_IsSubMessage(&ext->ext->UPB_PRIVATE(field))) {
ext_sub.UPB_PRIVATE(submsg) =
&ext->ext->UPB_PRIVATE(sub).UPB_PRIVATE(submsg);
} else {
ext_sub.UPB_PRIVATE(subenum) =
ext->ext->UPB_PRIVATE(sub).UPB_PRIVATE(subenum);
}
subs = &ext_sub;
}

switch (mode & kUpb_FieldMode_Mask) {
Expand Down
Loading

0 comments on commit 85c7cc2

Please sign in to comment.