1 /* 2 * Copyright 2019 Google 3 * SPDX-License-Identifier: MIT 4 */ 5 #pragma once 6 7 #include "aemu/base/AlignedBuf.h" 8 #include "aemu/base/Allocator.h" 9 10 #include <vector> 11 #include <unordered_set> 12 13 #include <inttypes.h> 14 15 namespace android { 16 namespace base { 17 18 // Class to make it easier to set up memory regions where it is fast 19 // to allocate buffers AND we don't care about freeing individual pieces, 20 // BUT it's necessary to preserve previous pointer values in between the first 21 // alloc() after a freeAll(), and the freeAll() itself, allowing some sloppy use of 22 // malloc in the first pass while we find out how much data was needed. 23 class BumpPool : public Allocator { 24 public: 25 BumpPool(size_t startingBytes = 4096) : mStorage(startingBytes / sizeof(uint64_t)) { } 26 // All memory allocated by this pool 27 // is automatically deleted when the pool 28 // is deconstructed. ~BumpPool()29 ~BumpPool() { 30 freeAll(); 31 } 32 alloc(size_t wantedSize)33 void* alloc(size_t wantedSize) override { 34 size_t wantedSizeRoundedUp = 35 sizeof(uint64_t) * ((wantedSize + sizeof(uint64_t) - 1) / (sizeof(uint64_t))); 36 37 mTotalWantedThisGeneration += wantedSizeRoundedUp; 38 if (mAllocPos + wantedSizeRoundedUp > mStorage.size() * sizeof(uint64_t)) { 39 mNeedRealloc = true; 40 void* fallbackPtr = malloc(wantedSizeRoundedUp); 41 mFallbackPtrs.insert(fallbackPtr); 42 return fallbackPtr; 43 } 44 void* allocPtr = (void*)(((unsigned char*)mStorage.data()) + mAllocPos); 45 mAllocPos += wantedSizeRoundedUp; 46 return allocPtr; 47 } 48 freeAll()49 void freeAll() { 50 mAllocPos = 0; 51 if (mNeedRealloc) { 52 mStorage.resize((mTotalWantedThisGeneration * 2) / sizeof(uint64_t)); 53 mNeedRealloc = false; 54 for (auto ptr : mFallbackPtrs) { 55 free(ptr); 56 } 57 mFallbackPtrs.clear(); 58 } 59 mTotalWantedThisGeneration = 0; 60 } 61 private: 62 AlignedBuf<uint64_t, 8> mStorage; 63 std::unordered_set<void*> mFallbackPtrs; 64 size_t mAllocPos = 0; 65 size_t mTotalWantedThisGeneration = 0; 66 bool mNeedRealloc = false; 67 }; 68 69 } // namespace base 70 } // namespace android 71