Commit 9552fbcd authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

tweak catch_exception taking fun-ptrs

Summary: To reduce build size, avoid creating unnecessary functions. If the provided callable is already a function-pointer, the callee will already not be inlined.

Differential Revision: D27984345

fbshipit-source-id: a5a31330541338eb04e802bd9dafd99188af3ab9
parent f35ba916
......@@ -74,7 +74,7 @@ fbstring exceptionStr(std::exception_ptr ep) {
[&]() -> fbstring {
return catch_exception<std::exception const&>(
[&]() -> fbstring { std::rethrow_exception(std::move(ep)); },
[](auto&& e) { return exceptionStr(e); });
static_cast<fbstring (&)(std::exception const&)>(exceptionStr));
},
[&]() -> fbstring {
return type ? demangle(*type) : "<unknown exception>";
......
......@@ -16,12 +16,14 @@
#include <folly/ScopeGuard.h>
#include <exception>
#include <iostream>
/*static*/ void folly::detail::ScopeGuardImplBase::warnAboutToCrash() noexcept {
/*static*/ void folly::detail::ScopeGuardImplBase::terminate() noexcept {
// Ensure the availability of std::cerr
std::ios_base::Init ioInit;
std::cerr
<< "This program will now terminate because a folly::ScopeGuard callback "
"threw an \nexception.\n";
std::rethrow_exception(std::current_exception());
}
......@@ -43,7 +43,7 @@ class ScopeGuardImplBase {
protected:
ScopeGuardImplBase(bool dismissed = false) noexcept : dismissed_(dismissed) {}
static void warnAboutToCrash() noexcept;
[[noreturn]] static void terminate() noexcept;
static ScopeGuardImplBase makeEmptyScopeGuard() noexcept {
return ScopeGuardImplBase{};
}
......@@ -125,7 +125,8 @@ class ScopeGuardImpl : public ScopeGuardImplBase {
void execute() noexcept(InvokeNoexcept) {
if (InvokeNoexcept) {
using R = decltype(function_());
auto catcher = []() -> R { warnAboutToCrash(), std::terminate(); };
auto catcher_word = reinterpret_cast<uintptr_t>(&terminate);
auto catcher = reinterpret_cast<R (*)()>(catcher_word);
catch_exception(function_, catcher);
} else {
function_();
......
......@@ -125,7 +125,9 @@ template <typename Ex, typename... Args>
///
/// Usage note:
/// Passing extra values as arguments rather than capturing them allows smaller
/// inlined native at the call-site.
/// inlined native code at the call-site. Passing function-pointers or function-
/// references rather than general callables with captures allows allows smaller
/// inlined native code at the call-site as well.
///
/// Example:
///
......@@ -138,11 +140,24 @@ template <typename Ex, typename... Args>
/// },
/// i);
/// }
template <typename F, typename... A>
template <
typename F,
typename... A,
typename FD = std::remove_pointer_t<std::decay_t<F>>,
std::enable_if_t<!std::is_function<FD>::value, int> = 0>
FOLLY_NOINLINE FOLLY_COLD auto invoke_cold(F&& f, A&&... a)
-> decltype(static_cast<F&&>(f)(static_cast<A&&>(a)...)) {
return static_cast<F&&>(f)(static_cast<A&&>(a)...);
}
template <
typename F,
typename... A,
typename FD = std::remove_pointer_t<std::decay_t<F>>,
std::enable_if_t<std::is_function<FD>::value, int> = 0>
FOLLY_ERASE auto invoke_cold(F&& f, A&&... a)
-> decltype(f(static_cast<A&&>(a)...)) {
return f(static_cast<A&&>(a)...);
}
/// invoke_noreturn_cold
///
......
......@@ -124,8 +124,12 @@ TEST_F(ExceptionTest, catch_exception) {
auto thrower = [](int i) { return [=]() -> int { throw i; }; };
EXPECT_EQ(3, folly::catch_exception(returner(3), returner(4)));
EXPECT_EQ(3, folly::catch_exception<int>(returner(3), identity));
EXPECT_EQ(3, folly::catch_exception<int>(returner(3), +identity));
EXPECT_EQ(3, folly::catch_exception<int>(returner(3), *+identity));
EXPECT_EQ(4, folly::catch_exception(thrower(3), returner(4)));
EXPECT_EQ(3, folly::catch_exception<int>(thrower(3), identity));
EXPECT_EQ(3, folly::catch_exception<int>(thrower(3), +identity));
EXPECT_EQ(3, folly::catch_exception<int>(thrower(3), *+identity));
}
TEST_F(ExceptionTest, rethrow_current_exception) {
......
......@@ -92,13 +92,13 @@ template <typename Arg>
auto appendObjectToString(std::string& str, const Arg* arg, int) -> decltype(
toAppend(std::declval<Arg>(), std::declval<std::string*>()),
std::declval<void>()) {
::folly::catch_exception<const std::exception&>(
::folly::catch_exception(
[&] { toAppend(*arg, &str); },
[&](const std::exception&) {
// If anything goes wrong in `toAppend()` fall back to
// appendRawObjectInfo()
::folly::logging::appendRawObjectInfo(str, arg);
});
// If anything goes wrong in `toAppend()` fall back to
// appendRawObjectInfo()
::folly::logging::appendRawObjectInfo<Arg>,
str,
arg);
}
template <typename Arg>
......
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