EightBit/M6502/src/Profiler.cpp

86 lines
2.2 KiB
C++

#include "stdafx.h"
#include "Profiler.h"
#include "Disassembly.h"
#include "Symbols.h"
EightBit::Profiler::Profiler(MOS6502& targetProcessor, Disassembly& disassemblerTarget, Symbols& symbolsTarget)
: processor(targetProcessor),
disassembler(disassemblerTarget),
symbols(symbolsTarget) {
instructionCounts.fill(0);
addressProfiles.fill(0);
addressCounts.fill(0);
BuildAddressScopes();
}
void EightBit::Profiler::Generate() {
StartingOutput.fire(EventArgs::empty());
EmitProfileInformation();
StartingOutput.fire(EventArgs::empty());
}
void EightBit::Profiler::EmitProfileInformation() {
{
StartingLineOutput.fire(EventArgs::empty());
// For each memory address
for (int address = 0; address < 0x10000; ++address) {
// If there are any cycles associated
auto cycles = addressProfiles[address];
if (cycles > 0) {
// Dump a profile/disassembly line
auto source = disassembler.disassemble(address);
ProfileLineEventArgs event(source, cycles);
EmitLine.fire(event);
}
}
FinishedLineOutput.fire(EventArgs::empty());
}
{
StartingScopeOutput.fire(EventArgs::empty());
for (auto& scopeCycle : scopeCycles) {
auto name = scopeCycle.first;
auto cycles = scopeCycle.second;
auto namedAddress = (size_t)symbols.addresses().find(name)->second;
auto count = addressCounts[namedAddress];
ProfileScopeEventArgs event(name, cycles, count);
EmitScope.fire(event);
}
FinishedScopeOutput.fire(EventArgs::empty());
}
}
void EightBit::Profiler::addInstruction(uint8_t instruction) {
++instructionCounts[instruction];
}
void EightBit::Profiler::addAddress(uint16_t address, int cycles) {
addressCounts[address]++;
addressProfiles[address] += cycles;
auto addressScope = addressScopes[address];
if (!addressScope.empty()) {
if (scopeCycles.find(addressScope) == scopeCycles.end())
scopeCycles[addressScope] = 0;
scopeCycles[addressScope] += cycles;
}
}
void EightBit::Profiler::BuildAddressScopes() {
for (auto& label : symbols.labels()) {
auto address = label.first;
auto key = label.second;
auto scope = symbols.scopes().find(key);
if (scope != symbols.scopes().end()) {
for (uint16_t i = address; i < address + scope->second; ++i) {
addressScopes[i] = key;
}
}
}
}