Skip to content

Commit a8153ce

Browse files
gyntclaude
andcommitted
AGENTS: the function resolvers are a second measurement switch
The struct resolver warning was documented in detail; the function resolvers were not mentioned at all. With MACRO_FUNCTION_RESOLVER(..., false, ...) the call goes to the original binary, so the compiler cannot see that the callee preserves ecx and the caller spills this, renaming every register after the call. It is also why /GL appears not to work. processSyncPacket read 26.2% purely because of this; enabling its callee took it to 79.2%, and enabling all 23 finished GameSynchronyState functions moved the namespace average 84.6% -> 85.7% with nothing getting worse. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent df087fe commit a8153ce

1 file changed

Lines changed: 13 additions & 2 deletions

File tree

‎AGENTS.md‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,12 +190,23 @@ of namespace average this way, and a snapshot taken on one side of that change c
190190
with anything measured on the other. `tools/reimplementation-control/enable_reimplemented_data.py`
191191
turns them back on; `git checkout -- src/OpenSHC/Globals/` turns them off again.
192192

193+
**The function resolvers are a second, separate switch, and they matter just as much.** Every
194+
`MACRO_FUNCTION_RESOLVER(..., false, Address::...)` in a `*.func.hpp` routes `MACRO_CALL`/`MACRO_CALL_MEMBER` to the
195+
*original binary*, so with it off the compiler never sees our callee. It cannot then know the callee leaves `ecx`
196+
alone, and the caller spills `this` into a callee-saved register, which renames every register downstream of the
197+
call. `processSyncPacket` read 26.2% for that reason alone; enabling its (already 100%) callee took it to 79.2%,
198+
and enabling all 23 finished functions of `GameSynchronyState` moved the namespace average 84.6% -> 85.7% with
199+
nothing getting worse. It is also the missing precondition for `cmake/compiler-flags-gl.txt`: `/GL` on both sides
200+
does nothing while the callee is still proxied. `tools/reimplementation-control/Enable-Reimplemented-Functions.ps1`
201+
flips them; like the struct resolvers they are never committed. Only enable a callee that is itself finished.
202+
193203
## Working on Many Functions
194204

195205
When restyling or improving a large set of functions, work in batches (e.g. per folder) and verify each batch:
196206

197-
0. Switch the global data reimplementations on (the `MACRO_STRUCT_RESOLVER` flag in `src/OpenSHC/Globals/*.hpp`)
198-
before measuring anything, and never commit those files. With the resolvers inactive, reccmp collapses every
207+
0. Switch **both** sets of reimplementations on before measuring anything, and never commit those files: the
208+
global data (the `MACRO_STRUCT_RESOLVER` flag in `src/OpenSHC/Globals/*.hpp`) and the finished functions
209+
(the `MACRO_FUNCTION_RESOLVER` flag in the `*.func.hpp` files). With the resolvers inactive, reccmp collapses every
199210
absolute address to one token, so a `this->` that should be the global instance, and a wrong field offset, both
200211
look like a match.
201212
1. Save a baseline: `reccmp_report.py --run save base.json`.

0 commit comments

Comments
 (0)