Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:16

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2023 Google LLC.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 #ifndef UPB_MEM_INTERNAL_ARENA_H_
0009 #define UPB_MEM_INTERNAL_ARENA_H_
0010 
0011 #include <stddef.h>
0012 #include <stdint.h>
0013 #include <string.h>
0014 
0015 // Must be last.
0016 #include "upb/port/def.inc"
0017 
0018 // This is QUITE an ugly hack, which specifies the number of pointers needed
0019 // to equal (or exceed) the storage required for one upb_Arena.
0020 //
0021 // We need this because the decoder inlines a upb_Arena for performance but
0022 // the full struct is not visible outside of arena.c. Yes, I know, it's awful.
0023 #define UPB_ARENA_SIZE_HACK 7
0024 
0025 // LINT.IfChange(upb_Arena)
0026 
0027 struct upb_Arena {
0028   char* UPB_ONLYBITS(ptr);
0029   char* UPB_ONLYBITS(end);
0030 };
0031 
0032 // LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/arena.ts:upb_Arena)
0033 
0034 #ifdef __cplusplus
0035 extern "C" {
0036 #endif
0037 
0038 void UPB_PRIVATE(_upb_Arena_SwapIn)(struct upb_Arena* des,
0039                                     const struct upb_Arena* src);
0040 void UPB_PRIVATE(_upb_Arena_SwapOut)(struct upb_Arena* des,
0041                                      const struct upb_Arena* src);
0042 
0043 // Returns whether |ptr| was allocated directly by |a| (so care must be used
0044 // with fused arenas).
0045 UPB_API bool UPB_ONLYBITS(_upb_Arena_Contains)(const struct upb_Arena* a,
0046                                                void* ptr);
0047 
0048 UPB_INLINE size_t UPB_PRIVATE(_upb_ArenaHas)(const struct upb_Arena* a) {
0049   return (size_t)(a->UPB_ONLYBITS(end) - a->UPB_ONLYBITS(ptr));
0050 }
0051 
0052 UPB_API_INLINE void* upb_Arena_Malloc(struct upb_Arena* a, size_t size) {
0053   void* UPB_PRIVATE(_upb_Arena_SlowMalloc)(struct upb_Arena * a, size_t size);
0054 
0055   size = UPB_ALIGN_MALLOC(size);
0056   const size_t span = size + UPB_ASAN_GUARD_SIZE;
0057   if (UPB_UNLIKELY(UPB_PRIVATE(_upb_ArenaHas)(a) < span)) {
0058     return UPB_PRIVATE(_upb_Arena_SlowMalloc)(a, span);
0059   }
0060 
0061   // We have enough space to do a fast malloc.
0062   void* ret = a->UPB_ONLYBITS(ptr);
0063   UPB_ASSERT(UPB_ALIGN_MALLOC((uintptr_t)ret) == (uintptr_t)ret);
0064   UPB_ASSERT(UPB_ALIGN_MALLOC(size) == size);
0065   UPB_UNPOISON_MEMORY_REGION(ret, size);
0066 
0067   a->UPB_ONLYBITS(ptr) += span;
0068 
0069   return ret;
0070 }
0071 
0072 UPB_API_INLINE void* upb_Arena_Realloc(struct upb_Arena* a, void* ptr,
0073                                        size_t oldsize, size_t size) {
0074   oldsize = UPB_ALIGN_MALLOC(oldsize);
0075   size = UPB_ALIGN_MALLOC(size);
0076   bool is_most_recent_alloc =
0077       (uintptr_t)ptr + oldsize == (uintptr_t)a->UPB_ONLYBITS(ptr);
0078 
0079   if (is_most_recent_alloc) {
0080     ptrdiff_t diff = size - oldsize;
0081     if ((ptrdiff_t)UPB_PRIVATE(_upb_ArenaHas)(a) >= diff) {
0082       a->UPB_ONLYBITS(ptr) += diff;
0083       return ptr;
0084     }
0085   } else if (size <= oldsize) {
0086     return ptr;
0087   }
0088 
0089   void* ret = upb_Arena_Malloc(a, size);
0090 
0091   if (ret && oldsize > 0) {
0092     memcpy(ret, ptr, UPB_MIN(oldsize, size));
0093   }
0094 
0095   return ret;
0096 }
0097 
0098 UPB_API_INLINE void upb_Arena_ShrinkLast(struct upb_Arena* a, void* ptr,
0099                                          size_t oldsize, size_t size) {
0100   oldsize = UPB_ALIGN_MALLOC(oldsize);
0101   size = UPB_ALIGN_MALLOC(size);
0102   // Must be the last alloc.
0103   UPB_ASSERT((char*)ptr + oldsize ==
0104              a->UPB_ONLYBITS(ptr) - UPB_ASAN_GUARD_SIZE);
0105   UPB_ASSERT(size <= oldsize);
0106   a->UPB_ONLYBITS(ptr) = (char*)ptr + size;
0107 }
0108 
0109 #ifdef __cplusplus
0110 } /* extern "C" */
0111 #endif
0112 
0113 #include "upb/port/undef.inc"
0114 
0115 #endif /* UPB_MEM_INTERNAL_ARENA_H_ */