JitRegCache: RCForkGuard
This commit is contained in:
parent
367a0bb672
commit
6c61d9a426
|
@ -970,7 +970,7 @@ BitSet8 Jit64::ComputeStaticGQRs(const PPCAnalyst::CodeBlock& cb) const
|
||||||
BitSet32 Jit64::CallerSavedRegistersInUse() const
|
BitSet32 Jit64::CallerSavedRegistersInUse() const
|
||||||
{
|
{
|
||||||
BitSet32 result;
|
BitSet32 result;
|
||||||
for (size_t i = 0; i < RegCache::NUM_XREGS; i++)
|
for (size_t i = 0; i < NUM_XREGS; i++)
|
||||||
{
|
{
|
||||||
if (!gpr.IsFreeX(i))
|
if (!gpr.IsFreeX(i))
|
||||||
result[i] = true;
|
result[i] = true;
|
||||||
|
|
|
@ -132,6 +132,7 @@ private:
|
||||||
class RCConstraint
|
class RCConstraint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
bool IsActive() const { return realized || bind || write || read || kill_imm; }
|
||||||
bool IsRealized() const { return realized; }
|
bool IsRealized() const { return realized; }
|
||||||
|
|
||||||
bool ShouldBind() const { return bind; }
|
bool ShouldBind() const { return bind; }
|
||||||
|
|
|
@ -267,6 +267,28 @@ void RCX64Reg::Unlock()
|
||||||
contents = std::monostate{};
|
contents = std::monostate{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCForkGuard::RCForkGuard(RegCache& rc_) : rc(&rc_), m_regs(rc_.m_regs), m_xregs(rc_.m_xregs)
|
||||||
|
{
|
||||||
|
ASSERT(!rc->IsAnyConstraintActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
RCForkGuard::RCForkGuard(RCForkGuard&& other) noexcept
|
||||||
|
: rc(other.rc), m_regs(std::move(other.m_regs)), m_xregs(std::move(other.m_xregs))
|
||||||
|
{
|
||||||
|
other.rc = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RCForkGuard::EndFork()
|
||||||
|
{
|
||||||
|
if (!rc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ASSERT(!rc->IsAnyConstraintActive());
|
||||||
|
rc->m_regs = m_regs;
|
||||||
|
rc->m_xregs = m_xregs;
|
||||||
|
rc = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
RegCache::RegCache(Jit64& jit) : m_jit{jit}
|
RegCache::RegCache(Jit64& jit) : m_jit{jit}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -595,6 +617,11 @@ RCX64Reg RegCache::Scratch(X64Reg xr)
|
||||||
return RCX64Reg{this, xr};
|
return RCX64Reg{this, xr};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCForkGuard RegCache::Fork()
|
||||||
|
{
|
||||||
|
return RCForkGuard{*this};
|
||||||
|
}
|
||||||
|
|
||||||
void RegCache::NewLock(preg_t preg)
|
void RegCache::NewLock(preg_t preg)
|
||||||
{
|
{
|
||||||
m_regs[preg].Lock();
|
m_regs[preg].Lock();
|
||||||
|
@ -663,3 +690,9 @@ void RegCache::Realize(preg_t preg)
|
||||||
|
|
||||||
m_constraints[preg].Realized();
|
m_constraints[preg].Realized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RegCache::IsAnyConstraintActive() const
|
||||||
|
{
|
||||||
|
return std::any_of(m_constraints.begin(), m_constraints.end(),
|
||||||
|
[](const auto& c) { return c.IsActive(); });
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ class RCX64Reg;
|
||||||
class RegCache;
|
class RegCache;
|
||||||
|
|
||||||
using preg_t = size_t;
|
using preg_t = size_t;
|
||||||
|
static constexpr size_t NUM_XREGS = 16;
|
||||||
|
|
||||||
class RCOpArg
|
class RCOpArg
|
||||||
{
|
{
|
||||||
|
@ -97,6 +98,28 @@ private:
|
||||||
std::variant<std::monostate, Gen::X64Reg, preg_t> contents;
|
std::variant<std::monostate, Gen::X64Reg, preg_t> contents;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RCForkGuard
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~RCForkGuard() { EndFork(); }
|
||||||
|
RCForkGuard(RCForkGuard&&) noexcept;
|
||||||
|
|
||||||
|
RCForkGuard(const RCForkGuard&) = delete;
|
||||||
|
RCForkGuard& operator=(const RCForkGuard&) = delete;
|
||||||
|
RCForkGuard& operator=(RCForkGuard&&) = delete;
|
||||||
|
|
||||||
|
void EndFork();
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class RegCache;
|
||||||
|
|
||||||
|
explicit RCForkGuard(RegCache& rc_);
|
||||||
|
|
||||||
|
RegCache* rc;
|
||||||
|
std::array<PPCCachedReg, 32> m_regs;
|
||||||
|
std::array<X64CachedReg, NUM_XREGS> m_xregs;
|
||||||
|
};
|
||||||
|
|
||||||
class RegCache
|
class RegCache
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -106,8 +129,6 @@ public:
|
||||||
MaintainState,
|
MaintainState,
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr size_t NUM_XREGS = 16;
|
|
||||||
|
|
||||||
explicit RegCache(Jit64& jit);
|
explicit RegCache(Jit64& jit);
|
||||||
virtual ~RegCache() = default;
|
virtual ~RegCache() = default;
|
||||||
|
|
||||||
|
@ -216,9 +237,12 @@ public:
|
||||||
RCX64Reg Bind(preg_t preg, RCMode mode);
|
RCX64Reg Bind(preg_t preg, RCMode mode);
|
||||||
RCX64Reg Scratch(Gen::X64Reg xr);
|
RCX64Reg Scratch(Gen::X64Reg xr);
|
||||||
|
|
||||||
|
RCForkGuard Fork();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class RCOpArg;
|
friend class RCOpArg;
|
||||||
friend class RCX64Reg;
|
friend class RCX64Reg;
|
||||||
|
friend class RCForkGuard;
|
||||||
|
|
||||||
virtual void StoreRegister(preg_t preg, const Gen::OpArg& new_loc) = 0;
|
virtual void StoreRegister(preg_t preg, const Gen::OpArg& new_loc) = 0;
|
||||||
virtual void LoadRegister(preg_t preg, Gen::X64Reg new_loc) = 0;
|
virtual void LoadRegister(preg_t preg, Gen::X64Reg new_loc) = 0;
|
||||||
|
@ -240,6 +264,8 @@ protected:
|
||||||
bool IsRealized(preg_t preg) const;
|
bool IsRealized(preg_t preg) const;
|
||||||
void Realize(preg_t preg);
|
void Realize(preg_t preg);
|
||||||
|
|
||||||
|
bool IsAnyConstraintActive() const;
|
||||||
|
|
||||||
Jit64& m_jit;
|
Jit64& m_jit;
|
||||||
std::array<PPCCachedReg, 32> m_regs;
|
std::array<PPCCachedReg, 32> m_regs;
|
||||||
std::array<X64CachedReg, NUM_XREGS> m_xregs;
|
std::array<X64CachedReg, NUM_XREGS> m_xregs;
|
||||||
|
|
Loading…
Reference in New Issue