Implémenter le compilateur ART juste à temps

Le runtime Android (ART) comprend un compilateur juste à temps (JIT) avec profilage de code qui améliore continuellement les performances des applications Android lors de leur exécution. Le compilateur JIT complète le compilateur AOT (Ahead-of-time) actuel d'ART et améliore les performances d'exécution, économise de l'espace de stockage et accélère les mises à jour des applications et du système. Il améliore également le compilateur AOT en évitant le ralentissement du système lors des mises à jour automatiques des applications ou la recompilation des applications lors des mises à jour en direct (OTA).

Bien que JIT et AOT utilisent le même compilateur avec un ensemble similaire d'optimisations, le code généré peut ne pas être identique. JIT utilise les informations de type d'exécution, peut faire une meilleure inline et rend possible la compilation par remplacement de pile (OSR), ce qui génère un code légèrement différent.

Architecture JIT

Architecture JIT
Figure 1. Architecture JIT.

Compilation JIT

La compilation JIT implique les activités suivantes :

Composition guidée par profil
Figure 2. Compilation guidée par profil.
  1. L'utilisateur exécute l'application, ce qui déclenche ensuite le chargement du fichier .dex par ART.
    • Si le fichier .oat (le binaire AOT pour le fichier .dex ) est disponible, ART l'utilise directement. Bien que les fichiers .oat soient générés régulièrement, ils ne contiennent pas toujours du code compilé (binaire AOT).
    • Si le fichier .oat ne contient pas de code compilé, ART exécute JIT et l'interpréteur pour exécuter le fichier .dex .
  2. JIT est activé pour toute application qui n'est pas compilée selon le filtre de compilation speed (qui dit « compilez autant que vous le pouvez à partir de l'application »).
  3. Les données du profil JIT sont sauvegardées dans un fichier dans un répertoire système auquel seule l'application peut accéder.
  4. Le démon de compilation AOT ( dex2oat ) analyse ce fichier pour piloter sa compilation.

    Démon JIT
    Figure 3. Activités du démon JIT.

Le service Google Play est un exemple utilisé par d'autres applications qui se comportent de manière similaire aux bibliothèques partagées.

Flux de travail JIT

Architecture JIT
Figure 4. Flux de données JIT.
  • Les informations de profilage sont stockées dans le cache de code et soumises à un garbage collection sous pression de mémoire.
    • Il n'y a aucune garantie qu'un instantané pris lorsque l'application était en arrière-plan contiendra des données complètes (c'est-à-dire tout ce qui a été traité en JIT).
    • Aucune tentative n'est faite pour garantir que tout est enregistré (car cela peut avoir un impact sur les performances d'exécution).
  • Les méthodes peuvent être dans trois états différents :
    • interprété (code dex)
    • JIT compilé
    • AOT compilé
    Si le code JIT et AOT existent (par exemple en raison de désoptimisations répétées), le code JIT est préféré.
  • La mémoire requise pour exécuter JIT sans affecter les performances de l'application de premier plan dépend de l'application en question. Les grandes applications nécessitent plus de mémoire que les petites applications. En général, les grosses applications se stabilisent autour de 4 Mo.

Activer la journalisation JIT

Pour activer la journalisation JIT, exécutez les commandes suivantes :

adb root
adb shell stop
adb shell setprop dalvik.vm.extra-opts -verbose:jit
adb shell start

Désactiver JIT

Pour désactiver JIT, exécutez les commandes suivantes :

adb root
adb shell stop
adb shell setprop dalvik.vm.usejit false
adb shell start

Forcer la compilation

Pour forcer la compilation, exécutez ce qui suit :

adb shell cmd package compile

Cas d'utilisation courants pour forcer la compilation d'un package spécifique :

  • Basé sur un profil :
    adb shell cmd package compile -m speed-profile -f my-package
    
  • Complet :
    adb shell cmd package compile -m speed -f my-package
    

Cas d'utilisation courants pour la compilation forcée de tous les packages :

  • Basé sur un profil :
    adb shell cmd package compile -m speed-profile -f -a
    
  • Complet :
    adb shell cmd package compile -m speed -f -a
    

Effacer les données de profil

Pour effacer les données de profil et supprimer le code compilé, exécutez la commande suivante :

  • Pour un package :
    adb shell cmd package compile --reset my-package
    
  • Pour tous les packages :
    adb shell cmd package compile --reset -a