Commit 209cc2f8 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

simplify Function is-small check

Summary:
In a way which also happens to improve build speed.

It turns out that the bulk of the improvement comes from removing the use of `std::is_nothrow_move_constructible` since it may internally have a `std::declval` in there. But that's not the only source of improvements.

```name=trunk
$ foundation/scripts/run-perf-compile --syntax folly/futures/test/FutureTest.cpp
     8,367,373,932      instructions:uP
```
```name=branch
$ foundation/scripts/run-perf-compile --syntax folly/futures/test/FutureTest.cpp
     8,101,850,897      instructions:uP
```

Reviewed By: luciang

Differential Revision: D32973629

fbshipit-source-id: 37c27763a4f622750719db11fee7cb23c0b0291e
parent ed9a4edd
...@@ -258,11 +258,6 @@ union Data { ...@@ -258,11 +258,6 @@ union Data {
std::aligned_storage<6 * sizeof(void*)>::type tiny; std::aligned_storage<6 * sizeof(void*)>::type tiny;
}; };
template <typename Fun, typename = Fun*>
using IsSmall = Conjunction<
bool_constant<(sizeof(Fun) <= sizeof(Data::tiny))>,
std::is_nothrow_move_constructible<Fun>>;
struct CoerceTag {}; struct CoerceTag {};
template <typename T> template <typename T>
...@@ -666,9 +661,6 @@ class Function final : private detail::function::FunctionTraits<FunctionType> { ...@@ -666,9 +661,6 @@ class Function final : private detail::function::FunctionTraits<FunctionType> {
using Call = typename Traits::Call; using Call = typename Traits::Call;
using Exec = detail::function::Exec; using Exec = detail::function::Exec;
template <typename Fun>
using IsSmall = detail::function::IsSmall<Fun>;
// The `data_` member is mutable to allow `constCastFunction` to work without // The `data_` member is mutable to allow `constCastFunction` to work without
// invoking undefined behavior. Const-correctness is only violated when // invoking undefined behavior. Const-correctness is only violated when
// `FunctionType` is a const function type (e.g., `int() const`) and `*this` // `FunctionType` is a const function type (e.g., `int() const`) and `*this`
...@@ -762,20 +754,22 @@ class Function final : private detail::function::FunctionTraits<FunctionType> { ...@@ -762,20 +754,22 @@ class Function final : private detail::function::FunctionTraits<FunctionType> {
typename Fun, typename Fun,
typename = typename =
std::enable_if_t<!detail::is_similar_instantiation_v<Function, Fun>>, std::enable_if_t<!detail::is_similar_instantiation_v<Function, Fun>>,
typename = typename Traits::template IfSafeResult<Fun>> typename = typename Traits::template IfSafeResult<Fun>,
bool IsSmall = sizeof(Fun) <=
sizeof(Data::tiny) && noexcept(Fun(FOLLY_DECLVAL(Fun)))>
/* implicit */ Function(Fun fun) noexcept( /* implicit */ Function(Fun fun) noexcept(
IsSmall<Fun>::value&& noexcept(Fun(static_cast<Fun&&>(fun)))) { IsSmall&& noexcept(Fun(static_cast<Fun&&>(fun)))) {
using Dispatch = conditional_t< using Dispatch = conditional_t<
IsSmall<Fun>::value && is_trivially_copyable_v<Fun>, IsSmall && is_trivially_copyable_v<Fun>,
detail::function::DispatchSmallTrivial, detail::function::DispatchSmallTrivial,
conditional_t< conditional_t<
IsSmall<Fun>::value, IsSmall,
detail::function::DispatchSmall, detail::function::DispatchSmall,
detail::function::DispatchBig>>; detail::function::DispatchBig>>;
if (detail::function::isEmptyFunction(fun)) { if (detail::function::isEmptyFunction(fun)) {
return; return;
} }
if FOLLY_CXX17_CONSTEXPR (IsSmall<Fun>::value) { if FOLLY_CXX17_CONSTEXPR (IsSmall) {
::new (&data_.tiny) Fun(static_cast<Fun&&>(fun)); ::new (&data_.tiny) Fun(static_cast<Fun&&>(fun));
} else { } else {
data_.big = new Fun(static_cast<Fun&&>(fun)); data_.big = new Fun(static_cast<Fun&&>(fun));
......
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