Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a83881e3 authored by Colin Cross's avatar Colin Cross
Browse files

libmemunreachable: clang-format everything

clang-format -i --sort-includes $(find . -name "*.cpp" -o -name "*.h")

Test: builds
Change-Id: Ia8e0677fe7f3f26dddba3a851cd2dfab9f14e421
parent 07a57f0f
Loading
Loading
Loading
Loading
+60 −74
Original line number Diff line number Diff line
@@ -33,9 +33,9 @@

#include "android-base/macros.h"

#include "anon_vma_naming.h"
#include "Allocator.h"
#include "LinkedList.h"
#include "anon_vma_naming.h"

// runtime interfaces used:
// abort
@@ -57,10 +57,9 @@ static constexpr size_t kChunkSize = 256 * 1024;
static constexpr size_t kUsableChunkSize = kChunkSize - kPageSize;
static constexpr size_t kMaxBucketAllocationSize = kChunkSize / 4;
static constexpr size_t kMinBucketAllocationSize = 8;
static constexpr unsigned int kNumBuckets = const_log2(kMaxBucketAllocationSize)
    - const_log2(kMinBucketAllocationSize) + 1;
static constexpr unsigned int kUsablePagesPerChunk = kUsableChunkSize
    / kPageSize;
static constexpr unsigned int kNumBuckets =
    const_log2(kMaxBucketAllocationSize) - const_log2(kMinBucketAllocationSize) + 1;
static constexpr unsigned int kUsablePagesPerChunk = kUsableChunkSize / kPageSize;

std::atomic<int> heap_count;

@@ -107,8 +106,7 @@ static inline unsigned int log2(size_t n) {
}

static inline unsigned int size_to_bucket(size_t size) {
  if (size < kMinBucketAllocationSize)
    return kMinBucketAllocationSize;
  if (size < kMinBucketAllocationSize) return kMinBucketAllocationSize;
  return log2(size - 1) + 1 - const_log2(kMinBucketAllocationSize);
}

