mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-24 14:00:03 +00:00
Merge pull request #5452 from unknownbrackets/win-fixes
Clean up some Windows leaks, optimize symbol map a bit
This commit is contained in:
commit
0dd9e2dbaf
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -87,6 +87,7 @@ namespace MIPSAnalyst
|
||||
bool isStraightLeaf;
|
||||
bool hasHash;
|
||||
bool usesVFPU;
|
||||
bool foundInSymbolMap;
|
||||
char name[64];
|
||||
};
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
PSP_Shutdown();
|
||||
ILOG("SELF-POWERDOWN!");
|
||||
screenManager()->switchScreen(new MainScreen());
|
||||
invalid_ = true;
|
||||
|
@ -60,7 +60,8 @@ CtrlMemView::CtrlMemView(HWND _wnd)
|
||||
|
||||
CtrlMemView::~CtrlMemView()
|
||||
{
|
||||
DeleteObject(font);
|
||||
DeleteObject(font);
|
||||
DeleteObject(underlineFont);
|
||||
}
|
||||
|
||||
void CtrlMemView::init()
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -123,6 +123,7 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent)
|
||||
}
|
||||
|
||||
CGEDebugger::~CGEDebugger() {
|
||||
DestroyWindow(displayList->GetHWND());
|
||||
CleanupPrimPreview();
|
||||
delete flags;
|
||||
delete lighting;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -138,6 +138,10 @@ namespace W32Util
|
||||
thread_->detach();
|
||||
}
|
||||
|
||||
AsyncBrowseDialog::~AsyncBrowseDialog() {
|
||||
delete thread_;
|
||||
}
|
||||
|
||||
bool AsyncBrowseDialog::GetResult(std::string &filename) {
|
||||
filename = filename_;
|
||||
return result_;
|
||||
|
@ -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_;
|
||||
|
@ -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,15 +1351,18 @@ namespace MainWindow
|
||||
break;
|
||||
|
||||
case ID_DEBUG_DISASSEMBLY:
|
||||
disasmWindow[0]->Show(true);
|
||||
if (disasmWindow[0])
|
||||
disasmWindow[0]->Show(true);
|
||||
break;
|
||||
|
||||
case ID_DEBUG_GEDEBUGGER:
|
||||
geDebuggerWindow->Show(true);
|
||||
if (geDebuggerWindow)
|
||||
geDebuggerWindow->Show(true);
|
||||
break;
|
||||
|
||||
case ID_DEBUG_MEMORYVIEW:
|
||||
memoryWindow[0]->Show(true);
|
||||
if (memoryWindow[0])
|
||||
memoryWindow[0]->Show(true);
|
||||
break;
|
||||
|
||||
case ID_DEBUG_EXTRACTFILE:
|
||||
@ -1549,10 +1569,13 @@ namespace MainWindow
|
||||
break;
|
||||
|
||||
case WM_USER + 1:
|
||||
disasmWindow[0]->NotifyMapLoaded();
|
||||
memoryWindow[0]->NotifyMapLoaded();
|
||||
if (disasmWindow[0])
|
||||
disasmWindow[0]->NotifyMapLoaded();
|
||||
if (memoryWindow[0])
|
||||
memoryWindow[0]->NotifyMapLoaded();
|
||||
|
||||
disasmWindow[0]->UpdateDialog();
|
||||
if (disasmWindow[0])
|
||||
disasmWindow[0]->UpdateDialog();
|
||||
|
||||
SetForegroundWindow(hwndMain);
|
||||
break;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user