Skip to content

Commit 1b04d38

Browse files
habermancopybara-github
authored andcommitted
Pack the field array and the subs array into one block of contiguous memory.
Instead of giving every MiniTable two parallel arrays (fields and subs), we now have one block of memory that contains both lists. For sub-message or enum fields, the `upb_MiniTableField` now contains a byte offset to where the `upb_MiniTable*` or `upb_MiniTableEnum*` can be found. The new design offers several benefits: 1. The sub-table requires fewer pointer-chasing indirections to find. 2. We no longer need the `upb_MiniTable*` to find the sub-MiniTable -- the `upb_MiniTableField*` is enough now. So APIs like `upb_MiniTable_GetSubMessageTable()` now require fewer parameters. 3. This unifies fields and extensions -- both can now find a sub-table using exactly the same code, with no need to distinguish between them. We still benefit from having two lists. If we tried to put the sub-table pointer directly into `upb_MiniTableField`, it would double the size of `upb_MiniTableField` from 12 to 24 bytes, due to alignment. Using the current design, sub-message fields only take 20 bytes, while others take 12, so this design is an improvement even if 100% of fields are sub-message fields. PiperOrigin-RevId: 824275694
1 parent 65579e4 commit 1b04d38

File tree

37 files changed

+433
-368
lines changed

37 files changed

+433
-368
lines changed

rust/upb/message.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -158,14 +158,8 @@ impl<T: AssociatedMiniTable> MessagePtr<T> {
158158
) -> Option<MessagePtr<ChildT>> {
159159
let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) };
160160

161-
let raw = unsafe {
162-
sys_msg::upb_Message_GetOrCreateMutableMessage(
163-
self.raw,
164-
T::mini_table(),
165-
f,
166-
arena.raw(),
167-
)
168-
};
161+
let raw =
162+
unsafe { sys_msg::upb_Message_GetOrCreateMutableMessage(self.raw, f, arena.raw()) };
169163
raw.map(|raw| MessagePtr { raw, _phantom: PhantomData })
170164
}
171165

