summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2021-01-06 04:31:05 +1100
committer Vas Crabb <vas@vastheman.com>2021-01-06 04:31:05 +1100
commit5b4353a07dcdc85d99053bddc4d3d197406ff8e6 (patch)
tree914bdc97a84094a487fa17050346da04cf1a9802
parent8a3c14c360600f01083ef912325c7f4b653d7ec7 (diff)
cpu: Slightly reduce the number of page protection state changes
-rw-r--r--src/devices/cpu/drcbex64.cpp1
-rw-r--r--src/devices/cpu/drcbex86.cpp1
-rw-r--r--src/devices/cpu/drccache.cpp33
-rw-r--r--src/devices/cpu/drccache.h1
-rw-r--r--src/devices/cpu/drcuml.cpp1
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;