/** * Read a map of {list_name : class_list} from json */ std::unordered_map<std::string, std::vector<std::string> > ConfigFiles::load_class_lists() { std::unordered_map<std::string, std::vector<std::string> > lists; std::string class_lists_filename; this->m_json.get("class_lists", "", class_lists_filename); if (class_lists_filename.empty()) { return lists; } std::ifstream input(class_lists_filename); Json::Reader reader; Json::Value root; bool parsing_succeeded = reader.parse(input, root); always_assert_log(parsing_succeeded, "Failed to parse class list json from file: %s\n%s", class_lists_filename.c_str(), reader.getFormattedErrorMessages().c_str()); for (Json::ValueIterator it = root.begin(); it != root.end(); ++it) { std::vector<std::string> class_list; Json::Value current_list = *it; for (Json::ValueIterator list_it = current_list.begin(); list_it != current_list.end(); ++list_it) { lists[it.key().asString()].push_back((*list_it).asString()); } } lists["secondary_dex_head.list"] = get_coldstart_classes(); return lists; }
void StaticSinkPass::run_pass(DexClassesVector& dexen, ConfigFiles& cfg) { auto method_list = cfg.get_coldstart_methods(); auto methods = strings_to_dexmethods(method_list); TRACE(SINK, 1, "methods used in coldstart: %lu\n", methods.size()); auto coldstart_classes = get_coldstart_classes(dexen, cfg); count_coldstart_statics(coldstart_classes); auto statics = get_noncoldstart_statics(coldstart_classes, methods); TRACE(SINK, 1, "statics not used in coldstart: %lu\n", statics.size()); remove_primary_dex_refs(dexen[0], statics); TRACE(SINK, 1, "statics after removing primary dex: %lu\n", statics.size()); auto sink_map = get_sink_map(dexen, coldstart_classes, statics); TRACE(SINK, 1, "statics with sinkable callsite: %lu\n", sink_map.size()); auto holder = move_statics_out(statics, sink_map); TRACE(SINK, 1, "methods in static holder: %lu\n", holder->get_dmethods().size()); DexClasses dc(1); dc.insert_at(holder, 0); dexen.emplace_back(std::move(dc)); }