mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-19 00:42:06 +00:00
sm: save 0x5000 of memory by sinning
This commit is contained in:
parent
496adb0018
commit
f98c7cba98
4 changed files with 63 additions and 13 deletions
|
@ -40,12 +40,28 @@ namespace ams::tipc::impl {
|
||||||
#define AMS_TIPC_IMPL_EXTRACT_SYNC_METHOD_ARGUMENTS(CLASSNAME, CMD_ID, RETURN, NAME, ARGS, ARGNAMES, VERSION_MIN, VERSION_MAX) \
|
#define AMS_TIPC_IMPL_EXTRACT_SYNC_METHOD_ARGUMENTS(CLASSNAME, CMD_ID, RETURN, NAME, ARGS, ARGNAMES, VERSION_MIN, VERSION_MAX) \
|
||||||
using NAME##ArgumentsType = ::ams::tipc::impl::SyncFunctionArgsType<&NAME##ArgumentsFunctionHolder::f>;
|
using NAME##ArgumentsType = ::ams::tipc::impl::SyncFunctionArgsType<&NAME##ArgumentsFunctionHolder::f>;
|
||||||
|
|
||||||
|
#define AMS_TIPC_IMPL_GET_MAXIMUM_REQUEST_SIZE(CLASSNAME, CMD_ID, RETURN, NAME, ARGS, ARGNAMES, VERSION_MIN, VERSION_MAX) \
|
||||||
|
, ::ams::tipc::impl::CommandMetaInfo<CMD_ID + 0x10, NAME##ArgumentsType>::InMessageTotalSize
|
||||||
|
|
||||||
|
#define AMS_TIPC_IMPL_GET_MAXIMUM_RESPONSE_SIZE(CLASSNAME, CMD_ID, RETURN, NAME, ARGS, ARGNAMES, VERSION_MIN, VERSION_MAX) \
|
||||||
|
, ::ams::tipc::impl::CommandMetaInfo<CMD_ID + 0x10, NAME##ArgumentsType>::OutMessageTotalSize
|
||||||
|
|
||||||
#define AMS_TIPC_IMPL_DEFINE_INTERFACE(BASECLASS, CLASSNAME, CMD_MACRO) \
|
#define AMS_TIPC_IMPL_DEFINE_INTERFACE(BASECLASS, CLASSNAME, CMD_MACRO) \
|
||||||
class CLASSNAME : public BASECLASS { \
|
class CLASSNAME : public BASECLASS { \
|
||||||
private: \
|
private: \
|
||||||
CMD_MACRO(CLASSNAME, AMS_TIPC_IMPL_DEFINE_SYNC_METHOD_HOLDER) \
|
CMD_MACRO(CLASSNAME, AMS_TIPC_IMPL_DEFINE_SYNC_METHOD_HOLDER) \
|
||||||
public: \
|
public: \
|
||||||
CMD_MACRO(CLASSNAME, AMS_TIPC_IMPL_EXTRACT_SYNC_METHOD_ARGUMENTS) \
|
CMD_MACRO(CLASSNAME, AMS_TIPC_IMPL_EXTRACT_SYNC_METHOD_ARGUMENTS) \
|
||||||
|
public: \
|
||||||
|
static constexpr size_t MaximumRequestSize = std::max<size_t>({ \
|
||||||
|
0 \
|
||||||
|
CMD_MACRO(CLASSNAME, AMS_TIPC_IMPL_GET_MAXIMUM_REQUEST_SIZE) \
|
||||||
|
}); \
|
||||||
|
\
|
||||||
|
static constexpr size_t MaximumResponseSize = std::max<size_t>({ \
|
||||||
|
0 \
|
||||||
|
CMD_MACRO(CLASSNAME, AMS_TIPC_IMPL_GET_MAXIMUM_RESPONSE_SIZE) \
|
||||||
|
}); \
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AMS_TIPC_IMPL_DEFINE_CONCEPT_HELPERS(CLASSNAME, CMD_ID, RETURN, NAME, ARGS, ARGNAMES, VERSION_MIN, VERSION_MAX) \
|
#define AMS_TIPC_IMPL_DEFINE_CONCEPT_HELPERS(CLASSNAME, CMD_ID, RETURN, NAME, ARGS, ARGNAMES, VERSION_MIN, VERSION_MAX) \
|
||||||
|
|
|
@ -319,6 +319,9 @@ namespace ams::tipc::impl {
|
||||||
static constexpr auto OutMessageResultIndex = svc::ipc::MessageBuffer::GetRawDataIndex(OutMessageHeader, OutSpecialHeader);
|
static constexpr auto OutMessageResultIndex = svc::ipc::MessageBuffer::GetRawDataIndex(OutMessageHeader, OutSpecialHeader);
|
||||||
static constexpr auto OutMessageRawDataIndex = OutMessageResultIndex + 1;
|
static constexpr auto OutMessageRawDataIndex = OutMessageResultIndex + 1;
|
||||||
|
|
||||||
|
static constexpr size_t InMessageTotalSize = (InMessageRawDataIndex * sizeof(u32)) + InDataSize;
|
||||||
|
static constexpr size_t OutMessageTotalSize = (OutMessageRawDataIndex * sizeof(u32)) + OutDataSize;
|
||||||
|
|
||||||
/* Construction of argument serialization structs. */
|
/* Construction of argument serialization structs. */
|
||||||
private:
|
private:
|
||||||
template<typename>
|
template<typename>
|
||||||
|
|
|
@ -44,16 +44,17 @@ namespace ams::tipc {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeferrableBase : public impl::DeferrableBaseTag {
|
class DeferrableBaseImpl : public impl::DeferrableBaseTag {
|
||||||
private:
|
private:
|
||||||
DeferralManagerBase *m_deferral_manager;
|
DeferralManagerBase *m_deferral_manager;
|
||||||
ObjectHolder m_object_holder;
|
ObjectHolder m_object_holder;
|
||||||
uintptr_t m_resume_key;
|
uintptr_t m_resume_key;
|
||||||
u8 m_message_buffer[svc::ipc::MessageBufferSize];
|
const u32 m_message_buffer_size;
|
||||||
|
u8 m_message_buffer_base[0];
|
||||||
public:
|
public:
|
||||||
ALWAYS_INLINE DeferrableBase() : m_deferral_manager(nullptr), m_object_holder(), m_resume_key() { /* ... */ }
|
ALWAYS_INLINE DeferrableBaseImpl(u32 mb_size) : m_deferral_manager(nullptr), m_object_holder(), m_resume_key(), m_message_buffer_size(mb_size) { /* ... */ }
|
||||||
|
|
||||||
~DeferrableBase();
|
~DeferrableBaseImpl();
|
||||||
|
|
||||||
ALWAYS_INLINE void SetDeferralManager(DeferralManagerBase *manager, os::NativeHandle reply_target, ServiceObjectBase *object) {
|
ALWAYS_INLINE void SetDeferralManager(DeferralManagerBase *manager, os::NativeHandle reply_target, ServiceObjectBase *object) {
|
||||||
m_deferral_manager = manager;
|
m_deferral_manager = manager;
|
||||||
|
@ -67,7 +68,7 @@ namespace ams::tipc {
|
||||||
template<IsResumeKey ResumeKey>
|
template<IsResumeKey ResumeKey>
|
||||||
ALWAYS_INLINE void RegisterRetry(ResumeKey key) {
|
ALWAYS_INLINE void RegisterRetry(ResumeKey key) {
|
||||||
m_resume_key = ConvertToInternalResumeKey(key);
|
m_resume_key = ConvertToInternalResumeKey(key);
|
||||||
std::memcpy(m_message_buffer, svc::ipc::GetMessageBuffer(), sizeof(m_message_buffer));
|
std::memcpy(m_message_buffer_base, svc::ipc::GetMessageBuffer(), m_message_buffer_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<IsResumeKey ResumeKey, typename F>
|
template<IsResumeKey ResumeKey, typename F>
|
||||||
|
@ -85,12 +86,42 @@ namespace ams::tipc {
|
||||||
m_resume_key = 0;
|
m_resume_key = 0;
|
||||||
|
|
||||||
/* Restore message buffer. */
|
/* Restore message buffer. */
|
||||||
std::memcpy(svc::ipc::GetMessageBuffer(), m_message_buffer, sizeof(m_message_buffer));
|
std::memcpy(svc::ipc::GetMessageBuffer(), m_message_buffer_base, m_message_buffer_size);
|
||||||
|
|
||||||
/* Process the request. */
|
/* Process the request. */
|
||||||
return port_manager->ProcessDeferredRequest(m_object_holder);
|
return port_manager->ProcessDeferredRequest(m_object_holder);
|
||||||
}
|
}
|
||||||
|
protected:
|
||||||
|
static consteval size_t GetMessageBufferOffsetBase();
|
||||||
};
|
};
|
||||||
|
static_assert(std::is_standard_layout<DeferrableBaseImpl>::value);
|
||||||
|
|
||||||
|
template<typename Interface>
|
||||||
|
class DeferrableBase : public DeferrableBaseImpl {
|
||||||
|
private:
|
||||||
|
static constexpr size_t MessageBufferRequiredSize = Interface::MaximumRequestSize;
|
||||||
|
private:
|
||||||
|
u8 m_message_buffer[MessageBufferRequiredSize];
|
||||||
|
public:
|
||||||
|
DeferrableBase();
|
||||||
|
private:
|
||||||
|
static consteval size_t GetMessageBufferOffset();
|
||||||
|
};
|
||||||
|
|
||||||
|
consteval size_t DeferrableBaseImpl::GetMessageBufferOffsetBase() {
|
||||||
|
return AMS_OFFSETOF(DeferrableBaseImpl, m_message_buffer_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Interface>
|
||||||
|
consteval size_t DeferrableBase<Interface>::GetMessageBufferOffset() {
|
||||||
|
return AMS_OFFSETOF(DeferrableBase<Interface>, m_message_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Interface>
|
||||||
|
ALWAYS_INLINE DeferrableBase<Interface>::DeferrableBase() : DeferrableBaseImpl(MessageBufferRequiredSize) {
|
||||||
|
static_assert(GetMessageBufferOffsetBase() == GetMessageBufferOffset());
|
||||||
|
static_assert(sizeof(DeferrableBase<Interface>) >= sizeof(DeferrableBaseImpl) + MessageBufferRequiredSize);
|
||||||
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
concept IsDeferrable = std::derived_from<T, impl::DeferrableBaseTag>;
|
concept IsDeferrable = std::derived_from<T, impl::DeferrableBaseTag>;
|
||||||
|
@ -100,11 +131,11 @@ namespace ams::tipc {
|
||||||
NON_MOVEABLE(DeferralManagerBase);
|
NON_MOVEABLE(DeferralManagerBase);
|
||||||
private:
|
private:
|
||||||
size_t m_object_count;
|
size_t m_object_count;
|
||||||
DeferrableBase *m_objects_base[0];
|
DeferrableBaseImpl *m_objects_base[0];
|
||||||
public:
|
public:
|
||||||
ALWAYS_INLINE DeferralManagerBase() : m_object_count(0) { /* ... */ }
|
ALWAYS_INLINE DeferralManagerBase() : m_object_count(0) { /* ... */ }
|
||||||
|
|
||||||
void AddObject(DeferrableBase &object, os::NativeHandle reply_target, ServiceObjectBase *service_object) {
|
void AddObject(DeferrableBaseImpl &object, os::NativeHandle reply_target, ServiceObjectBase *service_object) {
|
||||||
/* Set ourselves as the manager for the object. */
|
/* Set ourselves as the manager for the object. */
|
||||||
object.SetDeferralManager(this, reply_target, service_object);
|
object.SetDeferralManager(this, reply_target, service_object);
|
||||||
|
|
||||||
|
@ -113,7 +144,7 @@ namespace ams::tipc {
|
||||||
m_objects_base[m_object_count++] = std::addressof(object);
|
m_objects_base[m_object_count++] = std::addressof(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveObject(DeferrableBase *object) {
|
void RemoveObject(DeferrableBaseImpl *object) {
|
||||||
/* If the object is present, remove it. */
|
/* If the object is present, remove it. */
|
||||||
for (size_t i = 0; i < m_object_count; ++i) {
|
for (size_t i = 0; i < m_object_count; ++i) {
|
||||||
if (m_objects_base[i] == object) {
|
if (m_objects_base[i] == object) {
|
||||||
|
@ -148,7 +179,7 @@ namespace ams::tipc {
|
||||||
};
|
};
|
||||||
static_assert(std::is_standard_layout<DeferralManagerBase>::value);
|
static_assert(std::is_standard_layout<DeferralManagerBase>::value);
|
||||||
|
|
||||||
inline DeferrableBase::~DeferrableBase() {
|
inline DeferrableBaseImpl::~DeferrableBaseImpl() {
|
||||||
AMS_ASSUME(m_deferral_manager != nullptr);
|
AMS_ASSUME(m_deferral_manager != nullptr);
|
||||||
m_deferral_manager->RemoveObject(this);
|
m_deferral_manager->RemoveObject(this);
|
||||||
}
|
}
|
||||||
|
@ -156,7 +187,7 @@ namespace ams::tipc {
|
||||||
template<size_t N> requires (N > 0)
|
template<size_t N> requires (N > 0)
|
||||||
class DeferralManager final : public DeferralManagerBase {
|
class DeferralManager final : public DeferralManagerBase {
|
||||||
private:
|
private:
|
||||||
DeferrableBase *m_objects[N];
|
DeferrableBaseImpl *m_objects[N];
|
||||||
public:
|
public:
|
||||||
DeferralManager();
|
DeferralManager();
|
||||||
private:
|
private:
|
||||||
|
@ -175,7 +206,7 @@ namespace ams::tipc {
|
||||||
template<size_t N> requires (N > 0)
|
template<size_t N> requires (N > 0)
|
||||||
inline DeferralManager<N>::DeferralManager() : DeferralManagerBase() {
|
inline DeferralManager<N>::DeferralManager() : DeferralManagerBase() {
|
||||||
static_assert(GetObjectPointersOffset() == GetObjectPointersOffsetBase());
|
static_assert(GetObjectPointersOffset() == GetObjectPointersOffsetBase());
|
||||||
static_assert(sizeof(DeferralManager<N>) == sizeof(DeferralManagerBase) + N * sizeof(DeferrableBase *));
|
static_assert(sizeof(DeferralManager<N>) == sizeof(DeferralManagerBase) + N * sizeof(DeferrableBaseImpl *));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
namespace ams::sm {
|
namespace ams::sm {
|
||||||
|
|
||||||
/* Service definition. */
|
/* Service definition. */
|
||||||
class UserService : public tipc::DeferrableBase {
|
class UserService : public tipc::DeferrableBase<sm::impl::IUserInterface> {
|
||||||
private:
|
private:
|
||||||
os::ProcessId m_process_id;
|
os::ProcessId m_process_id;
|
||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
|
|
Loading…
Reference in a new issue