summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ryan Prichard <rprichard@google.com> 2024-04-12 02:03:25 -0700
committer Ryan Prichard <rprichard@google.com> 2024-04-16 19:33:03 +0000
commit366d45a8b5ccfe390258c5baf6a72a51aa0c7062 (patch)
treecab4e4d3be9f79e937d0dea7545dda9ddda5538d
parent1f8f41b219eed63ed3532c25cd11efaa692b8478 (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.h32
-rw-r--r--runtime/base/gc_visited_arena_pool.h31
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 =