| Index: src/common/memory.h
|
| diff --git a/src/common/memory.h b/src/common/memory.h
|
| index d6aa137d35c0fdb16e4af7bff2a0c5a1aea82be8..16a612b8cf36761f7179f897a1d01c3a716139af 100644
|
| --- a/src/common/memory.h
|
| +++ b/src/common/memory.h
|
| @@ -64,7 +64,8 @@ class PageAllocator {
|
| : page_size_(getpagesize()),
|
| last_(NULL),
|
| current_page_(NULL),
|
| - page_offset_(0) {
|
| + page_offset_(0),
|
| + pages_allocated_(0) {
|
| }
|
|
|
| ~PageAllocator() {
|
| @@ -112,6 +113,8 @@ class PageAllocator {
|
| return false;
|
| }
|
|
|
| + unsigned long pages_allocated() { return pages_allocated_; }
|
| +
|
| private:
|
| uint8_t *GetNPages(size_t num_pages) {
|
| #if defined(__x86_64__) || defined(__aarch64__) || defined(__aarch64__) || \
|
| @@ -136,6 +139,8 @@ class PageAllocator {
|
| header->num_pages = num_pages;
|
| last_ = header;
|
|
|
| + pages_allocated_ += num_pages;
|
| +
|
| return reinterpret_cast<uint8_t*>(a);
|
| }
|
|
|
| @@ -157,6 +162,7 @@ class PageAllocator {
|
| PageHeader *last_;
|
| uint8_t *current_page_;
|
| size_t page_offset_;
|
| + unsigned long pages_allocated_;
|
| };
|
|
|
| // Wrapper to use with STL containers
|
| @@ -165,12 +171,30 @@ struct PageStdAllocator : public std::allocator<T> {
|
| typedef typename std::allocator<T>::pointer pointer;
|
| typedef typename std::allocator<T>::size_type size_type;
|
|
|
| - explicit PageStdAllocator(PageAllocator& allocator): allocator_(allocator) {}
|
| + explicit PageStdAllocator(PageAllocator& allocator) : allocator_(allocator),
|
| + stackdata_(NULL),
|
| + stackdata_size_(0)
|
| + {}
|
| +
|
| template <class Other> PageStdAllocator(const PageStdAllocator<Other>& other)
|
| - : allocator_(other.allocator_) {}
|
| + : allocator_(other.allocator_),
|
| + stackdata_(nullptr),
|
| + stackdata_size_(0)
|
| + {}
|
| +
|
| + explicit PageStdAllocator(PageAllocator& allocator,
|
| + pointer stackdata,
|
| + size_type stackdata_size) : allocator_(allocator),
|
| + stackdata_(stackdata),
|
| + stackdata_size_(stackdata_size)
|
| + {}
|
|
|
| inline pointer allocate(size_type n, const void* = 0) {
|
| - return static_cast<pointer>(allocator_.Alloc(sizeof(T) * n));
|
| + const size_type size = sizeof(T) * n;
|
| + if (size <= stackdata_size_) {
|
| + return stackdata_;
|
| + }
|
| + return static_cast<pointer>(allocator_.Alloc(size));
|
| }
|
|
|
| inline void deallocate(pointer, size_type) {
|
| @@ -188,6 +212,8 @@ struct PageStdAllocator : public std::allocator<T> {
|
| template<typename Other> friend struct PageStdAllocator;
|
|
|
| PageAllocator& allocator_;
|
| + pointer stackdata_;
|
| + size_type stackdata_size_;
|
| };
|
|
|
| // A wasteful vector is a std::vector, except that it allocates memory from a
|
| @@ -200,6 +226,24 @@ class wasteful_vector : public std::vector<T, PageStdAllocator<T> > {
|
| : std::vector<T, PageStdAllocator<T> >(PageStdAllocator<T>(*allocator)) {
|
| std::vector<T, PageStdAllocator<T> >::reserve(size_hint);
|
| }
|
| + protected:
|
| + wasteful_vector(PageStdAllocator<T> allocator)
|
| + : std::vector<T, PageStdAllocator<T> >(allocator) {}
|
| +};
|
| +
|
| +// auto_wasteful_vector allocates space on the stack for N entries to avoid
|
| +// using the PageAllocator for small data, while still allowing for larger data.
|
| +template<class T, unsigned int N>
|
| +class auto_wasteful_vector : public wasteful_vector<T> {
|
| + T stackdata_[N];
|
| + public:
|
| + auto_wasteful_vector(PageAllocator* allocator)
|
| + : wasteful_vector<T>(
|
| + PageStdAllocator<T>(*allocator,
|
| + &stackdata_[0],
|
| + sizeof(stackdata_))) {
|
| + std::vector<T, PageStdAllocator<T> >::reserve(N);
|
| + }
|
| };
|
|
|
| } // namespace google_breakpad
|
|
|