Skip to content
This repository was archived by the owner on Apr 10, 2021. It is now read-only.

Commit 83cec6a

Browse files
profiler, the stuff of nightmares
1 parent 6314a77 commit 83cec6a

File tree

11 files changed

+235
-126
lines changed

11 files changed

+235
-126
lines changed

byond-extools/src/core/byond_structures.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,12 @@ struct ProcConstants
9999
Value usr;
100100
ExecutionContext* context;
101101
int unknown3;
102-
int unknown4;
103-
int unknown5;
102+
int unknown4; //some callback thing
103+
union
104+
{
105+
int unknown5;
106+
int extended_profile_id;
107+
};
104108
int arg_count;
105109
Value* args;
106110
};
@@ -121,12 +125,13 @@ struct ExecutionContext
121125
Value* stack;
122126
short local_var_count;
123127
short stack_size;
124-
int unknown;
128+
int unknown; //callback something
125129
Value* current_iterator;
126130
int iterator_allocated;
127131
int iterator_length;
128132
int iterator_index;
129-
char unknown4[7];
133+
int another_unknown2;
134+
char unknown4[3];
130135
char iterator_filtered_type;
131136
char unknown5;
132137
char iterator_unknown;
@@ -135,6 +140,11 @@ struct ExecutionContext
135140
char unknown7[2];
136141
bool paused;
137142
char unknown8[51];
143+
144+
int hash()
145+
{
146+
return constants->proc_id + (int)constants->args;
147+
}
138148
};
139149

140150
struct ProcSetupEntry

byond-extools/src/core/core.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "../tffi/tffi.h"
44
#include "../proxy/proxy_object.h"
55
#include "../optimizer/optimizer.h"
6+
#include "../extended_profiling/extended_profiling.h"
67

78
CrashProcPtr CrashProc;
89
SuspendPtr Suspend;
@@ -14,6 +15,8 @@ GetProcArrayEntryPtr GetProcArrayEntry;
1415
GetStringTableEntryPtr GetStringTableEntry;
1516
CallGlobalProcPtr CallGlobalProc;
1617
GetProfileInfoPtr GetProfileInfo;
18+
ProcCleanupPtr ProcCleanup;
19+
CreateContextPtr CreateContext;
1720

1821
ExecutionContext** Core::current_execution_context_ptr;
1922
ExecutionContext** Core::parent_context_ptr_hack;
@@ -36,9 +39,9 @@ bool Core::initialize()
3639
return initialized;
3740
}
3841

39-
void Core::Alert(const char* what) {
42+
void Core::Alert(std::string what) {
4043
#ifdef _WIN32
41-
MessageBoxA(NULL, what, "Ouch!", NULL);
44+
MessageBoxA(NULL, what.c_str(), "Ouch!", NULL);
4245
#else
4346
printf("%s\n", what);
4447
#endif
@@ -112,6 +115,7 @@ extern "C" EXPORT const char* core_initialize(int n_args, const char* args)
112115
return bad;
113116
}
114117
optimizer_initialize();
118+
extended_profiling_initialize();
115119
return good;
116120
}
117121

byond-extools/src/core/core.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace Core
2727
ExecutionContext* get_context();
2828
ExecutionContext* _get_parent_context();
2929
unsigned int register_opcode(std::string name, opcode_handler handler);
30-
void Alert(const char* what);
30+
void Alert(std::string what);
3131
bool initialize();
3232
extern bool initialized;
3333
Value get_stack_value(unsigned int which);

