Commit 9697d49e authored by tzik's avatar tzik Committed by Commit Bot

Tweak Callback's MaybeValid implementation for smaller binary size

http://crrev.com/40f8e9a571636737 gained the stripped binary size of
chrome by 40kB (147306728 to 147347688), which is mainly due to an extra
parameter set up on BindStateBase for each base::Bind() caller.

This CL removes the extra argument by merging it to single function with
another parameter. So that the binary loses back to the original size.
(147347688 to 147306728).

Bug: 869098
Change-Id: I7b60797c16a00472e9312466fdd2434395d8bbf7
Reviewed-on: https://chromium-review.googlesource.com/1158093
Commit-Queue: Taiju Tsuiki <tzik@chromium.org>
Reviewed-by: default avatarGabriel Charette <gab@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580152}
parent 0deeb96f
......@@ -734,48 +734,36 @@ std::enable_if_t<!FunctorTraits<Functor>::is_nullable, bool> IsNull(
return false;
}
// Used by ApplyCancellationTraits below.
// Used by QueryCancellationTraits below.
template <typename Functor, typename BoundArgsTuple, size_t... indices>
bool ApplyCancellationTraitsIsCancelledImpl(const Functor& functor,
const BoundArgsTuple& bound_args,
std::index_sequence<indices...>) {
return CallbackCancellationTraits<Functor, BoundArgsTuple>::IsCancelled(
functor, std::get<indices>(bound_args)...);
bool QueryCancellationTraitsImpl(BindStateBase::CancellationQueryMode mode,
const Functor& functor,
const BoundArgsTuple& bound_args,
std::index_sequence<indices...>) {
switch (mode) {
case BindStateBase::IS_CANCELLED:
return CallbackCancellationTraits<Functor, BoundArgsTuple>::IsCancelled(
functor, std::get<indices>(bound_args)...);
case BindStateBase::MAYBE_VALID:
return CallbackCancellationTraits<Functor, BoundArgsTuple>::MaybeValid(
functor, std::get<indices>(bound_args)...);
}
NOTREACHED();
}
// Relays |base| to corresponding CallbackCancellationTraits<>::Run(). Returns
// true if the callback |base| represents is canceled.
template <typename BindStateType>
bool ApplyCancellationTraitsIsCancelled(const BindStateBase* base) {
bool QueryCancellationTraits(const BindStateBase* base,
BindStateBase::CancellationQueryMode mode) {
const BindStateType* storage = static_cast<const BindStateType*>(base);
static constexpr size_t num_bound_args =
std::tuple_size<decltype(storage->bound_args_)>::value;
return ApplyCancellationTraitsIsCancelledImpl(
storage->functor_, storage->bound_args_,
return QueryCancellationTraitsImpl(
mode, storage->functor_, storage->bound_args_,
std::make_index_sequence<num_bound_args>());
};
// Used by ApplyCancellationTraits below.
template <typename Functor, typename BoundArgsTuple, size_t... indices>
bool ApplyCancellationTraitsMaybeValidImpl(const Functor& functor,
const BoundArgsTuple& bound_args,
std::index_sequence<indices...>) {
return CallbackCancellationTraits<Functor, BoundArgsTuple>::MaybeValid(
functor, std::get<indices>(bound_args)...);
}
// Relays |base| to corresponding CallbackCancellationTraits<>::Run(). Returns
// false if the callback |base| represents is guaranteed to be cancelled.
template <typename BindStateType>
bool ApplyCancellationTraitsMaybeValid(const BindStateBase* base) {
const BindStateType* storage = static_cast<const BindStateType*>(base);
static constexpr size_t num_bound_args =
std::tuple_size<decltype(storage->bound_args_)>::value;
return ApplyCancellationTraitsMaybeValidImpl(
storage->functor_, storage->bound_args_,
std::make_index_sequence<num_bound_args>());
};
// BindState<>
//
// This stores all the state passed into Bind().
......@@ -809,8 +797,7 @@ struct BindState final : BindStateBase {
ForwardBoundArgs&&... bound_args)
: BindStateBase(invoke_func,
&Destroy,
&ApplyCancellationTraitsIsCancelled<BindState>,
&ApplyCancellationTraitsMaybeValid<BindState>),
&QueryCancellationTraits<BindState>),
functor_(std::forward<ForwardFunctor>(functor)),
bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) {
DCHECK(!IsNull(functor_));
......
......@@ -11,12 +11,16 @@ namespace internal {
namespace {
bool ReturnFalse(const BindStateBase*) {
return false;
}
bool ReturnTrue(const BindStateBase*) {
return true;
bool QueryCancellationTraitsForNonCancellables(
const BindStateBase*,
BindStateBase::CancellationQueryMode mode) {
switch (mode) {
case BindStateBase::IS_CANCELLED:
return false;
case BindStateBase::MAYBE_VALID:
return true;
}
NOTREACHED();
}
} // namespace
......@@ -27,17 +31,18 @@ void BindStateBaseRefCountTraits::Destruct(const BindStateBase* bind_state) {
BindStateBase::BindStateBase(InvokeFuncStorage polymorphic_invoke,
void (*destructor)(const BindStateBase*))
: BindStateBase(polymorphic_invoke, destructor, &ReturnFalse, &ReturnTrue) {
}
BindStateBase::BindStateBase(InvokeFuncStorage polymorphic_invoke,
void (*destructor)(const BindStateBase*),
bool (*is_cancelled)(const BindStateBase*),
bool (*maybe_valid)(const BindStateBase*))
: BindStateBase(polymorphic_invoke,
destructor,
&QueryCancellationTraitsForNonCancellables) {}
BindStateBase::BindStateBase(
InvokeFuncStorage polymorphic_invoke,
void (*destructor)(const BindStateBase*),
bool (*query_cancellation_traits)(const BindStateBase*,
CancellationQueryMode))
: polymorphic_invoke_(polymorphic_invoke),
destructor_(destructor),
is_cancelled_(is_cancelled),
maybe_valid_(maybe_valid) {}
query_cancellation_traits_(query_cancellation_traits) {}
CallbackBase& CallbackBase::operator=(CallbackBase&& c) noexcept = default;
CallbackBase::CallbackBase(const CallbackBaseCopyable& c)
......
......@@ -50,6 +50,11 @@ class BASE_EXPORT BindStateBase
public:
REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
enum CancellationQueryMode {
IS_CANCELLED,
MAYBE_VALID,
};
using InvokeFuncStorage = void(*)();
private:
......@@ -57,8 +62,8 @@ class BASE_EXPORT BindStateBase
void (*destructor)(const BindStateBase*));
BindStateBase(InvokeFuncStorage polymorphic_invoke,
void (*destructor)(const BindStateBase*),
bool (*is_cancelled)(const BindStateBase*),
bool (*maybe_valid)(const BindStateBase*));
bool (*query_cancellation_traits)(const BindStateBase*,
CancellationQueryMode mode));
~BindStateBase() = default;
......@@ -74,10 +79,12 @@ class BASE_EXPORT BindStateBase
friend struct ::base::FakeBindState;
bool IsCancelled() const {
return is_cancelled_(this);
return query_cancellation_traits_(this, IS_CANCELLED);
}
bool MaybeValid() const { return maybe_valid_(this); }
bool MaybeValid() const {
return query_cancellation_traits_(this, MAYBE_VALID);
}
// In C++, it is safe to cast function pointers to function pointers of
// another type. It is not okay to use void*. We create a InvokeFuncStorage
......@@ -87,9 +94,8 @@ class BASE_EXPORT BindStateBase
// Pointer to a function that will properly destroy |this|.
void (*destructor_)(const BindStateBase*);
bool (*is_cancelled_)(const BindStateBase*);
bool (*maybe_valid_)(const BindStateBase*);
bool (*query_cancellation_traits_)(const BindStateBase*,
CancellationQueryMode mode);
DISALLOW_COPY_AND_ASSIGN(BindStateBase);
};
......
......@@ -24,18 +24,23 @@ void NopInvokeFunc() {}
// chance of colliding with another instantiation and breaking the
// one-definition-rule.
struct FakeBindState : internal::BindStateBase {
FakeBindState()
: BindStateBase(&NopInvokeFunc, &Destroy, &IsCancelled, &MaybeValid) {}
FakeBindState() : BindStateBase(&NopInvokeFunc, &Destroy, &IsCancelled) {}
private:
~FakeBindState() = default;
static void Destroy(const internal::BindStateBase* self) {
delete static_cast<const FakeBindState*>(self);
}
static bool IsCancelled(const internal::BindStateBase*) {
return false;
static bool IsCancelled(const internal::BindStateBase*,
internal::BindStateBase::CancellationQueryMode mode) {
switch (mode) {
case internal::BindStateBase::IS_CANCELLED:
return false;
case internal::BindStateBase::MAYBE_VALID:
return true;
}
NOTREACHED();
}
static bool MaybeValid(const internal::BindStateBase*) { return true; }
};
namespace {
......
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