在开机过程中统计解释执行调用的次数

添加打印

在选择开机模式的时候,想要统计不同的方式被调用的次数,那么就需要通过打log的方式对各种模式进行统计

  1. 编译执行到机器码打印
    文件路径:./art/compiler/optimizing/optimizing_compiler.cc
    打点函数:OptimizingCompiler::TryCompile()
    TryCompile是dex2oat的重要部分,负责从DEX指令码到机器码的生成。在该函数底部添加如下的打印

    TryCompile

  2. JitCompiler
    文件路径:./art/compiler/jit/jit_compiler.cc
    打点函数:JitCompiler::CompileMethod()
    这条打印主要是针对JitCompile的调用。如果需要生成机器码,JitCompile函数必然会调用上面的TryCompile函数。这里并没有将打印添加到JitCompile函数里面而是该函数被call之后,是想验证如果我们之后disable了JIT编译,就不应该看到仍然JitCompile被调用;另一方面我们也可以和TryCompile的打印统计进行比较。

    JitCompile

  1. JniCompile
    文件路径:./art/dex2oat/driver/compiler_driver.cc
    打点函数:CompileMethodQuick()
    这条打印主要针对JniCompile的调用。因此,对于纯解释执行,我们不希望它被call。该打印添加到JniCompile被call之后。

    JniCompile

  2. 解释执行的打印添加
    文件路径:./art/runtime/interpreter/interpreter_switch_impl-inl.h
    打点函数:ExecuteSwitchImplCpp()
    当一个JAVA方法以CPP解释方式执行时,该函数将被ART虚拟机调用。


    ExecuteSwitchImplCpp
  3. 汇编解释执行的打印添加
    文件路径:./art/runtime/interpreter/interpreter.cc
    打点函数:Execute()
    当一个JAVA方法以汇编解释方式执行时,该函数将会调用ExecuteMterpImpl函数。目前只能在汇编函数外部添加打印。


    ExecuteMterpImpl

选择c++/汇编解释执行的方式

文件路径:./art/runtime/interpreter/interpreter.cc
汇编解释执行:

#if ART_USE_CXX_INTERPRETER
static constexpr InterpreterImplKind kInterpreterImplKind = kSwitchImplKind;
#else
static constexpr InterpreterImplKind kInterpreterImplKind = kMterpImplKind;
#endif

C++解释执行

#if ART_USE_CXX_INTERPRETER
static constexpr InterpreterImplKind kInterpreterImplKind = kSwitchImplKind;
#else
static constexpr InterpreterImplKind kInterpreterImplKind = kMterpImplKind;
#endif

统计次数

需要在生成的log中抓取各个字符串出现的次数,脚本如下:

#!/bin/sh
#names=$(cat ./names.log)
echo "文件名:$1";

echo "OptimizingCompiler::TryCompile()";
grep -c "ZJH:Trycompile() is called!!! " $1

echo "JitCompile()";
grep -c "ZJH: JitCompile() is called!!! " $1

echo "JniCompile()";
grep -c "ZJH:Jnicompile() is called!!! " $1

echo "ExecuteSwitchImplCpp()";
grep -c "ZJH: ExecuteSwitchImplCpp() is called!! " $1

echo "ExecuteMterpImpl()";
grep -c "ZJH: ExecuteMterpImpl() is called!!! " $1
  1. 由于加入了大量的打印,需要给log区扩容,emulator启动后首先可以通过adb logcat -g查看缓冲区的大小,再通过adb logcat -G 256m将缓冲区的大小更改为256M


    image.png
  2. 配置完缓冲区的大小之后,重新开机,首先抓取log adb logcat > bootup.log
  3. 启动完成之后执行脚本统计各个方法被调用的次数


    image.png
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容