美文网首页程序员
java编译高级玩法:locked_region_code_in

java编译高级玩法:locked_region_code_in

作者: Gavinxixi臻 | 来源:发表于2019-10-15 15:50 被阅读0次

今天阅读Android Q WM代码时发现了一个高级的玩法,看名字就知道是通过注入方式实现自动为锁区域前后添加代码的方法。发现过程如下:

一段莫名其妙的注释

https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-mainline-10.0.0_r3/services/core/java/com/android/server/wm/ActivityTaskManagerService.java#362

    /* Global service lock used by the package the owns this service. */
    final WindowManagerGlobalLock mGlobalLock = new WindowManagerGlobalLock();
    /**
     * It is the same instance as {@link mGlobalLock}, just declared as a type that the
     * locked-region-code-injection does't recognize it. It is used to skip wrapping priority
     * booster for places that are already in the scope of another booster (e.g. computing oom-adj).
     *
     * @see WindowManagerThreadPriorityBooster
     */
    final Object mGlobalLockWithoutBoost = mGlobalLock;

每个词都能读懂,但合起来就似是而非的不太明白。为什么相同的锁对象要弄出两个引用?什么叫跳过优先级加速器的包围。搜索这两个锁的用法似乎也没有特别的差异。还好有进一步提示@see WindowManagerThreadPriorityBooster

没有地方使用的静态方法

WindowManagerThreadPriorityBooster本身代码比较好懂,就是根据情况调整线程优先级达到加速效果。关键是初始化和调用它的地方:
https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-mainline-10.0.0_r3/services/core/java/com/android/server/wm/WindowManagerService.java#873

    static void boostPriorityForLockedSection() {
        sThreadPriorityBooster.boost();
    }
    static void resetPriorityAfterLockedSection() {
        sThreadPriorityBooster.reset();
    }

从函数名称就能猜到肯定是在作用域前后调用这两个函数达到boost和reset的效果,燃鹅,搜索这个两个函数的调用地方,竟然没有?!?!

抓住了你的小尾巴

多亏我习惯使用OpenGrok来做项目代码搜索,马上还是发现了端倪


locked_injection_1.png

https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-mainline-10.0.0_r3/services/core/Android.bp#66

locked_injection_2.png
  1. 编译脚本里面做猫腻
  2. art-profile标记函数避免java编译时的空检查
    真相只有一个,这是用来直接注入到java生成的字节码中的!!

证据确凿验证猜想

直接去看lockedregioncodeinjection的源码,果然是个读取字节码然后转换输出的工具。具体逻辑就不深究了:
https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-mainline-10.0.0_r3/tools/locked_region_code_injection/src/lockedregioncodeinjection/Main.java#80

locked_injection_3.png

又回到最初的起点

final WindowManagerGlobalLock mGlobalLock = new WindowManagerGlobalLock();
final Object mGlobalLockWithoutBoost = mGlobalLock;

至此就能真正读懂开头那段注释了,使用locked-region-code-injection做代码注入的目标是WindowManagerGlobalLock,也就是只对mGlobalLock的锁区域做加速和恢复。而如果使用mGlobalLockWithoutBoost锁就表明:

  1. 这段区域可能已经被包含在mGlobalLock以经过加速
  2. 这段区域有其他带有加速的区域,例如AMS,看Android.bp中locked-region-code-injection的参数可知
  3. 这段区域不需要加速

相关文章

  • java编译高级玩法:locked_region_code_in

    今天阅读Android Q WM代码时发现了一个高级的玩法,看名字就知道是通过注入方式实现自动为锁区域前后添加代码...

  • Java的编译和反编译

    Java的编译和反编译 什么是编译 编译就是把C、C++、Java等高级语言转换成汇编语言、机器语言等低级语言的过...

  • 《疯狂java讲义》

    一、Java语言概述 高级语言运行机制 高级语言按程序的执行方式可分为编译型和解释型两种:-编译型:使用专门的编译...

  • 2021-01-29 Java学习

    以下均是自己对学习的理解,理解可能偏差 java 编译与反编译发展:机器语言--汇编语言--高级语言,例如java...

  • OC源码编译

    简介:   源码编译是学习高级语言底层的最直接的方法,你可以打断点进行各种花样玩法。该篇文章是记录自己编译源码遇到...

  • JVM底层和GC原理

    1 java一次编译到处运行是怎样实现的 java语言是一种高级语言,想要让计算机执行就需要通过编译。而j...

  • JVM为什么能一次编写处处运行?

    java是一种特殊的高级语言,java程序的运行过程必须经过先编译、后解释两个步骤。java源文件(.java)需...

  • JS系列(一):编译原理

    诸如 C / C++ / JAVA 等语言,都有对应的编译器,而编译器会将这些高级语言编译成目标机(目标系统,如W...

  • Java Review (Java开发环境)

    @ 高级语言运行机制编译型语言解释型语言 Java运行机制和JVM编写编译运行 JDK JREJDK、JRE与JV...

  • Java Review (Java开发环境)

    @ 高级语言运行机制编译型语言解释型语言 Java运行机制和JVM编写编译运行 JDK JREJDK、JRE与JV...

网友评论

    本文标题:java编译高级玩法:locked_region_code_in

    本文链接:https://www.haomeiwen.com/subject/amusmctx.html