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

Back out "[Folly] Optimize Function::operator() codegen"

Summary: There is a build failure with some versions of MSVC. Backing out the change while investigating.

Reviewed By: lhuang04

Differential Revision: D17520392

fbshipit-source-id: ee63795ff78c5ac638fc97a9db632437436fb758
parent 44833c41
...@@ -305,9 +305,6 @@ template < ...@@ -305,9 +305,6 @@ template <
!std::is_reference<To>::value || std::is_reference<From>::value>::type> !std::is_reference<To>::value || std::is_reference<From>::value>::type>
using SafeResultOf = decltype(static_cast<To>(std::declval<From>())); using SafeResultOf = decltype(static_cast<To>(std::declval<From>()));
template <typename T>
using CallArg = conditional_t<is_trivially_copyable<T>::value, T, T&&>;
template <typename F, typename R, typename... A> template <typename F, typename R, typename... A>
class FunctionTraitsSharedProxy { class FunctionTraitsSharedProxy {
std::shared_ptr<Function<F>> sp_; std::shared_ptr<Function<F>> sp_;
...@@ -348,7 +345,7 @@ struct FunctionTraits; ...@@ -348,7 +345,7 @@ struct FunctionTraits;
template <typename ReturnType, typename... Args> template <typename ReturnType, typename... Args>
struct FunctionTraits<ReturnType(Args...)> { struct FunctionTraits<ReturnType(Args...)> {
using Call = ReturnType (*)(CallArg<Args>..., Data&); using Call = ReturnType (*)(Data&, Args&&...);
using IsConst = std::false_type; using IsConst = std::false_type;
using ConstSignature = ReturnType(Args...) const; using ConstSignature = ReturnType(Args...) const;
using NonConstSignature = ReturnType(Args...); using NonConstSignature = ReturnType(Args...);
...@@ -359,24 +356,24 @@ struct FunctionTraits<ReturnType(Args...)> { ...@@ -359,24 +356,24 @@ struct FunctionTraits<ReturnType(Args...)> {
SafeResultOf<CallableResult<std::decay_t<F>&, Args...>, ReturnType>; SafeResultOf<CallableResult<std::decay_t<F>&, Args...>, ReturnType>;
template <typename Fun> template <typename Fun>
static ReturnType callSmall(CallArg<Args>... args, Data& p) { static ReturnType callSmall(Data& p, Args&&... args) {
return static_cast<ReturnType>((*static_cast<Fun*>( return static_cast<ReturnType>((*static_cast<Fun*>(
static_cast<void*>(&p.tiny)))(static_cast<Args&&>(args)...)); static_cast<void*>(&p.tiny)))(static_cast<Args&&>(args)...));
} }
template <typename Fun> template <typename Fun>
static ReturnType callBig(CallArg<Args>... args, Data& p) { static ReturnType callBig(Data& p, Args&&... args) {
return static_cast<ReturnType>( return static_cast<ReturnType>(
(*static_cast<Fun*>(p.big))(static_cast<Args&&>(args)...)); (*static_cast<Fun*>(p.big))(static_cast<Args&&>(args)...));
} }
static ReturnType uninitCall(CallArg<Args>..., Data&) { static ReturnType uninitCall(Data&, Args&&...) {
throw_exception<std::bad_function_call>(); throw_exception<std::bad_function_call>();
} }
ReturnType operator()(Args... args) { ReturnType operator()(Args... args) {
auto& fn = *static_cast<Function<NonConstSignature>*>(this); auto& fn = *static_cast<Function<NonConstSignature>*>(this);
return fn.call_(static_cast<Args&&>(args)..., fn.data_); return fn.call_(fn.data_, static_cast<Args&&>(args)...);
} }
using SharedProxy = using SharedProxy =
...@@ -385,7 +382,7 @@ struct FunctionTraits<ReturnType(Args...)> { ...@@ -385,7 +382,7 @@ struct FunctionTraits<ReturnType(Args...)> {
template <typename ReturnType, typename... Args> template <typename ReturnType, typename... Args>
struct FunctionTraits<ReturnType(Args...) const> { struct FunctionTraits<ReturnType(Args...) const> {
using Call = ReturnType (*)(CallArg<Args>..., Data&); using Call = ReturnType (*)(Data&, Args&&...);
using IsConst = std::true_type; using IsConst = std::true_type;
using ConstSignature = ReturnType(Args...) const; using ConstSignature = ReturnType(Args...) const;
using NonConstSignature = ReturnType(Args...); using NonConstSignature = ReturnType(Args...);
...@@ -396,24 +393,24 @@ struct FunctionTraits<ReturnType(Args...) const> { ...@@ -396,24 +393,24 @@ struct FunctionTraits<ReturnType(Args...) const> {
SafeResultOf<CallableResult<const std::decay_t<F>&, Args...>, ReturnType>; SafeResultOf<CallableResult<const std::decay_t<F>&, Args...>, ReturnType>;
template <typename Fun> template <typename Fun>
static ReturnType callSmall(CallArg<Args>... args, Data& p) { static ReturnType callSmall(Data& p, Args&&... args) {
return static_cast<ReturnType>((*static_cast<const Fun*>( return static_cast<ReturnType>((*static_cast<const Fun*>(
static_cast<void*>(&p.tiny)))(static_cast<Args&&>(args)...)); static_cast<void*>(&p.tiny)))(static_cast<Args&&>(args)...));
} }
template <typename Fun> template <typename Fun>
static ReturnType callBig(CallArg<Args>... args, Data& p) { static ReturnType callBig(Data& p, Args&&... args) {
return static_cast<ReturnType>( return static_cast<ReturnType>(
(*static_cast<const Fun*>(p.big))(static_cast<Args&&>(args)...)); (*static_cast<const Fun*>(p.big))(static_cast<Args&&>(args)...));
} }
static ReturnType uninitCall(CallArg<Args>..., Data&) { static ReturnType uninitCall(Data&, Args&&...) {
throw_exception<std::bad_function_call>(); throw_exception<std::bad_function_call>();
} }
ReturnType operator()(Args... args) const { ReturnType operator()(Args... args) const {
auto& fn = *static_cast<const Function<ConstSignature>*>(this); auto& fn = *static_cast<const Function<ConstSignature>*>(this);
return fn.call_(static_cast<Args&&>(args)..., fn.data_); return fn.call_(fn.data_, static_cast<Args&&>(args)...);
} }
using SharedProxy = using SharedProxy =
...@@ -423,7 +420,7 @@ struct FunctionTraits<ReturnType(Args...) const> { ...@@ -423,7 +420,7 @@ struct FunctionTraits<ReturnType(Args...) const> {
#if FOLLY_HAVE_NOEXCEPT_FUNCTION_TYPE #if FOLLY_HAVE_NOEXCEPT_FUNCTION_TYPE
template <typename ReturnType, typename... Args> template <typename ReturnType, typename... Args>
struct FunctionTraits<ReturnType(Args...) noexcept> { struct FunctionTraits<ReturnType(Args...) noexcept> {
using Call = ReturnType (*)(CallArg<Args>..., Data&) noexcept; using Call = ReturnType (*)(Data&, Args&&...) noexcept;
using IsConst = std::false_type; using IsConst = std::false_type;
using ConstSignature = ReturnType(Args...) const noexcept; using ConstSignature = ReturnType(Args...) const noexcept;
using NonConstSignature = ReturnType(Args...) noexcept; using NonConstSignature = ReturnType(Args...) noexcept;
...@@ -434,24 +431,24 @@ struct FunctionTraits<ReturnType(Args...) noexcept> { ...@@ -434,24 +431,24 @@ struct FunctionTraits<ReturnType(Args...) noexcept> {
SafeResultOf<CallableResult<std::decay_t<F>&, Args...>, ReturnType>; SafeResultOf<CallableResult<std::decay_t<F>&, Args...>, ReturnType>;
template <typename Fun> template <typename Fun>
static ReturnType callSmall(CallArg<Args>... args, Data& p) noexcept { static ReturnType callSmall(Data& p, Args&&... args) noexcept {
return static_cast<ReturnType>((*static_cast<Fun*>( return static_cast<ReturnType>((*static_cast<Fun*>(
static_cast<void*>(&p.tiny)))(static_cast<Args&&>(args)...)); static_cast<void*>(&p.tiny)))(static_cast<Args&&>(args)...));
} }
template <typename Fun> template <typename Fun>
static ReturnType callBig(CallArg<Args>... args, Data& p) noexcept { static ReturnType callBig(Data& p, Args&&... args) noexcept {
return static_cast<ReturnType>( return static_cast<ReturnType>(
(*static_cast<Fun*>(p.big))(static_cast<Args&&>(args)...)); (*static_cast<Fun*>(p.big))(static_cast<Args&&>(args)...));
} }
static ReturnType uninitCall(CallArg<Args>..., Data&) noexcept { static ReturnType uninitCall(Data&, Args&&...) noexcept {
terminate_with<std::bad_function_call>(); terminate_with<std::bad_function_call>();
} }
ReturnType operator()(Args... args) noexcept { ReturnType operator()(Args... args) noexcept {
auto& fn = *static_cast<Function<NonConstSignature>*>(this); auto& fn = *static_cast<Function<NonConstSignature>*>(this);
return fn.call_(static_cast<Args&&>(args)..., fn.data_); return fn.call_(fn.data_, static_cast<Args&&>(args)...);
} }
using SharedProxy = using SharedProxy =
...@@ -460,7 +457,7 @@ struct FunctionTraits<ReturnType(Args...) noexcept> { ...@@ -460,7 +457,7 @@ struct FunctionTraits<ReturnType(Args...) noexcept> {
template <typename ReturnType, typename... Args> template <typename ReturnType, typename... Args>
struct FunctionTraits<ReturnType(Args...) const noexcept> { struct FunctionTraits<ReturnType(Args...) const noexcept> {
using Call = ReturnType (*)(CallArg<Args>..., Data&) noexcept; using Call = ReturnType (*)(Data&, Args&&...) noexcept;
using IsConst = std::true_type; using IsConst = std::true_type;
using ConstSignature = ReturnType(Args...) const noexcept; using ConstSignature = ReturnType(Args...) const noexcept;
using NonConstSignature = ReturnType(Args...) noexcept; using NonConstSignature = ReturnType(Args...) noexcept;
...@@ -471,24 +468,24 @@ struct FunctionTraits<ReturnType(Args...) const noexcept> { ...@@ -471,24 +468,24 @@ struct FunctionTraits<ReturnType(Args...) const noexcept> {
SafeResultOf<CallableResult<const std::decay_t<F>&, Args...>, ReturnType>; SafeResultOf<CallableResult<const std::decay_t<F>&, Args...>, ReturnType>;
template <typename Fun> template <typename Fun>
static ReturnType callSmall(CallArg<Args>... args, Data& p) noexcept { static ReturnType callSmall(Data& p, Args&&... args) noexcept {
return static_cast<ReturnType>((*static_cast<const Fun*>( return static_cast<ReturnType>((*static_cast<const Fun*>(
static_cast<void*>(&p.tiny)))(static_cast<Args&&>(args)...)); static_cast<void*>(&p.tiny)))(static_cast<Args&&>(args)...));
} }
template <typename Fun> template <typename Fun>
static ReturnType callBig(CallArg<Args>... args, Data& p) noexcept { static ReturnType callBig(Data& p, Args&&... args) noexcept {
return static_cast<ReturnType>( return static_cast<ReturnType>(
(*static_cast<const Fun*>(p.big))(static_cast<Args&&>(args)...)); (*static_cast<const Fun*>(p.big))(static_cast<Args&&>(args)...));
} }
static ReturnType uninitCall(CallArg<Args>..., Data&) noexcept { static ReturnType uninitCall(Data&, Args&&...) noexcept {
throw_exception<std::bad_function_call>(); throw_exception<std::bad_function_call>();
} }
ReturnType operator()(Args... args) const noexcept { ReturnType operator()(Args... args) const noexcept {
auto& fn = *static_cast<const Function<ConstSignature>*>(this); auto& fn = *static_cast<const Function<ConstSignature>*>(this);
return fn.call_(static_cast<Args&&>(args)..., fn.data_); return fn.call_(fn.data_, static_cast<Args&&>(args)...);
} }
using SharedProxy = using SharedProxy =
...@@ -915,17 +912,14 @@ class FunctionRef; ...@@ -915,17 +912,14 @@ class FunctionRef;
template <typename ReturnType, typename... Args> template <typename ReturnType, typename... Args>
class FunctionRef<ReturnType(Args...)> final { class FunctionRef<ReturnType(Args...)> final {
template <typename Arg> using Call = ReturnType (*)(void*, Args&&...);
using CallArg = detail::function::CallArg<Arg>;
using Call = ReturnType (*)(CallArg<Args>&&..., void*);
static ReturnType uninitCall(CallArg<Args>&&..., void*) { static ReturnType uninitCall(void*, Args&&...) {
throw_exception<std::bad_function_call>(); throw_exception<std::bad_function_call>();
} }
template <typename Fun> template <typename Fun>
static ReturnType call(CallArg<Args>&&... args, void* object) { static ReturnType call(void* object, Args&&... args) {
using Pointer = std::add_pointer_t<Fun>; using Pointer = std::add_pointer_t<Fun>;
return static_cast<ReturnType>(invoke( return static_cast<ReturnType>(invoke(
static_cast<Fun&&>(*static_cast<Pointer>(object)), static_cast<Fun&&>(*static_cast<Pointer>(object)),
...@@ -970,7 +964,7 @@ class FunctionRef<ReturnType(Args...)> final { ...@@ -970,7 +964,7 @@ class FunctionRef<ReturnType(Args...)> final {
call_(&FunctionRef::call<Fun>) {} call_(&FunctionRef::call<Fun>) {}
ReturnType operator()(Args... args) const { ReturnType operator()(Args... args) const {
return call_(static_cast<Args&&>(args)..., object_); return call_(object_, static_cast<Args&&>(args)...);
} }
constexpr explicit operator bool() const noexcept { constexpr explicit operator bool() const noexcept {
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
*/ */
#pragma once #pragma once
#include <folly/Function.h>
#include <folly/Traits.h> #include <folly/Traits.h>
#include <folly/Utility.h> #include <folly/Utility.h>
#include <folly/functional/Invoke.h> #include <folly/functional/Invoke.h>
...@@ -67,12 +66,9 @@ class InlineFunctionRef; ...@@ -67,12 +66,9 @@ class InlineFunctionRef;
template <typename ReturnType, typename... Args, std::size_t Size> template <typename ReturnType, typename... Args, std::size_t Size>
class InlineFunctionRef<ReturnType(Args...), Size> { class InlineFunctionRef<ReturnType(Args...), Size> {
template <typename Arg>
using CallArg = function::CallArg<Arg>;
using Storage = using Storage =
std::aligned_storage_t<Size - sizeof(uintptr_t), sizeof(uintptr_t)>; std::aligned_storage_t<Size - sizeof(uintptr_t), sizeof(uintptr_t)>;
using Call = ReturnType (*)(CallArg<Args>..., const Storage&); using Call = ReturnType (*)(const Storage&, Args&&...);
struct InSituTag {}; struct InSituTag {};
struct RefTag {}; struct RefTag {};
...@@ -152,7 +148,7 @@ class InlineFunctionRef<ReturnType(Args...), Size> { ...@@ -152,7 +148,7 @@ class InlineFunctionRef<ReturnType(Args...), Size> {
* appropriate casting. * appropriate casting.
*/ */
ReturnType operator()(Args... args) const { ReturnType operator()(Args... args) const {
return call_(static_cast<Args&&>(args)..., storage_); return call_(storage_, static_cast<Args&&>(args)...);
} }
/** /**
...@@ -199,7 +195,7 @@ class InlineFunctionRef<ReturnType(Args...), Size> { ...@@ -199,7 +195,7 @@ class InlineFunctionRef<ReturnType(Args...), Size> {
} }
template <typename Func> template <typename Func>
static ReturnType callInline(CallArg<Args>... args, const Storage& object) { static ReturnType callInline(const Storage& object, Args&&... args) {
// The only type of pointer allowed is a function pointer, no other // The only type of pointer allowed is a function pointer, no other
// pointer types are invocable. // pointer types are invocable.
static_assert( static_assert(
...@@ -212,7 +208,7 @@ class InlineFunctionRef<ReturnType(Args...), Size> { ...@@ -212,7 +208,7 @@ class InlineFunctionRef<ReturnType(Args...), Size> {
} }
template <typename Func> template <typename Func>
static ReturnType callPointer(CallArg<Args>... args, const Storage& object) { static ReturnType callPointer(const Storage& object, Args&&... args) {
// When the function we were instantiated with was not trivial, the given // When the function we were instantiated with was not trivial, the given
// pointer points to a pointer, which pointers to the callable. So we // pointer points to a pointer, which pointers to the callable. So we
// cast to a pointer and then to the pointee. // cast to a pointer and then to the pointee.
......
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