39 #ifdef ADDRESS_SANITIZER
40 #include <sanitizer/asan_interface.h>
41 #endif // ADDRESS_SANITIZER
43 #include <google/protobuf/port_def.inc>
54 #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
56 static internal::ThreadLocalStorage<ThreadCache>*
thread_cache_ =
57 new internal::ThreadLocalStorage<ThreadCache>();
60 #elif defined(PROTOBUF_USE_DLLS)
72 hint_.store(
nullptr, std::memory_order_relaxed);
73 threads_.store(
nullptr, std::memory_order_relaxed);
83 threads_.store(serial, std::memory_order_relaxed);
85 std::memory_order_relaxed);
106 return space_allocated;
132 void (*cleanup)(
void*)) {
137 list->
next = cleanup_;
141 cleanup_ptr_ = &list->
nodes[0];
147 PROTOBUF_FUNC_ALIGN(32)
158 void (*cleanup)(
void*)) {
183 void (*cleanup)(
void*)) {
206 if (PROTOBUF_PREDICT_TRUE(serial !=
NULL && serial->
owner() == tc)) {
226 head_->set_pos(head_->size() - (limit_ - ptr_));
228 head_ =
arena_->NewBlock(head_,
n);
229 ptr_ = head_->Pointer(head_->pos());
230 limit_ = head_->Pointer(head_->size());
232 #ifdef ADDRESS_SANITIZER
233 ASAN_POISON_MEMORY_REGION(ptr_, limit_ - ptr_);
234 #endif // ADDRESS_SANITIZER
246 for (; serial; serial = serial->
next()) {
265 uint64 space_allocated = 0;
279 return space_allocated;
283 Block* initial_block,
284 void (*block_dealloc)(
void*,
size_t)) {
285 uint64 space_allocated = 0;
293 space_allocated += (
b->size());
295 #ifdef ADDRESS_SANITIZER
298 ASAN_UNPOISON_MEMORY_REGION(
b->Pointer(0),
b->size());
299 #endif // ADDRESS_SANITIZER
301 if (
b != initial_block) {
302 block_dealloc(
b,
b->size());
308 return space_allocated;
316 for (; serial; serial = serial->
next()) {
322 if (cleanup_ !=
NULL) {
323 CleanupListFallback();
330 size_t n = cleanup_ptr_ - &cleanup_->nodes[0];
335 for (
size_t i =
n;
i > 0;
i--) {
339 if (list ==
nullptr) {
357 serial->
ptr_ =
b->Pointer(
b->pos());
358 serial->
limit_ =
b->Pointer(
b->size());
369 for (; serial; serial = serial->
next()) {
370 if (serial->
owner() == me) {
384 }
while (!
threads_.compare_exchange_weak(
385 head, serial, std::memory_order_release, std::memory_order_relaxed));
394 void Arena::CallDestructorHooks() {
395 uint64 space_allocated = impl_.SpaceAllocated();
397 if (on_arena_reset_ !=
NULL) {
398 on_arena_reset_(
this, hooks_cookie_, space_allocated);
402 if (on_arena_destruction_ !=
NULL) {
403 on_arena_destruction_(
this, hooks_cookie_, space_allocated);
407 void Arena::OnArenaAllocation(
const std::type_info* allocated_type,
409 if (on_arena_allocation_ !=
NULL) {
410 on_arena_allocation_(allocated_type,
n, hooks_cookie_);