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

Let make_exception_wrapper construct on-heap objects in-place

Summary:
[Folly] Let `make_exception_wrapper` construct on-heap objects in-place.

Currently, it constructs on-heap objects on the stack and then move-constructs them into on-heap storage.

Reviewed By: ericniebler

Differential Revision: D5315104

fbshipit-source-id: cc0493e7d98aacadd342eb56601028ced4a19bb3
parent 6cf4cd30
...@@ -69,9 +69,9 @@ inline std::type_info const* exception_wrapper::uninit_type_( ...@@ -69,9 +69,9 @@ inline std::type_info const* exception_wrapper::uninit_type_(
return &typeid(void); return &typeid(void);
} }
template <class Ex, class DEx> template <class Ex, typename... As>
inline exception_wrapper::Buffer::Buffer(in_place_t, Ex&& ex) { inline exception_wrapper::Buffer::Buffer(in_place_type_t<Ex>, As&&... as_) {
::new (static_cast<void*>(&buff_)) DEx(std::forward<Ex>(ex)); ::new (static_cast<void*>(&buff_)) Ex(std::forward<As>(as_)...);
} }
template <class Ex> template <class Ex>
...@@ -280,14 +280,15 @@ inline exception_wrapper exception_wrapper::SharedPtr::get_exception_ptr_( ...@@ -280,14 +280,15 @@ inline exception_wrapper exception_wrapper::SharedPtr::get_exception_ptr_(
return that->sptr_.ptr_->get_exception_ptr_(); return that->sptr_.ptr_->get_exception_ptr_();
} }
template <class Ex, class DEx> template <class Ex, typename... As>
inline exception_wrapper::exception_wrapper(Ex&& ex, OnHeapTag) inline exception_wrapper::exception_wrapper(OnHeapTag, in_place_type_t<Ex>, As&&... as)
: sptr_{std::make_shared<SharedPtr::Impl<DEx>>(std::forward<Ex>(ex))}, : sptr_{std::make_shared<SharedPtr::Impl<Ex>>(std::forward<As>(as)...)},
vptr_(&SharedPtr::ops_) {} vptr_(&SharedPtr::ops_) {}
template <class Ex, class DEx> template <class Ex, typename... As>
inline exception_wrapper::exception_wrapper(Ex&& ex, InSituTag) inline exception_wrapper::exception_wrapper(InSituTag, in_place_type_t<Ex>, As&&... as)
: buff_{in_place, std::forward<Ex>(ex)}, vptr_(&InPlace<DEx>::ops_) {} : buff_{in_place<Ex>, std::forward<As>(as)...},
vptr_(&InPlace<Ex>::ops_) {}
inline exception_wrapper::exception_wrapper(exception_wrapper&& that) noexcept inline exception_wrapper::exception_wrapper(exception_wrapper&& that) noexcept
: exception_wrapper{} { : exception_wrapper{} {
...@@ -345,8 +346,9 @@ template < ...@@ -345,8 +346,9 @@ template <
exception_wrapper::IsRegularExceptionType<Ex_>>::value)> exception_wrapper::IsRegularExceptionType<Ex_>>::value)>
inline exception_wrapper::exception_wrapper(Ex&& ex) inline exception_wrapper::exception_wrapper(Ex&& ex)
: exception_wrapper{ : exception_wrapper{
exception_wrapper_detail::dont_slice(std::forward<Ex>(ex)), PlacementOf<Ex_>{},
PlacementOf<Ex_>{}} { in_place<Ex_>,
exception_wrapper_detail::dont_slice(std::forward<Ex>(ex))} {
} }
template < template <
...@@ -356,8 +358,21 @@ template < ...@@ -356,8 +358,21 @@ template <
exception_wrapper::IsRegularExceptionType<Ex_>::value)> exception_wrapper::IsRegularExceptionType<Ex_>::value)>
inline exception_wrapper::exception_wrapper(in_place_t, Ex&& ex) inline exception_wrapper::exception_wrapper(in_place_t, Ex&& ex)
: exception_wrapper{ : exception_wrapper{
exception_wrapper_detail::dont_slice(std::forward<Ex>(ex)), PlacementOf<Ex_>{},
PlacementOf<Ex_>{}} { in_place<Ex_>,
exception_wrapper_detail::dont_slice(std::forward<Ex>(ex))} {
}
template <
class Ex,
typename... As,
FOLLY_REQUIRES_DEF(
exception_wrapper::IsRegularExceptionType<Ex>::value)>
inline exception_wrapper::exception_wrapper(in_place_type_t<Ex>, As&&... as)
: exception_wrapper{
PlacementOf<Ex>{},
in_place<Ex>,
std::forward<As>(as)...} {
} }
inline void exception_wrapper::swap(exception_wrapper& that) noexcept { inline void exception_wrapper::swap(exception_wrapper& that) noexcept {
......
...@@ -226,8 +226,8 @@ class exception_wrapper final { ...@@ -226,8 +226,8 @@ class exception_wrapper final {
Buffer() : buff_{} {} Buffer() : buff_{} {}
template <class Ex, class DEx = _t<std::decay<Ex>>> template <class Ex, typename... As>
Buffer(in_place_t, Ex&& ex); Buffer(in_place_type_t<Ex>, As&&... as_);
template <class Ex> template <class Ex>
Ex& as() noexcept; Ex& as() noexcept;
template <class Ex> template <class Ex>
...@@ -309,10 +309,10 @@ class exception_wrapper final { ...@@ -309,10 +309,10 @@ class exception_wrapper final {
struct Impl final : public Base { struct Impl final : public Base {
Ex ex_; Ex ex_;
Impl() = default; Impl() = default;
explicit Impl(Ex const& ex) : Base{typeid(ex)}, ex_(ex) {} template <typename... As>
explicit Impl(Ex&& ex) explicit Impl(As&&... as)
: Base{typeid(ex)}, : Base{typeid(Ex)}, ex_(std::forward<As>(as)...) {}
ex_(std::move(ex)){}[[noreturn]] void throw_() const override; [[noreturn]] void throw_() const override;
std::exception const* get_exception_() const noexcept override; std::exception const* get_exception_() const noexcept override;
exception_wrapper get_exception_ptr_() const noexcept override; exception_wrapper get_exception_ptr_() const noexcept override;
}; };
...@@ -335,11 +335,11 @@ class exception_wrapper final { ...@@ -335,11 +335,11 @@ class exception_wrapper final {
}; };
VTable const* vptr_{&uninit_}; VTable const* vptr_{&uninit_};
template <class Ex, class DEx = _t<std::decay<Ex>>> template <class Ex, typename... As>
exception_wrapper(Ex&& ex, OnHeapTag); exception_wrapper(OnHeapTag, in_place_type_t<Ex>, As&&... as);
template <class Ex, class DEx = _t<std::decay<Ex>>> template <class Ex, typename... As>
exception_wrapper(Ex&& ex, InSituTag); exception_wrapper(InSituTag, in_place_type_t<Ex>, As&&... as);
template <class T> template <class T>
struct IsRegularExceptionType struct IsRegularExceptionType
...@@ -434,6 +434,12 @@ class exception_wrapper final { ...@@ -434,6 +434,12 @@ class exception_wrapper final {
FOLLY_REQUIRES(IsRegularExceptionType<Ex_>::value)> FOLLY_REQUIRES(IsRegularExceptionType<Ex_>::value)>
exception_wrapper(in_place_t, Ex&& ex); exception_wrapper(in_place_t, Ex&& ex);
template <
class Ex,
typename... As,
FOLLY_REQUIRES(IsRegularExceptionType<Ex>::value)>
exception_wrapper(in_place_type_t<Ex>, As&&... as);
//! Swaps the value of `*this` with the value of `that` //! Swaps the value of `*this` with the value of `that`
void swap(exception_wrapper& that) noexcept; void swap(exception_wrapper& that) noexcept;
...@@ -598,7 +604,7 @@ constexpr exception_wrapper::VTable exception_wrapper::InPlace<Ex>::ops_; ...@@ -598,7 +604,7 @@ constexpr exception_wrapper::VTable exception_wrapper::InPlace<Ex>::ops_;
*/ */
template <class Ex, typename... As> template <class Ex, typename... As>
exception_wrapper make_exception_wrapper(As&&... as) { exception_wrapper make_exception_wrapper(As&&... as) {
return exception_wrapper{Ex{std::forward<As>(as)...}}; return exception_wrapper{in_place<Ex>, std::forward<As>(as)...};
} }
/** /**
......
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