@@ -243,7 +237,7 @@ impl<T: AssociatedMiniTable> MessagePtr<T> {
243237
) -> Option<sys_map::RawMap> {
244238
unsafe {
245239
let f = sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index);
246-
let map_entry_mini_table = sys_mt::upb_MiniTable_SubMessage(T::mini_table(), f);
240+
let map_entry_mini_table = sys_mt::upb_MiniTable_SubMessage(f);
247241
sys_msg::upb_Message_GetOrCreateMutableMap(
248242
self.raw,
249243
map_entry_mini_table,

rust/upb/sys/message/message.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ unsafe extern "C" {
127127
/// - `f` must be a message-typed field associated with `m`
128128
pub fn upb_Message_GetOrCreateMutableMessage(
129129
m: RawMessage,
130-
mini_table: RawMiniTable,
131130
f: RawMiniTableField,
132131
arena: RawArena,
133132
) -> Option<RawMessage>;

rust/upb/sys/mini_table/mini_table.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ unsafe extern "C" {
7575
/// # Safety
7676
/// - `m` and `f` must be valid to deref
7777
/// - `f` must be a mesage or map typed field associated with `m`
78-
pub fn upb_MiniTable_SubMessage(m: RawMiniTable, f: RawMiniTableField) -> RawMiniTable;
78+
pub fn upb_MiniTable_SubMessage(f: RawMiniTableField) -> RawMiniTable;
7979

8080
/// Builds a mini table from the data encoded in the buffer [data, len]. If
8181
/// any errors occur, returns null and sets a status message if status is

upb/message/accessors.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@
1717
// Must be last.
1818
#include "upb/port/def.inc"
1919

20-
bool upb_Message_SetMapEntry(upb_Map* map, const upb_MiniTable* m,
21-
const upb_MiniTableField* f,
20+
bool upb_Message_SetMapEntry(upb_Map* map, const upb_MiniTableField* f,
2221
upb_Message* map_entry_message, upb_Arena* arena) {
2322
UPB_ASSERT(!upb_Message_IsFrozen(map_entry_message));
2423
const upb_MiniTable* map_entry_mini_table =
25-
upb_MiniTable_MapEntrySubMessage(m, f);
24+
upb_MiniTable_MapEntrySubMessage(f);
2625
UPB_ASSERT(map_entry_mini_table);
2726
const upb_MiniTableField* map_entry_key_field =
2827
upb_MiniTable_MapKey(map_entry_mini_table);

upb/message/accessors.h

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,7 @@ UPB_API_INLINE upb_Map* upb_Message_GetOrCreateMutableMap(
102102
const upb_MiniTableField* f, upb_Arena* arena);
103103

104104
UPB_API_INLINE upb_Message* upb_Message_GetOrCreateMutableMessage(
105-
upb_Message* msg, const upb_MiniTable* mini_table,
106-
const upb_MiniTableField* f, upb_Arena* arena);
105+
upb_Message* msg, const upb_MiniTableField* f, upb_Arena* arena);
107106

108107
UPB_API_INLINE upb_StringView
109108
upb_Message_GetString(const upb_Message* msg, const upb_MiniTableField* field,
@@ -117,9 +116,9 @@ UPB_API_INLINE uint64_t upb_Message_GetUInt64(const upb_Message* msg,
117116
const upb_MiniTableField* f,
118117
uint64_t default_val);
119118

120-
UPB_API_INLINE void upb_Message_SetClosedEnum(
121-
upb_Message* msg, const upb_MiniTable* msg_mini_table,
122-
const upb_MiniTableField* f, int32_t value);
119+
UPB_API_INLINE void upb_Message_SetClosedEnum(upb_Message* msg,
120+
const upb_MiniTableField* f,
121+
int32_t value);
123122

124123
// BaseField Setters ///////////////////////////////////////////////////////////
125124

@@ -302,14 +301,40 @@ UPB_API_INLINE const upb_MiniTableField* upb_Message_WhichOneof(
302301
const upb_MiniTableField* f);
303302

304303
// Updates a map entry given an entry message.
305-
bool upb_Message_SetMapEntry(upb_Map* map, const upb_MiniTable* mini_table,
306-
const upb_MiniTableField* field,
304+
bool upb_Message_SetMapEntry(upb_Map* map, const upb_MiniTableField* field,
307305
upb_Message* map_entry_message, upb_Arena* arena);
308306

309307
#ifdef __cplusplus
310308
} /* extern "C" */
311309
#endif
312310

311+
#if defined(__cplusplus)
312+
// Temporary overloads for functions whose signature has recently changed.
313+
UPB_DEPRECATE_AND_INLINE()
314+
inline upb_Message* upb_Message_GetOrCreateMutableMessage(
315+
upb_Message* msg, const upb_MiniTable* mini_table,
316+
const upb_MiniTableField* f, upb_Arena* arena) {
317+
return upb_Message_GetOrCreateMutableMessage(msg, f, arena);
318+
}
319+
320+
UPB_DEPRECATE_AND_INLINE()
321+
inline void upb_Message_SetClosedEnum(upb_Message* msg,
322+
const upb_MiniTable* msg_mini_table,
323+
const upb_MiniTableField* f,
324+
int32_t value) {
325+
upb_Message_SetClosedEnum(msg, f, value);
326+
}
327+
328+
UPB_DEPRECATE_AND_INLINE()
329+
inline bool upb_Message_SetMapEntry(upb_Map* map,
330+
const upb_MiniTable* mini_table,
331+
const upb_MiniTableField* field,
332+
upb_Message* map_entry_message,
333+
upb_Arena* arena) {
334+
return upb_Message_SetMapEntry(map, field, map_entry_message, arena);
335+
}
336+
#endif
337+
313338
#include "upb/port/undef.inc"
314339

315340
#endif // UPB_MESSAGE_ACCESSORS_H_

upb/message/accessors_test.cc

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,7 @@ TEST(GeneratedCode, SubMessage) {
333333
new_nested_message);
334334

335335
upb_Message* mutable_message = upb_Message_GetOrCreateMutableMessage(
336-
UPB_UPCAST(msg),
337-
&protobuf_0test_0messages__proto2__TestAllTypesProto2_msg_init,
338-
optional_message_field, arena);
336+
UPB_UPCAST(msg), optional_message_field, arena);
339337
EXPECT_EQ(
340338
true,
341339
protobuf_test_messages_proto2_TestAllTypesProto2_optional_nested_message(
@@ -438,13 +436,9 @@ TEST(GeneratedCode, GetMutableMessage) {
438436
const upb_MiniTableField* optional_message_field =
439437
find_proto2_field(kFieldOptionalNestedMessage);
440438
upb_Message* msg1 = upb_Message_GetOrCreateMutableMessage(
441-
UPB_UPCAST(msg),
442-
&protobuf_0test_0messages__proto2__TestAllTypesProto2_msg_init,
443-
optional_message_field, arena);
439+
UPB_UPCAST(msg), optional_message_field, arena);
444440
upb_Message* msg2 = upb_Message_GetOrCreateMutableMessage(
445-
UPB_UPCAST(msg),
446-
&protobuf_0test_0messages__proto2__TestAllTypesProto2_msg_init,
447-
optional_message_field, arena);
441+
UPB_UPCAST(msg), optional_message_field, arena);
448442
// Verify that newly constructed sub message is stored in msg.
449443
EXPECT_EQ(msg1, msg2);
450444

upb/message/compare.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ static bool _upb_Map_IsEqual(const upb_Map* map1, const upb_Map* map2,
7373
if (size1 != size2) return false;
7474

7575
const upb_MiniTableField* f = upb_MiniTable_MapValue(m);
76-
const upb_MiniTable* m2_value = upb_MiniTable_SubMessage(m, f);
76+
const upb_MiniTable* m2_value = upb_MiniTable_SubMessage(f);
7777
const upb_CType ctype = upb_MiniTableField_CType(f);
7878

7979
upb_MessageValue key, val1, val2;
@@ -109,7 +109,7 @@ static bool _upb_Message_BaseFieldsAreEqual(const upb_Message* msg1,
109109
if (!got1) return true; // Loop termination condition.
110110
if (f1 != f2) return false; // Must have identical fields set.
111111

112-
const upb_MiniTable* subm = upb_MiniTable_SubMessage(m, f1);
112+
const upb_MiniTable* subm = upb_MiniTable_SubMessage(f1);
113113
const upb_CType ctype = upb_MiniTableField_CType(f1);
114114

115115
bool eq;

upb/message/copy.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type,
9797
upb_MiniTable_MapValue(map_entry_table);
9898
const upb_MiniTable* value_sub =
9999
upb_MiniTableField_CType(value_field) == kUpb_CType_Message
100-
? upb_MiniTable_GetSubMessageTable(map_entry_table, value_field)
100+
? upb_MiniTable_GetSubMessageTable(value_field)
101101
: NULL;
102102
upb_CType value_field_type = upb_MiniTableField_CType(value_field);
103103
if (!upb_Clone_MessageValue(&val, value_field_type, value_sub, arena)) {
@@ -116,8 +116,7 @@ static upb_Map* upb_Message_Map_DeepClone(const upb_Map* map,
116116
upb_Message* clone,
117117
upb_Arena* arena) {
118118
UPB_ASSERT(!upb_Message_IsFrozen(clone));
119-
const upb_MiniTable* map_entry_table =
120-
upb_MiniTable_MapEntrySubMessage(mini_table, f);
119+
const upb_MiniTable* map_entry_table = upb_MiniTable_MapEntrySubMessage(f);
121120
UPB_ASSERT(map_entry_table);
122121

123122
const upb_MiniTableField* key_field = upb_MiniTable_MapKey(map_entry_table);
@@ -161,12 +160,12 @@ static bool upb_Message_Array_DeepClone(const upb_Array* array,
161160
upb_Message* clone, upb_Arena* arena) {
162161
UPB_ASSERT(!upb_Message_IsFrozen(clone));
163162
UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(field);
164-
upb_Array* cloned_array = upb_Array_DeepClone(
165-
array, upb_MiniTableField_CType(field),
166-
upb_MiniTableField_CType(field) == kUpb_CType_Message
167-
? upb_MiniTable_GetSubMessageTable(mini_table, field)
168-
: NULL,
169-
arena);
163+
upb_Array* cloned_array =
164+
upb_Array_DeepClone(array, upb_MiniTableField_CType(field),
165+
upb_MiniTableField_CType(field) == kUpb_CType_Message
166+
? upb_MiniTable_GetSubMessageTable(field)
167+
: NULL,
168+
arena);
170169

171170
// Clear out upb_Array* due to parent memcpy.
172171
upb_Message_SetBaseField(clone, field, &cloned_array);
@@ -198,7 +197,7 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src,
198197
const upb_Message* sub_message = upb_Message_GetMessage(src, field);
199198
if (sub_message != NULL) {
200199
const upb_MiniTable* sub_message_table =
201-
upb_MiniTable_GetSubMessageTable(mini_table, field);
200+
upb_MiniTable_GetSubMessageTable(field);
202201
upb_Message* dst_sub_message =
203202
upb_Message_DeepClone(sub_message, sub_message_table, arena);
204203
if (dst_sub_message == NULL) {

upb/message/internal/accessors.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -500,16 +500,14 @@ UPB_API_INLINE struct upb_Map* upb_Message_GetOrCreateMutableMap(
500500
}
501501

502502
UPB_API_INLINE struct upb_Message* upb_Message_GetOrCreateMutableMessage(
503-
struct upb_Message* msg, const upb_MiniTable* mini_table,
504-
const upb_MiniTableField* f, upb_Arena* arena) {
503+
struct upb_Message* msg, const upb_MiniTableField* f, upb_Arena* arena) {
505504
UPB_ASSERT(arena);
506505
UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Message);
507506
UPB_ASSUME(!upb_MiniTableField_IsExtension(f));
508507
struct upb_Message* sub_message =
509508
*UPB_PTR_AT(msg, f->UPB_ONLYBITS(offset), struct upb_Message*);
510509
if (!sub_message) {
511-
const upb_MiniTable* sub_mini_table =
512-
upb_MiniTable_SubMessage(mini_table, f);
510+
const upb_MiniTable* sub_mini_table = upb_MiniTable_SubMessage(f);
513511
UPB_ASSERT(sub_mini_table);
514512
sub_message = _upb_Message_New(sub_mini_table, arena);
515513
*UPB_PTR_AT(msg, f->UPB_ONLYBITS(offset), struct upb_Message*) =
@@ -645,13 +643,12 @@ UPB_API_INLINE void upb_Message_SetBaseFieldUInt64(struct upb_Message* msg,
645643
}
646644

647645
UPB_API_INLINE void upb_Message_SetClosedEnum(struct upb_Message* msg,
648-
const upb_MiniTable* m,
649646
const upb_MiniTableField* f,
650647
int32_t value) {
651648
UPB_ASSERT(upb_MiniTableField_IsClosedEnum(f));
652649
UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_4Byte);
653-
UPB_ASSERT(
654-
upb_MiniTableEnum_CheckValue(upb_MiniTable_GetSubEnumTable(m, f), value));
650+
UPB_ASSERT(upb_MiniTableEnum_CheckValue(upb_MiniTable_GetSubEnumTable(f),
651+
(uint32_t)value));
655652
upb_Message_SetBaseField(msg, f, &value);
656653
}
657654

upb/message/message.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m) {
251251

252252
for (size_t i = 0; i < field_count; i++) {
253253
const upb_MiniTableField* f = upb_MiniTable_GetFieldByIndex(m, i);
254-
const upb_MiniTable* m2 = upb_MiniTable_SubMessage(m, f);
254+
const upb_MiniTable* m2 = upb_MiniTable_SubMessage(f);
255255

256256
switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(f)) {
257257
case kUpb_FieldMode_Array: {
@@ -263,7 +263,7 @@ void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m) {
263263
upb_Map* map = upb_Message_GetMutableMap(msg, f);
264264
if (map) {
265265
const upb_MiniTableField* f2 = upb_MiniTable_MapValue(m2);
266-
const upb_MiniTable* m3 = upb_MiniTable_SubMessage(m2, f2);
266+
const upb_MiniTable* m3 = upb_MiniTable_SubMessage(f2);
267267
upb_Map_Freeze(map, m3);
268268
}
269269
break;

0 commit comments

Comments
 (0)