Branch data Line data Source code
# 1 : : // Copyright (c) 2011 The LevelDB Authors. All rights reserved. # 2 : : // Use of this source code is governed by a BSD-style license that can be # 3 : : // found in the LICENSE file. See the AUTHORS file for names of contributors. # 4 : : # 5 : : #include "util/arena.h" # 6 : : # 7 : : namespace leveldb { # 8 : : # 9 : : static const int kBlockSize = 4096; # 10 : : # 11 : : Arena::Arena() # 12 : 3160 : : alloc_ptr_(nullptr), alloc_bytes_remaining_(0), memory_usage_(0) {} # 13 : : # 14 : 3160 : Arena::~Arena() { # 15 [ + + ]: 18089 : for (size_t i = 0; i < blocks_.size(); i++) { # 16 : 14929 : delete[] blocks_[i]; # 17 : 14929 : } # 18 : 3160 : } # 19 : : # 20 : 14929 : char* Arena::AllocateFallback(size_t bytes) { # 21 [ - + ]: 14929 : if (bytes > kBlockSize / 4) { # 22 : : // Object is more than a quarter of our block size. Allocate it separately # 23 : : // to avoid wasting too much space in leftover bytes. # 24 : 0 : char* result = AllocateNewBlock(bytes); # 25 : 0 : return result; # 26 : 0 : } # 27 : : # 28 : : // We waste the remaining space in the current block. # 29 : 14929 : alloc_ptr_ = AllocateNewBlock(kBlockSize); # 30 : 14929 : alloc_bytes_remaining_ = kBlockSize; # 31 : : # 32 : 14929 : char* result = alloc_ptr_; # 33 : 14929 : alloc_ptr_ += bytes; # 34 : 14929 : alloc_bytes_remaining_ -= bytes; # 35 : 14929 : return result; # 36 : 14929 : } # 37 : : # 38 : 481710 : char* Arena::AllocateAligned(size_t bytes) { # 39 : 481710 : const int align = (sizeof(void*) > 8) ? sizeof(void*) : 8; # 40 : 481710 : static_assert((align & (align - 1)) == 0, # 41 : 481710 : "Pointer size should be a power of 2"); # 42 : 481710 : size_t current_mod = reinterpret_cast<uintptr_t>(alloc_ptr_) & (align - 1); # 43 [ + + ]: 481710 : size_t slop = (current_mod == 0 ? 0 : align - current_mod); # 44 : 481710 : size_t needed = bytes + slop; # 45 : 481710 : char* result; # 46 [ + + ]: 481710 : if (needed <= alloc_bytes_remaining_) { # 47 : 476772 : result = alloc_ptr_ + slop; # 48 : 476772 : alloc_ptr_ += needed; # 49 : 476772 : alloc_bytes_remaining_ -= needed; # 50 : 476772 : } else { # 51 : : // AllocateFallback always returned aligned memory # 52 : 4938 : result = AllocateFallback(bytes); # 53 : 4938 : } # 54 : 481710 : assert((reinterpret_cast<uintptr_t>(result) & (align - 1)) == 0); # 55 : 0 : return result; # 56 : 481710 : } # 57 : : # 58 : 14929 : char* Arena::AllocateNewBlock(size_t block_bytes) { # 59 : 14929 : char* result = new char[block_bytes]; # 60 : 14929 : blocks_.push_back(result); # 61 : 14929 : memory_usage_.fetch_add(block_bytes + sizeof(char*), # 62 : 14929 : std::memory_order_relaxed); # 63 : 14929 : return result; # 64 : 14929 : } # 65 : : # 66 : : } // namespace leveldb