UsageError("Command: %s", CommandLine().c_str());
UsageError(" Performs a dexopt analysis on the given dex file and returns whether or not");
UsageError(" the dex file needs to be dexopted.");
UsageError("Usage: dexoptanalyzer [options]...");
UsageError("");
UsageError(" --dex-file=<filename>: the dex file which should be analyzed.");
UsageError("");
UsageError(" --isa=<string>: the instruction set for which the analysis should be performed.");
UsageError("");
UsageError(" --compiler-filter=<string>: the target compiler filter to be used as reference");
UsageError(" when deciding if the dex file needs to be optimized.");
UsageError("");
UsageError(" --profile_analysis_result=<int>: the result of the profile analysis, used in");
UsageError(" deciding if the dex file needs to be optimized.");
UsageError("");
UsageError(" --image=<filename>: optional, the image to be used to decide if the associated");
UsageError(" oat file is up to date. Defaults to $ANDROID_ROOT/framework/boot.art.");
UsageError(" Example: --image=/system/framework/boot.art");
UsageError("");
UsageError(" --runtime-arg <argument>: used to specify various arguments for the runtime,");
UsageError(" such as initial heap size, maximum heap size, and verbose output.");
UsageError(" Use a separate --runtime-arg switch for each argument.");
UsageError(" Example: --runtime-arg -Xms256m");
UsageError("");
UsageError(" --android-data=<directory>: optional, the directory which should be used as");
UsageError(" android-data. By default ANDROID_DATA env variable is used.");
UsageError("");
UsageError(" --oat-fd=number: file descriptor of the oat file which should be analyzed");
UsageError("");
UsageError(" --vdex-fd=number: file descriptor of the vdex file corresponding to the oat file");
UsageError("");
UsageError(" --zip-fd=number: specifies a file descriptor corresponding to the dex file.");
UsageError("");
UsageError(" --downgrade: optional, if the purpose of dexopt is to downgrade the dex file");
UsageError(" By default, dexopt considers upgrade case.");
UsageError("");
UsageError(" --class-loader-context=<string spec>: a string specifying the intended");
UsageError(" runtime loading context for the compiled dex files.");
UsageError("");
UsageError(" --class-loader-context-fds=<fds>: a colon-separated list of file descriptors");
UsageError(" for dex files in --class-loader-context. Their order must be the same as");
UsageError(" dex files in flattened class loader context.");
UsageError("");
UsageError(" --flatten-class-loader-context: parse --class-loader-context, flatten it and");
UsageError(" print a colon-separated list of its dex files to standard output. Dexopt");
UsageError(" needed analysis is not performed when this option is set.");
UsageError("");
UsageError("Return code:");
UsageError(" To make it easier to integrate with the internal tools this command will make");
UsageError(" available its result (dexoptNeeded) as the exit/return code. i.e. it will not");
UsageError(" return 0 for success and a non zero values for errors as the conventional");
UsageError(" commands. The following return codes are possible:");
UsageError(" kNoDexOptNeeded = 0");
UsageError(" kDex2OatFromScratch = 1");
UsageError(" kDex2OatForBootImageOat = 2");
UsageError(" kDex2OatForFilterOat = 3");
UsageError(" kDex2OatForBootImageOdex = 4");
UsageError(" kDex2OatForFilterOdex = 5");
if (image_.empty()) { // If we don't receive the image, try to use the default one. // Tests may specify a different image (e.g. core image).
std::string error_msg;
std::string android_root = GetAndroidRootSafe(&error_msg); if (android_root.empty()) {
LOG(ERROR) << error_msg;
Usage("--image unspecified and ANDROID_ROOT not set.");
}
image_ = GetDefaultBootImageLocationSafe(
android_root, /*deny_art_apex_data_files=*/false, &error_msg); if (image_.empty()) {
LOG(ERROR) << error_msg;
Usage("--image unspecified and failed to get default boot image location.");
}
}
}
bool CreateRuntime(CompilerCallbacks* callbacks) const {
RuntimeOptions options; // The image could be custom, so make sure we explicitly pass it.
std::string img = "-Ximage:" + image_;
options.push_back(std::make_pair(img, nullptr)); // The instruction set of the image should match the instruction set we will test. constvoid* isa_opt = reinterpret_cast<constvoid*>(GetInstructionSetString(isa_));
options.push_back(std::make_pair("imageinstructionset", isa_opt)); // Explicit runtime args. for (constchar* runtime_arg : runtime_args_) {
options.push_back(std::make_pair(runtime_arg, nullptr));
} // Disable libsigchain. We don't don't need it to evaluate DexOptNeeded status.
options.push_back(std::make_pair("-Xno-sig-chain", nullptr)); // Pretend we are a compiler so that we can re-use the same infrastructure to load a different // ISA image and minimize the amount of things that get started.
options.push_back(std::make_pair("compilercallbacks", callbacks)); // Make sure we don't attempt to relocate. The tool should only retrieve the DexOptNeeded // status and not attempt to relocate the boot image.
options.push_back(std::make_pair("-Xnorelocate", nullptr));
if (!Runtime::Create(options, false)) {
LOG(ERROR) << "Unable to initialize runtime"; returnfalse;
} // Runtime::Create acquired the mutator_lock_ that is normally given away when we // Runtime::Start. Give it away now.
Thread::Current()->TransitionFromRunnableToSuspended(ThreadState::kNative);
// Only when the runtime is created can we create the class loader context: the // class loader context will open dex file and use the MemMap global lock that the // runtime owns.
std::unique_ptr<ClassLoaderContext> class_loader_context; if (!context_str_.empty()) {
class_loader_context = ClassLoaderContext::Create(context_str_); if (class_loader_context == nullptr) {
Usage("Invalid --class-loader-context '%s'", context_str_.c_str());
}
} if (class_loader_context != nullptr) {
size_t dir_index = dex_file_.rfind('/');
std::string classpath_dir = (dir_index != std::string::npos)
? dex_file_.substr(0, dir_index)
: "";
if (!class_loader_context->OpenDexFiles(classpath_dir,
context_fds_, /*only_read_checksums=*/ true)) { return ReturnCode::kDex2OatFromScratch;
}
}
std::unique_ptr<OatFileAssistant> oat_file_assistant;
oat_file_assistant = std::make_unique<OatFileAssistant>(dex_file_.c_str(),
isa_,
class_loader_context.get(), /*load_executable=*/ false, /*only_load_trusted_executable=*/ false, /*runtime_options=*/ nullptr,
vdex_fd_,
oat_fd_,
zip_fd_); // Always treat elements of the bootclasspath as up-to-date. // TODO(calin): this check should be in OatFileAssistant. if (oat_file_assistant->IsInBootClassPath()) { return ReturnCode::kNoDexOptNeeded;
}
// If the compiler filter depends on profiles but the profiles are empty, // change the test filter to kVerify. It's what dex2oat also does.
CompilerFilter::Filter actual_compiler_filter = compiler_filter_; if (CompilerFilter::DependsOnProfile(compiler_filter_) &&
profile_analysis_result_ == ProfileAnalysisResult::kDontOptimizeEmptyProfiles) {
actual_compiler_filter = CompilerFilter::kVerify;
}
// TODO: GetDexOptNeeded should get the raw analysis result instead of assume_profile_changed. bool assume_profile_changed = profile_analysis_result_ == ProfileAnalysisResult::kOptimize; int dexoptNeeded = oat_file_assistant->GetDexOptNeeded(actual_compiler_filter,
assume_profile_changed,
downgrade_);
// Convert OatFileAssistant codes to dexoptanalyzer codes. switch (dexoptNeeded) { case OatFileAssistant::kNoDexOptNeeded: return ReturnCode::kNoDexOptNeeded; case OatFileAssistant::kDex2OatFromScratch: return ReturnCode::kDex2OatFromScratch; case OatFileAssistant::kDex2OatForBootImage: return ReturnCode::kDex2OatForBootImageOat; case OatFileAssistant::kDex2OatForFilter: return ReturnCode::kDex2OatForFilterOat;
case -OatFileAssistant::kDex2OatForBootImage: return ReturnCode::kDex2OatForBootImageOdex; case -OatFileAssistant::kDex2OatForFilter: return ReturnCode::kDex2OatForFilterOdex; default:
LOG(ERROR) << "Unknown dexoptNeeded " << dexoptNeeded; return ReturnCode::kErrorUnknownDexOptNeeded;
}
}
// Parse arguments. Argument mistakes will lead to exit(kErrorInvalidArguments) in UsageError.
analyzer.ParseArgs(argc, argv); return analyzer.Run();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.