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