mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 18:00:17 +02:00
Move AllocateNewCodeBuffer from CPUBackend to a new CodeBufferManager interface
This commit is contained in:
1 parent
3376587b6a
commit
ab51958b26
4 files changed
+26
-27
No files matched your search
@@ -75,7 +75,7 @@ struct CustomIRResult {
|
||||
using BlockDelinkerFunc = void (*)(FEXCore::Core::CpuStateFrame* Frame, FEXCore::Context::ExitFunctionLinkData* Record);
|
||||
constexpr uint32_t TSC_SCALE_MAXIMUM = 1'000'000'000; ///< 1Ghz
|
||||
|
||||
class ContextImpl final : public FEXCore::Context::Context {
|
||||
class ContextImpl final : public FEXCore::Context::Context, CPU::CodeBufferManager {
|
||||
public:
|
||||
// Context base class implementation.
|
||||
bool InitCore() override;
|
||||
|
||||
@@ -309,42 +309,34 @@ namespace CPU {
|
||||
auto CPUBackend::GetEmptyCodeBuffer() -> CodeBuffer* {
|
||||
if (ThreadState->CurrentFrame->SignalHandlerRefCounter == 0) {
|
||||
if (CodeBuffers.empty()) {
|
||||
auto NewCodeBuffer = AllocateNewCodeBuffer(InitialCodeSize);
|
||||
EmplaceNewCodeBuffer(NewCodeBuffer);
|
||||
EmplaceNewCodeBuffer(manager.AllocateNew(InitialCodeSize));
|
||||
} else {
|
||||
// If we have more than one code buffer we are tracking then walk them and delete
|
||||
// This is a cleanup step
|
||||
CodeBuffers.resize(1);
|
||||
|
||||
// Set the current code buffer to the initial
|
||||
CurrentCodeBuffer = CodeBuffers[0];
|
||||
|
||||
if (CurrentCodeBuffer->Size != MaxCodeSize) {
|
||||
auto Size = CurrentCodeBuffer->Size;
|
||||
if (CurrentCodeBufferSize != MaxCodeSize) {
|
||||
CodeBuffers.clear();
|
||||
CurrentCodeBuffer.reset();
|
||||
|
||||
// Resize the code buffer and reallocate our code size
|
||||
Size *= 1.5;
|
||||
Size = std::min(Size, MaxCodeSize);
|
||||
CurrentCodeBufferSize *= 1.5;
|
||||
CurrentCodeBufferSize = std::min(CurrentCodeBufferSize, MaxCodeSize);
|
||||
|
||||
CurrentCodeBuffer = AllocateNewCodeBuffer(Size);
|
||||
EmplaceNewCodeBuffer(CurrentCodeBuffer);
|
||||
EmplaceNewCodeBuffer(manager.AllocateNew(CurrentCodeBufferSize));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We have signal handlers that have generated code
|
||||
// This means that we can not safely clear the code at this point in time
|
||||
// Allocate some new code buffers that we can switch over to instead
|
||||
auto NewCodeBuffer = AllocateNewCodeBuffer(InitialCodeSize);
|
||||
EmplaceNewCodeBuffer(NewCodeBuffer);
|
||||
EmplaceNewCodeBuffer(manager.AllocateNew(InitialCodeSize));
|
||||
}
|
||||
|
||||
return CurrentCodeBuffer.get();
|
||||
return CodeBuffers.back().get();
|
||||
}
|
||||
|
||||
void CPUBackend::EmplaceNewCodeBuffer(fextl::shared_ptr<CodeBuffer> Buffer) {
|
||||
CurrentCodeBuffer = Buffer;
|
||||
CurrentCodeBufferSize = Buffer->Size;
|
||||
CodeBuffers.emplace_back(Buffer);
|
||||
}
|
||||
|
||||
@@ -362,10 +354,11 @@ namespace CPU {
|
||||
}
|
||||
|
||||
CodeBuffer::~CodeBuffer() {
|
||||
// TODO: Assert that mutex is held?
|
||||
FEXCore::Allocator::VirtualFree(Ptr, Size);
|
||||
}
|
||||
|
||||
auto CPUBackend::AllocateNewCodeBuffer(size_t Size) -> fextl::shared_ptr<CodeBuffer> {
|
||||
auto CodeBufferManager::AllocateNew(size_t Size) -> fextl::shared_ptr<CodeBuffer> {
|
||||
#ifndef _WIN32
|
||||
// MDWE (Memory-Deny-Write-Execute) is a new Linux 6.3 feature.
|
||||
// It's equivalent to systemd's `MemoryDenyWriteExecute` but implemented entirely in the kernel.
|
||||
@@ -393,9 +386,10 @@ namespace CPU {
|
||||
|
||||
auto Buffer = fextl::make_shared<CodeBuffer>(Size);
|
||||
|
||||
if (static_cast<Context::ContextImpl*>(ThreadState->CTX)->Config.GlobalJITNaming()) {
|
||||
static_cast<Context::ContextImpl*>(ThreadState->CTX)->Symbols.RegisterJITSpace(Buffer->Ptr, Buffer->Size);
|
||||
}
|
||||
// TODO: Re-enable
|
||||
// if (static_cast<Context::ContextImpl*>(ThreadState->CTX)->Config.GlobalJITNaming()) {
|
||||
// static_cast<Context::ContextImpl*>(ThreadState->CTX)->Symbols.RegisterJITSpace(Buffer.Ptr, Buffer.Size);
|
||||
// }
|
||||
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,11 @@ namespace CPU {
|
||||
~CodeBuffer();
|
||||
};
|
||||
|
||||
class CodeBufferManager {
|
||||
public:
|
||||
fextl::shared_ptr<CodeBuffer> AllocateNew(size_t Size);
|
||||
};
|
||||
|
||||
class CPUBackend {
|
||||
public:
|
||||
|
||||
@@ -53,7 +58,7 @@ namespace CPU {
|
||||
* @param InitialCodeSize - Initial size for the code buffers
|
||||
* @param MaxCodeSize - Max size for the code buffers
|
||||
*/
|
||||
CPUBackend(FEXCore::Core::InternalThreadState* ThreadState, size_t InitialCodeSize, size_t MaxCodeSize);
|
||||
CPUBackend(FEXCore::Core::InternalThreadState*, size_t InitialCodeSize, size_t MaxCodeSize);
|
||||
|
||||
virtual ~CPUBackend();
|
||||
|
||||
@@ -163,12 +168,12 @@ namespace CPU {
|
||||
[[nodiscard]]
|
||||
CodeBuffer* GetEmptyCodeBuffer();
|
||||
|
||||
// This is the current code buffer that we are tracking
|
||||
std::shared_ptr<CodeBuffer> CurrentCodeBuffer;
|
||||
// This is the size of the last code buffer we allocated
|
||||
size_t CurrentCodeBufferSize = 0;
|
||||
|
||||
CodeBufferManager manager; // TODO: Rename
|
||||
|
||||
private:
|
||||
fextl::shared_ptr<CodeBuffer> AllocateNewCodeBuffer(size_t Size);
|
||||
|
||||
void EmplaceNewCodeBuffer(fextl::shared_ptr<CodeBuffer> Buffer);
|
||||
|
||||
// This is the array of code buffers. Unless signals force us to keep more than
|
||||
|
||||
@@ -693,7 +693,7 @@ CPUBackend::CompiledCode Arm64JITCore::CompileCode(uint64_t Entry, uint64_t Size
|
||||
|
||||
// Fairly excessive buffer range to make sure we don't overflow
|
||||
uint32_t BufferRange = SSACount * 16;
|
||||
if ((GetCursorOffset() + BufferRange) > (CurrentCodeBuffer->Size - Utils::FEX_PAGE_SIZE)) {
|
||||
if ((GetCursorOffset() + BufferRange) > (CurrentCodeBufferSize - Utils::FEX_PAGE_SIZE)) {
|
||||
CTX->ClearCodeCache(ThreadState);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user