Skip to content

Commit b17fcaf

Browse files
committed
Add plotting for pool allocators
1 parent 8952324 commit b17fcaf

12 files changed

+204
-3
lines changed

intercept

src/AdapterTracy.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ void AdapterTracy::setCounter(intercept::types::r_string name, float val) {
100100
tracy::Profiler::PlotData(name.c_str(), val);
101101
}
102102

103+
void AdapterTracy::setCounter(const char* name, float val) const {
104+
tracy::Profiler::PlotData(name, val);
105+
}
106+
103107
std::shared_ptr<ScopeInfo> AdapterTracy::createScopeStatic(const char* name, const char* filename, uint32_t fileline) const {
104108
auto info = std::make_shared<ScopeInfoTracy>();
105109
info->info = tracy::SourceLocationData{nullptr, name, filename,fileline, 0};

src/AdapterTracy.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ class AdapterTracy final : public ProfilerAdapter
1818
void setName(std::shared_ptr<ScopeTempStorage> tempStorage, const intercept::types::r_string& name) override;
1919
void setDescription(std::shared_ptr<ScopeTempStorage> tempStorage, const intercept::types::r_string& descr) override;
2020
void addLog(intercept::types::r_string message) override;
21-
void setCounter(intercept::types::r_string name, float val) override;
21+
void setCounter(intercept::types::r_string name, float val) override;
22+
void setCounter(const char* name, float val) const;
2223

2324
std::shared_ptr<ScopeInfo> createScopeStatic(const char* name, const char* filename, uint32_t fileline) const;
2425
static bool isConnected();

src/ArmaScriptProfiler.vcxproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
148148
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
149149
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
150+
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
150151
</ClCompile>
151152
<Link>
152153
<EnableCOMDATFolding>true</EnableCOMDATFolding>
@@ -169,6 +170,7 @@
169170
<ClInclude Include="AdapterChrome.hpp" />
170171
<ClInclude Include="AdapterTracy.hpp" />
171172
<ClInclude Include="EngineProfiling.h" />
173+
<ClInclude Include="FAllocHook.h" />
172174
<ClInclude Include="HookManager.hpp" />
173175
<ClInclude Include="ProfilerAdapter.hpp" />
174176
<ClInclude Include="scriptProfiler.hpp" />
@@ -245,6 +247,7 @@
245247
</ClCompile>
246248
<ClCompile Include="AdapterTracy.cpp" />
247249
<ClCompile Include="EngineProfiling.cpp" />
250+
<ClCompile Include="FAllocHook.cpp" />
248251
<ClCompile Include="HookManager.cpp" />
249252
<ClCompile Include="main.cpp" />
250253
<ClCompile Include="scriptProfiler.cpp" />

src/ArmaScriptProfiler.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@
8484
<ClInclude Include="SignalSlot.hpp">
8585
<Filter>Quelldateien</Filter>
8686
</ClInclude>
87+
<ClInclude Include="FAllocHook.h">
88+
<Filter>Headerdateien</Filter>
89+
</ClInclude>
8790
</ItemGroup>
8891
<ItemGroup>
8992
<ClCompile Include="scriptProfiler.cpp">
@@ -272,6 +275,9 @@
272275
<ClCompile Include="HookManager.cpp">
273276
<Filter>Quelldateien</Filter>
274277
</ClCompile>
278+
<ClCompile Include="FAllocHook.cpp">
279+
<Filter>Quelldateien</Filter>
280+
</ClCompile>
275281
</ItemGroup>
276282
<ItemGroup>
277283
<MASM Include="hooks.asm">

src/FAllocHook.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#include "FAllocHook.h"
2+
#include <containers.hpp>
3+
#include "AdapterTracy.hpp"
4+
extern std::shared_ptr<ProfilerAdapter> GProfilerAdapter;
5+
#include <Tracy.hpp>
6+
using namespace std::string_view_literals;
7+
8+
FAllocHook::FAllocHook()
9+
{
10+
}
11+
12+
13+
FAllocHook::~FAllocHook()
14+
{
15+
}
16+
17+
18+
extern "C" {
19+
uintptr_t engineAlloc;
20+
uintptr_t engineFree;
21+
intercept::types::rv_pool_allocator* freealloctmp;
22+
intercept::types::rv_pool_allocator* allocalloctmp;
23+
24+
void afterAlloc() {
25+
auto tracyProf = std::reinterpret_pointer_cast<AdapterTracy>(GProfilerAdapter);
26+
tracyProf->setCounter(allocalloctmp->_allocName, allocalloctmp->allocated_count);
27+
}
28+
29+
void afterFree() {
30+
auto tracyProf = std::reinterpret_pointer_cast<AdapterTracy>(GProfilerAdapter);
31+
tracyProf->setCounter(freealloctmp->_allocName, freealloctmp->allocated_count);
32+
}
33+
34+
35+
void engineAllocRedir();
36+
void engineFreeRedir();
37+
}
38+
39+
40+
HookManager::Pattern pat_allocReg{ // "Out of FastCAlloc slots"
41+
"xxxxxxxxxxxxxxx?????x????xxx????xx????xxxxx????xxxxxxxxxxx????xxxxxxxxx????x????xxxxxxxxx"sv,
42+
"\x40\x53\x48\x83\xEC\x30\x45\x33\xC9\x48\x8B\xD9\xC7\x44\x24\x00\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x48\x63\x15\x00\x00\x00\x00\x81\xFA\x00\x00\x00\x00\x7D\x1C\x48\x8D\x0D\x00\x00\x00\x00\x48\x8B\xC3\x48\x89\x1C\xD1\xFF\xC2\x89\x15\x00\x00\x00\x00\x48\x83\xC4\x30\x5B\xC3\x48\x8D\x0D\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x48\x8B\xC3\x48\x83\xC4\x30\x5B\xC3"sv
43+
};
44+
45+
HookManager::Pattern pat_allocC{
46+
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx????xxxx????xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx????xxxxxxxxxxx"sv,
47+
"\x40\x53\x48\x83\xEC\x20\xFF\x41\x60\x48\x8B\x41\x08\x48\x8B\xD9\x48\x3B\xC1\x74\x0B\x48\x85\xC0\x74\x06\x48\x83\xC0\xE0\x75\x2B\x48\x8D\x41\x18\x48\x8B\x49\x20\x48\x3B\xC8\x74\x0E\x48\x85\xC9\x74\x09\x48\x8D\x41\xE0\x48\x85\xC0\x75\x10\x48\x8B\xCB\xE8\x00\x00\x00\x00\x84\xC0\x0F\x84\x00\x00\x00\x00\x4C\x8B\x43\x08\x32\xC9\x45\x33\xD2\x4C\x3B\xC3\x74\x0B\x4D\x85\xC0\x74\x06\x49\x83\xC0\xE0\x75\x2A\x4C\x8B\x43\x20\x48\x8D\x43\x18\x4C\x3B\xC0\x0F\x84\x00\x00\x00\x00\x4D\x85\xC0\x74\x06\x49\x83\xC0\xE0\xEB\x03"sv
48+
};
49+
50+
HookManager::Pattern pat_freeC{
51+
"xxxxx????xxxxxxxxxxxxx?xxxxxxxxxxxxxxxxxxxxxxx????x????xxxxxx????xxxxxxx?xxxxxx????xxxxxxxxxx??xxxxxxxxxxx"sv,
52+
"\x48\x85\xD2\x0F\x84\x00\x00\x00\x00\x53\x48\x83\xEC\x20\x48\x63\x41\x58\x48\x89\x7C\x24\x00\x48\x8B\xFA\x48\xFF\xC8\x48\x8B\xD9\x48\x23\xC2\x48\x2B\xF8\x83\x3F\x00\x74\x28\x48\x8D\x0D\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x44\x8B\x07\x48\x8D\x0D\x00\x00\x00\x00\x48\x8B\xD7\x48\x8B\x7C\x24\x00\x48\x83\xC4\x20\x5B\xE9\x00\x00\x00\x00\x48\x8B\x47\x18\x48\x89\x02\x48\x83\x7F\x00\x00\x48\x89\x57\x18\x0F\x94\xC0\x48\x89\x7A\x08"sv
53+
};
54+
55+
void FAllocHook::init() {
56+
57+
auto found = hooks.findPattern(pat_allocReg, 0x0);
58+
59+
60+
61+
auto aicp = *reinterpret_cast<uint32_t*>(found + 0x1C);
62+
auto rip = found + 0x20;
63+
auto aic = *reinterpret_cast<int32_t*>(rip + aicp);
64+
65+
//+1C
66+
//70 C4 4C 01
67+
//014cc470
68+
//0002932C90
69+
70+
71+
auto aidp = *reinterpret_cast<uint32_t*>(found + 0x2B);
72+
rip = found + 0x2F;
73+
auto aid = reinterpret_cast<intercept::types::rv_pool_allocator**>(rip + aidp);
74+
//71 C4 4C 01
75+
76+
77+
auto allocF = hooks.findPattern(pat_allocC);
78+
engineAlloc = hooks.placeHookTotalOffs(allocF, reinterpret_cast<uintptr_t>(engineAllocRedir))+2;
79+
80+
auto FreeF = hooks.findPattern(pat_freeC);
81+
engineFree = hooks.placeHookTotalOffs(FreeF + 0x9, reinterpret_cast<uintptr_t>(engineFreeRedir));
82+
//
83+
//__debugbreak();
84+
85+
}

src/FAllocHook.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#pragma once
2+
#include "HookManager.hpp"
3+
4+
class FAllocHook
5+
{
6+
public:
7+
void init();
8+
FAllocHook();
9+
~FAllocHook();
10+
HookManager hooks;
11+
};
12+

src/HookManager.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <utility>
55
#include <vector>
66
#include <functional>
7+
#include <string_view>
78

89
//From ArmaDebugEngine
910

src/hooks.asm

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,87 @@ _TEXT SEGMENT
118118
compileCacheIns ENDP
119119

120120

121+
;FAllocHook
122+
123+
124+
EXTERN afterAlloc: PROC; ArmaProf::frameEnd
125+
EXTERN afterFree: PROC;
126+
127+
;JmpBacks
128+
EXTERN engineAlloc: qword
129+
EXTERN engineFree: qword
130+
131+
132+
133+
EXTERN freealloctmp: qword
134+
EXTERN allocalloctmp: qword
135+
136+
doEngineAlloc PROC
137+
138+
;fixup
139+
push rbx
140+
sub rsp, 20h
141+
inc dword ptr [rcx+60h]
142+
mov rax, [rcx+8]
143+
mov rbx, rcx
144+
jmp engineAlloc;
145+
146+
doEngineAlloc ENDP
147+
148+
doEngineFree PROC
149+
150+
;fixup
151+
push rbx
152+
sub rsp, 20h
153+
movsxd rax, dword ptr [rcx+58h]
154+
mov [rsp+30h], rdi
155+
jmp engineFree;
156+
doEngineFree ENDP
157+
158+
159+
;##########
160+
PUBLIC engineAllocRedir
161+
engineAllocRedir PROC
162+
mov allocalloctmp, rcx; get rid of this and just keep rcx on stack
163+
call doEngineAlloc;
164+
push rax;
165+
push rcx;
166+
push rdx;
167+
push r8;
168+
push r9;
169+
170+
call afterAlloc;
171+
172+
pop r9;
173+
pop r8;
174+
pop rdx;
175+
pop rcx;
176+
pop rax;
177+
178+
ret
179+
engineAllocRedir ENDP
180+
181+
;##########
182+
PUBLIC engineFreeRedir
183+
engineFreeRedir PROC
184+
mov freealloctmp, rcx; get rid of this, I keep track of rcx now anyway
185+
push rax;
186+
push r8;
187+
push rcx;
188+
push rdx;
189+
push rcx;
190+
call doEngineFree;
191+
call afterFree;
192+
pop rcx;
193+
pop rdx;
194+
pop rcx;
195+
pop r8;
196+
pop rax;
197+
ret
198+
engineFreeRedir ENDP
199+
200+
201+
121202

122203

123204

src/scriptProfiler.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,12 @@ void scriptProfiler::preStart() {
11591159
}
11601160
}
11611161

1162+
if (getCommandLineParam("-profilerEnableFAlloc")) {
1163+
allocHook = std::make_shared<FAllocHook>();
1164+
diag_log("ASP: FAlloc instrumentation enabled"sv);
1165+
allocHook->init();
1166+
}
1167+
11621168
if (getCommandLineParam("-profilerNoPaths"sv)) {
11631169
diag_log("ASP: Omitting file paths"sv);
11641170
GProfilerAdapter->setOmitFilePaths();

0 commit comments

Comments
 (0)