diff --git a/deps/ox/src/ox/fs/filesystem2/directory.hpp b/deps/ox/src/ox/fs/filesystem2/directory.hpp index acfa78fe..beb99dc7 100644 --- a/deps/ox/src/ox/fs/filesystem2/directory.hpp +++ b/deps/ox/src/ox/fs/filesystem2/directory.hpp @@ -135,7 +135,7 @@ Error Directory::write(PathIterator path, InodeId_t inode) noexcept { auto old = m_fs->read(m_inodeId); if (old.valid()) { const auto newSize = m_size + DirectoryEntry::spaceNeeded(name.size()); - auto cpy = new (ox_malloca(newSize)) Buffer(old); + auto cpy = ox_malloca(newSize, Buffer, old); cpy->setSize(newSize); auto val = cpy->malloc(name.size()); if (val.valid()) { diff --git a/deps/ox/src/ox/fs/test/tests.cpp b/deps/ox/src/ox/fs/test/tests.cpp index fa78312d..78d40e71 100644 --- a/deps/ox/src/ox/fs/test/tests.cpp +++ b/deps/ox/src/ox/fs/test/tests.cpp @@ -337,8 +337,7 @@ map tests = { "Ptr::subPtr", [](string) { constexpr auto buffLen = 5000; - uint8_t buff[buffLen]; - ox::ptrarith::Ptr p(buff, buffLen, 500, 500); + ox::ptrarith::Ptr p(ox_alloca(buffLen), buffLen, 500, 500); oxAssert(p.valid(), "Ptr::subPtr: Ptr p is invalid."); auto subPtr = p.subPtr(50); @@ -351,8 +350,7 @@ map tests = { [](string) { int err = 0; constexpr auto buffLen = 5000; - uint8_t buff[buffLen]; - auto list = new (buff) ox::ptrarith::NodeBuffer>(buffLen); + auto list = new (ox_alloca(buffLen)) ox::ptrarith::NodeBuffer>(buffLen); oxAssert(list->malloc(50).valid(), "NodeBuffer::insert: malloc 1 failed"); oxAssert(list->malloc(50).valid(), "NodeBuffer::insert: malloc 2 failed"); auto first = list->firstItem(); @@ -369,8 +367,7 @@ map tests = { constexpr auto str1Len = ox_strlen(str1) + 1; constexpr auto str2 = "Hello, Moon!"; constexpr auto str2Len = ox_strlen(str2) + 1; - uint8_t buff[buffLen]; - auto list = new (buff) ox::ptrarith::NodeBuffer>(buffLen); + auto list = new (ox_alloca(buffLen)) ox::ptrarith::NodeBuffer>(buffLen); ox::fs::FileStore32 fileStore(list, buffLen); oxAssert(fileStore.format() == 0, "FileStore::format failed."); oxAssert(fileStore.write(4, const_cast(str1), str1Len, 1) == 0, "FileStore::write 1 failed."); diff --git a/deps/ox/src/ox/std/CMakeLists.txt b/deps/ox/src/ox/std/CMakeLists.txt index c1d73b1c..b19a6d76 100644 --- a/deps/ox/src/ox/std/CMakeLists.txt +++ b/deps/ox/src/ox/std/CMakeLists.txt @@ -5,6 +5,7 @@ add_library( assert.cpp byteswap.cpp memops.cpp + new.cpp random.cpp strops.cpp ) diff --git a/deps/ox/src/ox/std/new.cpp b/deps/ox/src/ox/std/new.cpp new file mode 100644 index 00000000..f973522c --- /dev/null +++ b/deps/ox/src/ox/std/new.cpp @@ -0,0 +1,15 @@ +/* + * Copyright 2015 - 2018 gtalent2@gmail.com + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "new.hpp" + +namespace ox { + +template class MallocaPtr; + +} diff --git a/deps/ox/src/ox/std/new.hpp b/deps/ox/src/ox/std/new.hpp index 5a06856f..d1c774ef 100644 --- a/deps/ox/src/ox/std/new.hpp +++ b/deps/ox/src/ox/std/new.hpp @@ -8,6 +8,8 @@ #pragma once +#include + #include "types.hpp" #if defined(_MSC_VER) @@ -22,25 +24,95 @@ #endif +void *operator new(std::size_t, void*) noexcept; + + namespace ox { -constexpr auto MaxAllocaSize = 10 * 1024; +constexpr auto MallocaStackLimit = 1024; } #if defined(OX_USE_STDLIB) -#define ox_malloca(size) size > MaxAllocaSize ? malloc(size) : ox_alloca(size) -#else -#define ox_malloca(size) ox_alloca(size) +#define ox_malloca(size, Type, ...) ox::MallocaPtr(size, new (size > MallocaStackLimit ? new uint8_t[size] : ox_alloca(size)) Type(__VA_ARGS__)) +#else +#define ox_malloca(size, Type, ...) ox::MallocaPtr(size, ox_alloca(size)) #endif -inline void ox_freea(std::size_t size, void *ptr) { +inline constexpr void ox_freea(std::size_t size, void *ptr) { if constexpr(ox::defines::UseStdLib) { - if (size > ox::MaxAllocaSize) { - free(ptr); + if (size > ox::MallocaStackLimit) { + delete[] reinterpret_cast(ptr); } } } -void* operator new(std::size_t, void*) noexcept; +namespace ox { + +template +class MallocaPtr { + + private: + std::size_t m_size = 0; + T *m_val = nullptr; + + public: + inline MallocaPtr() noexcept = default; + + inline MallocaPtr(MallocaPtr &&other) noexcept { + m_size = other.m_size; + m_val = other.m_val; + other.m_size = 0; + } + + inline MallocaPtr(std::size_t size, T *val) noexcept { + m_size = size; + m_val = val; + } + + inline ~MallocaPtr() noexcept { + if constexpr(ox::defines::UseStdLib) { + if (m_size > ox::MallocaStackLimit) { + delete[] reinterpret_cast(m_val); + } + } + } + + inline const T *operator->() const noexcept { + return reinterpret_cast(m_val); + } + + inline T *operator->() noexcept { + return reinterpret_cast(m_val); + } + + inline operator const T*() const noexcept { + return reinterpret_cast(m_val); + } + + inline operator T*() noexcept { + return reinterpret_cast(m_val); + } + + inline const T &operator*() const noexcept { + return *reinterpret_cast(m_val); + } + + inline T &operator*() noexcept { + return *reinterpret_cast(m_val); + } + + inline bool operator==(const MallocaPtr &other) const noexcept { + return m_val == other.m_val && m_size == other.m_size; + } + + inline bool operator!=(const MallocaPtr &other) const noexcept { + return m_val != other.m_val || m_size != other.m_size; + } + +}; + +extern template class MallocaPtr; + +}