mirror of https://github.com/PCSX2/pcsx2.git
Debugger: Cache hash match results on symbol tree nodes
This commit is contained in:
parent
2c3abe33d5
commit
f963291970
|
@ -106,8 +106,8 @@ QVariant SymbolTreeModel::data(const QModelIndex& index, int role) const
|
|||
bool active = true;
|
||||
|
||||
// Gray out the names of symbols that have been overwritten in memory.
|
||||
if (index.column() == NAME && node->symbol.valid())
|
||||
active = symbolMatchesMemory(node->symbol);
|
||||
if (index.column() == NAME)
|
||||
active = node->matchesMemory();
|
||||
|
||||
// Gray out the values of variables that are dead.
|
||||
if (index.column() == VALUE && node->liveness().has_value())
|
||||
|
@ -521,80 +521,3 @@ bool SymbolTreeModel::nodeHasChildren(const ccc::ast::Node& logical_type, const
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SymbolTreeModel::symbolMatchesMemory(ccc::MultiSymbolHandle& symbol) const
|
||||
{
|
||||
bool matching = true;
|
||||
switch (symbol.descriptor())
|
||||
{
|
||||
case ccc::SymbolDescriptor::FUNCTION:
|
||||
{
|
||||
m_cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) -> void {
|
||||
const ccc::Function* function = database.functions.symbol_from_handle(symbol.handle());
|
||||
if (!function || function->original_hash() == 0)
|
||||
return;
|
||||
|
||||
matching = function->current_hash() == function->original_hash();
|
||||
});
|
||||
break;
|
||||
}
|
||||
case ccc::SymbolDescriptor::GLOBAL_VARIABLE:
|
||||
{
|
||||
m_cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) -> void {
|
||||
const ccc::GlobalVariable* global_variable = database.global_variables.symbol_from_handle(symbol.handle());
|
||||
if (!global_variable)
|
||||
return;
|
||||
|
||||
const ccc::SourceFile* source_file = database.source_files.symbol_from_handle(global_variable->source_file());
|
||||
if (!source_file)
|
||||
return;
|
||||
|
||||
matching = source_file->functions_match();
|
||||
});
|
||||
break;
|
||||
}
|
||||
case ccc::SymbolDescriptor::LOCAL_VARIABLE:
|
||||
{
|
||||
m_cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) -> void {
|
||||
const ccc::LocalVariable* local_variable = database.local_variables.symbol_from_handle(symbol.handle());
|
||||
if (!local_variable)
|
||||
return;
|
||||
|
||||
const ccc::Function* function = database.functions.symbol_from_handle(local_variable->function());
|
||||
if (!function)
|
||||
return;
|
||||
|
||||
const ccc::SourceFile* source_file = database.source_files.symbol_from_handle(function->source_file());
|
||||
if (!source_file)
|
||||
return;
|
||||
|
||||
matching = source_file->functions_match();
|
||||
});
|
||||
break;
|
||||
}
|
||||
case ccc::SymbolDescriptor::PARAMETER_VARIABLE:
|
||||
{
|
||||
m_cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) -> void {
|
||||
const ccc::ParameterVariable* parameter_variable = database.parameter_variables.symbol_from_handle(symbol.handle());
|
||||
if (!parameter_variable)
|
||||
return;
|
||||
|
||||
const ccc::Function* function = database.functions.symbol_from_handle(parameter_variable->function());
|
||||
if (!function)
|
||||
return;
|
||||
|
||||
const ccc::SourceFile* source_file = database.source_files.symbol_from_handle(function->source_file());
|
||||
if (!source_file)
|
||||
return;
|
||||
|
||||
matching = source_file->functions_match();
|
||||
});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return matching;
|
||||
}
|
||||
|
|
|
@ -76,8 +76,6 @@ protected:
|
|||
|
||||
static bool nodeHasChildren(const ccc::ast::Node& logical_type, const ccc::SymbolDatabase& database);
|
||||
|
||||
bool symbolMatchesMemory(ccc::MultiSymbolHandle& symbol) const;
|
||||
|
||||
std::unique_ptr<SymbolTreeNode> m_root;
|
||||
QString m_filter;
|
||||
DebugInterface& m_cpu;
|
||||
|
|
|
@ -41,6 +41,7 @@ bool SymbolTreeNode::readFromVM(DebugInterface& cpu, const ccc::SymbolDatabase&
|
|||
|
||||
data_changed |= updateDisplayString(cpu, database);
|
||||
data_changed |= updateLiveness(cpu);
|
||||
data_changed |= updateHash(cpu);
|
||||
|
||||
return data_changed;
|
||||
}
|
||||
|
@ -478,6 +479,94 @@ bool SymbolTreeNode::updateLiveness(DebugInterface& cpu)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SymbolTreeNode::updateHash(DebugInterface& cpu)
|
||||
{
|
||||
bool matching = true;
|
||||
|
||||
switch (symbol.descriptor())
|
||||
{
|
||||
case ccc::SymbolDescriptor::FUNCTION:
|
||||
{
|
||||
cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) -> void {
|
||||
const ccc::Function* function = database.functions.symbol_from_handle(symbol.handle());
|
||||
if (!function || function->original_hash() == 0)
|
||||
return;
|
||||
|
||||
matching = function->current_hash() == function->original_hash();
|
||||
});
|
||||
break;
|
||||
}
|
||||
case ccc::SymbolDescriptor::GLOBAL_VARIABLE:
|
||||
{
|
||||
cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) -> void {
|
||||
const ccc::GlobalVariable* global_variable = database.global_variables.symbol_from_handle(symbol.handle());
|
||||
if (!global_variable)
|
||||
return;
|
||||
|
||||
const ccc::SourceFile* source_file = database.source_files.symbol_from_handle(global_variable->source_file());
|
||||
if (!source_file)
|
||||
return;
|
||||
|
||||
matching = source_file->functions_match();
|
||||
});
|
||||
break;
|
||||
}
|
||||
case ccc::SymbolDescriptor::LOCAL_VARIABLE:
|
||||
{
|
||||
cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) -> void {
|
||||
const ccc::LocalVariable* local_variable = database.local_variables.symbol_from_handle(symbol.handle());
|
||||
if (!local_variable)
|
||||
return;
|
||||
|
||||
const ccc::Function* function = database.functions.symbol_from_handle(local_variable->function());
|
||||
if (!function)
|
||||
return;
|
||||
|
||||
const ccc::SourceFile* source_file = database.source_files.symbol_from_handle(function->source_file());
|
||||
if (!source_file)
|
||||
return;
|
||||
|
||||
matching = source_file->functions_match();
|
||||
});
|
||||
break;
|
||||
}
|
||||
case ccc::SymbolDescriptor::PARAMETER_VARIABLE:
|
||||
{
|
||||
cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) -> void {
|
||||
const ccc::ParameterVariable* parameter_variable = database.parameter_variables.symbol_from_handle(symbol.handle());
|
||||
if (!parameter_variable)
|
||||
return;
|
||||
|
||||
const ccc::Function* function = database.functions.symbol_from_handle(parameter_variable->function());
|
||||
if (!function)
|
||||
return;
|
||||
|
||||
const ccc::SourceFile* source_file = database.source_files.symbol_from_handle(function->source_file());
|
||||
if (!source_file)
|
||||
return;
|
||||
|
||||
matching = source_file->functions_match();
|
||||
});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (matching == m_matches_memory)
|
||||
return false;
|
||||
|
||||
m_matches_memory = matching;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SymbolTreeNode::matchesMemory() const
|
||||
{
|
||||
return m_matches_memory;
|
||||
}
|
||||
|
||||
bool SymbolTreeNode::anySymbolsValid(const ccc::SymbolDatabase& database) const
|
||||
{
|
||||
if (symbol.lookup_symbol(database))
|
||||
|
|
|
@ -62,6 +62,9 @@ public:
|
|||
|
||||
bool updateLiveness(DebugInterface& cpu);
|
||||
|
||||
bool updateHash(DebugInterface& cpu);
|
||||
bool matchesMemory() const;
|
||||
|
||||
bool anySymbolsValid(const ccc::SymbolDatabase& database) const;
|
||||
|
||||
const SymbolTreeNode* parent() const;
|
||||
|
@ -79,6 +82,7 @@ protected:
|
|||
QVariant m_value;
|
||||
QString m_display_value;
|
||||
std::optional<bool> m_liveness;
|
||||
bool m_matches_memory = true;
|
||||
|
||||
SymbolTreeNode* m_parent = nullptr;
|
||||
std::vector<std::unique_ptr<SymbolTreeNode>> m_children;
|
||||
|
|
Loading…
Reference in New Issue