Commit 385b4994 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Defer all initialization until allocation in IndexedMemPool

Summary: [Folly] Defer all initialization until allocation in `IndexedMemPool`. This provides a better guarantee that the constructor never dirties the allocated region by accidentally direct-initializing rather than default-initializing the linked list pointers in the mapped region.

Reviewed By: davidtgoldblatt

Differential Revision: D13046558

fbshipit-source-id: 1bde547525e2502607d01e68206d7f8c826baebd
parent 3222b57b
......@@ -210,19 +210,6 @@ struct IndexedMemPool : boost::noncopyable {
assert(errno == ENOMEM);
throw std::bad_alloc();
}
// Atom is expected to be std::atomic, which is trivially
// constructible, so we can avoid explicitly initializing the
// slots which would cause the whole mapped area to be paged in.
//
// TODO: Switch to is_trivially_constructible once support
// for GCC 4.9 is dropped for this file.
if /* constexpr */ (!std::is_trivial<Atom<uint32_t>>::value) {
for (size_t i = 1; i < actualCapacity_ + 1; i++) {
// Atom is enforced above to be nothrow-default-constructible
new (&slots_[i].localNext) Atom<uint32_t>;
new (&slots_[i].globalNext) Atom<uint32_t>;
}
}
}
/// Destroys all of the contained elements
......@@ -230,8 +217,6 @@ struct IndexedMemPool : boost::noncopyable {
using A = Atom<uint32_t>;
for (uint32_t i = maxAllocatedIndex(); i > 0; --i) {
Traits::cleanup(&slots_[i].elem);
}
for (size_t i = 1; i < actualCapacity_ + 1; i++) {
slots_[i].localNext.~A();
slots_[i].globalNext.~A();
}
......@@ -506,7 +491,14 @@ struct IndexedMemPool : boost::noncopyable {
// allocation failed
return 0;
}
Traits::initialize(&slot(idx).elem);
Slot& s = slot(idx);
// Atom is enforced above to be nothrow-default-constructible
// As an optimization, use default-initialization (no parens) rather
// than direct-initialization (with parens): these locations are
// stored-to before they are loaded-from
new (&s.localNext) Atom<uint32_t>;
new (&s.globalNext) Atom<uint32_t>;
Traits::initialize(&s.elem);
return idx;
}
......
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