Exemplo n.º 1
0
void PassManager::activate_pass(const char* name, const Json::Value& cfg) {
  std::string name_str(name);

  // Names may or may not have a "#<id>" suffix to indicate their order in the
  // pass list, which needs to be removed for matching.
  std::string pass_name = name_str.substr(0, name_str.find("#"));
  for (auto pass : m_registered_passes) {
    if (pass_name == pass->name()) {
      m_activated_passes.push_back(pass);

      // Retrieving the configuration specific to this particular run
      // of the pass.
      pass->configure_pass(JsonWrapper(cfg[name_str]));
      return;
    }
  }
  always_assert_log(false, "No pass named %s!", name);
}
Exemplo n.º 2
0
void TypeErasurePass::configure_pass(const JsonWrapper& jw) {
  jw.get("merged_type_mappings", "", m_merged_type_mapping_file);
  bool devirtualize_non_virtuals;
  jw.get("devirtualize", false, devirtualize_non_virtuals);
  bool process_method_meta;
  jw.get("process_method_meta", false, process_method_meta);
  int64_t max_num_dispatch_target;
  jw.get("max_num_dispatch_target", 0, max_num_dispatch_target);
  if (max_num_dispatch_target > 0) {
    m_max_num_dispatch_target =
        boost::optional<size_t>(static_cast<size_t>(max_num_dispatch_target));
  }
  bool merge_static_methods_within_shape;
  jw.get("merge_static_methods_within_shape", false,
         merge_static_methods_within_shape);
  bool merge_direct_methods_within_shape;
  jw.get("merge_direct_methods_within_shape", false,
         merge_direct_methods_within_shape);
  bool merge_nonvirt_methods_within_shape;
  jw.get("merge_nonvirt_methods_within_shape", false,
         merge_nonvirt_methods_within_shape);

  // load model specifications
  Json::Value models;
  jw.get("models", Json::Value(), models);
  if (models.isNull()) return;
  if (!models.isArray()) {
    fprintf(stderr, "[TERA] Wrong specification: \"models\" is not an array\n");
    return;
  }

  // load each model spec for erasure
  for (auto it = models.begin(); it != models.end(); ++it) {
    const auto& value = *it;
    if (!value.isObject()) {
      fprintf(stderr,
              "[TERA] Wrong specification: model in array not an object\n");
      m_model_specs.clear();
      return;
    }
    JsonWrapper model_spec = JsonWrapper(value);
    ModelSpec model;
    model_spec.get("enabled", true, model.enabled);
    std::string type_tag_config;
    model_spec.get("type_tag_config", "generate", type_tag_config);
    model.type_tag_config = get_type_tag_config(type_tag_config);
    size_t min_count;
    model_spec.get("min_count", 1, min_count);
    model.min_count = min_count > 0 ? min_count : 0;
    model_spec.get("name", "", model.name);
    std::vector<std::string> root_names;
    model_spec.get("roots", {}, root_names);
    load_types(root_names, model.roots);
    std::vector<std::string> excl_names;
    model_spec.get("exclude", {}, excl_names);
    load_types(excl_names, model.exclude_types);
    model_spec.get("class_name_prefix", "", model.class_name_prefix);
    Json::Value generated;
    model_spec.get("generated", Json::Value(), generated);
    if (!generated.isNull()) {
      if (!generated.isObject()) {
        fprintf(stderr,
                "[TERA] Wrong specification: model in array not an object\n");
        m_model_specs.clear();
        return;
      }
      JsonWrapper gen_spec = JsonWrapper(generated);
      std::vector<std::string> gen_names;
      gen_spec.get("other_roots", {}, gen_names);
      load_types(gen_names, model.gen_types);

      std::vector<std::string> gen_anno_names;
      gen_spec.get("annos", {}, gen_anno_names);
      load_types(gen_anno_names, model.gen_annos);
    }
    model_spec.get("include_primary_dex", false, model.include_primary_dex);
    model_spec.get("dex_sharding", false, model.dex_sharding);

    std::string merge_per_interdex_set;
    model_spec.get("merge_per_interdex_set", "disabled",
                   merge_per_interdex_set);
    model.merge_per_interdex_set =
        get_merge_per_interdex_type(merge_per_interdex_set);

    always_assert_log(!model.merge_per_interdex_set ||
                          (model.type_tag_config != TypeTagConfig::NONE),
                      "Cannot group when type tag is not needed.");
    always_assert_log(!model.dex_sharding || !model.merge_per_interdex_set,
                      "Cannot have both dex sharding and group sharding "
                      "enabled!");

    size_t max_count;
    model_spec.get("max_count", 0, max_count);
    Json::Value approximate_shaping;
    model_spec.get("approximate_shape_merging", Json::Value(),
                   model.approximate_shape_merging);
    model_spec.get("merge_types_with_static_fields", false,
                   model.merge_types_with_static_fields);
    model_spec.get("keep_debug_info", false, model.keep_debug_info);
    model_spec.get("exclude_reference_to_android_sdk", Json::Value(),
                   model.exclude_reference_to_android_sdk);
    if (max_count > 0) {
      model.max_count = boost::optional<size_t>(max_count);
    }
    model.devirtualize_non_virtuals = devirtualize_non_virtuals;
    model.process_method_meta = process_method_meta;
    model.merge_static_methods_within_shape = merge_static_methods_within_shape;
    model.merge_direct_methods_within_shape = merge_direct_methods_within_shape;
    model.merge_nonvirt_methods_within_shape =
        merge_nonvirt_methods_within_shape;
    if (!verify_model_spec(model)) {
      continue;
    }

    if (model.dex_sharding) {
      if (!model.enabled) {
        TRACE(TERA, 3, "Per dex Type Erased model not enabled. Skipping %s\n",
              model.name.c_str());
      } else {
        m_dex_sharding_model_specs.emplace_back(std::move(model));
      }
    } else {
      m_model_specs.emplace_back(std::move(model));
    }
  }

  TRACE(TERA, 1, "[TERA] valid model specs %ld\n", m_model_specs.size());
}