byond-extools/src/core/find_functions.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ bool Core::find_functions()
2121
FIND_OR_DIE(GetStringTableEntry, "55 8B EC 8B 4D 08 3B 0D ?? ?? ?? ?? 73 10 A1");
2222
FIND_OR_DIE(CallGlobalProc, "55 8B EC 81 EC 98 00 00 00 A1 ?? ?? ?? ?? 33 C5 89 45 FC 8B 55 14 8B 45 30 89 85 6C FF FF FF 53 8B 5D 24 56 8B 75 2C 57 8B 7D 28 81 FA FF FF 00 00 75 ?? 0F 57 C0 66 0F 13 85 68 FF FF FF 8B BD 6C FF FF FF 8B 9D 68 FF FF FF 85 F6");
2323
FIND_OR_DIE(GetProfileInfo, "55 8B EC A1 ?? ?? ?? ?? 56 8B 75 08 3B F0 73 30 8B ?? ?? ?? ?? ?? 85 C9 75 36 8D 04 80 C1 E0 03 50 FF 15 ?? ?? ?? ?? 83 C4 04 A3 ?? ?? ?? ?? 85 C0 75 12 68 ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 C4 04 33 C0 5E 5D C3 E8 ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? 8D 04 B6 8D 04 C1 5E 5D C3");
24+
FIND_OR_DIE(ProcCleanup, "55 8B EC 53 8B ?? ?? ?? ?? ?? 56 8B 75 08 57 8B 7E 44 85 FF 74 2A 8B 47 1C 89 46 44 FF 77 08 FF 37 E8 ?? ?? ?? ?? 8D 47 10 50 E8 ?? ?? ?? ?? FF 37 FF D3 57 FF D3 8B 7E 44 83 C4 14 85 FF 75 D6 FF 76 50 FF 76 48 E8");
25+
FIND_OR_DIE(CreateContext, "55 8B EC 83 EC 64 56 57 8B 7D 08 8B 4F 18 85 C9 0F 84 ?? ?? ?? ?? A1 ?? ?? ?? ?? 89 41 04 8B 4F 18 89 ?? ?? ?? ?? ?? 80 79 69 00");
2426
current_execution_context_ptr = *(ExecutionContext * **)Pocket::Sigscan::FindPattern(BYONDCORE, "A1 ?? ?? ?? ?? 8D ?? ?? ?? ?? ?? 83 C4 08 89 48 28 8D ?? ?? ?? ?? ?? 89 48 2C 83 3D ?? ?? ?? ?? ?? 74 25 8B 00 FF 30 E8 ?? ?? ?? ?? 83 C4 04 FF 30 E8 ?? ?? ?? ?? 83 C4 04 FF 30 68 ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 C4 08 66 ?? ?? ?? ?? ?? ?? A1 ?? ?? ?? ?? 75 28 A8 02 75 24 E8 ?? ?? ?? ?? 85 C0 75 09 50", 1);
2527
proc_setup_table = **(ProcSetupEntry * ***)Pocket::Sigscan::FindPattern(BYONDCORE, "A1 ?? ?? ?? ?? FF 34 B8 FF D6 47 83 C4 04 3B ?? ?? ?? ?? ?? 72 EA FF 35 ?? ?? ?? ?? FF D6 33 FF 83 C4 04 39 ?? ?? ?? ?? ?? 76 1E", 1);
2628
some_flags_including_profile = *(unsigned int**)Pocket::Sigscan::FindPattern(BYONDCORE, "F7 05 ?? ?? ?? ?? ?? ?? ?? ?? 74 34 8B 01 FF 30 E8 ?? ?? ?? ?? 83 C4 04 8B D8 E8 ?? ?? ?? ?? 8B F0 8B FA E8 ?? ?? ?? ?? 85 DB 74 02 FF 03 8B ?? ?? ?? ?? ?? 89 71 70 89 79 74 89 41 78 89 51 7C 83 3D ?? ?? ?? ?? ?? 5B 74 37", 2);

byond-extools/src/core/hooking.cpp

Lines changed: 2 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <fstream>
55
#include "json.hpp"
66
#include <stack>
7+
#include "../extended_profiling/extended_profiling.h"
78

89
#ifdef _WIN32
910
static PLH::CapstoneDisassembler* disassembler;
@@ -13,131 +14,16 @@ urmem::hook CrashProcDetour;
1314
CrashProcPtr oCrashProc;
1415
CallGlobalProcPtr oCallGlobalProc;
1516

