From b37148752520cab312d2816e088d65736dfc52dc Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 13 Feb 2021 00:15:05 -0800 Subject: [PATCH] sf: optimize argument parsing for const LargeData & --- .../sf/impl/sf_impl_command_serialization.hpp | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp b/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp index d403aa23d..6e576b092 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp @@ -412,9 +412,13 @@ namespace ams::sf::impl { size_t out_object_index; }; + template + using DecayForCommandMetaArguments = typename std::conditional::type> && !std::is_base_of::type>::value, T, typename std::decay::type>::type; + template struct CommandMetaInfo { public: + using ArgsTypeForInvoke = std::tuple...>; using ArgsType = std::tuple::type...>; using InDatas = TupleFilter::FilteredType; @@ -814,7 +818,7 @@ namespace ams::sf::impl { } /* Useful defines. */ - using ArgsType = typename CommandMeta::ArgsType; + using ArgsTypeForInvoke = typename CommandMeta::ArgsTypeForInvoke; using BufferArrayType = std::array; using OutRawHolderType = OutRawHolder; using OutHandleHolderType = OutHandleHolder; @@ -1000,7 +1004,7 @@ namespace ams::sf::impl { /* Argument deserialization. */ private: - template::type> + template::type> NX_CONSTEXPR T DeserializeArgumentImpl(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, OutHandleHolderType &out_handles_holder, InOutObjectHolderType &in_out_objects_holder) { constexpr auto Info = CommandMeta::ArgumentSerializationInfos[Index]; if constexpr (Info.arg_type == ArgumentType::InData) { @@ -1047,6 +1051,8 @@ namespace ams::sf::impl { constexpr auto Attributes = CommandMeta::BufferAttributes[Info.buffer_index]; if constexpr (Attributes & SfBufferAttr_In) { /* TODO: AMS_ABORT_UNLESS()? N does not bother. */ + static_assert(std::is_reference::value); + static_assert(std::is_const::type>::value); return *reinterpret_cast(buffers[Info.buffer_index].GetAddress()); } else if constexpr (Attributes & SfBufferAttr_Out) { return T(buffers[Info.buffer_index]); @@ -1063,12 +1069,12 @@ namespace ams::sf::impl { } template - NX_CONSTEXPR ArgsType DeserializeArgumentsImpl(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, OutHandleHolderType &out_handles_holder, InOutObjectHolderType &in_out_objects_holder, std::index_sequence) { - return ArgsType { DeserializeArgumentImpl(ctx, in_raw_data, out_raw_holder, buffers, out_handles_holder, in_out_objects_holder)..., }; + NX_CONSTEXPR ArgsTypeForInvoke DeserializeArgumentsImpl(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, OutHandleHolderType &out_handles_holder, InOutObjectHolderType &in_out_objects_holder, std::index_sequence) { + return ArgsTypeForInvoke { DeserializeArgumentImpl(ctx, in_raw_data, out_raw_holder, buffers, out_handles_holder, in_out_objects_holder)..., }; } public: - NX_CONSTEXPR ArgsType DeserializeArguments(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, OutHandleHolderType &out_handles_holder, InOutObjectHolderType &in_out_objects_holder) { - return DeserializeArgumentsImpl(ctx, in_raw_data, out_raw_holder, buffers, out_handles_holder, in_out_objects_holder, std::make_index_sequence::value>{}); + NX_CONSTEXPR ArgsTypeForInvoke DeserializeArguments(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, OutHandleHolderType &out_handles_holder, InOutObjectHolderType &in_out_objects_holder) { + return DeserializeArgumentsImpl(ctx, in_raw_data, out_raw_holder, buffers, out_handles_holder, in_out_objects_holder, std::make_index_sequence::value>{}); } }; @@ -1118,16 +1124,16 @@ namespace ams::sf::impl { /* Decoding/Invocation. */ { - typename CommandMeta::ArgsType args_tuple = ImplProcessorType::DeserializeArguments(ctx, in_raw_data, out_raw_holder, buffers, out_handles_holder, in_out_objects_holder); + typename CommandMeta::ArgsTypeForInvoke args_tuple = ImplProcessorType::DeserializeArguments(ctx, in_raw_data, out_raw_holder, buffers, out_handles_holder, in_out_objects_holder); /* Handle in process ID holder if relevant. */ if constexpr (CommandMeta::HasInProcessIdHolder) { /* TODO: More precise value than 32? */ - static_assert(std::tuple_size::value <= 32, "Commands must have <= 32 arguments"); + static_assert(std::tuple_size::value <= 32, "Commands must have <= 32 arguments"); os::ProcessId process_id{ctx.request.pid}; #define _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(n) do { \ - using ArgsType = typename CommandMeta::ArgsType; \ - if constexpr (n < std::tuple_size::value) { \ + using ArgsTypeForInvoke = typename CommandMeta::ArgsTypeForInvoke; \ + if constexpr (n < std::tuple_size::value) { \ if constexpr (CommandMeta::template IsInProcessIdHolderIndex) { \ R_TRY(MarshalProcessId(std::get(args_tuple), process_id)); \ } \ @@ -1149,7 +1155,7 @@ namespace ams::sf::impl { sf::IServiceObject * const this_ptr = ctx.srv_obj; const auto command_result = [this_ptr, invoke_impl, &args_tuple](std::index_sequence) ALWAYS_INLINE_LAMBDA { return invoke_impl(this_ptr, std::forward::type>(std::get(args_tuple))...); - }(std::make_index_sequence::value>()); + }(std::make_index_sequence::value>()); if (R_FAILED(command_result)) { cmif::PointerAndSize out_raw_data;