Optimized Symbolic Debug for speed (so Trace Logger has less overhead when Symbolic Trace is on)

This commit is contained in:
ansstuff 2013-09-19 20:51:41 +00:00
parent e59e6d35d6
commit 0e2422f90a
6 changed files with 140 additions and 186 deletions

View File

@ -77,9 +77,9 @@ bool debuggerDisplayROMoffsets = false;
char debug_str[35000] = {0};
char debug_cdl_str[500] = {0};
char* debug_decoration_name;
char* debug_decoration_comment;
char debug_str_decoration_comment[NL_MAX_MULTILINE_COMMENT_LEN + 10] = {0};
char* debug_decoration_comment;
char* debug_decoration_comment_end_pos;
// this is used to keep track of addresses that lines of Disassembly window correspond to
std::vector<unsigned int> disassembly_addresses;
@ -422,39 +422,40 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr)
if (symbDebugEnabled)
{
// Insert Name and Comment lines if needed
debug_decoration_name = 0;
debug_decoration_comment = 0;
decorateAddress(addr, &debug_decoration_name, &debug_decoration_comment);
if (debug_decoration_name)
// insert Name and Comment lines if needed
Name* node = findNode(getNamesPointerForAddress(addr), addr);
if (node)
{
strcat(debug_str, debug_decoration_name);
strcat(debug_str, ": \r\n");
// we added one line to the disassembly window
disassembly_addresses.push_back(addr);
i++;
}
if (debug_decoration_comment)
{
// make a copy
strcpy(debug_str_decoration_comment, debug_decoration_comment);
strcat(debug_str_decoration_comment, "\r\n");
debug_decoration_comment = debug_str_decoration_comment;
// divide the debug_str_decoration_comment into strings (Comment1, Comment2, ...)
char* end_pos = strstr(debug_decoration_comment, "\r\n");
while (end_pos)
if (node->name)
{
end_pos[0] = 0; // set \0 instead of \r
strcat(debug_str, "; ");
strcat(debug_str, debug_decoration_comment);
strcat(debug_str, "\r\n");
strcat(debug_str, node->name);
strcat(debug_str, ":\r\n");
// we added one line to the disassembly window
disassembly_addresses.push_back(addr);
i++;
}
if (node->comment)
{
// make a copy
strcpy(debug_str_decoration_comment, node->comment);
strcat(debug_str_decoration_comment, "\r\n");
// divide the debug_str_decoration_comment into strings (Comment1, Comment2, ...)
debug_decoration_comment = debug_str_decoration_comment;
debug_decoration_comment_end_pos = strstr(debug_decoration_comment, "\r\n");
while (debug_decoration_comment_end_pos)
{
debug_decoration_comment_end_pos[0] = 0; // set \0 instead of \r
strcat(debug_str, "; ");
strcat(debug_str, debug_decoration_comment);
strcat(debug_str, "\r\n");
// we added one line to the disassembly window
disassembly_addresses.push_back(addr);
i++;
end_pos += 2;
debug_decoration_comment = end_pos;
end_pos = strstr(end_pos, "\r\n");
debug_decoration_comment_end_pos += 2;
debug_decoration_comment = debug_decoration_comment_end_pos;
debug_decoration_comment_end_pos = strstr(debug_decoration_comment_end_pos, "\r\n");
}
}
}
}

View File