@@ -140,8 +138,7 @@ static void* MapAligned(size_t size, size_t align) {

  // Trim beginning
  if (aligned_ptr != ptr) {
    ptrdiff_t extra = reinterpret_cast<uintptr_t>(aligned_ptr)
        - reinterpret_cast<uintptr_t>(ptr);
    ptrdiff_t extra = reinterpret_cast<uintptr_t>(aligned_ptr) - reinterpret_cast<uintptr_t>(ptr);
    munmap(ptr, extra);
    map_size -= extra;
    ptr = aligned_ptr;
@@ -151,14 +148,13 @@ static void* MapAligned(size_t size, size_t align) {
  if (map_size != size) {
    assert(map_size > size);
    assert(ptr != NULL);
    munmap(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(ptr) + size),
        map_size - size);
    munmap(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(ptr) + size), map_size - size);
  }

#define PR_SET_VMA 0x53564d41
#define PR_SET_VMA_ANON_NAME 0
  prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME,
      reinterpret_cast<uintptr_t>(ptr), size, "leak_detector_malloc");
  prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, reinterpret_cast<uintptr_t>(ptr), size,
        "leak_detector_malloc");

  return ptr;
}
@@ -176,19 +172,14 @@ class Chunk {
  bool Empty();

  static Chunk* ptr_to_chunk(void* ptr) {
    return reinterpret_cast<Chunk*>(reinterpret_cast<uintptr_t>(ptr)
        & ~(kChunkSize - 1));
    return reinterpret_cast<Chunk*>(reinterpret_cast<uintptr_t>(ptr) & ~(kChunkSize - 1));
  }
  static bool is_chunk(void* ptr) {
    return (reinterpret_cast<uintptr_t>(ptr) & (kChunkSize - 1)) != 0;
  }

  unsigned int free_count() {
    return free_count_;
  }
  HeapImpl* heap() {
    return heap_;
  }
  unsigned int free_count() { return free_count_; }
  HeapImpl* heap() { return heap_; }
  LinkedList<Chunk*> node_;  // linked list sorted by minimum free count

 private:
@@ -210,13 +201,10 @@ class Chunk {
  char data_[0];

  unsigned int ptr_to_n(void* ptr) {
    ptrdiff_t offset = reinterpret_cast<uintptr_t>(ptr)
        - reinterpret_cast<uintptr_t>(data_);
    ptrdiff_t offset = reinterpret_cast<uintptr_t>(ptr) - reinterpret_cast<uintptr_t>(data_);
    return offset / allocation_size_;
  }
  void* n_to_ptr(unsigned int n) {
    return data_ + n * allocation_size_;
  }
  void* n_to_ptr(unsigned int n) { return data_ + n * allocation_size_; }
};
static_assert(sizeof(Chunk) <= kPageSize, "header must fit in page");

@@ -237,11 +225,15 @@ void Chunk::operator delete(void *ptr) {
  munmap(ptr, kChunkSize);
}

Chunk::Chunk(HeapImpl* heap, int bucket) :
    node_(this), heap_(heap), bucket_(bucket), allocation_size_(
        bucket_to_size(bucket)), max_allocations_(
        kUsableChunkSize / allocation_size_), first_free_bitmap_(0), free_count_(
        max_allocations_), frees_since_purge_(0) {
Chunk::Chunk(HeapImpl* heap, int bucket)
    : node_(this),
      heap_(heap),
      bucket_(bucket),
      allocation_size_(bucket_to_size(bucket)),
      max_allocations_(kUsableChunkSize / allocation_size_),
      first_free_bitmap_(0),
      free_count_(max_allocations_),
      frees_since_purge_(0) {
  memset(dirty_pages_, 0, sizeof(dirty_pages_));
  memset(free_bitmap_, 0xff, sizeof(free_bitmap_));
}
@@ -254,8 +246,7 @@ void* Chunk::Alloc() {
  assert(free_count_ > 0);

  unsigned int i = first_free_bitmap_;
  while (free_bitmap_[i] == 0)
    i++;
  while (free_bitmap_[i] == 0) i++;
  assert(i < arraysize(free_bitmap_));
  unsigned int bit = __builtin_ffs(free_bitmap_[i]) - 1;
  assert(free_bitmap_[i] & (1U << bit));
@@ -310,8 +301,7 @@ void Chunk::Purge() {
}

// Override new operator on HeapImpl to use mmap to allocate a page
void* HeapImpl::operator new(std::size_t count __attribute__((unused)))
    noexcept {
void* HeapImpl::operator new(std::size_t count __attribute__((unused))) noexcept {
  assert(count == sizeof(HeapImpl));
  void* mem = MapAligned(kPageSize, kPageSize);
  if (!mem) {
@@ -326,9 +316,7 @@ void HeapImpl::operator delete(void *ptr) {
  munmap(ptr, kPageSize);
}

HeapImpl::HeapImpl() :
    free_chunks_(), full_chunks_(), map_allocation_list_(NULL) {
}
HeapImpl::HeapImpl() : free_chunks_(), full_chunks_(), map_allocation_list_(NULL) {}

bool HeapImpl::Empty() {
  for (unsigned int i = 0; i < kNumBuckets; i++) {
@@ -397,8 +385,7 @@ void HeapImpl::FreeLocked(void *ptr) {
void* HeapImpl::MapAlloc(size_t size) {
  size = (size + kPageSize - 1) & ~(kPageSize - 1);

  MapAllocation* allocation = reinterpret_cast<MapAllocation*>(AllocLocked(
      sizeof(MapAllocation)));
  MapAllocation* allocation = reinterpret_cast<MapAllocation*>(AllocLocked(sizeof(MapAllocation)));
  void* ptr = MapAligned(size, kChunkSize);
  if (!ptr) {
    FreeLocked(allocation);
@@ -414,8 +401,7 @@ void* HeapImpl::MapAlloc(size_t size) {

void HeapImpl::MapFree(void* ptr) {
  MapAllocation** allocation = &map_allocation_list_;
  while (*allocation && (*allocation)->ptr != ptr)
    allocation = &(*allocation)->next;
  while (*allocation && (*allocation)->ptr != ptr) allocation = &(*allocation)->next;

  assert(*allocation != nullptr);

@@ -439,8 +425,8 @@ void HeapImpl::MoveToList(Chunk *chunk, LinkedList<Chunk*>* head) {

  LinkedList<Chunk*>* node = head;
  // Insert into new list, sorted by lowest free count
  while (node->next() != head && node->data() != nullptr
      && node->data()->free_count() < chunk->free_count())
  while (node->next() != head && node->data() != nullptr &&
         node->data()->free_count() < chunk->free_count())
    node = node->next();

  node->insert(chunk->node_);
+56 −71
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ class HeapImpl;
template <typename T>
class Allocator;


// Non-templated class that implements wraps HeapImpl to keep
// implementation out of the header file
class Heap {
@@ -65,12 +64,8 @@ public:
  }

  // Comparators, copied objects will be equal
  bool operator ==(const Heap& other) const {
    return impl_ == other.impl_;
  }
  bool operator !=(const Heap& other) const {
    return !(*this == other);
  }
  bool operator==(const Heap& other) const { return impl_ == other.impl_; }
  bool operator!=(const Heap& other) const { return !(*this == other); }

  // std::unique_ptr wrapper that allocates using allocate and deletes using
  // deallocate
@@ -80,8 +75,7 @@ public:
  template <class T, class... Args>
  unique_ptr<T> make_unique(Args&&... args) {
    HeapImpl* impl = impl_;
    return unique_ptr<T>(new (allocate<T>()) T(std::forward<Args>(args)...),
        [impl](void* ptr) {
    return unique_ptr<T>(new (allocate<T>()) T(std::forward<Args>(args)...), [impl](void* ptr) {
      reinterpret_cast<T*>(ptr)->~T();
      deallocate(impl, ptr);
    });
@@ -105,30 +99,25 @@ template<typename T>
class STLAllocator {
 public:
  using value_type = T;
  ~STLAllocator() {
  }
  ~STLAllocator() {}

  // Construct an STLAllocator on top of a Heap
  STLAllocator(const Heap& heap) :  // NOLINT, implicit
      heap_(heap) {
  }
  STLAllocator(const Heap& heap)
      :  // NOLINT, implicit
        heap_(heap) {}

  // Rebind an STLAllocator from an another STLAllocator
  template <typename U>
  STLAllocator(const STLAllocator<U>& other) :  // NOLINT, implicit
      heap_(other.heap_) {
  }
  STLAllocator(const STLAllocator<U>& other)
      :  // NOLINT, implicit
        heap_(other.heap_) {}

  STLAllocator(const STLAllocator&) = default;
  STLAllocator<T>& operator=(const STLAllocator<T>&) = default;

  T* allocate(std::size_t n) {
    return reinterpret_cast<T*>(heap_.allocate(n * sizeof(T)));
  }
  T* allocate(std::size_t n) { return reinterpret_cast<T*>(heap_.allocate(n * sizeof(T))); }

  void deallocate(T* ptr, std::size_t) {
    heap_.deallocate(ptr);
  }
  void deallocate(T* ptr, std::size_t) { heap_.deallocate(ptr); }

  template <typename U>
  bool operator==(const STLAllocator<U>& other) const {
@@ -146,7 +135,6 @@ protected:
  Heap heap_;
};


// Allocator extends STLAllocator with some convenience methods for allocating
// a single object and for constructing unique_ptr and shared_ptr objects with
// appropriate deleters.
@@ -155,14 +143,14 @@ class Allocator : public STLAllocator<T> {
 public:
  ~Allocator() {}

  Allocator(const Heap& other) : // NOLINT, implicit
      STLAllocator<T>(other) {
  }
  Allocator(const Heap& other)
      :  // NOLINT, implicit
        STLAllocator<T>(other) {}

  template <typename U>
  Allocator(const STLAllocator<U>& other) :  // NOLINT, implicit
      STLAllocator<T>(other) {
  }
  Allocator(const STLAllocator<U>& other)
      :  // NOLINT, implicit
        STLAllocator<T>(other) {}

  Allocator(const Allocator&) = default;
  Allocator<T>& operator=(const Allocator<T>&) = default;
@@ -171,12 +159,8 @@ class Allocator : public STLAllocator<T> {
  using STLAllocator<T>::deallocate;
  using STLAllocator<T>::heap_;

  T* allocate() {
    return STLAllocator<T>::allocate(1);
  }
  void deallocate(void* ptr) {
    heap_.deallocate(ptr);
  }
  T* allocate() { return STLAllocator<T>::allocate(1); }
  void deallocate(void* ptr) { heap_.deallocate(ptr); }

  using shared_ptr = Heap::shared_ptr<T>;

@@ -214,7 +198,8 @@ template<class Key, class T, class Compare = std::less<Key>>
using map = std::map<Key, T, Compare, Allocator<std::pair<const Key, T>>>;

template <class Key, class T, class Hash = std::hash<Key>, class KeyEqual = std::equal_to<Key>>
using unordered_map = std::unordered_map<Key, T, Hash, KeyEqual, Allocator<std::pair<const Key, T>>>;
using unordered_map =
    std::unordered_map<Key, T, Hash, KeyEqual, Allocator<std::pair<const Key, T>>>;

template <class Key, class Hash = std::hash<Key>, class KeyEqual = std::equal_to<Key>>
using unordered_set = std::unordered_set<Key, Hash, KeyEqual, Allocator<Key>>;
+6 −5
Original line number Diff line number Diff line
@@ -114,8 +114,8 @@ bool HeapWalker::DetectLeaks() {
  return true;
}

bool HeapWalker::Leaked(allocator::vector<Range>& leaked, size_t limit,
    size_t* num_leaks_out, size_t* leak_bytes_out) {
bool HeapWalker::Leaked(allocator::vector<Range>& leaked, size_t limit, size_t* num_leaks_out,
                        size_t* leak_bytes_out) {
  leaked.clear();

  size_t num_leaks = 0;
@@ -159,7 +159,8 @@ static bool MapOverPage(void* addr) {
  return true;
}

void HeapWalker::HandleSegFault(ScopedSignalHandler& handler, int signal, siginfo_t* si, void* /*uctx*/) {
void HeapWalker::HandleSegFault(ScopedSignalHandler& handler, int signal, siginfo_t* si,
                                void* /*uctx*/) {
  uintptr_t addr = reinterpret_cast<uintptr_t>(si->si_addr);
  if (addr != walking_ptr_) {
    handler.reset();
+18 −20
Original line number Diff line number Diff line
@@ -34,29 +34,29 @@ struct Range {
  bool operator==(const Range& other) const {
    return this->begin == other.begin && this->end == other.end;
  }
  bool operator!=(const Range& other) const {
    return !(*this == other);
  }
  bool operator!=(const Range& other) const { return !(*this == other); }
};

// Comparator for Ranges that returns equivalence for overlapping ranges
struct compare_range {
  bool operator()(const Range& a, const Range& b) const {
    return a.end <= b.begin;
  }
  bool operator()(const Range& a, const Range& b) const { return a.end <= b.begin; }
};

class HeapWalker {
 public:
  explicit HeapWalker(Allocator<HeapWalker> allocator) : allocator_(allocator),
    allocations_(allocator), allocation_bytes_(0),
	roots_(allocator), root_vals_(allocator),
	segv_handler_(allocator), walking_ptr_(0) {
  explicit HeapWalker(Allocator<HeapWalker> allocator)
      : allocator_(allocator),
        allocations_(allocator),
        allocation_bytes_(0),
        roots_(allocator),
        root_vals_(allocator),
        segv_handler_(allocator),
        walking_ptr_(0) {
    valid_allocations_range_.end = 0;
    valid_allocations_range_.begin = ~valid_allocations_range_.end;

    segv_handler_.install(SIGSEGV,
        [=](ScopedSignalHandler& handler, int signal, siginfo_t* siginfo, void* uctx) {
    segv_handler_.install(
        SIGSEGV, [=](ScopedSignalHandler& handler, int signal, siginfo_t* siginfo, void* uctx) {
          this->HandleSegFault(handler, signal, siginfo, uctx);
        });
  }
@@ -68,8 +68,7 @@ class HeapWalker {

  bool DetectLeaks();

  bool Leaked(allocator::vector<Range>&, size_t limit, size_t* num_leaks,
      size_t* leak_bytes);
  bool Leaked(allocator::vector<Range>&, size_t limit, size_t* num_leaks, size_t* leak_bytes);
  size_t Allocations();
  size_t AllocationBytes();

@@ -84,7 +83,6 @@ class HeapWalker {
  };

 private:

  void RecurseRoot(const Range& root);
  bool WordContainsAllocationPtr(uintptr_t ptr, Range* range, AllocationInfo** info);
  void HandleSegFault(ScopedSignalHandler&, int, siginfo_t*, void*);
+29 −35
Original line number Diff line number Diff line
@@ -55,15 +55,12 @@ void LeakFolding::ComputeDAG() {
}

void LeakFolding::AccumulateLeaks(SCCInfo* dominator) {
  std::function<void(SCCInfo*)> walk(std::allocator_arg, allocator_,
      [&](SCCInfo* scc) {
  std::function<void(SCCInfo*)> walk(std::allocator_arg, allocator_, [&](SCCInfo* scc) {
    if (scc->accumulator != dominator) {
      scc->accumulator = dominator;
      dominator->cuumulative_size += scc->size;
      dominator->cuumulative_count += scc->count;
          scc->node.Foreach([&](SCCInfo* ref) {
            walk(ref);
          });
      scc->node.Foreach([&](SCCInfo* ref) { walk(ref); });
    }
  });
  walk(dominator);
@@ -73,11 +70,9 @@ bool LeakFolding::FoldLeaks() {
  Allocator<LeakInfo> leak_allocator = allocator_;

  // Find all leaked allocations insert them into leak_map_ and leak_graph_
  heap_walker_.ForEachAllocation(
      [&](const Range& range, HeapWalker::AllocationInfo& allocation) {
  heap_walker_.ForEachAllocation([&](const Range& range, HeapWalker::AllocationInfo& allocation) {
    if (!allocation.referenced_from_root) {
          auto it = leak_map_.emplace(std::piecewise_construct,
              std::forward_as_tuple(range),
      auto it = leak_map_.emplace(std::piecewise_construct, std::forward_as_tuple(range),
                                  std::forward_as_tuple(range, allocator_));
      LeakInfo& leak = it.first->second;
      leak_graph_.push_back(&leak.node);
@@ -110,8 +105,8 @@ bool LeakFolding::FoldLeaks() {
  return true;
}

bool LeakFolding::Leaked(allocator::vector<LeakFolding::Leak>& leaked,
    size_t* num_leaks_out, size_t* leak_bytes_out) {
bool LeakFolding::Leaked(allocator::vector<LeakFolding::Leak>& leaked, size_t* num_leaks_out,
                         size_t* leak_bytes_out) {
  size_t num_leaks = 0;
  size_t leak_bytes = 0;
  for (auto& it : leak_map_) {
@@ -123,8 +118,7 @@ bool LeakFolding::Leaked(allocator::vector<LeakFolding::Leak>& leaked,
  for (auto& it : leak_map_) {
    const LeakInfo& leak = it.second;
    if (leak.scc->dominator) {
      leaked.emplace_back(Leak{leak.range,
        leak.scc->cuumulative_count - 1,
      leaked.emplace_back(Leak{leak.range, leak.scc->cuumulative_count - 1,
                               leak.scc->cuumulative_size - leak.range.size()});
    }
  }
Loading