From 97b2d9a3fa8f4ea7be9ddb226c13b1d4362eb099 Mon Sep 17 00:00:00 2001 From: schrodingerzhu Date: Sat, 21 Dec 2024 18:01:48 -0500 Subject: [PATCH] [proxy](7/n) proxy array headers --- src/snmalloc/backend_helpers/buddy.h | 2 +- src/snmalloc/ds_core/helpers.h | 16 ++-- src/snmalloc/ds_core/ptrwrap.h | 4 +- src/snmalloc/ds_core/redblacktree.h | 5 +- src/snmalloc/mem/freelist.h | 6 +- src/snmalloc/mem/remotecache.h | 9 +- src/snmalloc/pal/pal_linux.h | 4 +- src/snmalloc/pal/pal_posix.h | 4 +- src/snmalloc/proxy/array.h | 118 +++++++++++++++++++++++++++ src/test/func/memory/memory.cc | 2 + 10 files changed, 145 insertions(+), 25 deletions(-) create mode 100644 src/snmalloc/proxy/array.h diff --git a/src/snmalloc/backend_helpers/buddy.h b/src/snmalloc/backend_helpers/buddy.h index d7406468e..74edc97d8 100644 --- a/src/snmalloc/backend_helpers/buddy.h +++ b/src/snmalloc/backend_helpers/buddy.h @@ -23,7 +23,7 @@ namespace snmalloc RBTree tree{}; }; - std::array entries{}; + proxy::Array entries{}; // All RBtrees at or above this index should be empty. size_t empty_at_or_above{0}; diff --git a/src/snmalloc/ds_core/helpers.h b/src/snmalloc/ds_core/helpers.h index 9c203ec63..0b50422b4 100644 --- a/src/snmalloc/ds_core/helpers.h +++ b/src/snmalloc/ds_core/helpers.h @@ -2,10 +2,10 @@ #include "bits.h" #include "snmalloc/ds_core/defines.h" +#include "snmalloc/proxy/array.h" #include "snmalloc/proxy/type_traits.h" #include "snmalloc/proxy/utility.h" -#include #include namespace snmalloc @@ -50,7 +50,7 @@ namespace snmalloc }; static constexpr size_t rlength = bits::next_pow2_const(length); - std::array array; + proxy::Array array; public: constexpr const T& operator[](const size_t i) const @@ -65,7 +65,7 @@ namespace snmalloc }; #else template - using ModArray = std::array; + using ModArray = proxy::Array; #endif /** @@ -105,7 +105,7 @@ namespace snmalloc template< typename Fn, typename = - proxy::enable_if_t, function_ref>>> + proxy::enable_if_t, function_ref>>> function_ref(Fn&& fn) { data_ = static_cast(&fn); @@ -144,7 +144,7 @@ namespace snmalloc /** * The buffer that is used to store the formatted output. */ - std::array buffer; + proxy::Array buffer; /** * Space in the buffer, excluding a trailing null terminator. @@ -208,7 +208,7 @@ namespace snmalloc /** * Append a nullptr */ - void append(std::nullptr_t) + void append(decltype(nullptr)) { append("(nullptr)"); } @@ -254,7 +254,7 @@ namespace snmalloc append_char('-'); s = 0 - s; } - std::array buf{{0}}; + proxy::Array buf{{0}}; const char digits[] = "0123456789"; for (long i = static_cast(buf.size() - 1); i >= 0; i--) { @@ -284,7 +284,7 @@ namespace snmalloc { append_char('0'); append_char('x'); - std::array buf{{0}}; + proxy::Array buf{{0}}; const char hexdigits[] = "0123456789abcdef"; // Length of string including null terminator static_assert(sizeof(hexdigits) == 0x11); diff --git a/src/snmalloc/ds_core/ptrwrap.h b/src/snmalloc/ds_core/ptrwrap.h index 38e268eb6..fcb58dfdf 100644 --- a/src/snmalloc/ds_core/ptrwrap.h +++ b/src/snmalloc/ds_core/ptrwrap.h @@ -276,7 +276,7 @@ namespace snmalloc /** * nullptr is implicitly constructable at any bounds type */ - constexpr SNMALLOC_FAST_PATH CapPtr(const std::nullptr_t n) + constexpr SNMALLOC_FAST_PATH CapPtr(const decltype(nullptr) n) : unsafe_capptr(n) {} @@ -465,7 +465,7 @@ namespace snmalloc /** * nullptr is constructable at any bounds type */ - constexpr SNMALLOC_FAST_PATH AtomicCapPtr(const std::nullptr_t n) + constexpr SNMALLOC_FAST_PATH AtomicCapPtr(const decltype(nullptr) n) : unsafe_capptr(n) {} diff --git a/src/snmalloc/ds_core/redblacktree.h b/src/snmalloc/ds_core/redblacktree.h index 37b90ddb2..251fd3caa 100644 --- a/src/snmalloc/ds_core/redblacktree.h +++ b/src/snmalloc/ds_core/redblacktree.h @@ -1,6 +1,7 @@ #pragma once -#include +#include "snmalloc/proxy/array.h" + #include #include @@ -260,7 +261,7 @@ namespace snmalloc { friend class RBTree; - std::array path; + proxy::Array path; size_t length = 0; RBPath(typename Rep::Handle root) diff --git a/src/snmalloc/mem/freelist.h b/src/snmalloc/mem/freelist.h index 6e47ee20f..298c14ef9 100644 --- a/src/snmalloc/mem/freelist.h +++ b/src/snmalloc/mem/freelist.h @@ -701,11 +701,11 @@ namespace snmalloc */ // Pointer to the first element. - std::array head{nullptr}; + proxy::Array head{nullptr}; // Pointer to the reference to the last element. // In the empty case end[i] == &head[i] // This enables branch free enqueuing. - std::array end{nullptr}; + proxy::Array end{nullptr}; [[nodiscard]] Object::BQueuePtr* cast_end(uint32_t ix) const { @@ -724,7 +724,7 @@ namespace snmalloc } SNMALLOC_NO_UNIQUE_ADDRESS - std::array length{}; + proxy::Array length{}; public: constexpr Builder() = default; diff --git a/src/snmalloc/mem/remotecache.h b/src/snmalloc/mem/remotecache.h index 02b843e12..dd4812bc5 100644 --- a/src/snmalloc/mem/remotecache.h +++ b/src/snmalloc/mem/remotecache.h @@ -6,10 +6,9 @@ #include "metadata.h" #include "remoteallocator.h" #include "sizeclasstable.h" +#include "snmalloc/proxy/array.h" #include "snmalloc/proxy/atomic.h" -#include - namespace snmalloc { @@ -33,8 +32,8 @@ namespace snmalloc { static_assert(RINGS > 0); - std::array, RINGS> open_builder; - std::array open_meta = {0}; + proxy::Array, RINGS> open_builder; + proxy::Array open_meta = {0}; SNMALLOC_FAST_PATH size_t ring_set(typename Config::PagemapEntry::SlabMetadata* meta) @@ -191,7 +190,7 @@ namespace snmalloc template struct RemoteDeallocCache { - std::array, REMOTE_SLOTS> list; + proxy::Array, REMOTE_SLOTS> list; RemoteDeallocCacheBatchingImpl batching; diff --git a/src/snmalloc/pal/pal_linux.h b/src/snmalloc/pal/pal_linux.h index 133e00674..16090c839 100644 --- a/src/snmalloc/pal/pal_linux.h +++ b/src/snmalloc/pal/pal_linux.h @@ -183,8 +183,8 @@ namespace snmalloc // protected routine. if (false == syscall_not_working.load(proxy::memory_order_relaxed)) { - auto current = std::begin(buffer); - auto target = std::end(buffer); + auto current = proxy::begin(buffer); + auto target = proxy::end(buffer); while (auto length = target - current) { // Reading data via syscall from system entropy pool. diff --git a/src/snmalloc/pal/pal_posix.h b/src/snmalloc/pal/pal_posix.h index ac0e4c6d9..118e30b53 100644 --- a/src/snmalloc/pal/pal_posix.h +++ b/src/snmalloc/pal/pal_posix.h @@ -419,8 +419,8 @@ namespace snmalloc auto fd = open("/dev/urandom", flags, 0); if (fd > 0) { - auto current = std::begin(buffer); - auto target = std::end(buffer); + auto current = proxy::begin(buffer); + auto target = proxy::end(buffer); while (auto length = static_cast(target - current)) { ret = read(fd, current, length); diff --git a/src/snmalloc/proxy/array.h b/src/snmalloc/proxy/array.h new file mode 100644 index 000000000..7c4898fdf --- /dev/null +++ b/src/snmalloc/proxy/array.h @@ -0,0 +1,118 @@ +#pragma once + +#include "snmalloc/ds_core/defines.h" + +#ifndef SNMALLOC_USE_SELF_VENDORED_STL +# define SNMALLOC_USE_SELF_VENDORED_STL 0 +#endif + +#if SNMALLOC_USE_SELF_VENDORED_STL + +# if !defined(__GNUC__) && !defined(__clang__) +# error "cannot use vendored STL without GNU/Clang extensions" +# endif + +# include + +namespace snmalloc +{ + namespace proxy + { + template + struct Array + { + // N is potentially 0, so we mark it with __extension__ attribute. + // expose this to public to allow aggregate initialization + __extension__ T storage[N]; + + [[nodiscard]] constexpr SNMALLOC_FAST_PATH size_t size() const + { + return N; + } + + constexpr T& operator[](size_t i) + { + return storage[i]; + } + + constexpr const T& operator[](size_t i) const + { + return storage[i]; + } + + using value_type = T; + using size_type = size_t; + using iterator = T*; + using const_iterator = const T*; + + [[nodiscard]] constexpr SNMALLOC_FAST_PATH iterator begin() + { + return &storage[0]; + } + + [[nodiscard]] constexpr SNMALLOC_FAST_PATH const_iterator begin() const + { + return &storage[0]; + } + + [[nodiscard]] constexpr SNMALLOC_FAST_PATH iterator end() + { + return &storage[N]; + } + + [[nodiscard]] constexpr SNMALLOC_FAST_PATH const_iterator end() const + { + return &storage[N]; + } + + [[nodiscard]] constexpr SNMALLOC_FAST_PATH T* data() + { + return &storage[0]; + } + + [[nodiscard]] constexpr SNMALLOC_FAST_PATH const T* data() const + { + return &storage[0]; + } + }; + + template + constexpr T* begin(Array& a) + { + return a.begin(); + } + + template + constexpr T* end(Array& a) + { + return a.end(); + } + + template + constexpr const T* begin(const Array& a) + { + return a.begin(); + } + + template + constexpr const T* end(const Array& a) + { + return a.end(); + } + } // namespace proxy +} // namespace snmalloc +#else +# include + +namespace snmalloc +{ + namespace proxy + { + template + using Array = std::array; + + using std::begin; + using std::end; + } // namespace proxy +} // namespace snmalloc +#endif diff --git a/src/test/func/memory/memory.cc b/src/test/func/memory/memory.cc index c85659eab..6b52e89a8 100644 --- a/src/test/func/memory/memory.cc +++ b/src/test/func/memory/memory.cc @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,6 +6,7 @@ #include #include #include + #if ((defined(__linux__) && !defined(__ANDROID__)) || defined(__sun)) || \ defined(__OpenBSD__) && !defined(SNMALLOC_QEMU_WORKAROUND) /*