Qt/Debugger: Invalidate blocks on manual memory edit

Ensures recompiler isn't executing stale code.
This commit is contained in:
Stenzek 2024-09-09 20:19:26 +10:00
parent 830e0ad3ad
commit eeca12467c
No known key found for this signature in database
3 changed files with 51 additions and 11 deletions

View file

@ -6,9 +6,12 @@
#include "qthost.h"
#include "qtutils.h"
#include "common/assert.h"
#include "core/bus.h"
#include "core/cpu_code_cache.h"
#include "core/cpu_core_private.h"
#include "common/assert.h"
#include <QtCore/QSignalBlocker>
#include <QtGui/QCursor>
#include <QtGui/QFontDatabase>
@ -568,10 +571,27 @@ void DebuggerWindow::setMemoryViewRegion(Bus::MemoryRegion region)
m_active_memory_region = region;
static constexpr auto edit_ram_callback = [](size_t offset, size_t count) {
// shouldn't happen
if (offset > Bus::g_ram_size)
return;
const u32 start_page = static_cast<u32>(offset) / HOST_PAGE_SIZE;
const u32 end_page = static_cast<u32>(offset + count - 1) / HOST_PAGE_SIZE;
for (u32 i = start_page; i <= end_page; i++)
{
if (Bus::g_ram_code_bits[i])
CPU::CodeCache::InvalidateBlocksWithPageIndex(i);
}
};
const PhysicalMemoryAddress start = Bus::GetMemoryRegionStart(region);
const PhysicalMemoryAddress end = Bus::GetMemoryRegionEnd(region);
m_ui.memoryView->setData(start, Bus::GetMemoryRegionPointer(region), end - start,
Bus::IsMemoryRegionWritable(region));
void* const mem_ptr = Bus::GetMemoryRegionPointer(region);
const bool mem_writable = Bus::IsMemoryRegionWritable(region);
const MemoryViewWidget::EditCallback edit_callback =
((region == Bus::MemoryRegion::RAM) ? edit_ram_callback : nullptr);
m_ui.memoryView->setData(start, mem_ptr, end - start, mem_writable, edit_callback);
#define SET_REGION_RADIO_BUTTON(name, rb_region) \
do \

View file

@ -8,7 +8,7 @@
MemoryViewWidget::MemoryViewWidget(QWidget* parent /* = nullptr */, size_t address_offset /* = 0 */,
void* data_ptr /* = nullptr */, size_t data_size /* = 0 */,
bool data_editable /* = false */)
bool data_editable /* = false */, EditCallback edit_callback /* = nullptr */)
: QAbstractScrollArea(parent)
{
m_bytes_per_line = 16;
@ -19,7 +19,7 @@ MemoryViewWidget::MemoryViewWidget(QWidget* parent /* = nullptr */, size_t addre
connect(horizontalScrollBar(), &QScrollBar::valueChanged, this, &MemoryViewWidget::adjustContent);
if (data_ptr)
setData(address_offset, data_ptr, data_size, data_editable);
setData(address_offset, data_ptr, data_size, data_editable, edit_callback);
}
MemoryViewWidget::~MemoryViewWidget() = default;
@ -46,13 +46,15 @@ void MemoryViewWidget::updateMetrics()
m_char_height = fm.height();
}
void MemoryViewWidget::setData(size_t address_offset, void* data_ptr, size_t data_size, bool data_editable)
void MemoryViewWidget::setData(size_t address_offset, void* data_ptr, size_t data_size, bool data_editable,
EditCallback edit_callback)
{
m_data = data_ptr;
m_data_size = data_size;
m_data_editable = data_editable;
m_address_offset = address_offset;
m_selected_address = INVALID_SELECTED_ADDRESS;
m_edit_callback = edit_callback;
m_last_data_start_offset = 0;
m_last_data.clear();
adjustContent();
@ -137,7 +139,15 @@ void MemoryViewWidget::keyPressEvent(QKeyEvent* event)
if (m_selection_was_ascii)
{
expandCurrentDataToInclude(m_selected_address);
std::memcpy(static_cast<unsigned char*>(m_data) + m_selected_address, &ch, sizeof(unsigned char));
unsigned char* pdata = static_cast<unsigned char*>(m_data) + m_selected_address;
if (static_cast<unsigned char>(ch) != *pdata)
{
*pdata = static_cast<unsigned char>(ch);
if (m_edit_callback)
m_edit_callback(m_selected_address, 1);
}
m_selected_address = std::min(m_selected_address + 1, m_data_size - 1);
forceRefresh();
}
@ -157,7 +167,14 @@ void MemoryViewWidget::keyPressEvent(QKeyEvent* event)
expandCurrentDataToInclude(m_selected_address);
unsigned char* pdata = static_cast<unsigned char*>(m_data) + m_selected_address;
*pdata = (*pdata & ~(0xf0 >> (m_editing_nibble * 4))) | (nibble << ((1 - m_editing_nibble) * 4));
const unsigned char new_value =
(*pdata & ~(0xf0 >> (m_editing_nibble * 4))) | (nibble << ((1 - m_editing_nibble) * 4));
if (*pdata != new_value)
{
*pdata = new_value;
if (m_edit_callback)
m_edit_callback(m_selected_address, 1);
}
if (m_editing_nibble == 1)
{

View file

@ -9,16 +9,18 @@
class MemoryViewWidget : public QAbstractScrollArea
{
public:
Q_OBJECT
public:
using EditCallback = void (*)(size_t offset, size_t bytes);
MemoryViewWidget(QWidget* parent = nullptr, size_t address_offset = 0, void* data_ptr = nullptr, size_t data_size = 0,
bool data_editable = false);
bool data_editable = false, EditCallback edit_callback = nullptr);
~MemoryViewWidget();
size_t addressOffset() const { return m_address_offset; }
void setData(size_t address_offset, void* data_ptr, size_t data_size, bool data_editable);
void setData(size_t address_offset, void* data_ptr, size_t data_size, bool data_editable, EditCallback edit_callback);
void setHighlightRange(size_t start, size_t end);
void clearHighlightRange();
void scrolltoOffset(size_t offset);
@ -71,6 +73,7 @@ private:
int m_rows_visible;
EditCallback m_edit_callback = nullptr;
std::vector<u8> m_last_data;
size_t m_last_data_start_offset = 0;
};