Auto-generate files after cl/734258255

This commit is contained in:
Protobuf Team Bot 2025-03-06 21:18:27 +00:00
parent 256444c875
commit 3c50c0da0e
4 changed files with 248 additions and 22 deletions

View file

@ -4262,17 +4262,38 @@ bool UPB_PRIVATE(_upb_Message_AddUnknown)(upb_Message* msg, const char* data,
size_t len, upb_Arena* arena,
bool alias) {
UPB_ASSERT(!upb_Message_IsFrozen(msg));
if (alias) {
// Fast path if the field we're adding is immediately after the last added
// unknown field.
{
upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
if (in && in->size) {
upb_TaggedAuxPtr ptr = in->aux_data[in->size - 1];
if (upb_TaggedAuxPtr_IsUnknown(ptr)) {
upb_StringView* existing = upb_TaggedAuxPtr_UnknownData(ptr);
if (existing->data + existing->size == data) {
existing->size += len;
return true;
bool was_aliased = upb_TaggedAuxPtr_IsUnknownAliased(ptr);
if (alias) {
// Fast path if the field we're adding is immediately after the last
// added unknown field.
if (was_aliased && existing->data + existing->size == data) {
existing->size += len;
return true;
}
} else if (!was_aliased) {
// If part of the existing field was deleted at the beginning, we can
// reconstruct it by comparing the address of the end with the address
// of the entry itself; having the non-aliased tag means that the
// string_view and the data it points to are part of the same original
// upb_Arena_Malloc allocation, and the end of the string view
// represents the end of that allocation.
size_t prev_alloc_size =
(existing->data + existing->size) - (char*)existing;
if (SIZE_MAX - prev_alloc_size >= len) {
size_t new_alloc_size = prev_alloc_size + len;
if (upb_Arena_TryExtend(arena, existing, prev_alloc_size,
new_alloc_size)) {
memcpy(UPB_PTR_AT(existing, prev_alloc_size, void), data, len);
existing->size += len;
return true;
}
}
}
}
}
@ -4297,7 +4318,9 @@ bool UPB_PRIVATE(_upb_Message_AddUnknown)(upb_Message* msg, const char* data,
}
view->size = len;
upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
in->aux_data[in->size++] = upb_TaggedAuxPtr_MakeUnknownData(view);
in->aux_data[in->size++] = alias
? upb_TaggedAuxPtr_MakeUnknownDataAliased(view)
: upb_TaggedAuxPtr_MakeUnknownData(view);
return true;
}
@ -4309,8 +4332,40 @@ bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg,
UPB_ASSERT(count > 0);
size_t total_len = 0;
for (size_t i = 0; i < count; i++) {
if (SIZE_MAX - total_len < data[i].size) {
return false;
}
total_len += data[i].size;
}
{
upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
if (in && in->size) {
upb_TaggedAuxPtr ptr = in->aux_data[in->size - 1];
if (upb_TaggedAuxPtr_IsUnknown(ptr)) {
upb_StringView* existing = upb_TaggedAuxPtr_UnknownData(ptr);
if (!upb_TaggedAuxPtr_IsUnknownAliased(ptr)) {
size_t prev_alloc_size =
(existing->data + existing->size) - (char*)existing;
if (SIZE_MAX - prev_alloc_size >= total_len) {
size_t new_alloc_size = prev_alloc_size + total_len;
if (upb_Arena_TryExtend(arena, existing, prev_alloc_size,
new_alloc_size)) {
char* copy = UPB_PTR_AT(existing, prev_alloc_size, char);
for (size_t i = 0; i < count; i++) {
memcpy(copy, data[i].data, data[i].size);
copy += data[i].size;
}
existing->size += total_len;
return true;
}
}
}
}
}
}
if (SIZE_MAX - sizeof(upb_StringView) < total_len) return false;
if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, arena)) return false;
upb_StringView* view =
@ -4368,6 +4423,10 @@ upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown(upb_Message* msg,
} else if (unknown->data + unknown->size == data->data + data->size) {
// Truncate existing field
unknown->size -= data->size;
if (!upb_TaggedAuxPtr_IsUnknownAliased(unknown_ptr)) {
in->aux_data[*iter - 1] =
upb_TaggedAuxPtr_MakeUnknownDataAliased(unknown);
}
} else {
UPB_ASSERT(unknown->data < data->data &&
unknown->data + unknown->size > data->data + data->size);
@ -4386,7 +4445,10 @@ upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown(upb_Message* msg,
memmove(&in->aux_data[*iter + 1], &in->aux_data[*iter],
sizeof(upb_TaggedAuxPtr) * (in->size - *iter));
}
in->aux_data[*iter] = upb_TaggedAuxPtr_MakeUnknownData(suffix);
in->aux_data[*iter] = upb_TaggedAuxPtr_MakeUnknownDataAliased(suffix);
if (!upb_TaggedAuxPtr_IsUnknownAliased(unknown_ptr)) {
in->aux_data[*iter - 1] = upb_TaggedAuxPtr_MakeUnknownDataAliased(prefix);
}
in->size++;
suffix->data = data->data + data->size;
suffix->size = (prefix->data + prefix->size) - suffix->data;

View file

@ -789,7 +789,28 @@ UPB_API_INLINE void upb_Arena_ShrinkLast(struct upb_Arena* a, void* ptr,
UPB_ASSERT(_upb_Arena_WasLastAlloc(a, ptr, oldsize));
#endif
}
UPB_POISON_MEMORY_REGION((char*)ptr + size, oldsize - size);
UPB_POISON_MEMORY_REGION((char*)ptr + (size - UPB_ASAN_GUARD_SIZE),
oldsize - size);
}
UPB_API_INLINE bool upb_Arena_TryExtend(struct upb_Arena* a, void* ptr,
size_t oldsize, size_t size) {
UPB_TSAN_CHECK_WRITE(a->UPB_ONLYBITS(ptr));
UPB_ASSERT(size > oldsize);
size = UPB_ALIGN_MALLOC(size) + UPB_ASAN_GUARD_SIZE;
oldsize = UPB_ALIGN_MALLOC(oldsize) + UPB_ASAN_GUARD_SIZE;
if (size == oldsize) {
return true;
}
size_t extend = size - oldsize;
if ((char*)ptr + oldsize == a->UPB_ONLYBITS(ptr) &&
UPB_PRIVATE(_upb_ArenaHas)(a) >= extend) {
a->UPB_ONLYBITS(ptr) += extend;
UPB_UNPOISON_MEMORY_REGION((char*)ptr + (oldsize - UPB_ASAN_GUARD_SIZE),
extend);
return true;
}
return false;
}
#ifdef __cplusplus
@ -881,6 +902,16 @@ void upb_Arena_SetMaxBlockSize(size_t max);
UPB_API_INLINE void upb_Arena_ShrinkLast(upb_Arena* a, void* ptr,
size_t oldsize, size_t size);
// Attempts to extend the given alloc from arena, in place. Is generally
// only likely to succeed for the most recent allocation from this arena. If it
// succeeds, returns true and `ptr`'s allocation is now `size` rather than
// `oldsize`. Returns false if the allocation cannot be extended; `ptr`'s
// allocation is unmodified. See also upb_Arena_Realloc.
// REQUIRES: `size > oldsize`; to shrink, use `upb_Arena_Realloc` or
// `upb_Arena_ShrinkLast`.
UPB_API_INLINE bool upb_Arena_TryExtend(upb_Arena* a, void* ptr, size_t oldsize,
size_t size);
#ifdef UPB_TRACING_ENABLED
void upb_Arena_SetTraceHandler(void (*initArenaTraceHandler)(const upb_Arena*,
size_t size),
@ -3315,6 +3346,10 @@ extern const double kUpb_NaN;
// extensions. We can change this without breaking binary compatibility.
typedef struct upb_TaggedAuxPtr {
// Two lowest bits form a tag:
// 00 - non-aliased unknown data
// 10 - aliased unknown data
// 01 - extension
uintptr_t ptr;
} upb_TaggedAuxPtr;
@ -3330,14 +3365,18 @@ UPB_INLINE bool upb_TaggedAuxPtr_IsUnknown(upb_TaggedAuxPtr ptr) {
return (ptr.ptr != 0) && ((ptr.ptr & 1) == 0);
}
UPB_INLINE bool upb_TaggedAuxPtr_IsUnknownAliased(upb_TaggedAuxPtr ptr) {
return (ptr.ptr != 0) && ((ptr.ptr & 2) == 2);
}
UPB_INLINE upb_Extension* upb_TaggedAuxPtr_Extension(upb_TaggedAuxPtr ptr) {
UPB_ASSERT(upb_TaggedAuxPtr_IsExtension(ptr));
return (upb_Extension*)(ptr.ptr & ~1ULL);
return (upb_Extension*)(ptr.ptr & ~3ULL);
}
UPB_INLINE upb_StringView* upb_TaggedAuxPtr_UnknownData(upb_TaggedAuxPtr ptr) {
UPB_ASSERT(!upb_TaggedAuxPtr_IsExtension(ptr));
return (upb_StringView*)(ptr.ptr);
return (upb_StringView*)(ptr.ptr & ~3ULL);
}
UPB_INLINE upb_TaggedAuxPtr upb_TaggedAuxPtr_Null(void) {
@ -3353,6 +3392,9 @@ upb_TaggedAuxPtr_MakeExtension(const upb_Extension* e) {
return ptr;
}
// This tag means that the original allocation for this field starts with the
// string view and ends with the end of the content referenced by the string
// view.
UPB_INLINE upb_TaggedAuxPtr
upb_TaggedAuxPtr_MakeUnknownData(const upb_StringView* sv) {
upb_TaggedAuxPtr ptr;
@ -3360,6 +3402,15 @@ upb_TaggedAuxPtr_MakeUnknownData(const upb_StringView* sv) {
return ptr;
}
// This tag implies no guarantee between the relationship of the string view and
// the data it points to.
UPB_INLINE upb_TaggedAuxPtr
upb_TaggedAuxPtr_MakeUnknownDataAliased(const upb_StringView* sv) {
upb_TaggedAuxPtr ptr;
ptr.ptr = (uintptr_t)sv | 2;
return ptr;
}
typedef struct upb_Message_Internal {
// Total number of entries set in aux_data
uint32_t size;

View file

@ -4262,17 +4262,38 @@ bool UPB_PRIVATE(_upb_Message_AddUnknown)(upb_Message* msg, const char* data,
size_t len, upb_Arena* arena,
bool alias) {
UPB_ASSERT(!upb_Message_IsFrozen(msg));
if (alias) {
// Fast path if the field we're adding is immediately after the last added
// unknown field.
{
upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
if (in && in->size) {
upb_TaggedAuxPtr ptr = in->aux_data[in->size - 1];
if (upb_TaggedAuxPtr_IsUnknown(ptr)) {
upb_StringView* existing = upb_TaggedAuxPtr_UnknownData(ptr);
if (existing->data + existing->size == data) {
existing->size += len;
return true;
bool was_aliased = upb_TaggedAuxPtr_IsUnknownAliased(ptr);
if (alias) {
// Fast path if the field we're adding is immediately after the last
// added unknown field.
if (was_aliased && existing->data + existing->size == data) {
existing->size += len;
return true;
}
} else if (!was_aliased) {
// If part of the existing field was deleted at the beginning, we can
// reconstruct it by comparing the address of the end with the address
// of the entry itself; having the non-aliased tag means that the
// string_view and the data it points to are part of the same original
// upb_Arena_Malloc allocation, and the end of the string view
// represents the end of that allocation.
size_t prev_alloc_size =
(existing->data + existing->size) - (char*)existing;
if (SIZE_MAX - prev_alloc_size >= len) {
size_t new_alloc_size = prev_alloc_size + len;
if (upb_Arena_TryExtend(arena, existing, prev_alloc_size,
new_alloc_size)) {
memcpy(UPB_PTR_AT(existing, prev_alloc_size, void), data, len);
existing->size += len;
return true;
}
}
}
}
}
@ -4297,7 +4318,9 @@ bool UPB_PRIVATE(_upb_Message_AddUnknown)(upb_Message* msg, const char* data,
}
view->size = len;
upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
in->aux_data[in->size++] = upb_TaggedAuxPtr_MakeUnknownData(view);
in->aux_data[in->size++] = alias
? upb_TaggedAuxPtr_MakeUnknownDataAliased(view)
: upb_TaggedAuxPtr_MakeUnknownData(view);
return true;
}
@ -4309,8 +4332,40 @@ bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg,
UPB_ASSERT(count > 0);
size_t total_len = 0;
for (size_t i = 0; i < count; i++) {
if (SIZE_MAX - total_len < data[i].size) {
return false;
}
total_len += data[i].size;
}
{
upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
if (in && in->size) {
upb_TaggedAuxPtr ptr = in->aux_data[in->size - 1];
if (upb_TaggedAuxPtr_IsUnknown(ptr)) {
upb_StringView* existing = upb_TaggedAuxPtr_UnknownData(ptr);
if (!upb_TaggedAuxPtr_IsUnknownAliased(ptr)) {
size_t prev_alloc_size =
(existing->data + existing->size) - (char*)existing;
if (SIZE_MAX - prev_alloc_size >= total_len) {
size_t new_alloc_size = prev_alloc_size + total_len;
if (upb_Arena_TryExtend(arena, existing, prev_alloc_size,
new_alloc_size)) {
char* copy = UPB_PTR_AT(existing, prev_alloc_size, char);
for (size_t i = 0; i < count; i++) {
memcpy(copy, data[i].data, data[i].size);
copy += data[i].size;
}
existing->size += total_len;
return true;
}
}
}
}
}
}
if (SIZE_MAX - sizeof(upb_StringView) < total_len) return false;
if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, arena)) return false;
upb_StringView* view =
@ -4368,6 +4423,10 @@ upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown(upb_Message* msg,
} else if (unknown->data + unknown->size == data->data + data->size) {
// Truncate existing field
unknown->size -= data->size;
if (!upb_TaggedAuxPtr_IsUnknownAliased(unknown_ptr)) {
in->aux_data[*iter - 1] =
upb_TaggedAuxPtr_MakeUnknownDataAliased(unknown);
}
} else {
UPB_ASSERT(unknown->data < data->data &&
unknown->data + unknown->size > data->data + data->size);
@ -4386,7 +4445,10 @@ upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown(upb_Message* msg,
memmove(&in->aux_data[*iter + 1], &in->aux_data[*iter],
sizeof(upb_TaggedAuxPtr) * (in->size - *iter));
}
in->aux_data[*iter] = upb_TaggedAuxPtr_MakeUnknownData(suffix);
in->aux_data[*iter] = upb_TaggedAuxPtr_MakeUnknownDataAliased(suffix);
if (!upb_TaggedAuxPtr_IsUnknownAliased(unknown_ptr)) {
in->aux_data[*iter - 1] = upb_TaggedAuxPtr_MakeUnknownDataAliased(prefix);
}
in->size++;
suffix->data = data->data + data->size;
suffix->size = (prefix->data + prefix->size) - suffix->data;

View file

@ -791,7 +791,28 @@ UPB_API_INLINE void upb_Arena_ShrinkLast(struct upb_Arena* a, void* ptr,
UPB_ASSERT(_upb_Arena_WasLastAlloc(a, ptr, oldsize));
#endif
}
UPB_POISON_MEMORY_REGION((char*)ptr + size, oldsize - size);
UPB_POISON_MEMORY_REGION((char*)ptr + (size - UPB_ASAN_GUARD_SIZE),
oldsize - size);
}
UPB_API_INLINE bool upb_Arena_TryExtend(struct upb_Arena* a, void* ptr,
size_t oldsize, size_t size) {
UPB_TSAN_CHECK_WRITE(a->UPB_ONLYBITS(ptr));
UPB_ASSERT(size > oldsize);
size = UPB_ALIGN_MALLOC(size) + UPB_ASAN_GUARD_SIZE;
oldsize = UPB_ALIGN_MALLOC(oldsize) + UPB_ASAN_GUARD_SIZE;
if (size == oldsize) {
return true;
}
size_t extend = size - oldsize;
if ((char*)ptr + oldsize == a->UPB_ONLYBITS(ptr) &&
UPB_PRIVATE(_upb_ArenaHas)(a) >= extend) {
a->UPB_ONLYBITS(ptr) += extend;
UPB_UNPOISON_MEMORY_REGION((char*)ptr + (oldsize - UPB_ASAN_GUARD_SIZE),
extend);
return true;
}
return false;
}
#ifdef __cplusplus
@ -883,6 +904,16 @@ void upb_Arena_SetMaxBlockSize(size_t max);
UPB_API_INLINE void upb_Arena_ShrinkLast(upb_Arena* a, void* ptr,
size_t oldsize, size_t size);
// Attempts to extend the given alloc from arena, in place. Is generally
// only likely to succeed for the most recent allocation from this arena. If it
// succeeds, returns true and `ptr`'s allocation is now `size` rather than
// `oldsize`. Returns false if the allocation cannot be extended; `ptr`'s
// allocation is unmodified. See also upb_Arena_Realloc.
// REQUIRES: `size > oldsize`; to shrink, use `upb_Arena_Realloc` or
// `upb_Arena_ShrinkLast`.
UPB_API_INLINE bool upb_Arena_TryExtend(upb_Arena* a, void* ptr, size_t oldsize,
size_t size);
#ifdef UPB_TRACING_ENABLED
void upb_Arena_SetTraceHandler(void (*initArenaTraceHandler)(const upb_Arena*,
size_t size),
@ -3317,6 +3348,10 @@ extern const double kUpb_NaN;
// extensions. We can change this without breaking binary compatibility.
typedef struct upb_TaggedAuxPtr {
// Two lowest bits form a tag:
// 00 - non-aliased unknown data
// 10 - aliased unknown data
// 01 - extension
uintptr_t ptr;
} upb_TaggedAuxPtr;
@ -3332,14 +3367,18 @@ UPB_INLINE bool upb_TaggedAuxPtr_IsUnknown(upb_TaggedAuxPtr ptr) {
return (ptr.ptr != 0) && ((ptr.ptr & 1) == 0);
}
UPB_INLINE bool upb_TaggedAuxPtr_IsUnknownAliased(upb_TaggedAuxPtr ptr) {
return (ptr.ptr != 0) && ((ptr.ptr & 2) == 2);
}
UPB_INLINE upb_Extension* upb_TaggedAuxPtr_Extension(upb_TaggedAuxPtr ptr) {
UPB_ASSERT(upb_TaggedAuxPtr_IsExtension(ptr));
return (upb_Extension*)(ptr.ptr & ~1ULL);
return (upb_Extension*)(ptr.ptr & ~3ULL);
}
UPB_INLINE upb_StringView* upb_TaggedAuxPtr_UnknownData(upb_TaggedAuxPtr ptr) {
UPB_ASSERT(!upb_TaggedAuxPtr_IsExtension(ptr));
return (upb_StringView*)(ptr.ptr);
return (upb_StringView*)(ptr.ptr & ~3ULL);
}
UPB_INLINE upb_TaggedAuxPtr upb_TaggedAuxPtr_Null(void) {
@ -3355,6 +3394,9 @@ upb_TaggedAuxPtr_MakeExtension(const upb_Extension* e) {
return ptr;
}
// This tag means that the original allocation for this field starts with the
// string view and ends with the end of the content referenced by the string
// view.
UPB_INLINE upb_TaggedAuxPtr
upb_TaggedAuxPtr_MakeUnknownData(const upb_StringView* sv) {
upb_TaggedAuxPtr ptr;
@ -3362,6 +3404,15 @@ upb_TaggedAuxPtr_MakeUnknownData(const upb_StringView* sv) {
return ptr;
}
// This tag implies no guarantee between the relationship of the string view and
// the data it points to.
UPB_INLINE upb_TaggedAuxPtr
upb_TaggedAuxPtr_MakeUnknownDataAliased(const upb_StringView* sv) {
upb_TaggedAuxPtr ptr;
ptr.ptr = (uintptr_t)sv | 2;
return ptr;
}
typedef struct upb_Message_Internal {
// Total number of entries set in aux_data
uint32_t size;