Merge pull request #5452 from unknownbrackets/win-fixes

Clean up some Windows leaks, optimize symbol map a bit
This commit is contained in:
Henrik Rydgård 2014-02-15 09:31:37 +01:00
commit 0dd9e2dbaf
18 changed files with 117 additions and 29 deletions

View File

@ -15,6 +15,12 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
// These functions tends to be slow in debug mode.
// Comment this out if debugging the symbol map itself.
#if defined(_MSC_VER) && defined(_DEBUG)
#pragma optimize("gty", on)
#endif
#ifdef _WIN32
#include "Common/CommonWindows.h"
#include <WindowsX.h>
@ -488,13 +494,15 @@ void SymbolMap::AddFunction(const char* name, u32 address, u32 size, int moduleI
if (moduleIndex == -1) {
moduleIndex = GetModuleIndex(address);
} else if (moduleIndex == 0) {
sawUnknownModule = true;
}
// Is there an existing one?
u32 relAddress = GetModuleRelativeAddr(address, moduleIndex);
auto symbolKey = std::make_pair(moduleIndex, relAddress);
auto existing = functions.find(symbolKey);
if (existing == functions.end()) {
if (sawUnknownModule && existing == functions.end()) {
// Fall back: maybe it's got moduleIndex = 0.
existing = functions.find(std::make_pair(0, address));
}
@ -558,6 +566,15 @@ u32 SymbolMap::GetFunctionStart(u32 address) const {
return INVALID_ADDRESS;
}
u32 SymbolMap::FindPossibleFunctionAtAfter(u32 address) const {
lock_guard guard(lock_);
auto it = activeFunctions.lower_bound(address);
if (it == activeFunctions.end()) {
return (u32)-1;
}
return it->first;
}
u32 SymbolMap::GetFunctionSize(u32 startAddress) const {
lock_guard guard(lock_);
auto it = activeFunctions.find(startAddress);
@ -686,13 +703,15 @@ void SymbolMap::AddLabel(const char* name, u32 address, int moduleIndex) {
if (moduleIndex == -1) {
moduleIndex = GetModuleIndex(address);
} else if (moduleIndex == 0) {
sawUnknownModule = true;
}
// Is there an existing one?
u32 relAddress = GetModuleRelativeAddr(address, moduleIndex);
auto symbolKey = std::make_pair(moduleIndex, relAddress);
auto existing = labels.find(symbolKey);
if (existing == labels.end()) {
if (sawUnknownModule && existing == labels.end()) {
// Fall back: maybe it's got moduleIndex = 0.
existing = labels.find(std::make_pair(0, address));
}
@ -728,7 +747,7 @@ void SymbolMap::AddLabel(const char* name, u32 address, int moduleIndex) {
}
}
void SymbolMap::SetLabelName(const char* name, u32 address, bool updateImmediately) {
void SymbolMap::SetLabelName(const char* name, u32 address) {
lock_guard guard(lock_);
auto labelInfo = activeLabels.find(address);
if (labelInfo == activeLabels.end()) {
@ -740,10 +759,11 @@ void SymbolMap::SetLabelName(const char* name, u32 address, bool updateImmediate
strcpy(label->second.name,name);
label->second.name[127] = 0;
// Allow the caller to skip this as it causes extreme startup slowdown
// when this gets called for every function identified by the function replacement code.
if (updateImmediately) {
UpdateActiveSymbols();
// Refresh the active item if it exists.
auto active = activeLabels.find(address);
if (active != activeLabels.end() && active->second.module == label->second.module) {
activeLabels.erase(active);
activeLabels.insert(std::make_pair(address, label->second));
}
}
}
@ -792,13 +812,15 @@ void SymbolMap::AddData(u32 address, u32 size, DataType type, int moduleIndex) {
if (moduleIndex == -1) {
moduleIndex = GetModuleIndex(address);
} else if (moduleIndex == 0) {
sawUnknownModule = true;
}
// Is there an existing one?
u32 relAddress = GetModuleRelativeAddr(address, moduleIndex);
auto symbolKey = std::make_pair(moduleIndex, relAddress);
auto existing = data.find(symbolKey);
if (existing == data.end()) {
if (sawUnknownModule && existing == data.end()) {
// Fall back: maybe it's got moduleIndex = 0.
existing = data.find(std::make_pair(0, address));
}

View File

@ -63,7 +63,7 @@ typedef struct HWND__ *HWND;
class SymbolMap {
public:
SymbolMap() {}
SymbolMap() : sawUnknownModule(false) {}
void Clear();
void SortSymbols();
@ -95,10 +95,13 @@ public:
u32 GetFunctionSize(u32 startAddress) const;
bool SetFunctionSize(u32 startAddress, u32 newSize);
bool RemoveFunction(u32 startAddress, bool removeName);
// Search for the first address their may be a function after address.
// Only valid for currently loaded modules. Not guaranteed there will be a function.
u32 FindPossibleFunctionAtAfter(u32 address) const;
void AddLabel(const char* name, u32 address, int moduleIndex = -1);
std::string GetLabelString(u32 address) const;
void SetLabelName(const char* name, u32 address, bool updateImmediately = true);
void SetLabelName(const char* name, u32 address);
bool GetLabelValue(const char* name, u32& dest);
void AddData(u32 address, u32 size, DataType type, int moduleIndex = -1);
@ -160,6 +163,7 @@ private:
std::vector<ModuleEntry> modules;
mutable recursive_mutex lock_;
bool sawUnknownModule;
};
extern SymbolMap symbolMap;

View File

@ -385,16 +385,22 @@ skip:
bool isStraightLeaf = true;
u32 addr;
u32 addrNextSym = 0;
for (addr = startAddr; addr <= endAddr; addr += 4) {
// Use pre-existing symbol map info if available. May be more reliable.
SymbolInfo syminfo;
if (symbolMap.GetSymbolInfo(&syminfo, addr, ST_FUNCTION)) {
if (addrNextSym <= addr) {
addrNextSym = symbolMap.FindPossibleFunctionAtAfter(addr);
}
if (addrNextSym <= addr && symbolMap.GetSymbolInfo(&syminfo, addr, ST_FUNCTION)) {
addr = syminfo.address + syminfo.size - 4;
// We still need to insert the func for hashing purposes.
currentFunction.start = syminfo.address;
currentFunction.end = syminfo.address + syminfo.size - 4;
currentFunction.foundInSymbolMap = true;
functions.push_back(currentFunction);
currentFunction.foundInSymbolMap = false;
currentFunction.start = addr + 4;
furthestBranch = 0;
looking = false;
@ -485,7 +491,7 @@ skip:
for (auto iter = functions.begin(); iter != functions.end(); iter++) {
iter->size = iter->end - iter->start + 4;
if (insertSymbols) {
if (insertSymbols && !iter->foundInSymbolMap) {
char temp[256];
symbolMap.AddFunction(DefaultFunctionName(temp, iter->start), iter->start, iter->end - iter->start + 4);
}
@ -640,14 +646,12 @@ skip:
std::string existingLabel = symbolMap.GetLabelString(f.start);
char defaultLabel[256];
// If it was renamed, keep it. Only change the name if it's still the default.
if (existingLabel.empty() || !strcmp(existingLabel.c_str(), DefaultFunctionName(defaultLabel, f.start))) {
symbolMap.SetLabelName(mf->name, f.start, false);
if (existingLabel.empty() || existingLabel == DefaultFunctionName(defaultLabel, f.start)) {
symbolMap.SetLabelName(mf->name, f.start);
}
}
}
}
// Used to be called in SetLabelName, let's call it only once instead.
symbolMap.UpdateActiveSymbols();
}
void LoadHashMap(std::string filename) {

View File

@ -87,6 +87,7 @@ namespace MIPSAnalyst
bool isStraightLeaf;
bool hasHash;
bool usesVFPU;
bool foundInSymbolMap;
char name[64];
};

View File

@ -375,6 +375,11 @@ bool PSP_IsInited() {
}
void PSP_Shutdown() {
// Do nothing if we never inited.
if (!pspIsInited && !pspIsIniting) {
return;
}
#ifndef MOBILE_DEVICE
if (g_Config.bFuncHashMap) {
MIPSAnalyst::StoreHashMap();

View File

@ -590,9 +590,7 @@ void EmuScreen::render() {
// set back to running for the next frame
coreState = CORE_RUNNING;
} else if (coreState == CORE_POWERDOWN) {
if (PSP_IsInited()) {
PSP_Shutdown();
}
ILOG("SELF-POWERDOWN!");
screenManager()->switchScreen(new MainScreen());
invalid_ = true;

View File

@ -61,6 +61,7 @@ CtrlMemView::CtrlMemView(HWND _wnd)
CtrlMemView::~CtrlMemView()
{
DeleteObject(font);
DeleteObject(underlineFont);
}
void CtrlMemView::init()

View File

@ -171,7 +171,7 @@ CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu) : Di
bottomTabs->ShowTab(memHandle);
// init status bar
statusBarWnd = CreateStatusWindow(WS_CHILD | WS_VISIBLE, L"", m_hDlg, IDC_DISASMSTATUSBAR);
statusBarWnd = CreateWindowEx(0, STATUSCLASSNAME, L"", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, m_hDlg, (HMENU)IDC_DISASMSTATUSBAR, _hInstance, NULL);
if (g_Config.bDisplayStatusBar == false)
{
ShowWindow(statusBarWnd,SW_HIDE);
@ -187,6 +187,14 @@ CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu) : Di
CDisasm::~CDisasm()
{
DestroyWindow(statusBarWnd);
delete leftTabs;
delete bottomTabs;
delete breakpointList;
delete threadList;
delete stackTraceView;
delete moduleList;
}
void CDisasm::stepInto()

View File

@ -78,6 +78,9 @@ LRESULT CALLBACK CtrlDisplayListView::wndProc(HWND hwnd, UINT msg, WPARAM wParam
// Continue with window creation.
return win != NULL;
case WM_NCDESTROY:
delete win;
break;
case WM_SIZE:
win->redraw();
break;

View File

@ -39,6 +39,10 @@ public:
static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
static CtrlDisplayListView * getFrom(HWND wnd);
HWND GetHWND() {
return wnd;
}
void onPaint(WPARAM wParam, LPARAM lParam);
void onKeyDown(WPARAM wParam, LPARAM lParam);
void onMouseDown(WPARAM wParam, LPARAM lParam, int button);

View File

@ -123,6 +123,7 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent)
}
CGEDebugger::~CGEDebugger() {
DestroyWindow(displayList->GetHWND());
CleanupPrimPreview();
delete flags;
delete lighting;

View File

@ -1,5 +1,6 @@
#include "Common/CommonWindows.h"
#include <vector>
#include <algorithm>
#include "Windows/W32Util/DialogManager.h"
@ -68,6 +69,11 @@ void DialogManager::AddDlg(Dialog *dialog)
dialogs.push_back(dialog);
}
void DialogManager::RemoveDlg(Dialog *dialog)
{
dialogs.erase(std::remove(dialogs.begin(), dialogs.end(), dialog), dialogs.end());
}
bool DialogManager::IsDialogMessage(LPMSG message)
{

View File

@ -37,6 +37,7 @@ class DialogManager
{
public:
static void AddDlg(Dialog *dialog);
static void RemoveDlg(Dialog *dialog);
static bool IsDialogMessage(LPMSG message);
static void EnableAll(BOOL enable);
static void DestroyAll();

View File

@ -138,6 +138,10 @@ namespace W32Util
thread_->detach();
}
AsyncBrowseDialog::~AsyncBrowseDialog() {
delete thread_;
}
bool AsyncBrowseDialog::GetResult(std::string &filename) {
filename = filename_;
return result_;

View File

@ -28,6 +28,8 @@ namespace W32Util
// For a file (OPEN or SAVE.)
AsyncBrowseDialog(Type type, HWND parent, UINT completeMsg, std::wstring title, std::wstring initialFolder, std::wstring filter, std::wstring extension);
~AsyncBrowseDialog();
bool GetResult(std::string &filename);
Type GetType() {
return type_;

View File

@ -828,6 +828,23 @@ namespace MainWindow
DialogManager::AddDlg(memoryWindow[0]);
}
void DestroyDebugWindows() {
DialogManager::RemoveDlg(disasmWindow[0]);
if (disasmWindow[0])
delete disasmWindow[0];
disasmWindow[0] = 0;
DialogManager::RemoveDlg(geDebuggerWindow);
if (geDebuggerWindow)
delete geDebuggerWindow;
geDebuggerWindow = 0;
DialogManager::RemoveDlg(memoryWindow[0]);
if (memoryWindow[0])
delete memoryWindow[0];
memoryWindow[0] = 0;
}
void BrowseAndBoot(std::string defaultPath, bool browseDirectory) {
static std::wstring filter = L"All supported file types (*.iso *.cso *.pbp *.elf *.prx *.zip)|*.pbp;*.elf;*.iso;*.cso;*.prx;*.zip|PSP ROMs (*.iso *.cso *.pbp *.elf *.prx)|*.pbp;*.elf;*.iso;*.cso;*.prx|Homebrew/Demos installers (*.zip)|*.zip|All files (*.*)|*.*||";
for (int i = 0; i < (int)filter.length(); i++) {
@ -1334,14 +1351,17 @@ namespace MainWindow
break;
case ID_DEBUG_DISASSEMBLY:
if (disasmWindow[0])
disasmWindow[0]->Show(true);
break;
case ID_DEBUG_GEDEBUGGER:
if (geDebuggerWindow)
geDebuggerWindow->Show(true);
break;
case ID_DEBUG_MEMORYVIEW:
if (memoryWindow[0])
memoryWindow[0]->Show(true);
break;
@ -1549,9 +1569,12 @@ namespace MainWindow
break;
case WM_USER + 1:
if (disasmWindow[0])
disasmWindow[0]->NotifyMapLoaded();
if (memoryWindow[0])
memoryWindow[0]->NotifyMapLoaded();
if (disasmWindow[0])
disasmWindow[0]->UpdateDialog();
SetForegroundWindow(hwndMain);

View File

@ -51,6 +51,7 @@ namespace MainWindow
void Init(HINSTANCE hInstance);
BOOL Show(HINSTANCE hInstance, int nCmdShow);
void CreateDebugWindows();
void DestroyDebugWindows();
void Close();
void UpdateMenus();
void UpdateCommands();

View File

@ -343,7 +343,6 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
CtrlRegisterList::init();
CGEDebugger::Init();
DialogManager::AddDlg(memoryWindow[0] = new CMemoryDlg(_hInstance, hwndMain, currentDebugMIPS));
DialogManager::AddDlg(vfpudlg = new CVFPUDlg(_hInstance, hwndMain, currentDebugMIPS));
host = new WindowsHost(hwndMain, hwndDisplay);
@ -380,7 +379,7 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
accel = hAccelTable;
break;
case WINDOW_CPUDEBUGGER:
wnd = disasmWindow[0]->GetDlgHandle();
wnd = disasmWindow[0] ? disasmWindow[0]->GetDlgHandle() : 0;
accel = hDebugAccelTable;
break;
case WINDOW_GEDEBUGGER:
@ -405,6 +404,7 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
EmuThread_Stop();
MainWindow::DestroyDebugWindows();
DialogManager::DestroyAll();
timeEndPeriod(1);
delete host;