Commit 5ea745d4 authored by Omer Strulovich's avatar Omer Strulovich Committed by Facebook GitHub Bot

Revert D22189916: Use sized deallocation in SysAllocator and Arena

Differential Revision:
D22189916 (https://github.com/facebook/folly/commit/0d2bdbf0e0618bd9366d3c35345e091ee24f0fae)

Original commit changeset: e6fba48eaae0

fbshipit-source-id: 4ea03c56fda84240e178b2b4baf83a57d3afa344
parent 0d2bdbf0
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <folly/functional/Invoke.h> #include <folly/functional/Invoke.h>
#include <folly/lang/Align.h> #include <folly/lang/Align.h>
#include <folly/lang/Exception.h> #include <folly/lang/Exception.h>
#include <folly/memory/Malloc.h>
#include <folly/portability/Config.h> #include <folly/portability/Config.h>
#include <folly/portability/Malloc.h> #include <folly/portability/Malloc.h>
...@@ -413,9 +412,8 @@ class SysAllocator { ...@@ -413,9 +412,8 @@ class SysAllocator {
} }
return static_cast<T*>(p); return static_cast<T*>(p);
} }
void deallocate(T* p, size_t count) { void deallocate(T* p, size_t /* count */) {
using lifted = typename detail::lift_void_to_char<T>::type; std::free(p);
sizedFree(p, count * sizeof(lifted));
} }
friend bool operator==(Self const&, Self const&) noexcept { friend bool operator==(Self const&, Self const&) noexcept {
......
...@@ -22,8 +22,27 @@ ...@@ -22,8 +22,27 @@
namespace folly { namespace folly {
template <class Alloc>
std::pair<typename Arena<Alloc>::Block*, size_t>
Arena<Alloc>::Block::allocate(Alloc& alloc, size_t size, bool allowSlack) {
size_t allocSize = sizeof(Block) + size;
if (allowSlack) {
allocSize = ArenaAllocatorTraits<Alloc>::goodSize(alloc, allocSize);
}
void* mem = std::allocator_traits<Alloc>::allocate(alloc, allocSize);
return std::make_pair(new (mem) Block(), allocSize - sizeof(Block));
}
template <class Alloc>
void Arena<Alloc>::Block::deallocate(Alloc& alloc) {
this->~Block();
std::allocator_traits<Alloc>::deallocate(alloc, this, 1);
}
template <class Alloc> template <class Alloc>
void* Arena<Alloc>::allocateSlow(size_t size) { void* Arena<Alloc>::allocateSlow(size_t size) {
std::pair<Block*, size_t> p;
char* start; char* start;
size_t allocSize; size_t allocSize;
...@@ -36,41 +55,31 @@ void* Arena<Alloc>::allocateSlow(size_t size) { ...@@ -36,41 +55,31 @@ void* Arena<Alloc>::allocateSlow(size_t size) {
} }
if (size > minBlockSize()) { if (size > minBlockSize()) {
// Allocate a large block for this chunk only; don't change ptr_ and end_, // Allocate a large block for this chunk only, put it at the back of the
// let them point into a normal block (or none, if they're null) // list so it doesn't get used for small allocations; don't change ptr_
allocSize = sizeof(LargeBlock) + size; // and end_, let them point into a normal block (or none, if they're
void* mem = AllocTraits::allocate(alloc(), allocSize); // null)
auto blk = new (mem) LargeBlock(allocSize); p = Block::allocate(alloc(), size, false);
start = blk->start(); start = p.first->start();
largeBlocks_.push_front(*blk); blocks_.push_back(*p.first);
} else { } else {
// Allocate a normal sized block and carve out size bytes from it // Allocate a normal sized block and carve out size bytes from it
// Will allocate more than size bytes if convenient p = Block::allocate(alloc(), minBlockSize(), true);
// (via ArenaAllocatorTraits::goodSize()) as we'll try to pack small start = p.first->start();
// allocations in this block. blocks_.push_front(*p.first);
allocSize = blockGoodAllocSize();
void* mem = AllocTraits::allocate(alloc(), allocSize);
auto blk = new (mem) Block();
start = blk->start();
blocks_.push_front(*blk);
ptr_ = start + size; ptr_ = start + size;
end_ = start + allocSize - sizeof(Block); end_ = start + p.second;
assert(ptr_ <= end_);
} }
totalAllocatedSize_ += allocSize; assert(p.second >= size);
totalAllocatedSize_ += p.second + sizeof(Block);
return start; return start;
} }
template <class Alloc> template <class Alloc>
void Arena<Alloc>::merge(Arena<Alloc>&& other) { void Arena<Alloc>::merge(Arena<Alloc>&& other) {
FOLLY_SAFE_CHECK(
blockGoodAllocSize() == other.blockGoodAllocSize(),
"cannot merge arenas of different minBlockSize");
blocks_.splice_after(blocks_.before_begin(), other.blocks_); blocks_.splice_after(blocks_.before_begin(), other.blocks_);
other.blocks_.clear(); other.blocks_.clear();
largeBlocks_.splice_after(largeBlocks_.before_begin(), other.largeBlocks_);
other.largeBlocks_.clear();
other.ptr_ = other.end_ = nullptr; other.ptr_ = other.end_ = nullptr;
totalAllocatedSize_ += other.totalAllocatedSize_; totalAllocatedSize_ += other.totalAllocatedSize_;
other.totalAllocatedSize_ = 0; other.totalAllocatedSize_ = 0;
...@@ -78,15 +87,7 @@ void Arena<Alloc>::merge(Arena<Alloc>&& other) { ...@@ -78,15 +87,7 @@ void Arena<Alloc>::merge(Arena<Alloc>&& other) {
template <class Alloc> template <class Alloc>
Arena<Alloc>::~Arena() { Arena<Alloc>::~Arena() {
blocks_.clear_and_dispose([this](Block* b) { blocks_.clear_and_dispose([this](Block* b) { b->deallocate(this->alloc()); });
b->~Block();
AllocTraits::deallocate(alloc(), b, blockGoodAllocSize());
});
largeBlocks_.clear_and_dispose([this](LargeBlock* b) {
auto size = b->allocSize;
b->~LargeBlock();
AllocTraits::deallocate(alloc(), b, size);
});
} }
} // namespace folly } // namespace folly
...@@ -126,37 +126,30 @@ class Arena { ...@@ -126,37 +126,30 @@ class Arena {
Arena& operator=(Arena&&) = delete; Arena& operator=(Arena&&) = delete;
private: private:
using AllocTraits = std::allocator_traits<Alloc>; struct Block;
using BlockLink = boost::intrusive::slist_member_hook<>; typedef boost::intrusive::slist_member_hook<boost::intrusive::tag<Arena>>
BlockLink;
struct alignas(max_align_v) Block { struct alignas(max_align_v) Block {
BlockLink link; BlockLink link;
// Allocate a block with at least size bytes of storage.
// If allowSlack is true, allocate more than size bytes if convenient
// (via ArenaAllocatorTraits::goodSize()) as we'll try to pack small
// allocations in this block.
static std::pair<Block*, size_t>
allocate(Alloc& alloc, size_t size, bool allowSlack);
void deallocate(Alloc& alloc);
char* start() { char* start() {
return reinterpret_cast<char*>(this + 1); return reinterpret_cast<char*>(this + 1);
} }
private:
Block() = default; Block() = default;
~Block() = default; ~Block() = default;
}; };
constexpr size_t blockGoodAllocSize() {
return ArenaAllocatorTraits<Alloc>::goodSize(
alloc(), sizeof(Block) + minBlockSize());
}
struct alignas(max_align_v) LargeBlock {
BlockLink link;
const size_t allocSize;
char* start() {
return reinterpret_cast<char*>(this + 1);
}
LargeBlock(size_t s) : allocSize(s) {}
~LargeBlock() = default;
};
public: public:
static constexpr size_t kDefaultMinBlockSize = 4096 - sizeof(Block); static constexpr size_t kDefaultMinBlockSize = 4096 - sizeof(Block);
static constexpr size_t kNoSizeLimit = 0; static constexpr size_t kNoSizeLimit = 0;
...@@ -190,13 +183,6 @@ class Arena { ...@@ -190,13 +183,6 @@ class Arena {
boost::intrusive::cache_last<true>> boost::intrusive::cache_last<true>>
BlockList; BlockList;
typedef boost::intrusive::slist<
LargeBlock,
boost::intrusive::member_hook<LargeBlock, BlockLink, &LargeBlock::link>,
boost::intrusive::constant_time_size<false>,
boost::intrusive::cache_last<true>>
LargeBlockList;
void* allocateSlow(size_t size); void* allocateSlow(size_t size);
// Empty member optimization: package Alloc with a non-empty member // Empty member optimization: package Alloc with a non-empty member
...@@ -220,7 +206,6 @@ class Arena { ...@@ -220,7 +206,6 @@ class Arena {
AllocAndSize allocAndSize_; AllocAndSize allocAndSize_;
BlockList blocks_; BlockList blocks_;
LargeBlockList largeBlocks_;
char* ptr_; char* ptr_;
char* end_; char* end_;
size_t totalAllocatedSize_; size_t totalAllocatedSize_;
......
...@@ -21,9 +21,7 @@ ...@@ -21,9 +21,7 @@
namespace folly { namespace folly {
ThreadCachedArena::ThreadCachedArena(size_t minBlockSize, size_t maxAlign) ThreadCachedArena::ThreadCachedArena(size_t minBlockSize, size_t maxAlign)
: minBlockSize_(minBlockSize), : minBlockSize_(minBlockSize), maxAlign_(maxAlign) {}
maxAlign_(maxAlign),
zombies_(folly::in_place, minBlockSize) {}
SysArena* ThreadCachedArena::allocateThreadLocalArena() { SysArena* ThreadCachedArena::allocateThreadLocalArena() {
auto arena = new SysArena(minBlockSize_, SysArena::kNoSizeLimit, maxAlign_); auto arena = new SysArena(minBlockSize_, SysArena::kNoSizeLimit, maxAlign_);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment