File indexing completed on 2025-01-18 10:13:16
0001
0002
0003
0004
0005
0006
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
0016 #include "upb/port/def.inc"
0017
0018
0019
0020
0021
0022
0023 #define UPB_ARENA_SIZE_HACK 7
0024
0025
0026
0027 struct upb_Arena {
0028 char* UPB_ONLYBITS(ptr);
0029 char* UPB_ONLYBITS(end);
0030 };
0031
0032
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
0044
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
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
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 }
0111 #endif
0112
0113 #include "upb/port/undef.inc"
0114
0115 #endif