diff options
author | 2024-04-12 02:03:25 -0700 | |
---|---|---|
committer | 2024-04-16 19:33:03 +0000 | |
commit | 366d45a8b5ccfe390258c5baf6a72a51aa0c7062 (patch) | |
tree | cab4e4d3be9f79e937d0dea7545dda9ddda5538d | |
parent | 1f8f41b219eed63ed3532c25cd11efaa692b8478 (diff) |
TrackingAllocator and GcRootArenaAllocator: C++20 fixes
std::allocator<T> deprecates several member typedefs in C++17 and
removes them in C++20, so stop using them:
* pointer
* const_pointer
* reference
* const_reference
Reduce TrackingAllocatorImpl and GcRootArenaAllocator to what's
required by the Allocator requirements[1]:
* The only member typedef needed is value_type. All the others are
optional and were previously delegated to std::allocator<T>, so we
can rely on the default behavior.
* The hint parameter for allocate was supposed to be const void*, not
const T*. It's deprecated now, though.
* TrackingAllocatorImpl was inheriting from std::allocator<T>, and it
could have delegated allocate and deallocate to std::allocator<T>,
but instead it uses malloc/free, so just remove the base class
entirely.
* GcRootArenaAllocator: prefer delegation to
TrackingAllocator<T, kTag> over inheritance.
* rebind is non-optional because GcRootArenaAllocator and
TrackingAllocatorImpl's second template parameter is a value, not
a type (specifically, a value of type AllocatorTag).
* Remove explicit from the TrackingAllocatorImpl and
GcRootArenaAllocator copy constructors. The explicit on
TrackingAllocatorImpl caused a build error when I enabled
kEnableTrackingAllocator.
[1]: https://en.cppreference.com/w/cpp/named_req/Allocator
Bug: 311052584
Test: art_standalone_libartbase_tests
Test: art_standalone_runtime_tests
Test: remove cpp_std override and build Android
Change-Id: I4e6d4ee418c21fb24974a32129bc08d550a63b86
-rw-r--r-- | libartbase/base/allocator.h | 32 | ||||
-rw-r--r-- | runtime/base/gc_visited_arena_pool.h | 31 |
2 files changed, 25 insertions, 38 deletions
diff --git a/libartbase/base/allocator.h b/libartbase/base/allocator.h index c3f32282e8..876a47d470 100644 --- a/libartbase/base/allocator.h +++ b/libartbase/base/allocator.h @@ -102,26 +102,19 @@ inline void RegisterFree(AllocatorTag tag, size_t bytes) { } // namespace TrackedAllocators // Tracking allocator for use with STL types, tracks how much memory is used. -template<class T, AllocatorTag kTag> -class TrackingAllocatorImpl : public std::allocator<T> { +template <class T, AllocatorTag kTag> +class TrackingAllocatorImpl { + static_assert(kTag < kAllocatorTagCount, "kTag must be less than kAllocatorTagCount"); + public: - using value_type = typename std::allocator<T>::value_type; - using size_type = typename std::allocator<T>::size_type; - using difference_type = typename std::allocator<T>::difference_type; - using pointer = typename std::allocator<T>::pointer; - using const_pointer = typename std::allocator<T>::const_pointer; - using reference = typename std::allocator<T>::reference; - using const_reference = typename std::allocator<T>::const_reference; + using value_type = T; - // Used internally by STL data structures. + // Used internally by STL data structures. This copy constructor needs to be implicit. Don't wrap + // the line because that would break cpplint's detection of the implicit constructor. template <class U> - explicit TrackingAllocatorImpl( - [[maybe_unused]] const TrackingAllocatorImpl<U, kTag>& alloc) noexcept {} - + TrackingAllocatorImpl([[maybe_unused]] const TrackingAllocatorImpl<U, kTag>& alloc) noexcept {} // NOLINT [runtime/explicit] // Used internally by STL data structures. - TrackingAllocatorImpl() noexcept { - static_assert(kTag < kAllocatorTagCount, "kTag must be less than kAllocatorTagCount"); - } + TrackingAllocatorImpl() noexcept {} // Enables an allocator for objects of one type to allocate storage for objects of another type. // Used internally by STL data structures. @@ -130,14 +123,13 @@ class TrackingAllocatorImpl : public std::allocator<T> { using other = TrackingAllocatorImpl<U, kTag>; }; - pointer allocate(size_type n, [[maybe_unused]] const_pointer hint = 0) { + T* allocate(size_t n) { const size_t size = n * sizeof(T); TrackedAllocators::RegisterAllocation(GetTag(), size); - return reinterpret_cast<pointer>(malloc(size)); + return reinterpret_cast<T*>(malloc(size)); } - template <typename PT> - void deallocate(PT p, size_type n) { + void deallocate(T* p, size_t n) { const size_t size = n * sizeof(T); TrackedAllocators::RegisterFree(GetTag(), size); free(p); diff --git a/runtime/base/gc_visited_arena_pool.h b/runtime/base/gc_visited_arena_pool.h index 802303d2f8..4caaaf4b8f 100644 --- a/runtime/base/gc_visited_arena_pool.h +++ b/runtime/base/gc_visited_arena_pool.h @@ -291,22 +291,18 @@ class GcVisitedArenaPool final : public ArenaPool { // Allocator for class-table and intern-table hash-sets. It enables updating the // roots concurrently page-by-page. template <class T, AllocatorTag kTag> -class GcRootArenaAllocator : public TrackingAllocator<T, kTag> { +class GcRootArenaAllocator { + TrackingAllocator<T, kTag> tracking_alloc_; + public: - using value_type = typename TrackingAllocator<T, kTag>::value_type; - using size_type = typename TrackingAllocator<T, kTag>::size_type; - using difference_type = typename TrackingAllocator<T, kTag>::difference_type; - using pointer = typename TrackingAllocator<T, kTag>::pointer; - using const_pointer = typename TrackingAllocator<T, kTag>::const_pointer; - using reference = typename TrackingAllocator<T, kTag>::reference; - using const_reference = typename TrackingAllocator<T, kTag>::const_reference; + using value_type = T; - // Used internally by STL data structures. + // Used internally by STL data structures. This copy constructor needs to be implicit. Don't wrap + // the line because that would break cpplint's detection of the implicit constructor. template <class U> - explicit GcRootArenaAllocator( - [[maybe_unused]] const GcRootArenaAllocator<U, kTag>& alloc) noexcept {} + GcRootArenaAllocator([[maybe_unused]] const GcRootArenaAllocator<U, kTag>& alloc) noexcept {} // NOLINT [runtime/explicit] // Used internally by STL data structures. - GcRootArenaAllocator() noexcept : TrackingAllocator<T, kTag>() {} + GcRootArenaAllocator() noexcept {} // Enables an allocator for objects of one type to allocate storage for objects of another type. // Used internally by STL data structures. @@ -315,20 +311,19 @@ class GcRootArenaAllocator : public TrackingAllocator<T, kTag> { using other = GcRootArenaAllocator<U, kTag>; }; - pointer allocate(size_type n, [[maybe_unused]] const_pointer hint = nullptr) { + T* allocate(size_t n) { if (!gUseUserfaultfd) { - return TrackingAllocator<T, kTag>::allocate(n); + return tracking_alloc_.allocate(n); } size_t size = n * sizeof(T); GcVisitedArenaPool* pool = down_cast<GcVisitedArenaPool*>(Runtime::Current()->GetLinearAllocArenaPool()); - return reinterpret_cast<pointer>(pool->AllocSingleObjArena(size)); + return reinterpret_cast<T*>(pool->AllocSingleObjArena(size)); } - template <typename PT> - void deallocate(PT p, size_type n) { + void deallocate(T* p, size_t n) { if (!gUseUserfaultfd) { - TrackingAllocator<T, kTag>::deallocate(p, n); + tracking_alloc_.deallocate(p, n); return; } GcVisitedArenaPool* pool = |