Skip to content

Commit

Permalink
android: Properly handle the CMC GC strategy
Browse files Browse the repository at this point in the history
- With Google Play System Updates the base version of libart may differ
  from the Android version. For example, an Android 12 system could be
  using libart equivalent to the system version on Android 14.
- The function we were hooking in the MarkCompact GC was not the right
  spot to update the class pointers, causing crashes after some time.

Fixes #323, for real this time.
  • Loading branch information
mbricchi authored and oleavr committed Jul 17, 2024
1 parent dd80a24 commit eb0fa83
Showing 1 changed file with 18 additions and 12 deletions.
30 changes: 18 additions & 12 deletions lib/android.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}
Expand Down Expand Up @@ -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);
}
}
}
Expand Down

0 comments on commit eb0fa83

Please sign in to comment.