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

invoke_noreturn_cold

Summary:
[Folly] `invoke_noreturn_cold`, a helper function for invoking another function with arguments in a `[[noreturn]]` and `[[gnu::cold]]` context.

Potentially useful for making the bytecode at the call-site small for icache size or always-inlined fast-path size concerns, when constructing the exception object to be thrown is more complex than passing pre-existing values by reference, such as when computing a message is required.

Reviewed By: marshallcline

Differential Revision: D9509658

fbshipit-source-id: b8272629876f9e7e81ae0f7a7f06404484d297f2
parent 22a5896e
......@@ -92,4 +92,36 @@ terminate_with(Args&&... args) noexcept {
}
// clang-format on
/// invoke_noreturn_cold
///
/// Invoke the provided function with the provided arguments. If the invocation
/// returns, terminate.
///
/// May be used with throw_exception in cases where construction of the object
/// to be thrown requires more than just invoking its constructor with a given
/// sequence of arguments passed by reference - for example, if a string message
/// must be computed before being passed to the constructor of the object to be
/// thrown.
///
/// Usage note:
/// Passing extra values as arguments rather than capturing them allows smaller
/// bytecode at the call-site.
///
/// Example:
///
/// if (i < 0) {
/// invoke_noreturn_cold(
/// [](int j) {
/// throw_exceptions(runtime_error(to<string>("invalid: ", j)));
/// },
/// i);
/// }
template <typename F, typename... A>
[[noreturn]] FOLLY_NOINLINE FOLLY_COLD void invoke_noreturn_cold(
F&& f,
A&&... a) {
static_cast<F&&>(f)(static_cast<A&&>(a)...);
std::terminate();
}
} // namespace folly
......@@ -48,6 +48,15 @@ static std::string message_for_terminate_with(std::string const& what) {
// clang-format on
}
static std::string message_for_terminate() {
// clang-format off
return
folly::kIsGlibcxx ? "terminate called without an active exception" :
folly::kIsLibcpp ? "terminating" :
"" /* empty regex matches anything */;
// clang-format on
}
class MyException : public std::exception {
private:
char const* what_;
......@@ -93,3 +102,10 @@ TEST_F(ExceptionTest, terminate_with_variadic) {
folly::terminate_with<MyException>("hello world", 6),
message_for_terminate_with<MyException>("world"));
}
TEST_F(ExceptionTest, invoke_noreturn_cold) {
EXPECT_THROW(
folly::invoke_noreturn_cold([] { throw std::runtime_error("bad"); }),
std::runtime_error);
EXPECT_DEATH(folly::invoke_noreturn_cold([] {}), message_for_terminate());
}
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