fs: reduce path size 0x28 -> 0x18
This implements two optimizations on fs::Path, which N added in 12.0.0.
The current structure looks like:
```cpp
struct Path {
const char *m_str; // Points to the read-only path string
char *m_write_buffer_buffer; // Part of std::unique_ptr<char[], ams::fs::impl::Deleter>
ams::fs::impl::Deleter m_write_buffer_deleter; // Parse of std::unique_ptr<char[], ams::fs::impl::Deleter>, stores the size of the buffer.
size_t m_write_buffer_length; // Copy of the write buffer's size accessible to the Path() structure.
bool m_is_normalized; // Whether the path buffer is normalized
};
```
This is pretty wasteful. The write buffer size is stored twice, wasting 8 bytes, because one copy of the size isn't accessible to the path.
In addition, due to alignment, the bool wastes 7 padding bytes.
This commit:
* Encodes normalized in the low bit of the write buffer length, saving 8 bytes.
* Use a custom WriteBuffer class rather than generic unique_ptr, to avoid needing to store the WriteBuffer twice.
These each save 8 bytes, for a final size of 0x18 rather than 0x28.
This commit is contained in:
@@ -26,6 +26,8 @@ namespace ams::fs {
|
||||
|
||||
namespace impl {
|
||||
|
||||
class Newable;
|
||||
|
||||
void *Allocate(size_t size);
|
||||
void Deallocate(void *ptr, size_t size);
|
||||
|
||||
@@ -130,20 +132,27 @@ namespace ams::fs {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
std::unique_ptr<T, Deleter> MakeUnique() {
|
||||
static_assert(util::is_pod<T>::value);
|
||||
auto MakeUnique() {
|
||||
/* Check that we're not using MakeUnique unnecessarily. */
|
||||
static_assert(!std::derived_from<T, ::ams::fs::impl::Newable>);
|
||||
|
||||
return std::unique_ptr<T, Deleter>(static_cast<T *>(::ams::fs::impl::Allocate(sizeof(T))), Deleter(sizeof(T)));
|
||||
}
|
||||
|
||||
template<typename ArrayT>
|
||||
std::unique_ptr<ArrayT, Deleter> MakeUnique(size_t size) {
|
||||
auto MakeUnique(size_t size) {
|
||||
using T = typename std::remove_extent<ArrayT>::type;
|
||||
|
||||
static_assert(util::is_pod<ArrayT>::value);
|
||||
static_assert(std::is_array<ArrayT>::value);
|
||||
|
||||
/* Check that we're not using MakeUnique unnecessarily. */
|
||||
static_assert(!std::derived_from<T, ::ams::fs::impl::Newable>);
|
||||
|
||||
using ReturnType = std::unique_ptr<ArrayT, Deleter>;
|
||||
|
||||
const size_t alloc_size = sizeof(T) * size;
|
||||
return std::unique_ptr<ArrayT, Deleter>(static_cast<T *>(::ams::fs::impl::Allocate(alloc_size)), Deleter(alloc_size));
|
||||
return ReturnType(static_cast<T *>(::ams::fs::impl::Allocate(alloc_size)), Deleter(alloc_size));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user