33 #ifndef GOOGLE_PROTOBUF_ARENA_IMPL_H__
34 #define GOOGLE_PROTOBUF_ARENA_IMPL_H__
42 #ifdef ADDRESS_SANITIZER
43 #include <sanitizer/asan_interface.h>
44 #endif // ADDRESS_SANITIZER
46 #include <google/protobuf/port_def.inc>
55 return (
n + 7) &
static_cast<size_t>(-8);
73 void* (*block_alloc)(size_t);
74 void (*block_dealloc)(
void*, size_t);
78 : start_block_size(
options.start_block_size),
79 max_block_size(
options.max_block_size),
80 initial_block(
options.initial_block),
81 initial_block_size(
options.initial_block_size),
82 block_alloc(
options.block_alloc),
83 block_dealloc(
options.block_dealloc) {}
90 <<
": Initial block size too small for header.";
91 initial_block_ =
reinterpret_cast<Block*
>(
options_.initial_block);
93 initial_block_ =
NULL;
107 uint64 SpaceAllocated()
const;
110 void* AllocateAligned(
size_t n);
112 void* AllocateAlignedAndAddCleanup(
size_t n,
void (*cleanup)(
void*));
115 void AddCleanup(
void* elem,
void (*cleanup)(
void*));
118 void* AllocateAlignedFallback(
size_t n);
119 void* AllocateAlignedAndAddCleanupFallback(
size_t n,
void (*cleanup)(
void*));
120 void AddCleanupFallback(
void* elem,
void (*cleanup)(
void*));
154 void (*block_dealloc)(
void*,
size_t));
162 if (PROTOBUF_PREDICT_FALSE(
static_cast<size_t>(limit_ - ptr_) <
n)) {
163 return AllocateAlignedFallback(
n);
167 #ifdef ADDRESS_SANITIZER
168 ASAN_UNPOISON_MEMORY_REGION(ret,
n);
169 #endif // ADDRESS_SANITIZER
174 if (PROTOBUF_PREDICT_FALSE(cleanup_ptr_ == cleanup_limit_)) {
175 AddCleanupFallback(elem, cleanup);
178 cleanup_ptr_->elem = elem;
179 cleanup_ptr_->cleanup = cleanup;
184 void* ret = AllocateAligned(
n);
185 AddCleanup(ret, cleanup);
189 void*
owner()
const {
return owner_; }
194 void* AllocateAlignedFallback(
size_t n);
195 void AddCleanupFallback(
void* elem,
void (*cleanup)(
void*));
196 void CleanupListFallback();
223 return reinterpret_cast<char*
>(
this) +
n;
228 size_t size()
const {
return size_; }
239 #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
252 #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
257 #elif defined(PROTOBUF_USE_DLLS)
275 thread_cache().last_serial_arena = serial;
276 thread_cache().last_lifecycle_id_seen = lifecycle_id_;
281 hint_.store(serial, std::memory_order_release);
284 std::atomic<SerialArena*>
292 Block* NewBlock(
Block* last_block,
size_t min_bytes);
310 static const size_t kBlockHeaderSize =
311 (
sizeof(
Block) + 7) &
static_cast<size_t>(-8);
312 static const size_t kSerialArenaSize =
313 (
sizeof(
SerialArena) + 7) &
static_cast<size_t>(-8);
314 static_assert(kBlockHeaderSize % 8 == 0,
315 "kBlockHeaderSize must be a multiple of 8.");
316 static_assert(kSerialArenaSize % 8 == 0,
317 "kSerialArenaSize must be a multiple of 8.");
324 #include <google/protobuf/port_undef.inc>
326 #endif // GOOGLE_PROTOBUF_ARENA_IMPL_H__