diff --git a/lib/android.js b/lib/android.js index bdf1ace..d696b89 100644 --- a/lib/android.js +++ b/lib/android.js @@ -1808,6 +1808,9 @@ on_leave_gc_concurrent_copying_copying_phase (GumInvocationContext * ic) Gc: { copyingPhase: { onLeave: cm.on_leave_gc_concurrent_copying_copying_phase + }, + runFlip: { + onEnter: cm.on_leave_gc_concurrent_copying_copying_phase } } } @@ -1885,19 +1888,22 @@ function ensureArtKnowsHowToHandleReplacementMethods (vm) { const apiLevel = getAndroidApiLevel(); - let exportName = null; - if (apiLevel > 28) { - exportName = '_ZN3art2gc9collector17ConcurrentCopying12CopyingPhaseEv'; - } else if (apiLevel > 22) { - exportName = '_ZN3art2gc9collector17ConcurrentCopying12MarkingPhaseEv'; - } - - if (exportName !== null) { - Interceptor.attach(Module.getExportByName('libart.so', exportName), artController.hooks.Gc.copyingPhase); + const mayUseCollector = (apiLevel > 28) + ? new NativeFunction(Module.getExportByName('libart.so', '_ZNK3art2gc4Heap15MayUseCollectorENS0_13CollectorTypeE'), 'bool', ['pointer', 'int']) + : () => false; + const kCollectorTypeCMC = 3; - const collectorCMC = Module.findExportByName('libart.so', '_ZN3art2gc9collector11MarkCompact15CompactionPhaseEv'); - if (collectorCMC !== null) { - Interceptor.attach(collectorCMC, artController.hooks.Gc.copyingPhase); + if (mayUseCollector(getApi().artHeap, kCollectorTypeCMC)) { + Interceptor.attach(Module.getExportByName('libart.so', '_ZN3art6Thread15RunFlipFunctionEPS0_b'), artController.hooks.Gc.runFlip); + } else { + let exportName = null; + if (apiLevel > 28) { + exportName = '_ZN3art2gc9collector17ConcurrentCopying12CopyingPhaseEv'; + } else if (apiLevel > 22) { + exportName = '_ZN3art2gc9collector17ConcurrentCopying12MarkingPhaseEv'; + } + if (exportName !== null) { + Interceptor.attach(Module.getExportByName('libart.so', exportName), artController.hooks.Gc.copyingPhase); } } }