xref: /aosp_15_r20/art/runtime/alloc_instrumentation.md (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard WorkerIn order to buy some performance on the common, uninstrumented, fast path, we replace repeated
2*795d594fSAndroid Build Coastguard Workerchecks for both allocation instrumentation and allocator changes by  a single function table
3*795d594fSAndroid Build Coastguard Workerdispatch, and templatized allocation code that can be used to generate either instrumented
4*795d594fSAndroid Build Coastguard Workeror uninstrumented versions of allocation routines.
5*795d594fSAndroid Build Coastguard Worker
6*795d594fSAndroid Build Coastguard WorkerWhen we call an allocation routine, we always indirect through a thread-local function table that
7*795d594fSAndroid Build Coastguard Workereither points to instrumented or uninstrumented allocation routines. The instrumented code has a
8*795d594fSAndroid Build Coastguard Worker`kInstrumented` = true template argument (or `kIsInstrumented` in some places), the uninstrumented
9*795d594fSAndroid Build Coastguard Workercode has `kInstrumented` = false.
10*795d594fSAndroid Build Coastguard Worker
11*795d594fSAndroid Build Coastguard WorkerThe function table is thread-local. There appears to be no logical necessity for that; it just
12*795d594fSAndroid Build Coastguard Workermakes it easier to access from compiled Java code.
13*795d594fSAndroid Build Coastguard Worker
14*795d594fSAndroid Build Coastguard Worker- The function table is switched out by `InstrumentQuickAllocEntryPoints[Locked]`, and a
15*795d594fSAndroid Build Coastguard Workercorresponding `UninstrumentQuickAlloc`... function.
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker- These in turn are called by `SetStatsEnabled()`, `SetAllocationListener()`, et al, which
18*795d594fSAndroid Build Coastguard Workerrequire the mutator lock is not held.
19*795d594fSAndroid Build Coastguard Worker
20*795d594fSAndroid Build Coastguard Worker- With a started runtime, `SetEntrypointsInstrumented()` calls `ScopedSuspendAll(`) before updating
21*795d594fSAndroid Build Coastguard Worker  the function table.
22*795d594fSAndroid Build Coastguard Worker
23*795d594fSAndroid Build Coastguard WorkerMutual exclusion in the dispatch table is thus ensured by the fact that it is only updated while
24*795d594fSAndroid Build Coastguard Workerall other threads are suspended, and is only accessed with the mutator lock logically held,
25*795d594fSAndroid Build Coastguard Workerwhich inhibits suspension.
26*795d594fSAndroid Build Coastguard Worker
27*795d594fSAndroid Build Coastguard WorkerTo ensure correctness, we thus must:
28*795d594fSAndroid Build Coastguard Worker
29*795d594fSAndroid Build Coastguard Worker1. Suspend all threads when swapping out the dispatch table, and
30*795d594fSAndroid Build Coastguard Worker2. Make sure that we hold the mutator lock when accessing it.
31*795d594fSAndroid Build Coastguard Worker3. Not trust kInstrumented once we've given up the mutator lock, since it could have changed in the
32*795d594fSAndroid Build Coastguard Worker    interim.
33*795d594fSAndroid Build Coastguard Worker
34