void ArenaStack::UpdateBytesAllocated() { if (top_arena_ != nullptr) { // Update how many bytes we have allocated into the arena so that the arena pool knows how // much memory to zero out. Though ScopedArenaAllocator doesn't guarantee the memory is // zero-initialized, the Arena may be reused by ArenaAllocator which does guarantee this.
size_t allocated = static_cast<size_t>(top_ptr_ - top_arena_->Begin()); if (top_arena_->bytes_allocated_ < allocated) {
top_arena_->bytes_allocated_ = allocated;
}
}
}
void* ArenaStack::AllocWithMemoryTool(size_t bytes, ArenaAllocKind kind) { // We mark all memory for a newly retrieved arena as inaccessible and then // mark only the actually allocated memory as defined. That leaves red zones // and padding between allocations marked as inaccessible.
size_t rounded_bytes = RoundUp(bytes + kMemoryToolRedZoneBytes, 8);
uint8_t* ptr = top_ptr_; if (UNLIKELY(static_cast<size_t>(top_end_ - ptr) < rounded_bytes)) {
ptr = AllocateFromNextArena(rounded_bytes);
CHECK(ptr != nullptr) << "Failed to allocate memory";
MEMORY_TOOL_MAKE_NOACCESS(ptr, top_end_ - ptr);
}
CurrentStats()->RecordAlloc(bytes, kind);
top_ptr_ = ptr + rounded_bytes;
MEMORY_TOOL_MAKE_UNDEFINED(ptr, bytes); return ptr;
}
size_t ArenaStack::ApproximatePeakBytes() {
UpdateBytesAllocated();
size_t sum = 0; for (Arena* arena = bottom_arena_; arena != nullptr; arena = arena->next_) {
sum += arena->bytes_allocated_;
} return sum;
}
ScopedArenaAllocator::ScopedArenaAllocator(ScopedArenaAllocator&& other) noexcept
: DebugStackReference(std::move(other)),
DebugStackRefCounter(), // NOLINTBEGIN(bugprone-use-after-move) - the accessed fields are still valid after the move
ArenaAllocatorStats(other),
arena_stack_(other.arena_stack_),
mark_arena_(other.mark_arena_),
mark_ptr_(other.mark_ptr_),
mark_end_(other.mark_end_) {
other.DebugStackRefCounter::CheckNoRefs();
other.arena_stack_ = nullptr; // NOLINTEND(bugprone-use-after-move)
}
ScopedArenaAllocator::~ScopedArenaAllocator() { if (arena_stack_ != nullptr) {
DoReset();
}
}
void ScopedArenaAllocator::Reset() {
DoReset(); // If this allocator was Create()d, we need to move the arena_stack_->top_ptr_ past *this. if (mark_ptr_ == reinterpret_cast<uint8_t*>(this)) {
arena_stack_->top_ptr_ = mark_ptr_ + RoundUp(sizeof(ScopedArenaAllocator), 8);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.