@ -59,45 +59,6 @@ int isHex(char c)
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
}
/**
* Replaces all occurences of a substring in a string with a new string.
* The maximum size of the string after replacing is 1000.
* The caller must ensure that the src buffer is large enough.
*
* @param src Source string
* @param r String to replace
* @param w New string
**/
void replaceString(char* src, const char* r, const char* w)
{
static char buff[1001];
buff[0] = 0;
char* pos = src;
char* beg = src;
// Check parameters
if (!src || !r || !w)
{
MessageBox(0, "Error: Invalid parameter in function replaceString", "Error", MB_OK | MB_ICONERROR);
return;
}
// Replace sub strings
while ((pos = strstr(src, r)))
{
*pos = 0;
strcat(buff, src);
strcat(buff, w ? w : r);
src = pos + strlen(r);
}
strcat(buff, src);
strcpy(beg, buff);
}
/**
* Parses a line from a NL file.
* @param line The line to parse
@ -282,6 +243,7 @@ Name* parse(char* lines, const char* filename)
// Allocate a name structure to hold the parsed data from the next line
cur = (Name*)malloc(sizeof(Name));
cur->offsetNumeric = 0;
cur->offset = 0;
cur->next = 0;
cur->name = 0;
@ -375,8 +337,9 @@ Name* parse(char* lines, const char* filename)
nn->comment = strdup(cur->comment);
// The offset of the node
nn->offset = (char*)malloc(10);
nn->offset = (char*)malloc(6);
sprintf(nn->offset, "$%04X", offset + i);
nn->offsetNumeric = offset + i;
// The name of an array address is of the form NAME[INDEX]
sprintf(numbuff, "[%X]", i);
@ -390,8 +353,7 @@ Name* parse(char* lines, const char* filename)
{
prev->next = nn;
prev = prev->next;
}
else
} else
{
first = prev = nn;
}
@ -411,9 +373,9 @@ Name* parse(char* lines, const char* filename)
// offset and array size has already been validated in parseLine
continue;
}
}
else
} else
{
sscanf(cur->offset, "%*[$]%4X", &(cur->offsetNumeric));
// Add the node to the list of address nodes
if (prev)
{
@ -504,22 +466,34 @@ void freeList(Name* n)
**/
void replaceNames(Name* list, char* str)
{
Name* beg = list;
static char buff[1001];
char* pos;
char* src;
if (!str)
while (list)
{
MessageBox(0, "Error: Invalid parameter \"str\" in function replaceNames", "Error", MB_OK | MB_ICONERROR);
return;
}
while (beg)
{
if (beg->name)
if (list->name)
{
replaceString(str, beg->offset, beg->name);
// find and replace substrings
*buff = 0;
src = str;
while ((pos = strstr(src, list->offset)))
{
*pos = 0;
strcat(buff, src);
strcat(buff, list->name);
src = pos + 5; // 5 = strlen(beg->offset), because all offsets are in "$XXXX" format
}
// if any offsets were changed, replace str by buff
if (*buff)
{
strcat(buff, src);
// replace whole str
strcpy(str, buff);
}
}
beg = beg->next;
list = list->next;
}
}
@ -531,22 +505,31 @@ void replaceNames(Name* list, char* str)
* @offs The offset to search
* @return The node that has the given offset or 0.
**/
Name* searchNode(Name* node, const char* offs)
Name* findNode(Name* node, const char* offset)
{
while (node)
{
if (!strcmp(node->offset, offs))
{
if (!strcmp(node->offset, offset))
return node;
node = node->next;
}
return 0;
}
// same, but with offsetNumeric
Name* findNode(Name* node, uint16 offsetNumeric)
{
while (node)
{
if (node->offsetNumeric == offsetNumeric)
return node;
}
node = node->next;
}
return 0;
}
char* generateNLFilenameForAddress(unsigned int address)
char* generateNLFilenameForAddress(uint16 address)
{
if (address < 0x8000)
{
@ -559,7 +542,7 @@ char* generateNLFilenameForAddress(unsigned int address)
}
return NLfilename;
}
Name* getNamesPointerForAddress(unsigned int address)
Name* getNamesPointerForAddress(uint16 address)
{
if (address < 0x8000)
{
@ -572,7 +555,7 @@ Name* getNamesPointerForAddress(unsigned int address)
return lastBankNames;
}
}
void setNamesPointerForAddress(unsigned int address, Name* newNode)
void setNamesPointerForAddress(uint16 address, Name* newNode)
{
if (address < 0x8000)
{
@ -644,37 +627,6 @@ void loadNameFiles()
}
}
/**
* Returns pointers to name and comment to an offset in the disassembly output string
*
**/
void decorateAddress(unsigned int addr, char** str_name, char** str_comment)
{
Name* n;
sprintf(temp_chr, "$%04X", addr);
if (addr < 0x8000)
{
// Search address definition node for a RAM address
n = searchNode(ramBankNames, temp_chr);
} else
{
// Search address definition node for a ROM address
n = (addr >= 0xC000) ? searchNode(lastBankNames, temp_chr) : searchNode(loadedBankNames, temp_chr);
}
if (n)
{
// Return pointer to name
if (n->name && *n->name)
*str_name = n->name;
// Return pointer to comment
if (n->comment && *n->comment)
*str_comment = n->comment;
}
}
// bookmarks
std::vector<unsigned int> bookmarks_addr;
std::vector<std::string> bookmarks_name;
@ -850,17 +802,16 @@ BOOL CALLBACK SymbolicNamingCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
// offset
sprintf(temp_chr, "$%04X", newAddress);
SetDlgItemText(hwndDlg, IDC_SYMBOLIC_ADDRESS, temp_chr);
char* oldName = 0;
char* oldComment = 0;
decorateAddress(newAddress, &oldName, &oldComment);
// name
SendDlgItemMessage(hwndDlg, IDC_SYMBOLIC_NAME, EM_SETLIMITTEXT, NL_MAX_NAME_LEN, 0);
if (oldName && oldName[0])
SetDlgItemText(hwndDlg, IDC_SYMBOLIC_NAME, oldName);
// comment
SendDlgItemMessage(hwndDlg, IDC_SYMBOLIC_COMMENT, EM_SETLIMITTEXT, NL_MAX_MULTILINE_COMMENT_LEN, 0);
if (oldComment && oldComment[0])
SetDlgItemText(hwndDlg, IDC_SYMBOLIC_COMMENT, oldComment);
Name* node = findNode(getNamesPointerForAddress(newAddress), newAddress);
if (node)
{
SendDlgItemMessage(hwndDlg, IDC_SYMBOLIC_NAME, EM_SETLIMITTEXT, NL_MAX_NAME_LEN, 0);
if (node->name && node->name[0])
SetDlgItemText(hwndDlg, IDC_SYMBOLIC_NAME, node->name);
SendDlgItemMessage(hwndDlg, IDC_SYMBOLIC_COMMENT, EM_SETLIMITTEXT, NL_MAX_MULTILINE_COMMENT_LEN, 0);
if (node->comment && node->comment[0])
SetDlgItemText(hwndDlg, IDC_SYMBOLIC_COMMENT, node->comment);
}
// set focus to IDC_SYMBOLIC_NAME
SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_SYMBOLIC_NAME), true);
break;
@ -920,7 +871,7 @@ bool DoSymbolicDebugNaming(int offset, HWND parentHWND)
return false;
}
void AddNewSymbolicName(unsigned int newAddress, char* newOffset, char* newName, char* newComment)
void AddNewSymbolicName(uint16 newAddress, char* newOffset, char* newName, char* newComment)
{
Name* initialNode = getNamesPointerForAddress(newAddress);
Name* node = initialNode;
@ -945,7 +896,7 @@ void AddNewSymbolicName(unsigned int newAddress, char* newOffset, char* newName,
break;
}
if (newName[0])
if (*newName)
{
if (!initialNode)
{
@ -953,6 +904,7 @@ void AddNewSymbolicName(unsigned int newAddress, char* newOffset, char* newName,
node = (Name*)malloc(sizeof(Name));
node->offset = (char*)malloc(strlen(newOffset) + 1);
strcpy(node->offset, newOffset);
node->offsetNumeric = newAddress;
node->name = (char*)malloc(strlen(newName) + 1);
strcpy(node->name, newName);
node->comment = (char*)malloc(strlen(newComment) + 1);
@ -964,7 +916,7 @@ void AddNewSymbolicName(unsigned int newAddress, char* newOffset, char* newName,
// search the list
while (node)
{
if (!strcmp(node->offset, newOffset))
if (node->offsetNumeric == newAddress)
{
// found matching address - replace its name and comment
free(node->name);
@ -985,6 +937,7 @@ void AddNewSymbolicName(unsigned int newAddress, char* newOffset, char* newName,
node->next = newNode;
newNode->offset = (char*)malloc(strlen(newOffset) + 1);
strcpy(newNode->offset, newOffset);
newNode->offsetNumeric = newAddress;
newNode->name = (char*)malloc(strlen(newName) + 1);
strcpy(newNode->name, newName);
newNode->comment = (char*)malloc(strlen(newComment) + 1);
@ -1000,7 +953,7 @@ void AddNewSymbolicName(unsigned int newAddress, char* newOffset, char* newName,
Name* previousNode = 0;
while (node)
{
if (!strcmp(node->offset, newOffset))
if (node->offsetNumeric == newAddress)
{
// found matching address - delete it
free(node->offset);

View File

@ -27,6 +27,7 @@
struct Name
{
Name* next;
uint16 offsetNumeric;
char* offset;
char* name;
char* comment;
@ -38,11 +39,14 @@ extern std::vector<std::string> bookmarks_name;
extern int debuggerWasActive;
int checkCondition(const char* buffer, int num);
char* generateNLFilenameForAddress(unsigned int address);
Name* getNamesPointerForAddress(unsigned int address);
void setNamesPointerForAddress(unsigned int address, Name* newNode);
Name* findNode(Name* node, const char* offset);
Name* findNode(Name* node, uint16 offsetNumeric);
char* generateNLFilenameForAddress(uint16 address);
Name* getNamesPointerForAddress(uint16 address);
void setNamesPointerForAddress(uint16 address, Name* newNode);
void loadNameFiles();
void decorateAddress(unsigned int addr, char** str_name, char** str_comment);
void replaceNames(Name* list, char* str);
void AddDebuggerBookmark(HWND hwnd);
void AddDebuggerBookmark2(HWND hwnd, unsigned int addr);
@ -55,5 +59,5 @@ void GoToDebuggerBookmark(HWND hwnd);
int isHex(char c);
bool DoSymbolicDebugNaming(int offset, HWND parentHWND);
void AddNewSymbolicName(unsigned int newAddress, char* newOffset, char* newName, char* newComment);
void AddNewSymbolicName(uint16 newAddress, char* newOffset, char* newName, char* newComment);
void WriteNameFileToDisk(const char* filename, Name* node);

View File

@ -613,8 +613,6 @@ char EditString[3][20] = {"RAM","PPU","ROM"};
void UpdateCaption()
{
static char str[1000];
static char addrName[500];
static char addrNameCopy[500];
if (CursorEndAddy == -1)
{
@ -633,17 +631,12 @@ void UpdateCaption()
if (EditingMode == MODE_NES_MEMORY && symbDebugEnabled)
{
// when watching RAM we may as well see symbolic names
sprintf(addrName, "$%04X", CursorStartAddy);
strcpy(addrNameCopy, addrName);
// try to find the name for this address in loadedBankNames
replaceNames(getNamesPointerForAddress(CursorStartAddy), addrName);
// check if anything chenged in this string
if (strcmp(addrName, addrNameCopy))
// when watching RAM we may as well see Symbolic Debug names
Name* node = findNode(getNamesPointerForAddress(CursorStartAddy), CursorStartAddy);
if (node)
{
// changes found, so the string was decorated by symbolic name - then output it
strcat(str, " - ");
strcat(str, addrName);
strcat(str, node->name);
}
}
} else

View File

@ -75,10 +75,10 @@ char str_axystate[LOG_AXYSTATE_MAX_LEN] = {0}, str_procstatus[LOG_PROCSTATUS_MAX
char str_tabs[LOG_TABS_MASK+1] = {0}, str_address[LOG_ADDRESS_MAX_LEN] = {0}, str_data[LOG_DATA_MAX_LEN] = {0}, str_disassembly[LOG_DISASSEMBLY_MAX_LEN] = {0};
char str_result[LOG_LINE_MAX_LEN] = {0};
char str_temp[LOG_LINE_MAX_LEN] = {0};
char* tracer_decoration_name;
char* tracer_decoration_comment;
char str_decoration[NL_MAX_MULTILINE_COMMENT_LEN + 10] = {0};
char str_decoration_comment[NL_MAX_MULTILINE_COMMENT_LEN + 10] = {0};
char* tracer_decoration_comment;
char* tracer_decoration_comment_end_pos;
bool log_old_emu_paused = true; // thanks to this flag the window only updates once after the game is paused
extern bool JustFrameAdvanced;
@ -568,39 +568,41 @@ void FCEUD_TraceInstruction(uint8 *opcode, int size)
if (logging_options & LOG_SYMBOLIC)
{
// Insert Name and Comment lines if needed
tracer_decoration_name = 0;
tracer_decoration_comment = 0;
decorateAddress(addr, &tracer_decoration_name, &tracer_decoration_comment);
if (tracer_decoration_name)
Name* node = findNode(getNamesPointerForAddress(addr), addr);
if (node)
{
strcpy(str_decoration, tracer_decoration_name);
strcat(str_decoration, ": ");
OutputLogLine(str_decoration, true);
}
if (tracer_decoration_comment)
{
// make a copy
strcpy(str_decoration_comment, tracer_decoration_comment);
strcat(str_decoration_comment, "\r\n");
tracer_decoration_comment = str_decoration_comment;
// divide the str_decoration_comment into strings (Comment1, Comment2, ...)
char* end_pos = strstr(tracer_decoration_comment, "\r\n");
while (end_pos)
if (node->name)
{
end_pos[0] = 0; // set \0 instead of \r
strcpy(str_decoration, "; ");
strcat(str_decoration, tracer_decoration_comment);
strcpy(str_decoration, node->name);
strcat(str_decoration, ":");
OutputLogLine(str_decoration, true);
end_pos += 2;
tracer_decoration_comment = end_pos;
end_pos = strstr(end_pos, "\r\n");
}
if (node->comment)
{
// make a copy
strcpy(str_decoration_comment, node->comment);
strcat(str_decoration_comment, "\r\n");
tracer_decoration_comment = str_decoration_comment;
// divide the str_decoration_comment into strings (Comment1, Comment2, ...)
char* tracer_decoration_comment_end_pos = strstr(tracer_decoration_comment, "\r\n");
while (tracer_decoration_comment_end_pos)
{
tracer_decoration_comment_end_pos[0] = 0; // set \0 instead of \r
strcpy(str_decoration, "; ");
strcat(str_decoration, tracer_decoration_comment);
OutputLogLine(str_decoration, true);
tracer_decoration_comment_end_pos += 2;
tracer_decoration_comment = tracer_decoration_comment_end_pos;
tracer_decoration_comment_end_pos = strstr(tracer_decoration_comment_end_pos, "\r\n");
}
}
}
replaceNames(ramBankNames, a);
replaceNames(loadedBankNames, a);
replaceNames(lastBankNames, a);
}
strcpy(str_disassembly, a);
strncpy(str_disassembly, a, LOG_DISASSEMBLY_MAX_LEN);
str_disassembly[LOG_DISASSEMBLY_MAX_LEN - 1] = 0;
}
}

View File

@ -1272,11 +1272,12 @@ static int memory_readbytesigned(lua_State *L) {
static int GetWord(lua_State *L, bool isSigned)
{
uint16 addressLow = luaL_checkinteger(L,1);
uint16 addressHigh = addressLow + 1; // little endian
if (lua_type(L,2) == LUA_TNUMBER)
addressHigh = luaL_checkinteger(L,2);
uint32 result = FCEU_CheatGetByte(addressLow) + (FCEU_CheatGetByte(addressHigh) << 8);
// little endian, unless the high byte address is specified as a 2nd parameter
uint16 addressLow = luaL_checkinteger(L, 1);
uint16 addressHigh = addressLow + 1;
if (lua_type(L, 2) == LUA_TNUMBER)
addressHigh = luaL_checkinteger(L, 2);
uint16 result = FCEU_CheatGetByte(addressLow) | (FCEU_CheatGetByte(addressHigh) << 8);
return isSigned ? (int16)result : result;
}