mirror of
https://github.com/Vita3K/Vita3K-Android.git
synced 2025-02-26 08:15:30 +00:00
Memory allocation viewer (#375)
* Added an allocation viewer * Removed header comment for ui_allocations_dialogue I forgot to turn those off! Sorry. * Fix imgui_club submodule * Allocation viewer style fixes * Add extra whitespace
This commit is contained in:
parent
61b5f51730
commit
c068bf28f6
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -52,3 +52,6 @@
|
||||
[submodule "src/external/dlmalloc"]
|
||||
path = src/external/dlmalloc
|
||||
url = https://github.com/Vita3K/dlmalloc
|
||||
[submodule "src/external/imgui_club"]
|
||||
path = src/external/imgui_club
|
||||
url = https://github.com/ocornut/imgui_club.git
|
||||
|
@ -64,7 +64,7 @@ static bool is_thumb_mode(uc_engine *uc) {
|
||||
|
||||
static void code_hook(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) {
|
||||
CPUState &state = *static_cast<CPUState *>(user_data);
|
||||
const MemState &mem = *state.mem;
|
||||
MemState &mem = *state.mem;
|
||||
const uint8_t *const code = Ptr<const uint8_t>(static_cast<Address>(address)).get(mem);
|
||||
const size_t buffer_size = GB(4) - address;
|
||||
const bool thumb = is_thumb_mode(uc);
|
||||
@ -72,7 +72,7 @@ static void code_hook(uc_engine *uc, uint64_t address, uint32_t size, void *user
|
||||
LOG_TRACE("{}: {} {}", log_hex((uint64_t)uc), log_hex(address), disassembly);
|
||||
}
|
||||
|
||||
static void log_memory_access(uc_engine *uc, const char *type, Address address, int size, int64_t value, const MemState &mem) {
|
||||
static void log_memory_access(uc_engine *uc, const char *type, Address address, int size, int64_t value, MemState &mem) {
|
||||
const char *const name = mem_name(address, mem);
|
||||
LOG_TRACE("{}: {} {} bytes, address {} ( {} ), value {}", log_hex((uint64_t)uc), type, size, log_hex(address), name, log_hex(value));
|
||||
}
|
||||
@ -80,15 +80,15 @@ static void log_memory_access(uc_engine *uc, const char *type, Address address,
|
||||
static void read_hook(uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data) {
|
||||
assert(value == 0);
|
||||
|
||||
const CPUState &state = *static_cast<const CPUState *>(user_data);
|
||||
const MemState &mem = *state.mem;
|
||||
CPUState &state = *static_cast<CPUState *>(user_data);
|
||||
MemState &mem = *state.mem;
|
||||
memcpy(&value, Ptr<const void>(static_cast<Address>(address)).get(mem), size);
|
||||
log_memory_access(uc, "Read", static_cast<Address>(address), size, value, mem);
|
||||
}
|
||||
|
||||
static void write_hook(uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data) {
|
||||
const CPUState &state = *static_cast<const CPUState *>(user_data);
|
||||
const MemState &mem = *state.mem;
|
||||
CPUState &state = *static_cast<CPUState *>(user_data);
|
||||
MemState &mem = *state.mem;
|
||||
log_memory_access(uc, "Write", static_cast<Address>(address), size, value, mem);
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ src/ui_mutexes_dialog.cpp
|
||||
src/ui_semaphores_dialog.cpp
|
||||
src/ui_threads_dialog.cpp
|
||||
src/ui_controls_dialog.cpp
|
||||
src/ui_allocations_dialog.cpp
|
||||
)
|
||||
|
||||
target_include_directories(gui PUBLIC include)
|
||||
|
@ -39,6 +39,7 @@ void DrawLwMutexesDialog(HostState &host);
|
||||
void DrawLwCondvarsDialog(HostState &host);
|
||||
void DrawCondvarsDialog(HostState &host);
|
||||
void DrawEventFlagsDialog(HostState &host);
|
||||
void DrawAllocationsDialog(HostState &host);
|
||||
void DrawUI(HostState &host);
|
||||
void DrawCommonDialog(HostState &host);
|
||||
void DrawGameSelector(HostState &host, AppRunType *run_type);
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <dialog/state.h>
|
||||
|
||||
struct ImFont;
|
||||
struct MemoryEditor;
|
||||
|
||||
enum SelectorState {
|
||||
SELECT_APP
|
||||
@ -47,6 +48,7 @@ struct GuiState {
|
||||
bool mutexes_dialog = false;
|
||||
bool lwmutexes_dialog = false;
|
||||
bool eventflags_dialog = false;
|
||||
bool allocations_dialog = false;
|
||||
|
||||
// Optimisation menu
|
||||
bool texture_cache = true;
|
||||
@ -56,6 +58,8 @@ struct GuiState {
|
||||
|
||||
DialogState common_dialog;
|
||||
GamesSelector game_selector;
|
||||
MemoryEditor *memory_editor;
|
||||
size_t memory_editor_start, memory_editor_count;
|
||||
|
||||
// imgui
|
||||
ImFont *normal_font{};
|
||||
|
58
src/emulator/gui/src/ui_allocations_dialog.cpp
Normal file
58
src/emulator/gui/src/ui_allocations_dialog.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include <gui/functions.h>
|
||||
#include <gui/gui_constants.h>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <imgui_memory_editor.h>
|
||||
|
||||
#include <host/state.h>
|
||||
|
||||
#include <spdlog/fmt/fmt.h>
|
||||
|
||||
void DrawAllocationsDialog(HostState &host) {
|
||||
ImGui::Begin("Memory Allocations", &host.gui.allocations_dialog);
|
||||
|
||||
const std::lock_guard<std::mutex> lock(host.mem.generation_mutex);
|
||||
for (const auto &pair : host.mem.generation_names) {
|
||||
if (ImGui::TreeNode(fmt::format("{}: {}", pair.first, pair.second).c_str())) {
|
||||
long index = -1, count = 1;
|
||||
|
||||
for (long a = 0; a < host.mem.allocated_pages.size(); a++) {
|
||||
if (index != -1) {
|
||||
if (host.mem.allocated_pages[a] != pair.first) break;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (index == -1 && host.mem.allocated_pages[a] == pair.first) {
|
||||
index = a;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
ImGui::Text("Generation no longer exists.");
|
||||
} else {
|
||||
ImGui::Text("Range %08lx - %08lx.", index * KB(4), (index + count) * KB(4));
|
||||
ImGui::Text("Size: %li KB (%li page[s])", count * 4l, count);
|
||||
if (index != 0) {
|
||||
if (ImGui::Selectable("View/Edit")) {
|
||||
host.gui.memory_editor_start = index * KB(4);
|
||||
host.gui.memory_editor_count = count * KB(4);
|
||||
if (!host.gui.memory_editor) host.gui.memory_editor = new MemoryEditor;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
if (host.gui.memory_editor) {
|
||||
if (host.gui.memory_editor->Open) {
|
||||
host.gui.memory_editor->DrawWindow("Editor", host.mem.memory.get() + host.gui.memory_editor_start,
|
||||
host.gui.memory_editor_count, host.gui.memory_editor_start);
|
||||
} else {
|
||||
delete host.gui.memory_editor;
|
||||
host.gui.memory_editor = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
@ -116,5 +116,8 @@ void DrawUI(HostState &host) {
|
||||
if (host.gui.controls_dialog) {
|
||||
DrawControlsDialog(host);
|
||||
}
|
||||
if (host.gui.allocations_dialog) {
|
||||
DrawAllocationsDialog(host);
|
||||
}
|
||||
ImGui::PopFont();
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ void DrawMainMenuBar(HostState &host) {
|
||||
ImGui::MenuItem("Condition Variables", nullptr, &host.gui.condvars_dialog);
|
||||
ImGui::MenuItem("Lightweight Condition Variables", nullptr, &host.gui.lwcondvars_dialog);
|
||||
ImGui::MenuItem("Event Flags", nullptr, &host.gui.eventflags_dialog);
|
||||
ImGui::MenuItem("Memory Allocations", nullptr, &host.gui.allocations_dialog);
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -34,6 +35,7 @@ struct MemState {
|
||||
Generation generation = 0;
|
||||
Memory memory;
|
||||
Allocated allocated_pages;
|
||||
std::mutex generation_mutex;
|
||||
GenerationNames generation_names;
|
||||
};
|
||||
|
||||
@ -54,4 +56,4 @@ Address alloc(MemState &state, size_t size, const char *name);
|
||||
Address alloc_at(MemState &state, Address address, size_t size, const char *name);
|
||||
void free(MemState &state, Address address);
|
||||
uint32_t mem_available(MemState &state);
|
||||
const char *mem_name(Address address, const MemState &state);
|
||||
const char *mem_name(Address address, MemState &state);
|
||||
|
@ -48,6 +48,8 @@ static void alloc_inner(MemState &state, Address address, size_t page_count, All
|
||||
|
||||
const Generation generation = ++state.generation;
|
||||
std::fill_n(block, page_count, generation);
|
||||
|
||||
const std::lock_guard<std::mutex> lock(state.generation_mutex);
|
||||
state.generation_names[generation] = name;
|
||||
|
||||
#ifdef WIN32
|
||||
@ -159,7 +161,7 @@ uint32_t mem_available(MemState &state) {
|
||||
return address;
|
||||
}
|
||||
|
||||
const char *mem_name(Address address, const MemState &state) {
|
||||
const char *mem_name(Address address, MemState &state) {
|
||||
const size_t page = address / state.page_size;
|
||||
assert(page >= 0);
|
||||
assert(page < state.allocated_pages.size());
|
||||
@ -169,6 +171,7 @@ const char *mem_name(Address address, const MemState &state) {
|
||||
return "UNALLOCATED";
|
||||
}
|
||||
|
||||
const std::lock_guard<std::mutex> lock(state.generation_mutex);
|
||||
const GenerationNames::const_iterator found = state.generation_names.find(generation);
|
||||
assert(found != state.generation_names.end());
|
||||
if (found == state.generation_names.end()) {
|
||||
|
4
src/external/CMakeLists.txt
vendored
4
src/external/CMakeLists.txt
vendored
@ -64,8 +64,10 @@ target_include_directories(microprofile PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/micr
|
||||
set_property(TARGET microprofile PROPERTY CXX_STANDARD 11)
|
||||
target_compile_definitions(microprofile PUBLIC MICROPROFILE_ENABLED=0 MICROPROFILE_GPU_TIMERS=0)
|
||||
|
||||
# The imgui target is including both imgui and imgui_club.
|
||||
add_library(imgui STATIC imgui/imgui.cpp imgui/imgui_draw.cpp imgui/imgui_widgets.cpp)
|
||||
target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/imgui")
|
||||
target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/imgui"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/imgui_club/imgui_memory_editor/")
|
||||
|
||||
add_library(miniz STATIC miniz/miniz.c miniz/miniz.h)
|
||||
target_include_directories(miniz PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/miniz")
|
||||
|
1
src/external/imgui_club
vendored
Submodule
1
src/external/imgui_club
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 378e32ac92aa120512ee1aeb90522c9214e9b694
|
Loading…
x
Reference in New Issue
Block a user