16-
#define TOMICROS(x) std::chrono::duration_cast<std::chrono::microseconds>(x).count()
17-
18-
struct ExtendedProfile
19-
{
20-
unsigned int proc_id;
21-
int* bytecode; //facilitate faster searches up the call stack
22-
std::vector<ExtendedProfile*> subcalls;
23-
std::chrono::time_point<std::chrono::steady_clock> start_time;
24-
std::chrono::time_point<std::chrono::steady_clock> end_time;
25-
unsigned long long total_time = 0;
26-
int call_id = 0;
27-
};
28-
29-
ExtendedProfile* proc_being_profiled;
30-
ExtendedProfile* profile_result;
31-
std::stack<ExtendedProfile*> call_stack;
32-
33-
void output_subcalls(std::string base, std::ofstream& output, ExtendedProfile* profile, int depth)
34-
{
35-
base += Core::get_proc(profile->proc_id).name+";";
36-
//Core::Alert(base.c_str());
37-
if (!(profile->subcalls.empty()))
38-
{
39-
output << base << "self " << TOMICROS(profile->subcalls.back()->start_time - profile->start_time) << "\n";
40-
for (ExtendedProfile* sub : profile->subcalls)
41-
{
42-
output_subcalls(base, output, sub, ++depth);
43-
}
44-
ExtendedProfile* last_sub = profile->subcalls.back();
45-
output << base << "self " << TOMICROS(profile_result->end_time - last_sub->end_time) << "\n";
46-
}
47-
else
48-
{
49-
base.pop_back();
50-
output << base << " "<< TOMICROS(profile->end_time - profile->start_time) << "\n";
51-
}
52-
}
53-
54-
void dump_extended_profile()
55-
{
56-
/*nlohmann::json result;
57-
result["version"] = "0.0.1";
58-
result["$schema"] = "https://www.speedscope.app/file-format-schema.json";
59-
result["name"] = Core::get_proc(profile_result->proc_id).name;
60-
result["activeProfileIndex"] = 1;
61-
62-
nlohmann::json shared;
63-
std::vector<std::pair<std::string, std::string>> frames;
64-
frames.push_back({ "name", "self" });
65-
frames.push_back({"name", Core::get_proc(profile_result->proc_id).name });
66-
for (ExtendedProfile* sub : profile_result->subcalls)
67-
{
68-
frames.push_back({ "name", Core::get_proc(sub->proc_id).name });
69-
}
70-
shared["frames"] = frames;
71-
result["shared"] = shared;
72-
73-
nlohmann::json profile;
74-
profile["type"] = "sampled";
75-
profile["name"] = Core::get_proc(profile_result->proc_id).name;
76-
profile["unit"] = "microseconds";
77-
profile["startValue"] = 0;
78-
profile["endValue"] = profile_result->total_time;
79-
80-
81-
std::ofstream output("extended_profile.txt");
82-
output << result.dump();*/
83-
std::ofstream output("extended_profile.txt");
84-
output_subcalls("", output, profile_result, 0);
85-
output.flush();
86-
}
17+
//ExecutionContext* last_suspended_ec;
8718

8819
trvh __cdecl hCallGlobalProc(char unk1, int unk2, int proc_type, unsigned int proc_id, int const_0, char unk3, int unk4, Value* argList, unsigned int argListLen, int const_0_2, int const_0_3)
8920
{
90-
int call_id = 0;
91-
if (extended_profiling_procs.find(proc_id) != extended_profiling_procs.end())
92-
{
93-
proc_being_profiled = new ExtendedProfile();
94-
proc_being_profiled->proc_id = proc_id;
95-
proc_being_profiled->bytecode = Core::get_context()->bytecode;
96-
proc_being_profiled->start_time = std::chrono::high_resolution_clock::now();
97-
call_stack.push(proc_being_profiled);
98-
}
99-
if (proc_being_profiled && proc_being_profiled->proc_id != proc_id)
100-
{
101-
call_id = rand();
102-
ExecutionContext* parent_ctx = Core::_get_parent_context();
103-
if (call_stack.top()->proc_id == Core::get_proc(parent_ctx->bytecode).id)
104-
{
105-
ExtendedProfile* subcall = new ExtendedProfile();
106-
subcall->proc_id = proc_id;
107-
subcall->bytecode = Core::get_proc(proc_id).get_bytecode();
108-
subcall->start_time = std::chrono::high_resolution_clock::now();
109-
subcall->call_id = call_id;
110-
call_stack.top()->subcalls.push_back(subcall);
111-
call_stack.push(subcall);
112-
}
113-
}
11421
if (proc_hooks.find(proc_id) != proc_hooks.end())
11522
{
11623
trvh result = proc_hooks[proc_id](argList, argListLen);
117-
Core::Alert("hook");
11824
return result;
11925
}
12026
trvh result = oCallGlobalProc(unk1, unk2, proc_type, proc_id, const_0, unk3, unk4, argList, argListLen, const_0_2, const_0_3);
121-
if (proc_being_profiled)
122-
{
123-
ExtendedProfile* top = call_stack.top();
124-
if (top->proc_id == proc_id)
125-
{
126-
ExtendedProfile* sub = call_stack.top();
127-
sub->end_time = std::chrono::high_resolution_clock::now();
128-
call_stack.pop();
129-
sub->total_time = std::chrono::duration_cast<std::chrono::microseconds>(sub->end_time - sub->start_time).count();
130-
}
131-
if (proc_being_profiled->proc_id == proc_id)
132-
{
133-
proc_being_profiled->end_time = std::chrono::high_resolution_clock::now();
134-
proc_being_profiled->total_time = std::chrono::duration_cast<std::chrono::microseconds>(proc_being_profiled->end_time - proc_being_profiled->start_time).count();
135-
profile_result = proc_being_profiled;
136-
proc_being_profiled = nullptr;
137-
dump_extended_profile();
138-
//Core::Alert("Extended profile results written to file");
139-
}
140-
}
14127
return result;
14228
}
14329

