ARTist中dex2oat和原生dex2oat的区别

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhu929033262/article/details/78580278

为了更好了解ARTist的工作原理,这里分析下ARTist中dex2oat的特殊之处。
dex2oat的基本流程请参考我之前的文章:dex2oat源码流程分析

首先看原生dex2oat的代码流程:
dex2oat的代码流程

首先第一个区别在Compile函数:

  void Compile() {
    TimingLogger::ScopedTiming t("dex2oat Compile", timings_);
    compiler_phases_timings_.reset(new CumulativeLogger("compilation times"));

    // Handle and ClassLoader creation needs to come after Runtime::Create
    jobject class_loader = nullptr;
    Thread* self = Thread::Current();
    if (!boot_image_option_.empty()) {
      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
      OpenClassPathFiles(runtime_->GetClassPathString(), dex_files_, &class_path_files_);
      ScopedObjectAccess soa(self);

      // Classpath: first the class-path given.
      std::vector<const DexFile*> class_path_files;
      for (auto& class_path_file : class_path_files_) {
        class_path_files.push_back(class_path_file.get());
      }

      // Store the classpath we have right now.
      key_value_store_->Put(OatHeader::kClassPathKey,
                            OatFile::EncodeDexFileDependencies(class_path_files));

      // Then the dex files we'll compile. Thus we'll resolve the class-path first.
      class_path_files.insert(class_path_files.end(), dex_files_.begin(), dex_files_.end());

      class_loader = class_linker->CreatePathClassLoader(self, class_path_files);

-------------------------------------------------------------------------------------------------------------------
      /* artist setup and module management */

      ArtistLog::SetupArtistLogging();

      VLOG(artist) << "START ARTIST SETUP (dex2oat)";

      ModuleManager& module_manager = ModuleManager::getInstance();

      // TODO eventually the modules should register themselves, e.g., from their own .so
      module_manager.registerModule("trace", make_shared<TraceModule>());
      module_manager.registerModule("logtimization", make_shared<LogtimizationModule>());

      // initialize modules
      module_manager.initializeModules(dex_files_, class_loader);

      VLOG(artist) << "END ARTIST SETUP (dex2oat)";
-------------------------------------------------------------------------------------------------------------------

    }

    driver_ = new CompilerDriver(compiler_options_.get(),
                                 verification_results_,
                                 &method_inliner_map_,
                                 compiler_kind_,
                                 instruction_set_,
                                 instruction_set_features_.get(),
                                 image_,
                                 image_classes_.release(),
                                 compiled_classes_.release(),
                                 nullptr,
                                 thread_count_,
                                 dump_stats_,
                                 dump_passes_,
                                 dump_cfg_file_name_,
                                 compiler_phases_timings_.get(),
                                 swap_fd_,
                                 profile_file_);

    driver_->CompileAll(class_loader, dex_files_, timings_);
  }

ARTist比原生代码多出了横线中间的部分,ModuleManager::getInstance()返回一个ModuleManager句柄,然后module_manager.registerModule按照key,value索引把Module存放在_modules这个map中,module_manager.initializeModules代码如下:

void ModuleManager::initializeModules(vector<const DexFile*> dex_files, jobject jclass_loader) {
  VLOG(artistd) << "ModuleManager: initializing modules ";
  if (init_flag.exchange(true)) {  // atomic check and set
      string msg = "ModuleManager: Attempting to initialize modules more than once.";
    ErrorHandler::abortCompilation(msg);
  }

  _dex_file_env = make_shared<DexfileEnvironment>(dex_files);

  for (auto it : _modules) {
    auto id = it.first;
    auto module = it.second;
    auto codelib = module->createCodeLib();

    // initialize environment for codelib if present
    if (codelib != nullptr) {
      VLOG(artistd) << "ModuleManager: initializing codelib environment for module " << id;

      const MethodSignature signature = codelib->getCodeClass();
      const DexFile* codelib_dexfile = nullptr;
      for (auto && dexfile : dex_files) {
        // check whether `dexfile` defines the code lib class (lookup by signature)
        if (ArtUtils::FindClassDefIdxFromName(dexfile, signature)) {
          codelib_dexfile = dexfile;
          VLOG(artistd) << "ModuleManager: Found " << signature << " in dex file " << codelib_dexfile->GetLocation();
          break;
        }
      }
      if (codelib_dexfile == nullptr) {
        auto msg = "Could not find dexfile defining codelib class " + signature
                   + " (requires codelib). Deactivating module " + id + ".";
        VLOG(artistd) << msg;
        module->setEnabled(false);
      } else {
        _dex_file_env->declareCodelib(codelib_dexfile);
        _environments[id] = make_shared<CodeLibEnvironment>(_dex_file_env, codelib_dexfile, codelib, jclass_loader);
      }
    }
  }

  VLOG(artistd) << "ModuleManager: initialized " << _environments.size() << " codelib environments (" << _modules.size() << " modules)";
  init_flag = true;
}

首先遍历_modules,对于每一个注册的module,查找其对应的codelib,找到后再用_dex_file_env->declareCodelib注册声明其codelib的dex文件。看一下这个函数:

void DexfileEnvironment::declareCodelib(const DexFile* codelib_dex_file) {
  CHECK(codelib_dex_file != nullptr);
  VLOG(artistd) << "declaring dex file as codelib: " << codelib_dex_file->GetLocation();

  // preconditions: all dex files are known beforehand and we only, step by step, move codelib dex files over from
  // the app dex files list
  CHECK(find(_all.begin(), _all.end(), codelib_dex_file) != _all.end());

  auto app_iter = find(_app_dex_files.begin(), _app_dex_files.end(), codelib_dex_file);
  CHECK(app_iter != _all.end());
  _app_dex_files.erase(app_iter);

  CHECK(find(_codelibs.begin(), _codelibs.end(), codelib_dex_file) == _codelibs.end());
  _codelibs.push_back(codelib_dex_file);
}

最终把codelib_dex_file文件注册在DexfileEnvironment的_codelibs对象中保存。

compile之后的CompilerDriver基本未修改,只是加入了引入codelib_environment.h和artist_log.h两个头文件。

再看编译参数多出来的地方,修改后的编译参数:

export LD_LIBRARY_PATH=/data/app/saarland.cispa.artist.artistgui-1/lib/arm:/data/user/0/saarland.cispa.artist.artistgui/files/artist/lib/;/data/user/0/saarland.cispa.artist.artistgui/files/artist/dex2oat –oat-file=/data/app/com.xidian.testapp-1/oat/arm/base.odex –compiler-backend=Optimizing –compiler-filter=everything –generate-debug-info –compile-pic –dex-file=/data/user/0/saarland.cispa.artist.artistgui/files/base_merged-signed.apk –dex-location=/data/app/com.xidian.testapp-1/base.apk –checksum-rewriting
阅读更多
想对作者说点什么? 我来说一句
相关热词

没有更多推荐了,返回首页