From 10c3e3dfb6a1ff3926d45631d114af651d6cc2f3 Mon Sep 17 00:00:00 2001 From: Eric Salo Date: Sun, 3 Dec 2023 20:45:27 -0800 Subject: [PATCH] upb: move some extension-related message functions PiperOrigin-RevId: 587586555 --- upb/message/BUILD | 2 + upb/message/internal/extension.c | 63 ++++++++++++++++++++++ upb/message/internal/extension.h | 1 - upb/message/internal/message.c | 58 ++++++++++++++++++++ upb/message/internal/message.h | 10 ++-- upb/message/message.c | 92 ++------------------------------ upb/message/message.h | 5 -- 7 files changed, 132 insertions(+), 99 deletions(-) create mode 100644 upb/message/internal/extension.c create mode 100644 upb/message/internal/message.c diff --git a/upb/message/BUILD b/upb/message/BUILD index b218502306..6c7d3eb55c 100644 --- a/upb/message/BUILD +++ b/upb/message/BUILD @@ -94,6 +94,8 @@ cc_library( srcs = [ "array.c", "array.h", + "internal/extension.c", + "internal/message.c", "map.c", "map.h", "map_sorter.c", diff --git a/upb/message/internal/extension.c b/upb/message/internal/extension.c new file mode 100644 index 0000000000..6998f26f9f --- /dev/null +++ b/upb/message/internal/extension.c @@ -0,0 +1,63 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google LLC. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "upb/message/internal/extension.h" + +#include + +#include "upb/mem/arena.h" +#include "upb/message/internal/extension.h" +#include "upb/message/internal/message.h" +#include "upb/message/types.h" +#include "upb/mini_table/extension.h" + +// Must be last. +#include "upb/port/def.inc" + +const upb_Message_Extension* _upb_Message_Getext( + const upb_Message* msg, const upb_MiniTableExtension* e) { + size_t n; + const upb_Message_Extension* ext = _upb_Message_Getexts(msg, &n); + + // For now we use linear search exclusively to find extensions. + // If this becomes an issue due to messages with lots of extensions, + // we can introduce a table of some sort. + for (size_t i = 0; i < n; i++) { + if (ext[i].ext == e) { + return &ext[i]; + } + } + + return NULL; +} + +const upb_Message_Extension* _upb_Message_Getexts(const upb_Message* msg, + size_t* count) { + const upb_Message_Internal* in = upb_Message_Getinternal(msg); + if (in->internal) { + *count = (in->internal->size - in->internal->ext_begin) / + sizeof(upb_Message_Extension); + return UPB_PTR_AT(in->internal, in->internal->ext_begin, void); + } else { + *count = 0; + return NULL; + } +} + +upb_Message_Extension* _upb_Message_GetOrCreateExtension( + upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* arena) { + upb_Message_Extension* ext = + (upb_Message_Extension*)_upb_Message_Getext(msg, e); + if (ext) return ext; + if (!UPB_PRIVATE(_upb_Message_Realloc)(msg, sizeof(upb_Message_Extension), arena)) return NULL; + upb_Message_Internal* in = upb_Message_Getinternal(msg); + in->internal->ext_begin -= sizeof(upb_Message_Extension); + ext = UPB_PTR_AT(in->internal, in->internal->ext_begin, void); + memset(ext, 0, sizeof(upb_Message_Extension)); + ext->ext = e; + return ext; +} diff --git a/upb/message/internal/extension.h b/upb/message/internal/extension.h index ab653abc84..799b32a837 100644 --- a/upb/message/internal/extension.h +++ b/upb/message/internal/extension.h @@ -8,7 +8,6 @@ #ifndef UPB_MESSAGE_INTERNAL_EXTENSION_H_ #define UPB_MESSAGE_INTERNAL_EXTENSION_H_ -#include "upb/base/descriptor_constants.h" #include "upb/base/string_view.h" #include "upb/mem/arena.h" #include "upb/message/message.h" diff --git a/upb/message/internal/message.c b/upb/message/internal/message.c new file mode 100644 index 0000000000..94ed339a72 --- /dev/null +++ b/upb/message/internal/message.c @@ -0,0 +1,58 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google LLC. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "upb/message/message.h" + +#include +#include + +#include "upb/base/internal/log2.h" +#include "upb/mem/arena.h" +#include "upb/message/internal/message.h" +#include "upb/message/internal/types.h" + +// Must be last. +#include "upb/port/def.inc" + +const float kUpb_FltInfinity = INFINITY; +const double kUpb_Infinity = INFINITY; +const double kUpb_NaN = NAN; + +static const size_t realloc_overhead = sizeof(upb_Message_InternalData); + +bool UPB_PRIVATE(_upb_Message_Realloc)(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 + realloc_overhead)); + upb_Message_InternalData* internal = upb_Arena_Malloc(arena, size); + if (!internal) return false; + internal->size = size; + internal->unknown_end = realloc_overhead; + internal->ext_begin = size; + 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 ext_bytes = in->internal->size - in->internal->ext_begin; + size_t new_ext_begin = new_size - ext_bytes; + upb_Message_InternalData* internal = + upb_Arena_Realloc(arena, in->internal, in->internal->size, new_size); + if (!internal) return false; + if (ext_bytes) { + // Need to move extension data to the end. + char* ptr = (char*)internal; + memmove(ptr + new_ext_begin, ptr + internal->ext_begin, ext_bytes); + } + internal->ext_begin = new_ext_begin; + internal->size = new_size; + in->internal = internal; + } + UPB_ASSERT(in->internal->ext_begin - in->internal->unknown_end >= need); + return true; +} diff --git a/upb/message/internal/message.h b/upb/message/internal/message.h index acb981555d..c93ff783f9 100644 --- a/upb/message/internal/message.h +++ b/upb/message/internal/message.h @@ -18,11 +18,9 @@ #include #include +#include "upb/mem/arena.h" #include "upb/message/internal/extension.h" #include "upb/message/internal/types.h" -#include "upb/message/message.h" -#include "upb/mini_table/extension.h" -#include "upb/mini_table/extension_registry.h" #include "upb/mini_table/message.h" // Must be last. @@ -65,9 +63,6 @@ struct upb_Message_InternalData { * char data[size - sizeof(upb_Message_InternalData)]; */ }; -/* Maps upb_CType -> memory size. */ -extern char _upb_CTypeo_size[12]; - UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* m) { return m->size + sizeof(upb_Message_Internal); } @@ -97,6 +92,9 @@ void _upb_Message_DiscardUnknown_shallow(upb_Message* msg); bool _upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len, upb_Arena* arena); +bool UPB_PRIVATE(_upb_Message_Realloc)(upb_Message* msg, size_t need, + upb_Arena* arena); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/upb/message/message.c b/upb/message/message.c index 265d30df13..01a881457e 100644 --- a/upb/message/message.c +++ b/upb/message/message.c @@ -7,60 +7,22 @@ #include "upb/message/message.h" -#include - -#include "upb/base/internal/log2.h" #include "upb/message/internal/message.h" +#include "upb/message/internal/types.h" // Must be last. #include "upb/port/def.inc" -const float kUpb_FltInfinity = INFINITY; -const double kUpb_Infinity = INFINITY; -const double kUpb_NaN = NAN; - -static const size_t overhead = sizeof(upb_Message_InternalData); +static const size_t message_overhead = sizeof(upb_Message_InternalData); upb_Message* upb_Message_New(const upb_MiniTable* mini_table, upb_Arena* arena) { return _upb_Message_New(mini_table, arena); } -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)); - upb_Message_InternalData* internal = upb_Arena_Malloc(arena, size); - if (!internal) return false; - internal->size = size; - internal->unknown_end = overhead; - internal->ext_begin = size; - 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 ext_bytes = in->internal->size - in->internal->ext_begin; - size_t new_ext_begin = new_size - ext_bytes; - upb_Message_InternalData* internal = - upb_Arena_Realloc(arena, in->internal, in->internal->size, new_size); - if (!internal) return false; - if (ext_bytes) { - /* Need to move extension data to the end. */ - char* ptr = (char*)internal; - memmove(ptr + new_ext_begin, ptr + internal->ext_begin, ext_bytes); - } - internal->ext_begin = new_ext_begin; - internal->size = new_size; - in->internal = internal; - } - UPB_ASSERT(in->internal->ext_begin - in->internal->unknown_end >= need); - return true; -} - bool _upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len, upb_Arena* arena) { - if (!realloc_internal(msg, len, arena)) return false; + if (!UPB_PRIVATE(_upb_Message_Realloc)(msg, len, arena)) return false; upb_Message_Internal* in = upb_Message_Getinternal(msg); memcpy(UPB_PTR_AT(in->internal, in->internal->unknown_end, char), data, len); in->internal->unknown_end += len; @@ -70,14 +32,14 @@ bool _upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len, void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) { upb_Message_Internal* in = upb_Message_Getinternal(msg); if (in->internal) { - in->internal->unknown_end = overhead; + in->internal->unknown_end = message_overhead; } } const char* upb_Message_GetUnknown(const upb_Message* msg, size_t* len) { const upb_Message_Internal* in = upb_Message_Getinternal(msg); if (in->internal) { - *len = in->internal->unknown_end - overhead; + *len = in->internal->unknown_end - message_overhead; return (char*)(in->internal + 1); } else { *len = 0; @@ -103,50 +65,6 @@ void upb_Message_DeleteUnknown(upb_Message* msg, const char* data, size_t len) { in->internal->unknown_end -= len; } -const upb_Message_Extension* _upb_Message_Getexts(const upb_Message* msg, - size_t* count) { - const upb_Message_Internal* in = upb_Message_Getinternal(msg); - if (in->internal) { - *count = (in->internal->size - in->internal->ext_begin) / - sizeof(upb_Message_Extension); - return UPB_PTR_AT(in->internal, in->internal->ext_begin, void); - } else { - *count = 0; - return NULL; - } -} - -const upb_Message_Extension* _upb_Message_Getext( - const upb_Message* msg, const upb_MiniTableExtension* e) { - size_t n; - const upb_Message_Extension* ext = _upb_Message_Getexts(msg, &n); - - /* For now we use linear search exclusively to find extensions. If this - * becomes an issue due to messages with lots of extensions, we can introduce - * a table of some sort. */ - for (size_t i = 0; i < n; i++) { - if (ext[i].ext == e) { - return &ext[i]; - } - } - - return NULL; -} - -upb_Message_Extension* _upb_Message_GetOrCreateExtension( - upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* arena) { - upb_Message_Extension* ext = - (upb_Message_Extension*)_upb_Message_Getext(msg, e); - if (ext) return ext; - if (!realloc_internal(msg, sizeof(upb_Message_Extension), arena)) return NULL; - upb_Message_Internal* in = upb_Message_Getinternal(msg); - in->internal->ext_begin -= sizeof(upb_Message_Extension); - ext = UPB_PTR_AT(in->internal, in->internal->ext_begin, void); - memset(ext, 0, sizeof(upb_Message_Extension)); - ext->ext = e; - return ext; -} - size_t upb_Message_ExtensionCount(const upb_Message* msg) { size_t count; _upb_Message_Getexts(msg, &count); diff --git a/upb/message/message.h b/upb/message/message.h index 705803acbe..80d0796ffd 100644 --- a/upb/message/message.h +++ b/upb/message/message.h @@ -29,11 +29,6 @@ extern "C" { UPB_API upb_Message* upb_Message_New(const upb_MiniTable* mini_table, upb_Arena* arena); -// Adds unknown data (serialized protobuf data) to the given message. -// The data is copied into the message instance. -void upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len, - upb_Arena* arena); - // Returns a reference to the message's unknown data. const char* upb_Message_GetUnknown(const upb_Message* msg, size_t* len);