@@ -155,7 +41,6 @@ void hCrashProc(char* error, int argument)
15541
#endif
15642
}
15743

158-
15944
void* Core::install_hook(void* original, void* hook)
16045
{
16146
#ifdef _WIN32

byond-extools/src/core/internal_functions.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ typedef SuspendedProc* (*SuspendPtr)(ExecutionContext* ctx) __attribute__((regpa
3838
typedef void(*StartTimingPtr)(SuspendedProc*) __attribute__((regparm(3)));
3939
#endif
4040
typedef ProfileInfo* (*GetProfileInfoPtr)(unsigned int proc_id);
41+
typedef void(*ProcCleanupPtr)(ExecutionContext* thing_that_just_executed); //this one is hooked to help with extended profiling
42+
typedef void(*CreateContextPtr)(void* unknown, ExecutionContext* new_ctx);
4143

4244
extern CrashProcPtr CrashProc;
4345
extern StartTimingPtr StartTiming;
@@ -48,4 +50,6 @@ extern GetStringTableIndexPtr GetStringTableIndex;
4850
extern GetProcArrayEntryPtr GetProcArrayEntry;
4951
extern GetStringTableEntryPtr GetStringTableEntry;
5052
extern CallGlobalProcPtr CallGlobalProc;
51-
extern GetProfileInfoPtr GetProfileInfo;
53+
extern GetProfileInfoPtr GetProfileInfo;
54+
extern ProcCleanupPtr ProcCleanup;
55+
extern CreateContextPtr CreateContext;

byond-extools/src/core/proc_management.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "proc_management.h"
22
#include "../dmdism/disassembly.h"
33
#include "../dmdism/disassembler.h"
4+
#include "../extended_profiling/extended_profiling.h"
45

56
std::vector<Core::Proc> procs_by_id;
67
std::unordered_map<std::string, Core::Proc> procs_by_name;
@@ -57,6 +58,11 @@ ProfileInfo* Core::Proc::profile()
5758
return GetProfileInfo(id);
5859
}
5960

61+
void Core::Proc::extended_profile()
62+
{
63+
procs_to_profile[id] = true;
64+
}
65+
6066
void Core::Proc::hook(ProcHook hook_func)
6167
{
6268
proc_hooks[id] = hook_func;
@@ -131,5 +137,11 @@ bool Core::populate_proc_list()
131137
procs_by_bytecode[p.get_bytecode()] = p;
132138
i++;
133139
}
140+
//Temporary - fake proc used by profiler
141+
Proc sleep = Proc();
142+
sleep.id = i;
143+
sleep.name = "SLEEP";
144+
procs_by_id.push_back(sleep);
145+
procs_by_name["SLEEP"] = sleep;
134146
return true;
135147
}

byond-extools/src/core/proc_management.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ namespace Core
3636
void assemble(Disassembly disasm);
3737

3838
ProfileInfo* profile();
39+
void extended_profile();
3940
void hook(ProcHook hook_func);
4041
Value call(std::vector<Value> arguments, Value usr = Value::Null(), Value src = Value::Null());
4142

@@ -48,6 +49,16 @@ namespace Core
4849
{
4950
return id == rhs.id;
5051
}
52+
53+
operator int()
54+
{
55+
return id;
56+
}
57+
58+
operator std::string()
59+
{
60+
return name;
61+
}
5162
};
5263

5364
Proc get_proc(std::string name);

byond-extools/src/core/various_testing.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ trvh update_light_objects;
5454
void init_testing()
5555
{
5656
Core::enable_profiling();
57-
//extended_profiling_procs[Core::get_proc("/datum/controller/subsystem/atoms/proc/InitializeAtoms").id] = true;
57+
Core::get_proc("/datum/explosion/New").extended_profile();
58+
//Core::get_proc("/client/verb/test_reentry").extended_profile();
59+
//Core::get_proc("/client/verb/test_extended_profiling").extended_profile();
60+
//extended_profiling_procs[.id] = true;
5861
//Core::get_proc("/proc/cheap_hypotenuse_hook").hook(cheap_hypotenuse);
5962
//Core::get_proc("/proc/measure_get_variable").hook(measure_get_variable);
6063
//Core::get_proc("/proc/laugh").hook(show_profiles);

0 commit comments

Comments
 (0)