Cleanup the breakpoint code a bit, fix updating the breakpoint window when clicking in the bp column in the code view.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1607 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2008-12-20 14:00:33 +00:00
parent 66853d6f1b
commit 01598750b9
12 changed files with 157 additions and 165 deletions

View File

@ -269,7 +269,7 @@ bool CBoot::BootUp(const SCoreStartupParameter& _StartupPara)
Boot_ELF(_StartupPara.m_strFilename.c_str());
UpdateDebugger_MapLoaded();
CBreakPoints::AddAutoBreakpoints();
BreakPoints::AddAutoBreakpoints();
}
break;

View File

@ -31,14 +31,9 @@
#include "../PowerPC/Jit64/Jit.h"
#include "Debugger_BreakPoints.h"
CBreakPoints::TBreakPoints CBreakPoints::m_BreakPoints;
CBreakPoints::TMemChecks CBreakPoints::m_MemChecks;
u32 CBreakPoints::m_iBreakOnCount = 0;
BreakPoints::TBreakPoints BreakPoints::m_BreakPoints;
TMemCheck::TMemCheck()
{
numHits = 0;
}
MemChecks::TMemChecks MemChecks::m_MemChecks;
void TMemCheck::Action(u32 iValue, u32 addr, bool write, int size, u32 pc)
{
@ -57,7 +52,7 @@ void TMemCheck::Action(u32 iValue, u32 addr, bool write, int size, u32 pc)
}
}
bool CBreakPoints::IsAddressBreakPoint(u32 _iAddress)
bool BreakPoints::IsAddressBreakPoint(u32 _iAddress)
{
std::vector<TBreakPoint>::iterator iter;
@ -68,7 +63,7 @@ bool CBreakPoints::IsAddressBreakPoint(u32 _iAddress)
return false;
}
bool CBreakPoints::IsTempBreakPoint(u32 _iAddress)
bool BreakPoints::IsTempBreakPoint(u32 _iAddress)
{
std::vector<TBreakPoint>::iterator iter;
@ -79,7 +74,82 @@ bool CBreakPoints::IsTempBreakPoint(u32 _iAddress)
return false;
}
TMemCheck *CBreakPoints::GetMemCheck(u32 address)
void BreakPoints::Add(u32 em_address, bool temp)
{
if (!IsAddressBreakPoint(em_address)) // only add new addresses
{
TBreakPoint pt; // breakpoint settings
pt.bOn = true;
pt.bTemporary = temp;
pt.iAddress = em_address;
m_BreakPoints.push_back(pt);
// jit.NotifyBreakpoint(em_address, true);
}
}
void BreakPoints::Remove(u32 _iAddress)
{
std::vector<TBreakPoint>::iterator iter;
for (iter = m_BreakPoints.begin(); iter != m_BreakPoints.end(); ++iter)
{
if ((*iter).iAddress == _iAddress)
{
m_BreakPoints.erase(iter);
// jit.NotifyBreakpoint(em_address, false);
break;
}
}
}
void BreakPoints::Clear()
{
m_BreakPoints.clear();
Host_UpdateBreakPointView();
}
void BreakPoints::AddAutoBreakpoints()
{
#if defined(_DEBUG) || defined(DEBUGFAST)
#if 1
const char *bps[] = {
"PPCHalt",
};
for (int i = 0; i < sizeof(bps) / sizeof(const char *); i++)
{
Symbol *symbol = g_symbolDB.GetSymbolFromName(bps[i]);
if (symbol)
AddBreakPoint(symbol->address, false);
}
#endif
#endif
}
void BreakPoints::DeleteByAddress(u32 _Address)
{
// first check breakpoints
{
std::vector<TBreakPoint>::iterator iter;
for (iter = m_BreakPoints.begin(); iter != m_BreakPoints.end(); ++iter)
{
if ((*iter).iAddress == _Address)
{
m_BreakPoints.erase(iter);
return;
}
}
}
}
void MemChecks::Add(const TMemCheck& _rMemoryCheck)
{
m_MemChecks.push_back(_rMemoryCheck);
}
TMemCheck *MemChecks::GetMemCheck(u32 address)
{
std::vector<TMemCheck>::iterator iter;
for (iter = m_MemChecks.begin(); iter != m_MemChecks.end(); ++iter)
@ -100,89 +170,13 @@ TMemCheck *CBreakPoints::GetMemCheck(u32 address)
return 0;
}
void CBreakPoints::AddBreakPoint(u32 em_address, bool temp)
void MemChecks::Clear()
{
if (!IsAddressBreakPoint(em_address)) // only add new addresses
{
TBreakPoint pt; // breakpoint settings
pt.bOn = true;
pt.bTemporary = temp;
pt.iAddress = em_address;
m_BreakPoints.push_back(pt);
// jit.NotifyBreakpoint(em_address, true);
}
}
void CBreakPoints::RemoveBreakPoint(u32 _iAddress)
{
std::vector<TBreakPoint>::iterator iter;
for (iter = m_BreakPoints.begin(); iter != m_BreakPoints.end(); ++iter)
{
if ((*iter).iAddress == _iAddress)
{
m_BreakPoints.erase(iter);
// jit.NotifyBreakpoint(em_address, false);
break;
}
}
}
void CBreakPoints::ClearAllBreakPoints()
{
m_BreakPoints.clear();
m_MemChecks.clear();
Host_UpdateBreakPointView();
}
// update breakpoint window
void CBreakPoints::UpdateBreakPointView()
void MemChecks::DeleteByAddress(u32 _Address)
{
Host_UpdateBreakPointView();
}
void CBreakPoints::AddMemoryCheck(const TMemCheck& _rMemoryCheck)
{
m_MemChecks.push_back(_rMemoryCheck);
}
void CBreakPoints::AddAutoBreakpoints()
{
#if defined(_DEBUG) || defined(DEBUGFAST)
#if 1
const char *bps[] = {
"PPCHalt",
};
for (int i = 0; i < sizeof(bps) / sizeof(const char *); i++)
{
Symbol *symbol = g_symbolDB.GetSymbolFromName(bps[i]);
if (symbol)
AddBreakPoint(symbol->address, false);
}
Host_UpdateBreakPointView();
#endif
#endif
}
void CBreakPoints::DeleteElementByAddress(u32 _Address)
{
// first check breakpoints
{
std::vector<TBreakPoint>::iterator iter;
for (iter = m_BreakPoints.begin(); iter != m_BreakPoints.end(); ++iter)
{
if ((*iter).iAddress == _Address)
{
m_BreakPoints.erase(iter);
Host_UpdateBreakPointView();
return;
}
}
}
// second memory check checkpoint
std::vector<TMemCheck>::iterator iter;
for (iter = m_MemChecks.begin(); iter != m_MemChecks.end(); ++iter)
{

View File

@ -32,7 +32,9 @@ struct TBreakPoint
struct TMemCheck
{
TMemCheck();
TMemCheck() {
numHits = 0;
}
u32 StartAddress;
u32 EndAddress;
@ -49,51 +51,51 @@ struct TMemCheck
void Action(u32 _iValue, u32 addr, bool write, int size, u32 pc);
};
class CBreakPoints
// Code breakpoints.
class BreakPoints
{
public:
typedef std::vector<TBreakPoint> TBreakPoints;
typedef std::vector<TMemCheck> TMemChecks;
static const TBreakPoints& GetBreakPoints() { return m_BreakPoints; }
static const TMemChecks& GetMemChecks() { return m_MemChecks; }
// is address breakpoint
static bool IsAddressBreakPoint(u32 _iAddress);
//memory breakpoint
static TMemCheck *GetMemCheck(u32 address);
// is break on count
static void SetBreakCount(u32 count) { m_iBreakOnCount = count; }
static u32 GetBreakCount() { return m_iBreakOnCount; }
static bool IsTempBreakPoint(u32 _iAddress);
// AddBreakPoint
static void AddBreakPoint(u32 em_address, bool temp=false);
static void Add(u32 em_address, bool temp=false);
// Remove Breakpoint
static void RemoveBreakPoint(u32 _iAddress);
static void Remove(u32 _iAddress);
static void Clear();
static void AddMemoryCheck(const TMemCheck& _rMemoryCheck);
static void ClearAllBreakPoints();
static void UpdateBreakPointView();
static void AddAutoBreakpoints();
static void DeleteElementByAddress(u32 _Address);
static void DeleteByAddress(u32 _Address);
private:
static TBreakPoints m_BreakPoints;
static TMemChecks m_MemChecks;
static u32 m_iBreakOnCount;
};
// Memory breakpoints
class MemChecks
{
public:
typedef std::vector<TMemCheck> TMemChecks;
static TMemChecks m_MemChecks;
static const TMemChecks& GetMemChecks() { return m_MemChecks; }
static void Add(const TMemCheck& _rMemoryCheck);
//memory breakpoint
static TMemCheck *GetMemCheck(u32 address);
static void DeleteByAddress(u32 _Address);
void Clear();
};
#endif

View File

@ -81,24 +81,27 @@ bool PPCDebugInterface::isAlive()
bool PPCDebugInterface::isBreakpoint(unsigned int address)
{
return CBreakPoints::IsAddressBreakPoint(address);
return BreakPoints::IsAddressBreakPoint(address);
}
void PPCDebugInterface::setBreakpoint(unsigned int address)
{
CBreakPoints::AddBreakPoint(address);
BreakPoints::Add(address);
}
void PPCDebugInterface::clearBreakpoint(unsigned int address)
{
CBreakPoints::RemoveBreakPoint(address);
BreakPoints::Remove(address);
}
void PPCDebugInterface::clearAllBreakpoints() {}
void PPCDebugInterface::toggleBreakpoint(unsigned int address)
{
CBreakPoints::IsAddressBreakPoint(address) ? CBreakPoints::RemoveBreakPoint(address) : CBreakPoints::AddBreakPoint(address);
if (BreakPoints::IsAddressBreakPoint(address))
BreakPoints::Remove(address);
else
BreakPoints::Add(address);
}
void PPCDebugInterface::insertBLR(unsigned int address)

View File

@ -115,7 +115,7 @@ void PatchFunctions()
Symbol *symbol = g_symbolDB.GetSymbolFromName(OSPatches[i].m_szPatchName);
if (symbol > 0)
{
CBreakPoints::AddBreakPoint(symbol->address, false);
BreakPoints::Add(symbol->address, false);
LOG(HLE,"Adding BP to %s %08x", OSBreakPoints[i].m_szPatchName, symbol->address);
}
}

View File

@ -69,19 +69,19 @@ void CCPU::Run()
}*/
//2: check for breakpoint
if (CBreakPoints::IsAddressBreakPoint(PC))
if (BreakPoints::IsAddressBreakPoint(PC))
{
LOG(GEKKO, "Hit Breakpoint - %08x", PC);
EnableStepping(true);
if (CBreakPoints::IsTempBreakPoint(PC))
CBreakPoints::RemoveBreakPoint(PC);
if (BreakPoints::IsTempBreakPoint(PC))
BreakPoints::Remove(PC);
Host_UpdateDisasmDialog();
break;
}
/* if (!Core::g_CoreStartupParameter.bUseJIT && CBreakPoints::GetBreakCount() == PowerPC::ppcState.DebugCount)
/* if (!Core::g_CoreStartupParameter.bUseJIT && BreakPoints::GetBreakCount() == PowerPC::ppcState.DebugCount)
{
LOG(GEKKO, "Hit DebugCount breakpoint - %i", PowerPC::ppcState.DebugCount);
EnableStepping(true);
@ -183,19 +183,12 @@ void CCPU::SingleStep()
}
//2: check for breakpoint
if (CBreakPoints::IsAddressBreakPoint(PC))
if (BreakPoints::IsAddressBreakPoint(PC))
{
LOG(GEKKO, "Hit Breakpoint - %08x", PC);
EnableStepping(true);
if (CBreakPoints::IsTempBreakPoint(PC))
CBreakPoints::RemoveBreakPoint(PC);
break;
}
if (!Core::g_CoreStartupParameter.bUseJIT && CBreakPoints::GetBreakCount() == PowerPC::ppcState.DebugCount)
{
LOG(GEKKO, "Hit DebugCount breakpoint - %i", PowerPC::ppcState.DebugCount);
EnableStepping(true);
if (BreakPoints::IsTempBreakPoint(PC))
BreakPoints::Remove(PC);
break;
}

View File

@ -25,6 +25,7 @@
#include "../../Core.h"
#include "../../PatchEngine.h"
#include "../../CoreTiming.h"
#include "../../Debugger/Debugger_Breakpoints.h"
#include "../PowerPC.h"
#include "../Profiler.h"
#include "../PPCTables.h"
@ -42,15 +43,14 @@ using namespace PowerPC;
extern int blocksExecuted;
// Dolphin's PowerPC->x86 JIT dynamic recompiler
// All code by ector (hrydgard)
// (Nearly) all code by ector (hrydgard)
// Features:
// * x86 & x64 support, lots of shared code.
// * Basic block linking
// * Fast dispatcher
// Unfeatures:
// * Does not recompile all instructions. Often falls back to inserting a CALL to the corresponding JIT function.
// * Does not recompile all instructions - sometimes falls back to inserting a CALL to the corresponding JIT function.
// Various notes below
@ -74,22 +74,22 @@ extern int blocksExecuted;
// This can even be seen in one homebrew Wii demo - RayTracer.elf
// Other considerations
//Many instructions have shorter forms for EAX. However, I believe their performance boost
//will be as small to be negligble, so I haven't dirtied up the code with that. AMD recommends it in their
//optimization manuals, though.
//
// Many instructions have shorter forms for EAX. However, I believe their performance boost
// will be as small to be negligble, so I haven't dirtied up the code with that. AMD recommends it in their
// optimization manuals, though.
//
// We support block linking. Reserve space at the exits of every block for a full 5-byte jmp. Save 16-bit offsets
// from the starts of each block, marking the exits so that they can be nicely patched at any time.
// * Blocks do NOT use call/ret, they only jmp to each other and to the dispatcher when necessary.
//
// Blocks do NOT use call/ret, they only jmp to each other and to the dispatcher when necessary.
//
// All blocks that can be precompiled will be precompiled. Code will be memory protected - any write will mark
// the region as non-compilable, and all links to the page will be torn out and replaced with dispatcher jmps.
//
// Alternatively, icbi instruction SHOULD mark where we can't compile
// Seldom-happening events will be handled by adding a decrement of a counter to all blr instructions (which are
//
// Seldom-happening events is handled by adding a decrement of a counter to all blr instructions (which are
// expensive anyway since we need to return to dispatcher, except when they can be predicted).
// TODO: SERIOUS synchronization problem with the video plugin setting tokens and breakpoints in dual core mode!!!
@ -114,10 +114,6 @@ extern int blocksExecuted;
R5-R12 are volatile -> dropped on blr.
* classic inlining across calls.
Metroid wants
subc
subfe
Low hanging fruit:
stfd -- guaranteed in memory
cmpl
@ -381,7 +377,6 @@ namespace CPUCompare
//Analyze the block, collect all instructions it is made of (including inlining,
//if that is enabled), reorder instructions for optimal performance, and join joinable instructions.
PPCAnalyst::Flatten(em_address, &size, &js.st, &js.gpa, &js.fpa, &code_buffer);
PPCAnalyst::CodeOp *ops = code_buffer.codebuffer;

View File

@ -17,6 +17,7 @@
#include "BreakPointDlg.h"
#include "Common.h"
#include "Host.h"
#include "Debugger.h"
#include "StringUtil.h"
#include "Debugger/Debugger_BreakPoints.h"
@ -76,8 +77,8 @@ void BreakPointDlg::OnOK(wxCommandEvent& /*event*/)
u32 Address = 0;
if (AsciiToHex(AddressString.mb_str(), Address))
{
CBreakPoints::AddBreakPoint(Address);
CBreakPoints::UpdateBreakPointView();
BreakPoints::Add(Address);
Host_UpdateBreakPointView();
Close();
}
}

