mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-12 23:16:40 +00:00
sf: optimize argument parsing for const LargeData &
This commit is contained in:
parent
5c97469348
commit
b371487525
1 changed files with 17 additions and 11 deletions
|
@ -412,9 +412,13 @@ namespace ams::sf::impl {
|
||||||
size_t out_object_index;
|
size_t out_object_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using DecayForCommandMetaArguments = typename std::conditional<sf::IsLargeData<typename std::decay<T>::type> && !std::is_base_of<impl::OutBaseTag, typename std::decay<T>::type>::value, T, typename std::decay<T>::type>::type;
|
||||||
|
|
||||||
template<typename... Arguments>
|
template<typename... Arguments>
|
||||||
struct CommandMetaInfo {
|
struct CommandMetaInfo {
|
||||||
public:
|
public:
|
||||||
|
using ArgsTypeForInvoke = std::tuple<DecayForCommandMetaArguments<Arguments>...>;
|
||||||
using ArgsType = std::tuple<typename std::decay<Arguments>::type...>;
|
using ArgsType = std::tuple<typename std::decay<Arguments>::type...>;
|
||||||
|
|
||||||
using InDatas = TupleFilter<InDataFilter>::FilteredType<ArgsType>;
|
using InDatas = TupleFilter<InDataFilter>::FilteredType<ArgsType>;
|
||||||
|
@ -814,7 +818,7 @@ namespace ams::sf::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Useful defines. */
|
/* Useful defines. */
|
||||||
using ArgsType = typename CommandMeta::ArgsType;
|
using ArgsTypeForInvoke = typename CommandMeta::ArgsTypeForInvoke;
|
||||||
using BufferArrayType = std::array<cmif::PointerAndSize, CommandMeta::NumBuffers>;
|
using BufferArrayType = std::array<cmif::PointerAndSize, CommandMeta::NumBuffers>;
|
||||||
using OutRawHolderType = OutRawHolder<CommandMeta::OutDataSize, CommandMeta::OutDataAlign>;
|
using OutRawHolderType = OutRawHolder<CommandMeta::OutDataSize, CommandMeta::OutDataAlign>;
|
||||||
using OutHandleHolderType = OutHandleHolder<CommandMeta::NumOutMoveHandles, CommandMeta::NumOutCopyHandles>;
|
using OutHandleHolderType = OutHandleHolder<CommandMeta::NumOutMoveHandles, CommandMeta::NumOutCopyHandles>;
|
||||||
|
@ -1000,7 +1004,7 @@ namespace ams::sf::impl {
|
||||||
|
|
||||||
/* Argument deserialization. */
|
/* Argument deserialization. */
|
||||||
private:
|
private:
|
||||||
template<size_t Index, typename T = typename std::tuple_element<Index, ArgsType>::type>
|
template<size_t Index, typename T = typename std::tuple_element<Index, ArgsTypeForInvoke>::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) {
|
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];
|
constexpr auto Info = CommandMeta::ArgumentSerializationInfos[Index];
|
||||||
if constexpr (Info.arg_type == ArgumentType::InData) {
|
if constexpr (Info.arg_type == ArgumentType::InData) {
|
||||||
|
@ -1047,6 +1051,8 @@ namespace ams::sf::impl {
|
||||||
constexpr auto Attributes = CommandMeta::BufferAttributes[Info.buffer_index];
|
constexpr auto Attributes = CommandMeta::BufferAttributes[Info.buffer_index];
|
||||||
if constexpr (Attributes & SfBufferAttr_In) {
|
if constexpr (Attributes & SfBufferAttr_In) {
|
||||||
/* TODO: AMS_ABORT_UNLESS()? N does not bother. */
|
/* TODO: AMS_ABORT_UNLESS()? N does not bother. */
|
||||||
|
static_assert(std::is_reference<T>::value);
|
||||||
|
static_assert(std::is_const<typename std::remove_reference<T>::type>::value);
|
||||||
return *reinterpret_cast<const T *>(buffers[Info.buffer_index].GetAddress());
|
return *reinterpret_cast<const T *>(buffers[Info.buffer_index].GetAddress());
|
||||||
} else if constexpr (Attributes & SfBufferAttr_Out) {
|
} else if constexpr (Attributes & SfBufferAttr_Out) {
|
||||||
return T(buffers[Info.buffer_index]);
|
return T(buffers[Info.buffer_index]);
|
||||||
|
@ -1063,12 +1069,12 @@ namespace ams::sf::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t... Is>
|
template<size_t... Is>
|
||||||
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<Is...>) {
|
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<Is...>) {
|
||||||
return ArgsType { DeserializeArgumentImpl<Is>(ctx, in_raw_data, out_raw_holder, buffers, out_handles_holder, in_out_objects_holder)..., };
|
return ArgsTypeForInvoke { DeserializeArgumentImpl<Is>(ctx, in_raw_data, out_raw_holder, buffers, out_handles_holder, in_out_objects_holder)..., };
|
||||||
}
|
}
|
||||||
public:
|
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) {
|
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<std::tuple_size<ArgsType>::value>{});
|
return DeserializeArgumentsImpl(ctx, in_raw_data, out_raw_holder, buffers, out_handles_holder, in_out_objects_holder, std::make_index_sequence<std::tuple_size<ArgsTypeForInvoke>::value>{});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1118,16 +1124,16 @@ namespace ams::sf::impl {
|
||||||
|
|
||||||
/* Decoding/Invocation. */
|
/* 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. */
|
/* Handle in process ID holder if relevant. */
|
||||||
if constexpr (CommandMeta::HasInProcessIdHolder) {
|
if constexpr (CommandMeta::HasInProcessIdHolder) {
|
||||||
/* TODO: More precise value than 32? */
|
/* TODO: More precise value than 32? */
|
||||||
static_assert(std::tuple_size<typename CommandMeta::ArgsType>::value <= 32, "Commands must have <= 32 arguments");
|
static_assert(std::tuple_size<typename CommandMeta::ArgsTypeForInvoke>::value <= 32, "Commands must have <= 32 arguments");
|
||||||
os::ProcessId process_id{ctx.request.pid};
|
os::ProcessId process_id{ctx.request.pid};
|
||||||
#define _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(n) do { \
|
#define _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(n) do { \
|
||||||
using ArgsType = typename CommandMeta::ArgsType; \
|
using ArgsTypeForInvoke = typename CommandMeta::ArgsTypeForInvoke; \
|
||||||
if constexpr (n < std::tuple_size<ArgsType>::value) { \
|
if constexpr (n < std::tuple_size<ArgsTypeForInvoke>::value) { \
|
||||||
if constexpr (CommandMeta::template IsInProcessIdHolderIndex<n>) { \
|
if constexpr (CommandMeta::template IsInProcessIdHolderIndex<n>) { \
|
||||||
R_TRY(MarshalProcessId(std::get<n>(args_tuple), process_id)); \
|
R_TRY(MarshalProcessId(std::get<n>(args_tuple), process_id)); \
|
||||||
} \
|
} \
|
||||||
|
@ -1149,7 +1155,7 @@ namespace ams::sf::impl {
|
||||||
sf::IServiceObject * const this_ptr = ctx.srv_obj;
|
sf::IServiceObject * const this_ptr = ctx.srv_obj;
|
||||||
const auto command_result = [this_ptr, invoke_impl, &args_tuple]<size_t ...Ix>(std::index_sequence<Ix...>) ALWAYS_INLINE_LAMBDA {
|
const auto command_result = [this_ptr, invoke_impl, &args_tuple]<size_t ...Ix>(std::index_sequence<Ix...>) ALWAYS_INLINE_LAMBDA {
|
||||||
return invoke_impl(this_ptr, std::forward<typename std::tuple_element<Ix, TrueArgumentsTuple>::type>(std::get<Ix>(args_tuple))...);
|
return invoke_impl(this_ptr, std::forward<typename std::tuple_element<Ix, TrueArgumentsTuple>::type>(std::get<Ix>(args_tuple))...);
|
||||||
}(std::make_index_sequence<std::tuple_size<typename CommandMeta::ArgsType>::value>());
|
}(std::make_index_sequence<std::tuple_size<typename CommandMeta::ArgsTypeForInvoke>::value>());
|
||||||
|
|
||||||
if (R_FAILED(command_result)) {
|
if (R_FAILED(command_result)) {
|
||||||
cmif::PointerAndSize out_raw_data;
|
cmif::PointerAndSize out_raw_data;
|
||||||
|
|
Loading…
Reference in a new issue