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