Move AllocateNewCodeBuffer from CPUBackend to a new CodeBufferManager interface

This commit is contained in:
Tony Wasserka committed 2025-06-01 22:42:55 +02:00
1 parent 3376587b6a
commit ab51958b26
4 files changed
+26 -27

No files matched your search

+1 -1
View File
@@ -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;
+14 -20
View File
@@ -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;
}
+10 -5
View File
@@ -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
+1 -1
View File
@@ -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);
}