mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-07 07:21:25 +12:00
Add new typemap for always existing objects
Not to be confused with singletons or global variables.
This commit is contained in:
parent
7db2e2537f
commit
8517ccfdfa
6 changed files with 136 additions and 6 deletions
|
@ -41,7 +41,7 @@ void spu_recompiler::init()
|
||||||
if (!m_spurt)
|
if (!m_spurt)
|
||||||
{
|
{
|
||||||
m_cache = fxm::get<spu_cache>();
|
m_cache = fxm::get<spu_cache>();
|
||||||
m_spurt = fxm::get_always<spu_runtime>();
|
m_spurt = g_fxo->get<spu_runtime>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -538,8 +538,6 @@ spu_runtime::spu_runtime()
|
||||||
fs::file(m_cache_path + "spu.log", fs::rewrite);
|
fs::file(m_cache_path + "spu.log", fs::rewrite);
|
||||||
fs::file(m_cache_path + "spu-ir.log", fs::rewrite);
|
fs::file(m_cache_path + "spu-ir.log", fs::rewrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_SUCCESS(SPU, "SPU Recompiler Runtime initialized...");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool spu_runtime::add(u64 last_reset_count, void* _where, spu_function_t compiled)
|
bool spu_runtime::add(u64 last_reset_count, void* _where, spu_function_t compiled)
|
||||||
|
@ -4165,7 +4163,7 @@ public:
|
||||||
if (!m_spurt)
|
if (!m_spurt)
|
||||||
{
|
{
|
||||||
m_cache = fxm::get<spu_cache>();
|
m_cache = fxm::get<spu_cache>();
|
||||||
m_spurt = fxm::get_always<spu_runtime>();
|
m_spurt = g_fxo->get<spu_runtime>();
|
||||||
cpu_translator::initialize(m_jit.get_context(), m_jit.get_engine());
|
cpu_translator::initialize(m_jit.get_context(), m_jit.get_engine());
|
||||||
|
|
||||||
const auto md_name = llvm::MDString::get(m_context, "branch_weights");
|
const auto md_name = llvm::MDString::get(m_context, "branch_weights");
|
||||||
|
|
|
@ -76,6 +76,10 @@ public:
|
||||||
public:
|
public:
|
||||||
spu_runtime();
|
spu_runtime();
|
||||||
|
|
||||||
|
spu_runtime(const spu_runtime&) = delete;
|
||||||
|
|
||||||
|
spu_runtime& operator=(const spu_runtime&) = delete;
|
||||||
|
|
||||||
const std::string& get_cache_path() const
|
const std::string& get_cache_path() const
|
||||||
{
|
{
|
||||||
return m_cache_path;
|
return m_cache_path;
|
||||||
|
@ -226,7 +230,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<spu_runtime> m_spurt;
|
spu_runtime* m_spurt{};
|
||||||
|
|
||||||
u32 m_pos;
|
u32 m_pos;
|
||||||
u32 m_size;
|
u32 m_size;
|
||||||
|
|
|
@ -785,6 +785,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "Utilities/typemap.h"
|
#include "Utilities/typemap.h"
|
||||||
|
#include "util/fixed_typemap.hpp"
|
||||||
|
|
||||||
extern utils::typemap g_typemap;
|
extern utils::typemap g_typemap;
|
||||||
|
|
||||||
|
@ -793,3 +794,7 @@ constexpr utils::typemap* g_idm = &g_typemap;
|
||||||
using utils::id_new;
|
using utils::id_new;
|
||||||
using utils::id_any;
|
using utils::id_any;
|
||||||
using utils::id_always;
|
using utils::id_always;
|
||||||
|
|
||||||
|
extern stx::manual_fixed_typemap<void> g_fixed_typemap;
|
||||||
|
|
||||||
|
constexpr stx::manual_fixed_typemap<void>* g_fxo = &g_fixed_typemap;
|
||||||
|
|
|
@ -46,6 +46,8 @@
|
||||||
#include "Emu/RSX/VK/VulkanAPI.h"
|
#include "Emu/RSX/VK/VulkanAPI.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
stx::manual_fixed_typemap<void> g_fixed_typemap;
|
||||||
|
|
||||||
utils::typemap g_typemap{nullptr};
|
utils::typemap g_typemap{nullptr};
|
||||||
|
|
||||||
cfg_root g_cfg;
|
cfg_root g_cfg;
|
||||||
|
@ -318,6 +320,7 @@ void Emulator::Init()
|
||||||
idm::init();
|
idm::init();
|
||||||
fxm::init();
|
fxm::init();
|
||||||
g_idm->init();
|
g_idm->init();
|
||||||
|
g_fxo->reset();
|
||||||
|
|
||||||
// Reset defaults, cache them
|
// Reset defaults, cache them
|
||||||
g_cfg.from_default();
|
g_cfg.from_default();
|
||||||
|
@ -1511,6 +1514,7 @@ void Emulator::Load(const std::string& title_id, bool add_only, bool force_globa
|
||||||
LOG_NOTICE(LOADER, "Cache: %s", _main->cache);
|
LOG_NOTICE(LOADER, "Cache: %s", _main->cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_fxo->init();
|
||||||
fxm::import<GSRender>(Emu.GetCallbacks().get_gs_render); // TODO: must be created in appropriate sys_rsx syscall
|
fxm::import<GSRender>(Emu.GetCallbacks().get_gs_render); // TODO: must be created in appropriate sys_rsx syscall
|
||||||
fxm::import<pad_thread>(Emu.GetCallbacks().get_pad_handler, m_title_id);
|
fxm::import<pad_thread>(Emu.GetCallbacks().get_pad_handler, m_title_id);
|
||||||
network_thread_init();
|
network_thread_init();
|
||||||
|
@ -1735,6 +1739,7 @@ void Emulator::Stop(bool restart)
|
||||||
idm::clear();
|
idm::clear();
|
||||||
fxm::clear();
|
fxm::clear();
|
||||||
g_idm->init();
|
g_idm->init();
|
||||||
|
g_fxo->reset();
|
||||||
|
|
||||||
LOG_NOTICE(GENERAL, "Objects cleared...");
|
LOG_NOTICE(GENERAL, "Objects cleared...");
|
||||||
|
|
||||||
|
|
118
rpcs3/util/fixed_typemap.hpp
Normal file
118
rpcs3/util/fixed_typemap.hpp
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <util/typeindices.hpp>
|
||||||
|
|
||||||
|
namespace stx
|
||||||
|
{
|
||||||
|
// Typemap with exactly one object of each used type, created on init() and destroyed on clear()
|
||||||
|
template <typename /*Tag*/>
|
||||||
|
class manual_fixed_typemap
|
||||||
|
{
|
||||||
|
// Save default constructor and destructor
|
||||||
|
struct typeinfo
|
||||||
|
{
|
||||||
|
void(*create)(void*& ptr) noexcept;
|
||||||
|
void(*destroy)(void*& ptr) noexcept;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void call_ctor(void*& ptr) noexcept
|
||||||
|
{
|
||||||
|
// Call default constructor only if available
|
||||||
|
if constexpr (std::is_default_constructible_v<T>)
|
||||||
|
{
|
||||||
|
// Don't overwrite if already exists
|
||||||
|
if (!ptr)
|
||||||
|
{
|
||||||
|
ptr = new T{};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void call_dtor(void*& ptr) noexcept
|
||||||
|
{
|
||||||
|
delete static_cast<T*>(ptr);
|
||||||
|
ptr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static typeinfo make_typeinfo()
|
||||||
|
{
|
||||||
|
typeinfo r;
|
||||||
|
r.create = &call_ctor<T>;
|
||||||
|
r.destroy = &call_dtor<T>;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<void*[]> m_list;
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr manual_fixed_typemap() noexcept = default;
|
||||||
|
|
||||||
|
manual_fixed_typemap(const manual_fixed_typemap&) = delete;
|
||||||
|
|
||||||
|
manual_fixed_typemap(manual_fixed_typemap&& r) noexcept
|
||||||
|
{
|
||||||
|
std::swap(m_list, r.m_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
manual_fixed_typemap& operator=(const manual_fixed_typemap&) = delete;
|
||||||
|
|
||||||
|
manual_fixed_typemap& operator=(manual_fixed_typemap&& r) noexcept
|
||||||
|
{
|
||||||
|
manual_fixed_typemap x(std::move(*this));
|
||||||
|
std::swap(m_list, x.m_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroy all objects and keep them in uninitialized state, must be called first
|
||||||
|
void reset() noexcept
|
||||||
|
{
|
||||||
|
if (!m_list)
|
||||||
|
{
|
||||||
|
m_list = std::make_unique<void*[]>(stx::typeinfo_v<typeinfo>.count());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& type : stx::typeinfo_v<typeinfo>)
|
||||||
|
{
|
||||||
|
type.destroy(m_list[type.index()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default initialize all objects if possible and not already initialized
|
||||||
|
void init() noexcept
|
||||||
|
{
|
||||||
|
for (auto& type : stx::typeinfo_v<typeinfo>)
|
||||||
|
{
|
||||||
|
type.create(m_list[type.index()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Explicitly (re)initialize object of type T possibly with dynamic type As and arguments
|
||||||
|
template <typename T, typename As = T, typename... Args>
|
||||||
|
T* init(Args&&... args) noexcept
|
||||||
|
{
|
||||||
|
auto& ptr = m_list[stx::type_counter<typeinfo>::template type<std::decay_t<T>>.index()];
|
||||||
|
|
||||||
|
if (ptr)
|
||||||
|
{
|
||||||
|
delete static_cast<T*>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* obj = static_cast<T*>(new std::decay_t<As>(std::forward<Args>(args)...));
|
||||||
|
ptr = obj;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtain object pointer (the only thread safe function)
|
||||||
|
template <typename T>
|
||||||
|
T* get() const noexcept
|
||||||
|
{
|
||||||
|
return static_cast<T*>(m_list[stx::type_counter<typeinfo>::template type<std::decay_t<T>>.index()]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue