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

RFC: Embed exception_wrapper directly into Try

Summary:
[Folly] RFC: Embed `exception_wrapper` directly into `Try`.

Rather than storing it elsewhere on the heap. With `exception_wrapper` at 24 bytes on x64, it may now be small enough. However, it will expand the size of `Try<T>` for `sizeof(T) <= 16`, giving `Try` a new minimum size of 32 bytes on x64 instead of 16.

Reviewed By: ericniebler

Differential Revision: D5051436

fbshipit-source-id: 10d59686d64382c88d54340c97567eafb3e2f682
parent 27249d44
main v2022.02.14.00 v2022.02.07.00 v2022.01.31.00 v2022.01.24.00 v2022.01.17.00 v2022.01.10.00 v2022.01.03.00 v2021.12.27.00 v2021.12.20.00 v2021.12.13.00 v2021.12.06.00 v2021.11.29.00 v2021.11.15.00 v2021.11.08.00 v2021.11.01.00 v2021.10.25.00 v2021.10.18.00 v2021.10.11.00 v2021.10.04.00 v2021.09.27.00 v2021.09.20.00 v2021.09.13.00 v2021.09.06.00 v2021.08.30.00 v2021.08.23.00 v2021.08.02.00 v2021.07.22.00 v2021.07.20.01 v2021.07.20.00 v2021.06.28.00 v2021.06.14.00 v2021.06.07.00 v2021.05.31.00 v2021.05.24.00 v2021.05.17.00 v2021.05.10.00 v2021.05.03.00 v2021.04.26.00 v2021.04.19.00 v2021.04.12.00 v2021.04.05.00 v2021.03.29.00 v2021.03.22.00 v2021.03.15.00 v2021.03.08.00 v2021.03.01.00 v2021.02.22.00 v2021.02.15.00 v2021.02.08.00 v2021.02.01.00 v2021.01.25.00 v2021.01.18.01 v2021.01.18.00 v2021.01.11.00 v2021.01.04.00 v2020.12.28.00 v2020.12.21.00 v2020.12.14.00 v2020.12.07.00 v2020.11.30.00 v2020.11.23.00 v2020.11.16.00 v2020.11.09.00 v2020.11.02.00 v2020.10.26.00 v2020.10.19.00 v2020.10.12.00 v2020.10.05.00 v2020.09.28.00 v2020.09.21.00 v2020.09.14.00 v2020.09.07.00 v2020.08.31.00 v2020.08.24.00 v2020.08.17.00 v2020.08.10.00 v2020.08.03.00 v2020.07.27.00 v2020.07.20.00 v2020.07.13.00 v2020.07.06.00 v2020.06.29.00 v2020.06.15.00 v2020.06.08.00 v2020.06.01.00 v2020.05.25.00 v2020.05.18.00 v2020.05.11.00 v2020.05.04.00 v2020.04.27.00 v2020.04.20.00 v2020.04.13.00 v2020.04.06.00 v2020.03.30.00 v2020.03.23.00 v2020.03.16.00 v2020.03.09.00 v2020.03.02.00 v2020.02.24.00 v2020.02.17.00 v2020.02.10.00 v2020.02.03.00 v2020.01.27.00 v2020.01.20.00 v2020.01.13.00 v2020.01.06.00 v2019.12.30.00 v2019.12.23.00 v2019.12.16.00 v2019.12.09.00 v2019.12.06.00 v2019.12.02.00 v2019.11.11.00 v2019.11.04.00 v2019.10.28.00 v2019.10.21.00 v2019.10.14.00 v2019.10.07.00 v2019.09.30.00 v2019.09.23.00 v2019.09.16.00 v2019.09.09.00 v2019.09.02.00 v2019.08.26.00 v2019.08.19.00 v2019.08.12.00 v2019.08.05.00 v2019.07.29.00 v2019.07.22.00 v2019.06.17.00 v2019.06.10.00 v2019.06.03.00 v2019.05.27.00 v2019.05.20.00 v2019.05.13.00 v2019.05.06.00 v2019.04.29.00 v2019.04.22.00 v2019.04.15.00 v2019.04.08.00 v2019.04.01.00 v2019.03.25.00 v2019.03.18.00 v2019.03.04.00 v2019.02.25.00 v2019.02.18.00 v2019.02.11.00 v2019.02.04.00 v2019.01.28.00 v2019.01.21.00 v2019.01.14.00 v2019.01.07.00 v2018.12.31.00 v2018.12.24.00 v2018.12.17.00 v2018.12.10.00 v2018.12.03.00 v2018.11.26.00 v2018.11.19.00 v2018.11.12.00 v2018.11.05.00 v2018.10.29.00 v2018.10.22.00 v2018.10.15.00 v2018.10.08.00 v2018.10.01.00 v2018.09.24.00 v2018.09.17.00 v2018.09.10.01 v2018.09.10.00 v2018.09.03.01 v2018.09.03.00 v2018.08.27.00 v2018.08.20.00 v2018.08.13.00 v2018.08.09.00 v2018.08.06.00 v2018.07.30.00 v2018.07.23.00 v2018.07.16.00 v2018.07.09.00 v2018.07.02.00 v2018.06.25.00 v2018.06.18.00 v2018.06.11.00 v2018.06.04.00 v2018.05.28.00 v2018.05.21.00 v2018.05.14.00 v2018.05.07.00 v2018.04.30.00 v2018.04.23.00 v2018.04.16.00 v2018.04.09.00 v2018.04.02.00 v2018.03.26.00 v2018.03.19.00 v2018.03.12.00 v2018.03.05.00 v2018.02.26.00 v2018.02.19.00 v2018.02.12.00 v2018.02.05.00 v2018.01.29.00 v2018.01.22.00 v2018.01.15.00 v2018.01.08.00 v2018.01.01.00 v2017.12.25.00 v2017.12.18.00 v2017.12.11.00 v2017.12.04.00 v2017.11.27.00 v2017.11.20.00 v2017.11.13.00 v2017.11.06.00 v2017.10.30.00 v2017.10.23.00 v2017.10.16.00 v2017.10.09.00 v2017.10.02.00 v2017.09.25.00 v2017.09.18.00 v2017.09.11.00 v2017.09.04.00 v2017.08.28.00 v2017.08.21.00 v2017.08.14.00 v2017.08.07.00 v2017.07.31.00 v2017.07.24.00 v2017.07.17.01 v2017.07.17.00 v2017.07.10.00 v2017.07.03.00 v2017.06.26.01 v2017.06.26.00 v2017.06.19.00 v2017.06.12.00 v2017.06.05.00 v2017.05.29.00
No related merge requests found
...@@ -26,7 +26,7 @@ Try<T>::Try(Try<T>&& t) noexcept : contains_(t.contains_) { ...@@ -26,7 +26,7 @@ Try<T>::Try(Try<T>&& t) noexcept : contains_(t.contains_) {
if (contains_ == Contains::VALUE) { if (contains_ == Contains::VALUE) {
new (&value_)T(std::move(t.value_)); new (&value_)T(std::move(t.value_));
} else if (contains_ == Contains::EXCEPTION) { } else if (contains_ == Contains::EXCEPTION) {
new (&e_)std::unique_ptr<exception_wrapper>(std::move(t.e_)); new (&e_) exception_wrapper(std::move(t.e_));
} }
} }
...@@ -40,8 +40,7 @@ Try<T>::Try(typename std::enable_if<std::is_same<Unit, T2>::value, ...@@ -40,8 +40,7 @@ Try<T>::Try(typename std::enable_if<std::is_same<Unit, T2>::value,
new (&value_) T(); new (&value_) T();
} else if (t.hasException()) { } else if (t.hasException()) {
contains_ = Contains::EXCEPTION; contains_ = Contains::EXCEPTION;
new (&e_) std::unique_ptr<exception_wrapper>( new (&e_) exception_wrapper(t.exception());
std::make_unique<exception_wrapper>(t.exception()));
} }
} }
...@@ -56,7 +55,7 @@ Try<T>& Try<T>::operator=(Try<T>&& t) noexcept { ...@@ -56,7 +55,7 @@ Try<T>& Try<T>::operator=(Try<T>&& t) noexcept {
if (contains_ == Contains::VALUE) { if (contains_ == Contains::VALUE) {
new (&value_)T(std::move(t.value_)); new (&value_)T(std::move(t.value_));
} else if (contains_ == Contains::EXCEPTION) { } else if (contains_ == Contains::EXCEPTION) {
new (&e_)std::unique_ptr<exception_wrapper>(std::move(t.e_)); new (&e_) exception_wrapper(std::move(t.e_));
} }
return *this; return *this;
} }
...@@ -70,8 +69,7 @@ Try<T>::Try(const Try<T>& t) { ...@@ -70,8 +69,7 @@ Try<T>::Try(const Try<T>& t) {
if (contains_ == Contains::VALUE) { if (contains_ == Contains::VALUE) {
new (&value_)T(t.value_); new (&value_)T(t.value_);
} else if (contains_ == Contains::EXCEPTION) { } else if (contains_ == Contains::EXCEPTION) {
new (&e_)std::unique_ptr<exception_wrapper>(); new (&e_) exception_wrapper(t.e_);
e_ = std::make_unique<exception_wrapper>(*(t.e_));
} }
} }
...@@ -85,8 +83,7 @@ Try<T>& Try<T>::operator=(const Try<T>& t) { ...@@ -85,8 +83,7 @@ Try<T>& Try<T>::operator=(const Try<T>& t) {
if (contains_ == Contains::VALUE) { if (contains_ == Contains::VALUE) {
new (&value_)T(t.value_); new (&value_)T(t.value_);
} else if (contains_ == Contains::EXCEPTION) { } else if (contains_ == Contains::EXCEPTION) {
new (&e_)std::unique_ptr<exception_wrapper>(); new (&e_) exception_wrapper(t.e_);
e_ = std::make_unique<exception_wrapper>(*(t.e_));
} }
return *this; return *this;
} }
...@@ -96,7 +93,7 @@ Try<T>::~Try() { ...@@ -96,7 +93,7 @@ Try<T>::~Try() {
if (LIKELY(contains_ == Contains::VALUE)) { if (LIKELY(contains_ == Contains::VALUE)) {
value_.~T(); value_.~T();
} else if (UNLIKELY(contains_ == Contains::EXCEPTION)) { } else if (UNLIKELY(contains_ == Contains::EXCEPTION)) {
e_.~unique_ptr<exception_wrapper>(); e_.~exception_wrapper();
} }
} }
...@@ -122,7 +119,7 @@ template <class T> ...@@ -122,7 +119,7 @@ template <class T>
void Try<T>::throwIfFailed() const { void Try<T>::throwIfFailed() const {
if (contains_ != Contains::VALUE) { if (contains_ != Contains::VALUE) {
if (contains_ == Contains::EXCEPTION) { if (contains_ == Contains::EXCEPTION) {
e_->throw_exception(); e_.throw_exception();
} else { } else {
throw UsingUninitializedTry(); throw UsingUninitializedTry();
} }
...@@ -131,7 +128,7 @@ void Try<T>::throwIfFailed() const { ...@@ -131,7 +128,7 @@ void Try<T>::throwIfFailed() const {
void Try<void>::throwIfFailed() const { void Try<void>::throwIfFailed() const {
if (!hasValue_) { if (!hasValue_) {
e_->throw_exception(); e_.throw_exception();
} }
} }
......
...@@ -93,8 +93,7 @@ class Try { ...@@ -93,8 +93,7 @@ class Try {
* @param e The exception_wrapper * @param e The exception_wrapper
*/ */
explicit Try(exception_wrapper e) explicit Try(exception_wrapper e)
: contains_(Contains::EXCEPTION), : contains_(Contains::EXCEPTION), e_(std::move(e)) {}
e_(std::make_unique<exception_wrapper>(std::move(e))) {}
/* /*
* DEPRECATED * DEPRECATED
...@@ -107,10 +106,10 @@ class Try { ...@@ -107,10 +106,10 @@ class Try {
: contains_(Contains::EXCEPTION) { : contains_(Contains::EXCEPTION) {
try { try {
std::rethrow_exception(ep); std::rethrow_exception(ep);
} catch (const std::exception& e) { } catch (std::exception& e) {
e_ = std::make_unique<exception_wrapper>(std::current_exception(), e); e_ = exception_wrapper(std::current_exception(), e);
} catch (...) { } catch (...) {
e_ = std::make_unique<exception_wrapper>(std::current_exception()); e_ = exception_wrapper(std::current_exception());
} }
} }
...@@ -195,21 +194,21 @@ class Try { ...@@ -195,21 +194,21 @@ class Try {
*/ */
template <class Ex> template <class Ex>
bool hasException() const { bool hasException() const {
return hasException() && e_->is_compatible_with<Ex>(); return hasException() && e_.is_compatible_with<Ex>();
} }
exception_wrapper& exception() { exception_wrapper& exception() {
if (UNLIKELY(!hasException())) { if (UNLIKELY(!hasException())) {
throw TryException("exception(): Try does not contain an exception"); throw TryException("exception(): Try does not contain an exception");
} }
return *e_; return e_;
} }
const exception_wrapper& exception() const { const exception_wrapper& exception() const {
if (UNLIKELY(!hasException())) { if (UNLIKELY(!hasException())) {
throw TryException("exception(): Try does not contain an exception"); throw TryException("exception(): Try does not contain an exception");
} }
return *e_; return e_;
} }
/* /*
...@@ -220,11 +219,18 @@ class Try { ...@@ -220,11 +219,18 @@ class Try {
* @returns True if the Try held an Ex and func was executed, false otherwise * @returns True if the Try held an Ex and func was executed, false otherwise
*/ */
template <class Ex, class F> template <class Ex, class F>
bool withException(F func) {
if (!hasException()) {
return false;
}
return e_.with_exception(std::move(func));
}
template <class Ex, class F>
bool withException(F func) const { bool withException(F func) const {
if (!hasException()) { if (!hasException()) {
return false; return false;
} }
return e_->with_exception(std::move(func)); return e_.with_exception(std::move(func));
} }
template <bool isTry, typename R> template <bool isTry, typename R>
...@@ -241,7 +247,7 @@ class Try { ...@@ -241,7 +247,7 @@ class Try {
Contains contains_; Contains contains_;
union { union {
T value_; T value_;
std::unique_ptr<exception_wrapper> e_; exception_wrapper e_;
}; };
}; };
...@@ -265,9 +271,7 @@ class Try<void> { ...@@ -265,9 +271,7 @@ class Try<void> {
* *
* @param e The exception_wrapper * @param e The exception_wrapper
*/ */
explicit Try(exception_wrapper e) explicit Try(exception_wrapper e) : hasValue_(false), e_(std::move(e)) {}
: hasValue_(false),
e_(std::make_unique<exception_wrapper>(std::move(e))) {}
/* /*
* DEPRECATED * DEPRECATED
...@@ -280,18 +284,16 @@ class Try<void> { ...@@ -280,18 +284,16 @@ class Try<void> {
try { try {
std::rethrow_exception(ep); std::rethrow_exception(ep);
} catch (const std::exception& e) { } catch (const std::exception& e) {
e_ = std::make_unique<exception_wrapper>(std::current_exception(), e); e_ = exception_wrapper(std::current_exception(), e);
} catch (...) { } catch (...) {
e_ = std::make_unique<exception_wrapper>(std::current_exception()); e_ = exception_wrapper(std::current_exception());
} }
} }
// Copy assigner // Copy assigner
Try& operator=(const Try<void>& t) { Try& operator=(const Try<void>& t) {
hasValue_ = t.hasValue_; hasValue_ = t.hasValue_;
if (t.e_) { e_ = t.e_;
e_ = std::make_unique<exception_wrapper>(*t.e_);
}
return *this; return *this;
} }
// Copy constructor // Copy constructor
...@@ -315,7 +317,7 @@ class Try<void> { ...@@ -315,7 +317,7 @@ class Try<void> {
// @returns True if the Try contains an exception of type Ex, false otherwise // @returns True if the Try contains an exception of type Ex, false otherwise
template <class Ex> template <class Ex>
bool hasException() const { bool hasException() const {
return hasException() && e_->is_compatible_with<Ex>(); return hasException() && e_.is_compatible_with<Ex>();
} }
/* /*
...@@ -327,14 +329,14 @@ class Try<void> { ...@@ -327,14 +329,14 @@ class Try<void> {
if (UNLIKELY(!hasException())) { if (UNLIKELY(!hasException())) {
throw TryException("exception(): Try does not contain an exception"); throw TryException("exception(): Try does not contain an exception");
} }
return *e_; return e_;
} }
const exception_wrapper& exception() const { const exception_wrapper& exception() const {
if (UNLIKELY(!hasException())) { if (UNLIKELY(!hasException())) {
throw TryException("exception(): Try does not contain an exception"); throw TryException("exception(): Try does not contain an exception");
} }
return *e_; return e_;
} }
/* /*
...@@ -345,11 +347,18 @@ class Try<void> { ...@@ -345,11 +347,18 @@ class Try<void> {
* @returns True if the Try held an Ex and func was executed, false otherwise * @returns True if the Try held an Ex and func was executed, false otherwise
*/ */
template <class Ex, class F> template <class Ex, class F>
bool withException(F func) {
if (!hasException()) {
return false;
}
return e_.with_exception(std::move(func));
}
template <class Ex, class F>
bool withException(F func) const { bool withException(F func) const {
if (!hasException()) { if (!hasException()) {
return false; return false;
} }
return e_->with_exception(std::move(func)); return e_.with_exception(std::move(func));
} }
template <bool, typename R> template <bool, typename R>
...@@ -359,7 +368,7 @@ class Try<void> { ...@@ -359,7 +368,7 @@ class Try<void> {
private: private:
bool hasValue_; bool hasValue_;
std::unique_ptr<exception_wrapper> e_{nullptr}; exception_wrapper e_;
}; };
/* /*
......
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