View File

@ -47,7 +47,7 @@ void CBreakPointView::Update()
InsertColumn(4, wxT("Flags"), wxLIST_FORMAT_CENTER, 100);
char szBuffer[64];
const CBreakPoints::TBreakPoints& rBreakPoints = CBreakPoints::GetBreakPoints();
const BreakPoints::TBreakPoints& rBreakPoints = BreakPoints::GetBreakPoints();
for (size_t i = 0; i < rBreakPoints.size(); i++)
{
const TBreakPoint& rBP = rBreakPoints[i];
@ -74,7 +74,7 @@ void CBreakPointView::Update()
}
}
const CBreakPoints::TMemChecks& rMemChecks = CBreakPoints::GetMemChecks();
const MemChecks::TMemChecks& rMemChecks = MemChecks::GetMemChecks();
for (size_t i = 0; i < rMemChecks.size(); i++)
{
const TMemCheck& rMemCheck = rMemChecks[i];
@ -106,7 +106,6 @@ void CBreakPointView::Update()
SetItemData(Item, rMemCheck.StartAddress);
}
Refresh();
}
@ -116,6 +115,8 @@ void CBreakPointView::DeleteCurrentSelection()
if (Item >= 0)
{
u32 Address = (u32)GetItemData(Item);
CBreakPoints::DeleteElementByAddress(Address);
BreakPoints::DeleteByAddress(Address);
MemChecks::DeleteByAddress(Address);
Update();
}
}

