From 163187e91bafdb80b5a6b49e3726696672cac84d Mon Sep 17 00:00:00 2001 From: lizzie Date: Sun, 31 Aug 2025 21:12:46 +0000 Subject: [PATCH] [heap_tracker] use std::set instead of inhouse rbtree (depends on #374) Signed-off-by: lizzie --- src/common/heap_tracker.cpp | 23 +++++++++--------- src/common/heap_tracker.h | 47 ++++++++----------------------------- 2 files changed, 21 insertions(+), 49 deletions(-) diff --git a/src/common/heap_tracker.cpp b/src/common/heap_tracker.cpp index 7a80c2684c..8c99fc1d23 100644 --- a/src/common/heap_tracker.cpp +++ b/src/common/heap_tracker.cpp @@ -1,9 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include -#include - +#include "common/assert.h" #include "common/heap_tracker.h" #include "common/logging/log.h" @@ -23,6 +21,8 @@ inline s64 GetMaxPermissibleResidentMapCount() { HeapTracker::HeapTracker(Common::HostMemory& buffer) : m_buffer(buffer), m_max_resident_map_count(GetMaxPermissibleResidentMapCount()) {} +HeapTracker::~HeapTracker() = default; + void HeapTracker::Map(size_t virtual_offset, size_t host_offset, size_t length, MemoryPermission perm, bool is_separate_heap) { bool rebuild_required = false; @@ -48,10 +48,10 @@ void HeapTracker::Map(size_t virtual_offset, size_t host_offset, size_t length, // Insert into mappings. m_map_count++; - const auto it = m_mappings.insert(*map); + auto const [it, _] = m_mappings.insert(*map); // Update tick before possible rebuild. - it->tick = m_tick++; + const_cast(*it).tick = m_tick++; // Check if we need to rebuild. if (m_resident_map_count >= m_max_resident_map_count) { @@ -62,7 +62,7 @@ void HeapTracker::Map(size_t virtual_offset, size_t host_offset, size_t length, m_buffer.Map(it->vaddr, it->paddr, it->size, it->perm, false); // This map is now resident. - it->is_resident = true; + const_cast(*it).is_resident = true; m_resident_map_count++; m_resident_mappings.insert(*it); } @@ -95,7 +95,7 @@ void HeapTracker::Unmap(size_t virtual_offset, size_t size, bool is_separate_hea // If resident, erase from resident map. if (item->is_resident) { ASSERT(--m_resident_map_count >= 0); - m_resident_mappings.erase(m_resident_mappings.iterator_to(*item)); + m_resident_mappings.erase(m_resident_mappings.find(*item)); } // Erase from map. @@ -134,8 +134,7 @@ void HeapTracker::Protect(size_t virtual_offset, size_t size, MemoryPermission p }; // Try to get the next mapping corresponding to this address. - const auto it = m_mappings.nfind(key); - + const auto it = m_mappings.find(key); if (it == m_mappings.end()) { // There are no separate heap mappings remaining. next = end; @@ -143,7 +142,7 @@ void HeapTracker::Protect(size_t virtual_offset, size_t size, MemoryPermission p } else if (it->vaddr == cur) { // We are in range. // Update permission bits. - it->perm = perm; + const_cast(*it).perm = perm; // Determine next address and whether we should protect. next = cur + it->size; @@ -184,7 +183,7 @@ void HeapTracker::RebuildSeparateHeapAddressSpace() { for (size_t i = 0; i < evict_count && it != m_resident_mappings.end(); i++) { // Unmark and unmap. - it->is_resident = false; + const_cast(*it).is_resident = false; m_buffer.Unmap(it->vaddr, it->size, false); // Advance. @@ -215,7 +214,7 @@ void HeapTracker::SplitHeapMapLocked(VAddr offset) { // Adjust the left map. const size_t left_size = offset - left->vaddr; - left->size = left_size; + const_cast(*left).size = left_size; // Create the new right map. auto* const right = new SeparateHeapMap{ diff --git a/src/common/heap_tracker.h b/src/common/heap_tracker.h index a616606f86..107916a591 100644 --- a/src/common/heap_tracker.h +++ b/src/common/heap_tracker.h @@ -3,19 +3,15 @@ #pragma once -#include #include -#include #include +#include #include "common/host_memory.h" -#include "common/intrusive_red_black_tree.h" namespace Common { struct SeparateHeapMap { - Common::IntrusiveRedBlackTreeNode addr_node{}; - Common::IntrusiveRedBlackTreeNode tick_node{}; VAddr vaddr{}; PAddr paddr{}; size_t size{}; @@ -25,33 +21,22 @@ struct SeparateHeapMap { }; struct SeparateHeapMapAddrComparator { - static constexpr int Compare(const SeparateHeapMap& lhs, const SeparateHeapMap& rhs) { - if (lhs.vaddr < rhs.vaddr) { - return -1; - } else if (lhs.vaddr <= (rhs.vaddr + rhs.size - 1)) { - return 0; - } else { - return 1; - } + constexpr bool operator()(const SeparateHeapMap& lhs, const SeparateHeapMap& rhs) const noexcept { + return lhs.vaddr < rhs.vaddr; } }; - struct SeparateHeapMapTickComparator { - static constexpr int Compare(const SeparateHeapMap& lhs, const SeparateHeapMap& rhs) { - if (lhs.tick < rhs.tick) { - return -1; - } else if (lhs.tick > rhs.tick) { - return 1; - } else { - return SeparateHeapMapAddrComparator::Compare(lhs, rhs); - } + constexpr bool operator()(const SeparateHeapMap& lhs, const SeparateHeapMap& rhs) const noexcept { + if (lhs.tick != rhs.tick) + return lhs.tick < rhs.tick; + return SeparateHeapMapAddrComparator()(lhs, rhs); } }; class HeapTracker { public: explicit HeapTracker(Common::HostMemory& buffer); - ~HeapTracker() = default; + ~HeapTracker(); void Map(size_t virtual_offset, size_t host_offset, size_t length, MemoryPermission perm, bool is_separate_heap); @@ -60,24 +45,12 @@ public: inline u8* VirtualBasePointer() noexcept { return m_buffer.VirtualBasePointer(); } - -private: - using AddrTreeTraits = - Common::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<&SeparateHeapMap::addr_node>; - using AddrTree = AddrTreeTraits::TreeType; - - using TickTreeTraits = - Common::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<&SeparateHeapMap::tick_node>; - using TickTree = TickTreeTraits::TreeType; - - AddrTree m_mappings{}; - TickTree m_resident_mappings{}; - private: void SplitHeapMap(VAddr offset, size_t size); void SplitHeapMapLocked(VAddr offset); void RebuildSeparateHeapAddressSpace(); -private: + std::set m_mappings{}; + std::set m_resident_mappings{}; Common::HostMemory& m_buffer; const s64 m_max_resident_map_count; std::shared_mutex m_rebuild_lock{};