|
|
|
@ -4719,6 +4719,10 @@ upb_alloc upb_alloc_global = {&upb_global_allocfunc}; |
|
|
|
|
|
|
|
|
|
// Must be last.
|
|
|
|
|
|
|
|
|
|
static UPB_ATOMIC(size_t) max_block_size = 32 << 10; |
|
|
|
|
|
|
|
|
|
void upb_Arena_SetMaxBlockSize(size_t max) { max_block_size = max; } |
|
|
|
|
|
|
|
|
|
typedef struct upb_MemBlock { |
|
|
|
|
// Atomic only for the benefit of SpaceAllocated().
|
|
|
|
|
UPB_ATOMIC(struct upb_MemBlock*) next; |
|
|
|
@ -4956,7 +4960,14 @@ static bool _upb_Arena_AllocBlock(upb_Arena* a, size_t size) { |
|
|
|
|
if (!ai->block_alloc) return false; |
|
|
|
|
upb_MemBlock* last_block = upb_Atomic_Load(&ai->blocks, memory_order_acquire); |
|
|
|
|
size_t last_size = last_block != NULL ? last_block->size : 128; |
|
|
|
|
size_t block_size = UPB_MAX(size, last_size * 2) + kUpb_MemblockReserve; |
|
|
|
|
|
|
|
|
|
// Don't naturally grow beyond the max block size.
|
|
|
|
|
size_t clamped_size = UPB_MIN(last_size * 2, max_block_size); |
|
|
|
|
|
|
|
|
|
// We may need to exceed the max block size if the user requested a large
|
|
|
|
|
// allocation.
|
|
|
|
|
size_t block_size = UPB_MAX(size, clamped_size) + kUpb_MemblockReserve; |
|
|
|
|
|
|
|
|
|
upb_MemBlock* block = |
|
|
|
|
upb_malloc(_upb_ArenaInternal_BlockAlloc(ai), block_size); |
|
|
|
|
|
|
|
|
|