Skip to content

Commit

Permalink
Add optional instruction level profiling
Browse files Browse the repository at this point in the history
  • Loading branch information
dedmen committed Jan 23, 2019
1 parent 53a46a5 commit 83848ad
Showing 1 changed file with 111 additions and 57 deletions.
168 changes: 111 additions & 57 deletions src/scriptProfiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ using namespace std::chrono_literals;
static sqf_script_type GameDataProfileScope_type;
std::shared_ptr<ProfilerAdapter> GProfilerAdapter; //Needs to be above!! profiler
scriptProfiler profiler{};

bool instructionLevelProfiling = false;

class GameDataProfileScope : public game_data {

Expand Down Expand Up @@ -581,7 +581,7 @@ game_value callExtensionRedirect(uintptr_t st, game_value_parameter ext, game_va
}


std::string getCommandLineParam(std::string_view needle) {
std::optional<std::string> getCommandLineParam(std::string_view needle) {
std::string commandLine = GetCommandLineA();
auto found = commandLine.find(needle);
if (found != std::string::npos) {
Expand All @@ -597,21 +597,26 @@ std::string getCommandLineParam(std::string_view needle) {

scriptProfiler::scriptProfiler() {
std::string commandLine = GetCommandLineA();

if (getCommandLineParam("-profilerEnableInstruction"sv)) {
instructionLevelProfiling = true;
}

auto startAdapter = getCommandLineParam("-profilerAdapter"sv);

if (!startAdapter.empty()) {
if (startAdapter == "Chrome"sv) {
if (startAdapter) {
if (*startAdapter == "Chrome"sv) {
auto chromeAdapter = std::make_shared<AdapterChrome>();
GProfilerAdapter = chromeAdapter;

auto chromeOutput = getCommandLineParam("-profilerOutput"sv);
if (!chromeOutput.empty())
chromeAdapter->setTargetFile(chromeOutput);
} else if (startAdapter == "Brofiler"sv) {
if (chromeOutput)
chromeAdapter->setTargetFile(*chromeOutput);
} else if (*startAdapter == "Brofiler"sv) {
GProfilerAdapter = std::make_shared<AdapterBrofiler>();
} else if (startAdapter == "Arma"sv) {
} else if (*startAdapter == "Arma"sv) {
GProfilerAdapter = std::make_shared<AdapterArmaDiag>();
} else if (startAdapter == "Tracy"sv) {
} else if (*startAdapter == "Tracy"sv) {
GProfilerAdapter = std::make_shared<AdapterTracy>();
}
} else {
Expand Down Expand Up @@ -719,15 +724,27 @@ namespace intercept::__internal {
class GameInstructionVariable : public game_instruction {
public:
r_string name;
static inline std::unordered_map<size_t, std::shared_ptr<ScopeInfo>> descriptions;
virtual bool exec(game_state& state, vm_context& t) {
//static const r_string InstrName = "I_Variable"sv;
//static Brofiler::EventDescription* autogenerated_description = ::Brofiler::EventDescription::Create(InstrName, __FILE__, __LINE__);
//Brofiler::Event autogenerated_event_639(*autogenerated_description);
//
//if (autogenerated_event_639.data)
// autogenerated_event_639.data->altName = name;

typedef bool(__thiscall *OrigEx)(game_instruction*, game_state&, vm_context&);

if (instructionLevelProfiling) {
static r_string setVar("getVar");

auto found = descriptions.find(reinterpret_cast<size_t>(name.data()));
if (found == descriptions.end()) {

auto newStuff = GProfilerAdapter->createScope(setVar,name,0);
auto ret = descriptions.insert({reinterpret_cast<size_t>(name.data()), newStuff});
found = ret.first;
}

auto temp = GProfilerAdapter->enterScope(found->second);
auto res = reinterpret_cast<OrigEx>(oldFunc.vt_GameInstructionVariable)(this, state, t);
GProfilerAdapter->leaveScope(temp);
return res;
}

return reinterpret_cast<OrigEx>(oldFunc.vt_GameInstructionVariable)(this, state, t);
}
virtual int stack_size(void* t) const { return 0; }
Expand All @@ -738,7 +755,7 @@ class GameInstructionOperator : public game_instruction {
public:
const intercept::__internal::game_operators *_operators;

//static inline std::map<size_t, Brofiler::EventDescription*> descriptions;
static inline std::unordered_map<size_t, std::shared_ptr<ScopeInfo>> descriptions;

virtual bool exec(game_state& state, vm_context& t) {
/*
Expand Down Expand Up @@ -772,7 +789,26 @@ class GameInstructionOperator : public game_instruction {
}
*/

typedef bool(__thiscall *OrigEx)(game_instruction*, game_state&, vm_context&);

if (instructionLevelProfiling) {
auto instructionName = _operators->_name;

auto found = descriptions.find(reinterpret_cast<size_t>(instructionName.data()));
if (found == descriptions.end()) {

auto newStuff = GProfilerAdapter->createScope(instructionName,{},0);
auto ret = descriptions.insert({reinterpret_cast<size_t>(instructionName.data()), newStuff});
found = ret.first;
}

auto temp = GProfilerAdapter->enterScope(found->second);
auto res = reinterpret_cast<OrigEx>(oldFunc.vt_GameInstructionOperator)(this, state, t);
GProfilerAdapter->leaveScope(temp);
return res;
}

return reinterpret_cast<OrigEx>(oldFunc.vt_GameInstructionOperator)(this, state, t);
}
virtual int stack_size(void* t) const { return 0; }
Expand All @@ -783,23 +819,29 @@ class GameInstructionFunction : public game_instruction {
public:
const intercept::__internal::game_functions *_functions;

//static inline std::map<const char*, Brofiler::EventDescription*> descriptions;
static inline std::unordered_map<size_t, std::shared_ptr<ScopeInfo>> descriptions;

virtual bool exec(game_state& state, vm_context& t) {
//auto found = descriptions.find(_functions->_name.data());
//if (found == descriptions.end()) {
// found = descriptions.insert({ _functions->_name.data(),::Brofiler::EventDescription::Create(_functions->_name, __FILE__, __LINE__) }).first;
//}
//
////static const r_string InstrName = "I_Function"sv;
////static Brofiler::EventDescription* autogenerated_description = ::Brofiler::EventDescription::Create(InstrName, __FILE__, __LINE__);
//Brofiler::Event autogenerated_event_639(*(found->second));
//
//if (autogenerated_event_639.data)
// autogenerated_event_639.data->sourceCode = t.sdoc._content;
typedef bool(__thiscall *OrigEx)(game_instruction*, game_state&, vm_context&);

if (instructionLevelProfiling) {
auto instructionName = _functions->_name;

auto found = descriptions.find(reinterpret_cast<size_t>(instructionName.data()));
if (found == descriptions.end()) {

auto newStuff = GProfilerAdapter->createScope(instructionName,{},0);
auto ret = descriptions.insert({reinterpret_cast<size_t>(instructionName.data()), newStuff});
found = ret.first;
}

auto temp = GProfilerAdapter->enterScope(found->second);
auto res = reinterpret_cast<OrigEx>(oldFunc.vt_GameInstructionFunction)(this, state, t);
GProfilerAdapter->leaveScope(temp);
return res;
}


typedef bool(__thiscall *OrigEx)(game_instruction*, game_state&, vm_context&);
return reinterpret_cast<OrigEx>(oldFunc.vt_GameInstructionFunction)(this, state, t);
}
virtual int stack_size(void* t) const { return 0; }
Expand All @@ -825,15 +867,27 @@ class GameInstructionAssignment : public game_instruction {
public:
r_string name;
bool forceLocal;
static inline std::unordered_map<size_t, std::shared_ptr<ScopeInfo>> descriptions;
virtual bool exec(game_state& state, vm_context& t) {
//static const r_string InstrName = "I_Assignment"sv;
//static Brofiler::EventDescription* autogenerated_description = ::Brofiler::EventDescription::Create(InstrName, __FILE__, __LINE__);
//Brofiler::Event autogenerated_event_639(*autogenerated_description);
//
//if (autogenerated_event_639.data)
// autogenerated_event_639.data->altName = name;

typedef bool(__thiscall *OrigEx)(game_instruction*, game_state&, vm_context&);

if (instructionLevelProfiling) {
static r_string setVar("assignVar");

auto found = descriptions.find(reinterpret_cast<size_t>(name.data()));
if (found == descriptions.end()) {

auto newStuff = GProfilerAdapter->createScope(setVar,name,0);
auto ret = descriptions.insert({reinterpret_cast<size_t>(name.data()), newStuff});
found = ret.first;
}

auto temp = GProfilerAdapter->enterScope(found->second);
auto res = reinterpret_cast<OrigEx>(oldFunc.vt_GameInstructionAssignment)(this, state, t);
GProfilerAdapter->leaveScope(temp);
return res;
}

return reinterpret_cast<OrigEx>(oldFunc.vt_GameInstructionAssignment)(this, state, t);
}
virtual int stack_size(void* t) const { return 0; }
Expand Down Expand Up @@ -910,7 +964,7 @@ void scriptProfiler::preStart() {
GVt = *static_cast<vtables*>(*iface);
DWORD dwVirtualProtectBackup;


//#TODO only do if instruction profiling startparameter is present
game_instruction* ins;
//ins = new GameInstructionConst();
//VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionConst), 14u, 0x40u, &dwVirtualProtectBackup);
Expand All @@ -919,26 +973,26 @@ void scriptProfiler::preStart() {
//VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionConst), 14u, dwVirtualProtectBackup, &dwVirtualProtectBackup);
//delete ins;
//
//ins = new GameInstructionVariable();
//VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionVariable), 14u, 0x40u, &dwVirtualProtectBackup);
//oldFunc.vt_GameInstructionVariable = GVt.vt_GameInstructionVariable[3];
//GVt.vt_GameInstructionVariable[3] = (*reinterpret_cast<void***>(ins))[3];
//VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionVariable), 14u, dwVirtualProtectBackup, &dwVirtualProtectBackup);
//delete ins;
//
ins = new GameInstructionVariable();
VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionVariable), 14u, 0x40u, &dwVirtualProtectBackup);
oldFunc.vt_GameInstructionVariable = GVt.vt_GameInstructionVariable[3];
GVt.vt_GameInstructionVariable[3] = (*reinterpret_cast<void***>(ins))[3];
VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionVariable), 14u, dwVirtualProtectBackup, &dwVirtualProtectBackup);
delete ins;

ins = new GameInstructionOperator();
VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionOperator), 14u, 0x40u, &dwVirtualProtectBackup);
oldFunc.vt_GameInstructionOperator = GVt.vt_GameInstructionOperator[3];
GVt.vt_GameInstructionOperator[3] = (*reinterpret_cast<void***>(ins))[3];
VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionOperator), 14u, dwVirtualProtectBackup, &dwVirtualProtectBackup);
delete ins;

//ins = new GameInstructionFunction();
//VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionFunction), 14u, 0x40u, &dwVirtualProtectBackup);
//oldFunc.vt_GameInstructionFunction = GVt.vt_GameInstructionFunction[3];
//GVt.vt_GameInstructionFunction[3] = (*reinterpret_cast<void***>(ins))[3];
//VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionFunction), 14u, dwVirtualProtectBackup, &dwVirtualProtectBackup);
//delete ins;
ins = new GameInstructionFunction();
VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionFunction), 14u, 0x40u, &dwVirtualProtectBackup);
oldFunc.vt_GameInstructionFunction = GVt.vt_GameInstructionFunction[3];
GVt.vt_GameInstructionFunction[3] = (*reinterpret_cast<void***>(ins))[3];
VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionFunction), 14u, dwVirtualProtectBackup, &dwVirtualProtectBackup);
delete ins;

//ins = new GameInstructionArray();
//VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionArray), 14u, 0x40u, &dwVirtualProtectBackup);
Expand All @@ -947,12 +1001,12 @@ void scriptProfiler::preStart() {
//VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionArray), 14u, dwVirtualProtectBackup, &dwVirtualProtectBackup);
//delete ins;
//
//ins = new GameInstructionAssignment();
//VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionAssignment), 14u, 0x40u, &dwVirtualProtectBackup);
//oldFunc.vt_GameInstructionAssignment = GVt.vt_GameInstructionAssignment[3];
//GVt.vt_GameInstructionAssignment[3] = (*reinterpret_cast<void***>(ins))[3];
//VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionAssignment), 14u, dwVirtualProtectBackup, &dwVirtualProtectBackup);
//delete ins;
ins = new GameInstructionAssignment();
VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionAssignment), 14u, 0x40u, &dwVirtualProtectBackup);
oldFunc.vt_GameInstructionAssignment = GVt.vt_GameInstructionAssignment[3];
GVt.vt_GameInstructionAssignment[3] = (*reinterpret_cast<void***>(ins))[3];
VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionAssignment), 14u, dwVirtualProtectBackup, &dwVirtualProtectBackup);
delete ins;

//ins = new GameInstructionNewExpression();
//VirtualProtect(reinterpret_cast<LPVOID>(GVt.vt_GameInstructionNewExpression), 14u, 0x40u, &dwVirtualProtectBackup);
Expand Down

0 comments on commit 83848ad

Please sign in to comment.