WIP: DO-NOT-MERGE: NCE experiments: Initial LRU

This commit is contained in:
MrPurple666 2025-04-02 02:11:32 -03:00
parent 27ceda2c6c
commit 3d43fecece
2 changed files with 71 additions and 1 deletions

View file

@ -0,0 +1,57 @@
#pragma once
#include <list>
#include <unordered_map>
template<typename KeyType, typename ValueType>
class LRUCache {
public:
explicit LRUCache(size_t capacity) : capacity(capacity) {}
ValueType* get(const KeyType& key) {
auto it = cache_map.find(key);
if (it == cache_map.end()) {
return nullptr;
}
// Move the accessed item to the front of the list (most recently used)
cache_list.splice(cache_list.begin(), cache_list, it->second.first);
return &(it->second.second);
}
void put(const KeyType& key, const ValueType& value) {
auto it = cache_map.find(key);
if (it != cache_map.end()) {
// Key exists, update value and move to front
it->second.second = value;
cache_list.splice(cache_list.begin(), cache_list, it->second.first);
return;
}
// Remove the least recently used item if cache is full
if (cache_map.size() >= capacity) {
auto last = cache_list.back();
cache_map.erase(last);
cache_list.pop_back();
}
// Insert new item at the front
cache_list.push_front(key);
cache_map[key] = {cache_list.begin(), value};
}
void clear() {
cache_map.clear();
cache_list.clear();
}
size_t size() const {
return cache_map.size();
}
private:
size_t capacity;
std::list<KeyType> cache_list;
std::unordered_map<KeyType, std::pair<typename std::list<KeyType>::iterator, ValueType>> cache_map;
};

View file

@ -13,6 +13,7 @@
#include "core/hle/kernel/code_set.h"
#include "core/hle/kernel/k_typed_address.h"
#include "core/hle/kernel/physical_memory.h"
#include "lru_cache.h"
namespace Core::NCE {
@ -60,8 +61,20 @@ private:
void WriteCntpctHandler(ModuleDestLabel module_dest, oaknut::XReg dest_reg);
private:
static constexpr size_t CACHE_SIZE = 1024; // Cache size for patch entries
LRUCache<uintptr_t, PatchTextAddress> patch_cache{CACHE_SIZE};
void BranchToPatch(uintptr_t module_dest) {
curr_patch->m_branch_to_patch_relocations.push_back({c.offset(), module_dest});
// Try to get existing patch entry from cache
if (auto* cached_patch = patch_cache.get(module_dest)) {
curr_patch->m_branch_to_patch_relocations.push_back({c.offset(), *cached_patch});
return;
}
// If not in cache, create new entry and cache it
const auto patch_addr = c.offset();
curr_patch->m_branch_to_patch_relocations.push_back({patch_addr, module_dest});
patch_cache.put(module_dest, patch_addr);
}
void BranchToModule(uintptr_t module_dest) {