View File

@ -22,6 +22,7 @@
#include "HW/Memmap.h"
#include "BreakPointDlg.h"
#include "MemoryCheckDlg.h"
#include "Host.h"
#include "IniFile.h"
#include "Debugger/Debugger_BreakPoints.h" // for TMemCheck
@ -205,7 +206,7 @@ CBreakPointWindow::OnDelete(wxCommandEvent& event)
void
CBreakPointWindow::OnClear(wxCommandEvent& event)
{
CBreakPoints::ClearAllBreakPoints();
BreakPoints::Clear();
}
// ============
@ -244,11 +245,11 @@ CBreakPointWindow::OnAddBreakPointMany(wxCommandEvent& event)
u32 Address = 0;
if (AsciiToHex(line.c_str(), Address))
{
CBreakPoints::AddBreakPoint(Address);
BreakPoints::Add(Address);
}
}
// only update after we are done with the loop
CBreakPoints::UpdateBreakPointView();
Host_UpdateBreakPointView();
}
else
{
@ -338,7 +339,7 @@ CBreakPointWindow::OnAddMemoryCheckMany(wxCommandEvent& event)
MemCheck.Break = true;
}
if(doCommon)
if (doCommon)
{
// settings for the memory check
MemCheck.OnRead = true;
@ -346,11 +347,11 @@ CBreakPointWindow::OnAddMemoryCheckMany(wxCommandEvent& event)
MemCheck.Log = true;
//MemCheck.Break = false; // this is also what sets Active "on" in the breakpoint window
// so don't think it's off because we are only writing this to the log
CBreakPoints::AddMemoryCheck(MemCheck);
MemChecks::Add(MemCheck);
}
}
// update after we are done with the loop
CBreakPoints::UpdateBreakPointView();
Host_UpdateBreakPointView();
}
else
{

View File

@ -119,6 +119,7 @@ void CCodeView::OnMouseDown(wxMouseEvent& event)
{
debugger->toggleBreakpoint(YToAddress(y));
redraw();
Host_UpdateBreakPointView();
}
event.Skip(true);

View File

@ -19,6 +19,7 @@
#include "Common.h"
#include "Debugger.h"
#include "StringUtil.h"
#include "Host.h"
#include "Debugger/Debugger_BreakPoints.h"
BEGIN_EVENT_TABLE(MemoryCheckDlg,wxDialog)
@ -100,8 +101,8 @@ void MemoryCheckDlg::OnOK(wxCommandEvent& /*event*/)
MemCheck.Log = true;
MemCheck.Break = true;
CBreakPoints::AddMemoryCheck(MemCheck);
CBreakPoints::UpdateBreakPointView();
MemChecks::Add(MemCheck);
Host_UpdateBreakPointView();
Close();
}
}