From 5b4353a07dcdc85d99053bddc4d3d197406ff8e6 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Wed, 6 Jan 2021 04:31:05 +1100 Subject: cpu: Slightly reduce the number of page protection state changes --- src/devices/cpu/drcbex64.cpp | 1 + src/devices/cpu/drcbex86.cpp | 1 + src/devices/cpu/drccache.cpp | 33 +++++++++++++++++++++++++++------ src/devices/cpu/drccache.h | 1 + src/devices/cpu/drcuml.cpp | 1 - 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/devices/cpu/drcbex64.cpp b/src/devices/cpu/drcbex64.cpp index 5a1809229e5..716dd57b8d0 100644 --- a/src/devices/cpu/drcbex64.cpp +++ b/src/devices/cpu/drcbex64.cpp @@ -833,6 +833,7 @@ void drcbe_x64::reset() int drcbe_x64::execute(code_handle &entry) { // call our entry point which will jump to the destination + m_cache.codegen_complete(); return (*m_entry)(m_rbpvalue, (x86code *)entry.codeptr()); } diff --git a/src/devices/cpu/drcbex86.cpp b/src/devices/cpu/drcbex86.cpp index d60060b0d26..1d894713b43 100644 --- a/src/devices/cpu/drcbex86.cpp +++ b/src/devices/cpu/drcbex86.cpp @@ -803,6 +803,7 @@ void drcbe_x86::reset() int drcbe_x86::execute(code_handle &entry) { // call our entry point which will jump to the destination + m_cache.codegen_complete(); return (*m_entry)((x86code *)entry.codeptr()); } diff --git a/src/devices/cpu/drccache.cpp b/src/devices/cpu/drccache.cpp index 4a41cdcddb0..44ff2cf9371 100644 --- a/src/devices/cpu/drccache.cpp +++ b/src/devices/cpu/drccache.cpp @@ -47,7 +47,8 @@ drc_cache::drc_cache(size_t bytes) : m_limit(m_near + m_cache.size()), m_end(m_limit), m_codegen(nullptr), - m_size(m_cache.size()) + m_size(m_cache.size()), + m_executable(false) { // alignment and page size must be powers of two, cache must be page-aligned assert(!(CACHE_ALIGNMENT & (CACHE_ALIGNMENT - 1))); @@ -83,7 +84,11 @@ void drc_cache::flush() // just reset the top back to the base and re-seed m_top = m_base; - m_cache.set_access(0, m_size, osd::virtual_memory_allocation::READ_WRITE); + if (m_executable) + { + m_cache.set_access(0, m_size, osd::virtual_memory_allocation::READ_WRITE); + m_executable = false; + } } @@ -169,7 +174,11 @@ void *drc_cache::alloc_temporary(size_t bytes) return nullptr; // otherwise, update the cache top - m_cache.set_access(0, m_size, osd::virtual_memory_allocation::READ_WRITE); + if (m_executable) + { + m_cache.set_access(0, m_size, osd::virtual_memory_allocation::READ_WRITE); + m_executable = false; + } m_top = ALIGN_PTR_UP(ptr + bytes, CACHE_ALIGNMENT); return ptr; } @@ -198,13 +207,21 @@ void drc_cache::dealloc(void *memory, size_t bytes) void drc_cache::codegen_init() { - m_cache.set_access(0, m_size, osd::virtual_memory_allocation::READ_WRITE); + if (m_executable) + { + m_cache.set_access(0, m_size, osd::virtual_memory_allocation::READ_WRITE); + m_executable = false; + } } void drc_cache::codegen_complete() { - m_cache.set_access(m_base - m_near, ALIGN_PTR_UP(m_top, m_cache.page_size()) - m_base, osd::virtual_memory_allocation::READ_EXECUTE); + if (!m_executable) + { + m_cache.set_access(m_base - m_near, ALIGN_PTR_UP(m_top, m_cache.page_size()) - m_base, osd::virtual_memory_allocation::READ_EXECUTE); + m_executable = true; + } } @@ -223,7 +240,11 @@ drccodeptr *drc_cache::begin_codegen(uint32_t reserve_bytes) return nullptr; // otherwise, return a pointer to the cache top - m_cache.set_access(0, m_size, osd::virtual_memory_allocation::READ_WRITE); + if (m_executable) + { + m_cache.set_access(0, m_size, osd::virtual_memory_allocation::READ_WRITE); + m_executable = false; + } m_codegen = m_top; return &m_top; } diff --git a/src/devices/cpu/drccache.h b/src/devices/cpu/drccache.h index 07b0f847b81..b79e7d57d72 100644 --- a/src/devices/cpu/drccache.h +++ b/src/devices/cpu/drccache.h @@ -93,6 +93,7 @@ private: drccodeptr m_end; // first allocated byte in cache drccodeptr m_codegen; // start of current generated code block size_t const m_size; // size of the cache in bytes + bool m_executable; // whether cached code is currently executable // oob management struct oob_handler diff --git a/src/devices/cpu/drcuml.cpp b/src/devices/cpu/drcuml.cpp index af7e97cee4c..fd93018b35a 100644 --- a/src/devices/cpu/drcuml.cpp +++ b/src/devices/cpu/drcuml.cpp @@ -350,7 +350,6 @@ void drcuml_block::end() // generate the code via the back-end m_drcuml.cache().codegen_init(); m_drcuml.generate(*this, &m_inst[0], m_nextinst); - m_drcuml.cache().codegen_complete(); // block is no longer in use m_inuse = false; -- cgit v1.2.3