Use help-text generator for dex2oat
The use of a static text blob makes keeping the dex2oat help text up
to date difficult. Change to use the new cmdline help-text generator
code.
Test: dex2oat --help
Change-Id: I1139cba2c773242e15f863d7efd2c7050c05ab4f
diff --git a/cmdline/cmdline_parser.h b/cmdline/cmdline_parser.h
index 86e3b2c..22eb44c 100644
--- a/cmdline/cmdline_parser.h
+++ b/cmdline/cmdline_parser.h
@@ -755,10 +755,12 @@
vios.Stream();
}
}
- vios.Stream() << "The following arguments are ignored for compatibility:" << std::endl;
- ScopedIndentation si(&vios);
- for (auto ign : ignore_list_) {
- vios.Stream() << ign << std::endl;
+ if (!ignore_list_.empty()) {
+ vios.Stream() << "The following arguments are ignored for compatibility:" << std::endl;
+ ScopedIndentation si(&vios);
+ for (auto ign : ignore_list_) {
+ vios.Stream() << ign << std::endl;
+ }
}
}
diff --git a/cmdline/detail/cmdline_parse_argument_detail.h b/cmdline/detail/cmdline_parse_argument_detail.h
index f5cbda9..0f73a76 100644
--- a/cmdline/detail/cmdline_parse_argument_detail.h
+++ b/cmdline/detail/cmdline_parse_argument_detail.h
@@ -145,6 +145,8 @@
template <typename T = TArg> // Necessary to get SFINAE to kick in.
void DumpHelp(VariableIndentationOutputStream& vios) {
+ // Separate arguments
+ vios.Stream() << std::endl;
for (auto cname : names_) {
std::string_view name = cname;
auto& os = vios.Stream();
diff --git a/compiler/driver/compiler_options_map-inl.h b/compiler/driver/compiler_options_map-inl.h
index e80fb46..fcbc0f2 100644
--- a/compiler/driver/compiler_options_map-inl.h
+++ b/compiler/driver/compiler_options_map-inl.h
@@ -31,17 +31,29 @@
namespace art {
+template <>
+struct CmdlineType<CompilerFilter::Filter> : CmdlineTypeParser<CompilerFilter::Filter> {
+ Result Parse(const std::string& option) {
+ CompilerFilter::Filter compiler_filter;
+ if (!CompilerFilter::ParseCompilerFilter(option.c_str(), &compiler_filter)) {
+ return Result::Failure(
+ android::base::StringPrintf("Unknown --compiler-filter value %s", option.c_str()));
+ }
+ return Result::Success(compiler_filter);
+ }
+
+ static const char* Name() {
+ return "CompilerFilter";
+ }
+ static const char* DescribeType() {
+ return CompilerFilter::DescribeOptions();
+ }
+};
+
template <class Base>
inline bool ReadCompilerOptions(Base& map, CompilerOptions* options, std::string* error_msg) {
if (map.Exists(Base::CompilerFilter)) {
- CompilerFilter::Filter compiler_filter;
- if (!CompilerFilter::ParseCompilerFilter(map.Get(Base::CompilerFilter)->c_str(),
- &compiler_filter)) {
- *error_msg = android::base::StringPrintf("Unknown --compiler-filter value %s",
- map.Get(Base::CompilerFilter)->c_str());
- return false;
- }
- options->SetCompilerFilter(compiler_filter);
+ options->SetCompilerFilter(*map.Get(Base::CompilerFilter));
}
map.AssignIfExists(Base::CompileArtTest, &options->compile_art_test_);
map.AssignIfExists(Base::HugeMethodMaxThreshold, &options->huge_method_threshold_);
@@ -108,7 +120,9 @@
inline void AddCompilerOptionsArgumentParserOptions(Builder& b) {
b.
Define("--compiler-filter=_")
- .template WithType<std::string>()
+ .template WithType<CompilerFilter::Filter>()
+ .WithHelp("Select compiler filter\n"
+ "Default: speed-profile if profile provided, speed otherwise")
.IntoKey(Map::CompilerFilter)
.Define({"--compile-art-test", "--no-compile-art-test"})
@@ -116,31 +130,49 @@
.IntoKey(Map::CompileArtTest)
.Define("--huge-method-max=_")
.template WithType<unsigned int>()
+ .WithHelp("threshold size for a huge method for compiler filter tuning.")
.IntoKey(Map::HugeMethodMaxThreshold)
.Define("--large-method-max=_")
.template WithType<unsigned int>()
+ .WithHelp("threshold size for a large method for compiler filter tuning.")
.IntoKey(Map::LargeMethodMaxThreshold)
.Define("--num-dex-methods=_")
.template WithType<unsigned int>()
+ .WithHelp("threshold size for a small dex file for compiler filter tuning. If the input\n"
+ "has fewer than this many methods and the filter is not interpret-only or\n"
+ "verify-none or verify-at-runtime, overrides the filter to use speed")
.IntoKey(Map::NumDexMethodsThreshold)
.Define("--inline-max-code-units=_")
.template WithType<unsigned int>()
+ .WithHelp("the maximum code units that a methodcan have to be considered for inlining.\n"
+ "A zero value will disable inlining. Honored only by Optimizing. Has priority\n"
+ "over the --compiler-filter option. Intended for development/experimental use.")
.IntoKey(Map::InlineMaxCodeUnitsThreshold)
.Define({"--generate-debug-info", "-g", "--no-generate-debug-info"})
.WithValues({true, true, false})
+ .WithHelp("Generate (or don't generate) debug information for native debugging, such as\n"
+ "stack unwinding information, ELF symbols and dwarf sections. If used without\n"
+ "--debuggable it will be best effort only. Does not affect the generated\n"
+ "code. Disabled by default.")
.IntoKey(Map::GenerateDebugInfo)
.Define({"--generate-mini-debug-info", "--no-generate-mini-debug-info"})
.WithValues({true, false})
+ .WithHelp("Whether or not to generate minimal amount of LZMA-compressed debug\n"
+ "information necessary to print backtraces (disabled by default).")
.IntoKey(Map::GenerateMiniDebugInfo)
.Define({"--generate-build-id", "--no-generate-build-id"})
.WithValues({true, false})
+ .WithHelp("Generate GNU-compatible linker build ID ELF section with SHA-1 of the file\n"
+ "content (and thus stable across identical builds)")
.IntoKey(Map::GenerateBuildID)
.Define({"--deduplicate-code=_"})
.template WithType<bool>()
.WithValueMap({{"false", false}, {"true", true}})
+ .WithHelp("enable|disable code deduplication. Deduplicated code will have an arbitrary\n"
+ "symbol tagged with [DEDUPED].")
.IntoKey(Map::DeduplicateCode)
.Define({"--count-hotness-in-compiled-code"})
@@ -153,18 +185,24 @@
.IntoKey(Map::CheckProfiledMethods)
.Define({"--dump-timings"})
+ .WithHelp("Display a breakdown of where time was spent.")
.IntoKey(Map::DumpTimings)
.Define({"--dump-pass-timings"})
+ .WithHelp("Display a breakdown time spent in optimization passes for each compiled"
+ " method.")
.IntoKey(Map::DumpPassTimings)
.Define({"--dump-stats"})
+ .WithHelp("Display overall compilation statistics.")
.IntoKey(Map::DumpStats)
.Define("--debuggable")
+ .WithHelp("Produce code debuggable with a java-debugger.")
.IntoKey(Map::Debuggable)
.Define("--baseline")
+ .WithHelp("Produce code using the baseline compilation")
.IntoKey(Map::Baseline)
.Define("--top-k-profile-threshold=_")
@@ -184,8 +222,12 @@
.Define("--dump-cfg=_")
.template WithType<std::string>()
+ .WithHelp("Dump control-flow graphs (CFGs) to specified file.")
.IntoKey(Map::DumpCFG)
.Define("--dump-cfg-append")
+ .WithHelp("when dumping CFGs to an existing file, append new CFG data to existing data\n"
+ "(instead of overwriting existing data with new data, which is the default\n"
+ "behavior). This option is only meaningful when used with --dump-cfg.")
.IntoKey(Map::DumpCFGAppend)
.Define("--register-allocation-strategy=_")
@@ -195,6 +237,8 @@
.Define("--resolve-startup-const-strings=_")
.template WithType<bool>()
.WithValueMap({{"false", false}, {"true", true}})
+ .WithHelp("If true, the compiler eagerly resolves strings referenced from const-string\n"
+ "of startup methods.")
.IntoKey(Map::ResolveStartupConstStrings)
.Define("--initialize-app-image-classes=_")
@@ -204,10 +248,13 @@
.Define("--verbose-methods=_")
.template WithType<ParseStringList<','>>()
+ .WithHelp("Restrict the dumped CFG data to methods whose name is listed.\n"
+ "Eg: --verbose-methods=toString,hashCode")
.IntoKey(Map::VerboseMethods)
.Define("--max-image-block-size=_")
.template WithType<unsigned int>()
+ .WithHelp("Maximum solid block size for compressed images.")
.IntoKey(Map::MaxImageBlockSize);
}
diff --git a/compiler/driver/compiler_options_map.def b/compiler/driver/compiler_options_map.def
index 40a6284..b1398c9 100644
--- a/compiler/driver/compiler_options_map.def
+++ b/compiler/driver/compiler_options_map.def
@@ -36,7 +36,7 @@
// Parse-able keys from the command line.
// TODO: Add type parser.
-COMPILER_OPTIONS_KEY (std::string, CompilerFilter)
+COMPILER_OPTIONS_KEY (CompilerFilter::Filter, CompilerFilter)
COMPILER_OPTIONS_KEY (bool, CompileArtTest)
COMPILER_OPTIONS_KEY (Unit, PIC)
COMPILER_OPTIONS_KEY (unsigned int, HugeMethodMaxThreshold)
diff --git a/compiler/driver/compiler_options_map.h b/compiler/driver/compiler_options_map.h
index af212d6..14f5112 100644
--- a/compiler/driver/compiler_options_map.h
+++ b/compiler/driver/compiler_options_map.h
@@ -22,6 +22,7 @@
#include "base/variant_map.h"
#include "cmdline_types.h"
+#include "compiler_filter.h"
namespace art {
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 3e0bb88..fe826c1 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -230,307 +230,12 @@
UsageError("Usage: dex2oat [options]...");
UsageError("");
- UsageError(" -j<number>: specifies the number of threads used for compilation.");
- UsageError(" Default is the number of detected hardware threads available on the");
- UsageError(" host system.");
- UsageError(" Example: -j12");
- UsageError("");
- UsageError(" --cpu-set=<set>: sets the cpu affinity to <set>. The <set> argument is a comma");
- UsageError(" separated list of CPUs.");
- UsageError(" Example: --cpu-set=0,1,2,3");
- UsageError("");
- UsageError(" --dex-file=<dex-file>: specifies a .dex, .jar, or .apk file to compile.");
- UsageError(" Example: --dex-file=/system/framework/core.jar");
- UsageError("");
- UsageError(" --dex-location=<dex-location>: specifies an alternative dex location to");
- UsageError(" encode in the oat file for the corresponding --dex-file argument.");
- UsageError(" Example: --dex-file=/home/build/out/system/framework/core.jar");
- UsageError(" --dex-location=/system/framework/core.jar");
- UsageError("");
- UsageError(" --zip-fd=<file-descriptor>: specifies a file descriptor of a zip file");
- UsageError(" containing a classes.dex file to compile.");
- UsageError(" Example: --zip-fd=5");
- UsageError("");
- UsageError(" --zip-location=<zip-location>: specifies a symbolic name for the file");
- UsageError(" corresponding to the file descriptor specified by --zip-fd.");
- UsageError(" Example: --zip-location=/system/app/Calculator.apk");
- UsageError("");
- UsageError(" --oat-file=<file.oat>: specifies an oat output destination via a filename.");
- UsageError(" Example: --oat-file=/system/framework/boot.oat");
- UsageError("");
- UsageError(" --oat-symbols=<file.oat>: specifies a symbolized oat output destination.");
- UsageError(" Example: --oat-file=symbols/system/framework/boot.oat");
- UsageError("");
- UsageError(" --oat-fd=<number>: specifies the oat output destination via a file descriptor.");
- UsageError(" Example: --oat-fd=6");
- UsageError("");
- UsageError(" --input-vdex-fd=<number>: specifies the vdex input source via a file descriptor.");
- UsageError(" Example: --input-vdex-fd=6");
- UsageError("");
- UsageError(" --output-vdex-fd=<number>: specifies the vdex output destination via a file");
- UsageError(" descriptor.");
- UsageError(" Example: --output-vdex-fd=6");
- UsageError("");
- UsageError(" --oat-location=<oat-name>: specifies a symbolic name for the file corresponding");
- UsageError(" to the file descriptor specified by --oat-fd.");
- UsageError(" Example: --oat-location=/data/dalvik-cache/system@app@Calculator.apk.oat");
- UsageError("");
- UsageError(" --oat-symbols=<file.oat>: specifies a destination where the oat file is copied.");
- UsageError(" This is equivalent to file copy as build post-processing step.");
- UsageError(" It is intended to be used with --strip and it happens before it.");
- UsageError(" Example: --oat-symbols=/symbols/system/framework/boot.oat");
- UsageError("");
- UsageError(" --strip: remove all debugging sections at the end (but keep mini-debug-info).");
- UsageError(" This is equivalent to the \"strip\" command as build post-processing step.");
- UsageError(" It is intended to be used with --oat-symbols and it happens after it.");
- UsageError(" Example: --oat-symbols=/symbols/system/framework/boot.oat");
- UsageError("");
- UsageError(" --image=<file.art>: specifies an output image filename.");
- UsageError(" Example: --image=/system/framework/boot.art");
- UsageError("");
- UsageError(" --image-fd=<number>: same as --image but accepts a file descriptor instead.");
- UsageError(" Cannot be used together with --image.");
- UsageError("");
- UsageError(" --image-format=(uncompressed|lz4|lz4hc):");
- UsageError(" Which format to store the image.");
- UsageError(" Example: --image-format=lz4");
- UsageError(" Default: uncompressed");
- UsageError("");
- UsageError(" --base=<hex-address>: specifies the base address when creating a boot image.");
- UsageError(" Example: --base=0x50000000");
- UsageError("");
- UsageError(" --boot-image=<file.art>: provide the image file for the boot class path.");
- UsageError(" Do not include the arch as part of the name, it is added automatically.");
- UsageError(" Example: --boot-image=/system/framework/boot.art");
- UsageError(" (specifies /system/framework/<arch>/boot.art as the image file)");
- UsageError(" Example: --boot-image=boot.art:boot-framework.art");
- UsageError(" (specifies <bcp-path1>/<arch>/boot.art as the image file and");
- UsageError(" <bcp-path2>/<arch>/boot-framework.art as the image extension file");
- UsageError(" with paths taken from corresponding boot class path components)");
- UsageError(" Example: --boot-image=/apex/com.android.art/boot.art:/system/framework/*:*");
- UsageError(" (specifies /apex/com.android.art/<arch>/boot.art as the image");
- UsageError(" file and search for extensions in /framework/system and boot");
- UsageError(" class path components' paths)");
- UsageError(" Default: $ANDROID_ROOT/system/framework/boot.art");
- UsageError("");
- UsageError(" --android-root=<path>: used to locate libraries for portable linking.");
- UsageError(" Example: --android-root=out/host/linux-x86");
- UsageError(" Default: $ANDROID_ROOT");
- UsageError("");
- UsageError(" --instruction-set=(arm|arm64|x86|x86_64): compile for a particular");
- UsageError(" instruction set.");
- UsageError(" Example: --instruction-set=x86");
- UsageError(" Default: arm");
- UsageError("");
- UsageError(" --instruction-set-features=...,: Specify instruction set features");
- UsageError(" On target the value 'runtime' can be used to detect features at run time.");
- UsageError(" If target does not support run-time detection the value 'runtime'");
- UsageError(" has the same effect as the value 'default'.");
- UsageError(" Note: the value 'runtime' has no effect if it is used on host.");
- UsageError(" Example: --instruction-set-features=div");
- UsageError(" Default: default");
- UsageError("");
- UsageError(" --compiler-backend=(Quick|Optimizing): select compiler backend");
- UsageError(" set.");
- UsageError(" Example: --compiler-backend=Optimizing");
- UsageError(" Default: Optimizing");
- UsageError("");
- UsageError(" --compiler-filter="
- "(assume-verified"
- "|extract"
- "|verify"
- "|quicken"
- "|space-profile"
- "|space"
- "|speed-profile"
- "|speed"
- "|everything-profile"
- "|everything):");
- UsageError(" select compiler filter.");
- UsageError(" Example: --compiler-filter=everything");
- UsageError(" Default: speed-profile if --profile-file or --profile-file-fd is used,");
- UsageError(" speed otherwise");
- UsageError("");
- UsageError(" --huge-method-max=<method-instruction-count>: threshold size for a huge");
- UsageError(" method for compiler filter tuning.");
- UsageError(" Example: --huge-method-max=%d", CompilerOptions::kDefaultHugeMethodThreshold);
- UsageError(" Default: %d", CompilerOptions::kDefaultHugeMethodThreshold);
- UsageError("");
- UsageError(" --large-method-max=<method-instruction-count>: threshold size for a large");
- UsageError(" method for compiler filter tuning.");
- UsageError(" Example: --large-method-max=%d", CompilerOptions::kDefaultLargeMethodThreshold);
- UsageError(" Default: %d", CompilerOptions::kDefaultLargeMethodThreshold);
- UsageError("");
- UsageError(" --num-dex-methods=<method-count>: threshold size for a small dex file for");
- UsageError(" compiler filter tuning. If the input has fewer than this many methods");
- UsageError(" and the filter is not interpret-only or verify-none or verify-at-runtime, ");
- UsageError(" overrides the filter to use speed");
- UsageError(" Example: --num-dex-method=%d", CompilerOptions::kDefaultNumDexMethodsThreshold);
- UsageError(" Default: %d", CompilerOptions::kDefaultNumDexMethodsThreshold);
- UsageError("");
- UsageError(" --inline-max-code-units=<code-units-count>: the maximum code units that a method");
- UsageError(" can have to be considered for inlining. A zero value will disable inlining.");
- UsageError(" Honored only by Optimizing. Has priority over the --compiler-filter option.");
- UsageError(" Intended for development/experimental use.");
- UsageError(" Example: --inline-max-code-units=%d",
- CompilerOptions::kDefaultInlineMaxCodeUnits);
- UsageError(" Default: %d", CompilerOptions::kDefaultInlineMaxCodeUnits);
- UsageError("");
- UsageError(" --dump-timings: display a breakdown of where time was spent");
- UsageError("");
- UsageError(" --dump-pass-timings: display a breakdown of time spent in optimization");
- UsageError(" passes for each compiled method.");
- UsageError("");
- UsageError(" -g");
- UsageError(" --generate-debug-info: Generate debug information for native debugging,");
- UsageError(" such as stack unwinding information, ELF symbols and DWARF sections.");
- UsageError(" If used without --debuggable, it will be best-effort only.");
- UsageError(" This option does not affect the generated code. (disabled by default)");
- UsageError("");
- UsageError(" --no-generate-debug-info: Do not generate debug information for native debugging.");
- UsageError("");
- UsageError(" --generate-mini-debug-info: Generate minimal amount of LZMA-compressed");
- UsageError(" debug information necessary to print backtraces. (disabled by default)");
- UsageError("");
- UsageError(" --no-generate-mini-debug-info: Do not generate backtrace info.");
- UsageError("");
- UsageError(" --generate-build-id: Generate GNU-compatible linker build ID ELF section with");
- UsageError(" SHA-1 of the file content (and thus stable across identical builds)");
- UsageError("");
- UsageError(" --no-generate-build-id: Do not generate the build ID ELF section.");
- UsageError("");
- UsageError(" --debuggable: Produce code debuggable with Java debugger.");
- UsageError("");
- UsageError(" --avoid-storing-invocation: Avoid storing the invocation args in the key value");
- UsageError(" store. Used to test determinism with different args.");
- UsageError("");
- UsageError(" --write-invocation-to=<file>: Write the invocation commandline to the given file");
- UsageError(" for later use. Used to test determinism with different host architectures.");
- 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(" --profile-file=<filename>: specify profiler output file to use for compilation.");
- UsageError("");
- UsageError(" --profile-file-fd=<number>: same as --profile-file but accepts a file descriptor.");
- UsageError(" Cannot be used together with --profile-file.");
- UsageError("");
- UsageError(" --swap-file=<file-name>: specifies a file to use for swap.");
- UsageError(" Example: --swap-file=/data/tmp/swap.001");
- UsageError("");
- UsageError(" --swap-fd=<file-descriptor>: specifies a file to use for swap (by descriptor).");
- UsageError(" Example: --swap-fd=10");
- UsageError("");
- UsageError(" --swap-dex-size-threshold=<size>: specifies the minimum total dex file size in");
- UsageError(" bytes to allow the use of swap.");
- UsageError(" Example: --swap-dex-size-threshold=1000000");
- UsageError(" Default: %zu", kDefaultMinDexFileCumulativeSizeForSwap);
- UsageError("");
- UsageError(" --swap-dex-count-threshold=<count>: specifies the minimum number of dex files to");
- UsageError(" allow the use of swap.");
- UsageError(" Example: --swap-dex-count-threshold=10");
- UsageError(" Default: %zu", kDefaultMinDexFilesForSwap);
- UsageError("");
- UsageError(" --very-large-app-threshold=<size>: specifies the minimum total dex file size in");
- UsageError(" bytes to consider the input \"very large\" and reduce compilation done.");
- UsageError(" Example: --very-large-app-threshold=100000000");
- UsageError("");
- UsageError(" --app-image-fd=<file-descriptor>: specify output file descriptor for app image.");
- UsageError(" The image is non-empty only if a profile is passed in.");
- UsageError(" Example: --app-image-fd=10");
- UsageError("");
- UsageError(" --app-image-file=<file-name>: specify a file name for app image.");
- UsageError(" Example: --app-image-file=/data/dalvik-cache/system@app@Calculator.apk.art");
- UsageError("");
- UsageError(" --multi-image: specify that separate oat and image files be generated for ");
- UsageError(" each input dex file; the default for boot image and boot image extension.");
- UsageError("");
- UsageError(" --single-image: specify that a single oat and image file be generated for ");
- UsageError(" all input dex files; the default for app image.");
- UsageError("");
- UsageError(" --force-determinism: force the compiler to emit a deterministic output.");
- UsageError("");
- UsageError(" --dump-cfg=<cfg-file>: dump control-flow graphs (CFGs) to specified file.");
- UsageError(" Example: --dump-cfg=output.cfg");
- UsageError("");
- UsageError(" --dump-cfg-append: when dumping CFGs to an existing file, append new CFG data to");
- UsageError(" existing data (instead of overwriting existing data with new data, which is");
- UsageError(" the default behavior). This option is only meaningful when used with");
- UsageError(" --dump-cfg.");
- UsageError("");
- UsageError(" --verbose-methods=<method-names>: Restrict dumped CFG data to methods whose name");
- UsageError(" contain one of the method names passed as argument");
- UsageError(" Example: --verbose-methods=toString,hashCode");
- UsageError("");
- UsageError(" --classpath-dir=<directory-path>: directory used to resolve relative class paths.");
- UsageError("");
- UsageError(" --class-loader-context=<string spec>: a string specifying the intended");
- UsageError(" runtime loading context for the compiled dex files.");
- UsageError("");
- UsageError(" --stored-class-loader-context=<string spec>: a string specifying the intended");
- UsageError(" runtime loading context that is stored in the oat file. Overrides");
- UsageError(" --class-loader-context. Note that this ignores the classpath_dir arg.");
- UsageError("");
- UsageError(" It describes how the class loader chain should be built in order to ensure");
- UsageError(" classes are resolved during dex2aot as they would be resolved at runtime.");
- UsageError(" This spec will be encoded in the oat file. If at runtime the dex file is");
- UsageError(" loaded in a different context, the oat file will be rejected.");
- UsageError("");
- UsageError(" The chain is interpreted in the natural 'parent order', meaning that class");
- UsageError(" loader 'i+1' will be the parent of class loader 'i'.");
- UsageError(" The compilation sources will be appended to the classpath of the first class");
- UsageError(" loader.");
- UsageError("");
- UsageError(" E.g. if the context is 'PCL[lib1.dex];DLC[lib2.dex]' and ");
- UsageError(" --dex-file=src.dex then dex2oat will setup a PathClassLoader with classpath ");
- UsageError(" 'lib1.dex:src.dex' and set its parent to a DelegateLastClassLoader with ");
- UsageError(" classpath 'lib2.dex'.");
- UsageError("");
- UsageError(" Note that the compiler will be tolerant if the source dex files specified");
- UsageError(" with --dex-file are found in the classpath. The source dex files will be");
- UsageError(" removed from any class loader's classpath possibly resulting in empty");
- UsageError(" class loaders.");
- UsageError("");
- UsageError(" Example: --class-loader-context=PCL[lib1.dex:lib2.dex];DLC[lib3.dex]");
- 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(" --dirty-image-objects=<file-path>: list of known dirty objects in the image.");
- UsageError(" The image writer will group them together.");
- UsageError("");
- UsageError(" --updatable-bcp-packages-file=<file-path>: file with a list of updatable");
- UsageError(" boot class path packages. Classes in these packages and sub-packages");
- UsageError(" shall not be resolved during app compilation to avoid AOT assumptions");
- UsageError(" being invalidated after applying updates to these components.");
- UsageError("");
- UsageError(" --compact-dex-level=none|fast: None avoids generating compact dex, fast");
- UsageError(" generates compact dex with low compile time. If speed-profile is specified as");
- UsageError(" the compiler filter and the profile is not empty, the default compact dex");
- UsageError(" level is always used.");
- UsageError("");
- UsageError(" --deduplicate-code=true|false: enable|disable code deduplication. Deduplicated");
- UsageError(" code will have an arbitrary symbol tagged with [DEDUPED].");
- UsageError("");
- UsageError(" --copy-dex-files=true|false: enable|disable copying the dex files into the");
- UsageError(" output vdex.");
- UsageError("");
- UsageError(" --compilation-reason=<string>: optional metadata specifying the reason for");
- UsageError(" compiling the apk. If specified, the string will be embedded verbatim in");
- UsageError(" the key value store of the oat file.");
- UsageError(" Example: --compilation-reason=install");
- UsageError("");
- UsageError(" --resolve-startup-const-strings=true|false: If true, the compiler eagerly");
- UsageError(" resolves strings referenced from const-string of startup methods.");
- UsageError("");
- UsageError(" --max-image-block-size=<size>: Maximum solid block size for compressed images.");
- UsageError("");
- UsageError(" --compile-individually: Compiles dex files individually, unloading classes in");
- UsageError(" between compiling each file.");
- UsageError("");
+
+ std::stringstream oss;
+ VariableIndentationOutputStream vios(&oss);
+ auto parser = CreateDex2oatArgumentParser();
+ parser.DumpHelp(vios);
+ UsageError(oss.str().c_str());
std::cerr << "See log for usage error information\n";
exit(EXIT_FAILURE);
}
diff --git a/dex2oat/dex2oat_options.cc b/dex2oat/dex2oat_options.cc
index 81b9c98..c7c62d7 100644
--- a/dex2oat/dex2oat_options.cc
+++ b/dex2oat/dex2oat_options.cc
@@ -34,6 +34,7 @@
}
static const char* Name() { return "InstructionSet"; }
+ static const char* DescribeType() { return "arm|arm64|x86|x86_64|none"; }
};
#define COMPILER_OPTIONS_MAP_TYPE Dex2oatArgumentMap
@@ -57,18 +58,44 @@
builder.
Define("--dex-file=_")
.WithType<std::vector<std::string>>().AppendValues()
+ .WithHelp("Specifies a .dex, .jar, or .apk file to compile.\n"
+ "Eg: --dex-file=/system/framework/core.jar")
+ .WithMetavar("<dex-file>")
.IntoKey(M::DexFiles)
.Define("--dex-location=_")
.WithType<std::vector<std::string>>().AppendValues()
+ .WithMetavar("<dex-location>")
+ .WithHelp("specifies an alternative dex location to encode in the oat file for the\n"
+ "corresponding --dex-file argument. The first --dex-location corresponds to\n"
+ "the first --dex-file, the second to the second and so on.\n"
+ "Eg: --dex-file=/home/build/out/system/framework/core.jar\n"
+ " --dex-location=/system/framework/core.jar")
.IntoKey(M::DexLocations)
.Define("--zip-fd=_")
.WithType<int>()
+ .WithHelp("specifies a file descriptor of a zip file containing a classes.dex file to\n"
+ "compile. Eg: --zip-fd=5")
.IntoKey(M::ZipFd)
.Define("--zip-location=_")
.WithType<std::string>()
+ .WithHelp("Specifies a symbolic name for the file corresponding to the FD given by\n"
+ "--zip-fd.")
.IntoKey(M::ZipLocation)
.Define("--boot-image=_")
.WithType<std::string>()
+ .WithHelp("provide the image file for the boot class path.\n"
+ "Do not include the arch as part of the name, it is added automatically.\n"
+ "Example: --boot-image=/system/framework/boot.art\n"
+ " (specifies /system/framework/<arch>/boot.art as the image file)\n"
+ "Example: --boot-image=boot.art:boot-framework.art\n"
+ " (specifies <bcp-path1>/<arch>/boot.art as the image file and\n"
+ " <bcp-path2>/<arch>/boot-framework.art as the image extension file\n"
+ " with paths taken from corresponding boot class path components)\n"
+ "Example: --boot-image=/apex/com.android.art/boot.art:/system/framework/*:*\n"
+ " (specifies /apex/com.android.art/<arch>/boot.art as the image\n"
+ " file and search for extensions in /framework/system and boot\n"
+ " class path components' paths)\n"
+ "Default: $ANDROID_ROOT/system/framework/boot.art")
.IntoKey(M::BootImage);
}
@@ -76,35 +103,53 @@
builder.
Define("--input-vdex-fd=_")
.WithType<int>()
+ .WithHelp("specifies the vdex input source via a file descriptor.")
.IntoKey(M::InputVdexFd)
.Define("--input-vdex=_")
.WithType<std::string>()
+ .WithHelp("specifies the vdex input source via a filename.")
.IntoKey(M::InputVdex)
.Define("--output-vdex-fd=_")
+ .WithHelp("specifies the vdex output destination via a file descriptor.")
.WithType<int>()
.IntoKey(M::OutputVdexFd)
.Define("--output-vdex=_")
.WithType<std::string>()
+ .WithHelp("specifies the vdex output destination via a filename.")
.IntoKey(M::OutputVdex)
.Define("--dm-fd=_")
.WithType<int>()
+ .WithHelp("specifies the dm output destination via a file descriptor.")
.IntoKey(M::DmFd)
.Define("--dm-file=_")
.WithType<std::string>()
+ .WithHelp("specifies the dm output destination via a filename.")
.IntoKey(M::DmFile)
.Define("--oat-file=_")
.WithType<std::string>()
+ .WithHelp(" Specifies an oat output destination via a filename.\n"
+ "Eg: --oat-file=/system/framework/boot.oat")
.IntoKey(M::OatFile)
.Define("--oat-symbols=_")
.WithType<std::string>()
+ .WithHelp("Specifies a symbolized oat output destination.\n"
+ "Eg: --oat-symbols=symbols/system/framework/boot.oat")
.IntoKey(M::OatSymbols)
.Define("--strip")
+ .WithHelp("remove all debugging sections at the end (but keep mini-debug-info).\n"
+ "This is equivalent to the \"strip\" command as build post-processing step.\n"
+ "It is intended to be used with --oat-symbols and it happens after it.\n"
+ "Eg: --oat-symbols=/symbols/system/framework/boot.oat")
.IntoKey(M::Strip)
.Define("--oat-fd=_")
.WithType<int>()
+ .WithHelp("Specifies the oat output destination via a file descriptor. Eg: --oat-fd=5")
.IntoKey(M::OatFd)
.Define("--oat-location=_")
.WithType<std::string>()
+ .WithHelp("specifies a symbolic name for the file corresponding to the file descriptor\n"
+ "specified by --oat-fd.\n"
+ "Eg: --oat-location=/data/dalvik-cache/system@app@Calculator.apk.oat")
.IntoKey(M::OatLocation);
}
@@ -112,33 +157,52 @@
builder.
Define("--image=_")
.WithType<std::string>()
+ .WithHelp("specifies an output image filename. Eg: --image=/system/framework/boot.art")
.IntoKey(M::ImageFilename)
.Define("--image-fd=_")
.WithType<int>()
+ .WithHelp("specifies an output image file descriptor. Cannot be used with --image.\n"
+ "Eg: --image-fd=7")
.IntoKey(M::ImageFd)
.Define("--base=_")
.WithType<std::string>()
+ .WithHelp("Specifies the base address when creating a boot image. Eg: --base=0x50000000")
+ .WithMetavar("{hex address}")
.IntoKey(M::Base)
.Define("--app-image-file=_")
.WithType<std::string>()
+ .WithHelp("Specify a file name for app image. Only used if a profile is passed in.")
.IntoKey(M::AppImageFile)
.Define("--app-image-fd=_")
.WithType<int>()
+ .WithHelp("Specify a file descriptor for app image. Only used if a profile is passed in.")
.IntoKey(M::AppImageFileFd)
.Define({"--multi-image", "--single-image"})
.WithValues({true, false})
+ .WithHelp("Specifies if separate oat and image files should be generated for each dex\n"
+ "file. --multi-image is default for boot image and --single-image for app\n"
+ "images.")
.IntoKey(M::MultiImage)
.Define("--dirty-image-objects=_")
.WithType<std::string>()
+ .WithHelp("list of known dirty objects in the image. The image writer will group them"
+ " together")
.IntoKey(M::DirtyImageObjects)
.Define("--updatable-bcp-packages-file=_")
.WithType<std::string>()
+ .WithHelp("file with a list of updatable boot class path packages. Classes in these\n"
+ "packages and sub-packages shall not be resolved during app compilation to\n"
+ "avoid AOT assumptions being invalidated after applying updates to these\n"
+ "components."
+ )
.IntoKey(M::UpdatableBcpPackagesFile)
.Define("--image-format=_")
.WithType<ImageHeader::StorageMode>()
.WithValueMap({{"lz4", ImageHeader::kStorageModeLZ4},
{"lz4hc", ImageHeader::kStorageModeLZ4HC},
{"uncompressed", ImageHeader::kStorageModeUncompressed}})
+ .WithHelp("Which format to store the image Defaults to uncompressed. Eg:"
+ " --image-format=lz4")
.IntoKey(M::ImageFormat);
}
@@ -146,15 +210,19 @@
builder.
Define("--swap-file=_")
.WithType<std::string>()
+ .WithHelp("Specify a file to use for swap. Eg: --swap-file=/data/tmp/swap.001")
.IntoKey(M::SwapFile)
.Define("--swap-fd=_")
.WithType<int>()
+ .WithHelp("Specify a file to use for swap by file-descriptor. Eg: --swap-fd=3")
.IntoKey(M::SwapFileFd)
.Define("--swap-dex-size-threshold=_")
.WithType<unsigned int>()
+ .WithHelp("specifies the minimum total dex file size in bytes to allow the use of swap.")
.IntoKey(M::SwapDexSizeThreshold)
.Define("--swap-dex-count-threshold=_")
.WithType<unsigned int>()
+ .WithHelp("specifies the minimum number of dex file to allow the use of swap.")
.IntoKey(M::SwapDexCountThreshold);
}
@@ -165,9 +233,11 @@
.IntoKey(M::Passes)
.Define("--profile-file=_")
.WithType<std::string>()
+ .WithHelp("Specify profiler output file to use for compilation using a filename.")
.IntoKey(M::Profile)
.Define("--profile-file-fd=_")
.WithType<int>()
+ .WithHelp("Specify profiler output file to use for compilation using a file-descriptor.")
.IntoKey(M::ProfileFd)
.Define("--no-inline-from=_")
.WithType<std::string>()
@@ -178,16 +248,27 @@
builder.
Define("--instruction-set=_")
.WithType<InstructionSet>()
+ .WithHelp("Compile for a particular instruction set.")
.IntoKey(M::TargetInstructionSet)
.Define("--instruction-set-variant=_")
.WithType<std::string>()
+ .WithHelp("Specify instruction set features using variant name.\n"
+ "Eg: --instruction-set-variant=silvermont")
+ .WithMetavar("{Variant Name}")
.IntoKey(M::TargetInstructionSetVariant)
.Define("--instruction-set-features=_")
.WithType<std::string>()
+ .WithHelp("Specify instruction set features.\n"
+ "On target the value 'runtime' can be used to detect features at run time.\n"
+ "If target does not support run-time detection the value 'runtime'\n"
+ "has the same effect as the value 'default'.\n"
+ "Note: the value 'runtime' has no effect if it is used on host.\n"
+ "Example: --instruction-set-features=div\n"
+ "Default: default")
.IntoKey(M::TargetInstructionSetFeatures);
}
-static Parser CreateArgumentParser() {
+Parser CreateDex2oatArgumentParser() {
std::unique_ptr<Builder> parser_builder = std::make_unique<Builder>();
AddInputMappings(*parser_builder);
@@ -199,33 +280,50 @@
parser_builder->
Define({"--watch-dog", "--no-watch-dog"})
+ .WithHelp("Enable or disable the watchdog timer.")
.WithValues({true, false})
.IntoKey(M::Watchdog)
.Define("--watchdog-timeout=_")
.WithType<int>()
+ .WithHelp("Set the watchdog timeout value in seconds.")
.IntoKey(M::WatchdogTimeout)
.Define("-j_")
.WithType<unsigned int>()
+ .WithHelp("specifies the number of threads used for compilation. Default is the number\n"
+ "of detected hardware threads available on the host system.")
.IntoKey(M::Threads)
.Define("--cpu-set=_")
.WithType<std::vector<int32_t>>()
+ .WithHelp("sets the cpu affinitiy to the given <set>. The <set> is a comma separated\n"
+ "list of cpus. Eg: --cpu-set=0,1,2,3")
+ .WithMetavar("<set>")
.IntoKey(M::CpuSet)
.Define("--android-root=_")
.WithType<std::string>()
+ .WithHelp("Used to locate libraries for portable linking.\n"
+ "Eg: --android-root=out/host/linux-x86\n"
+ "Default: $ANDROID_ROOT")
.IntoKey(M::AndroidRoot)
.Define("--compiler-backend=_")
.WithType<Compiler::Kind>()
.WithValueMap({{"Quick", Compiler::Kind::kQuick},
{"Optimizing", Compiler::Kind::kOptimizing}})
+ .WithHelp("Select a compiler backend set. Default: optimizing")
.IntoKey(M::Backend)
.Define("--host")
+ .WithHelp("Run in host mode")
.IntoKey(M::Host)
.Define("--avoid-storing-invocation")
+ .WithHelp("Avoid storing the invocation args in the key-value store. Used to test\n"
+ "determinism with different args.")
.IntoKey(M::AvoidStoringInvocation)
.Define("--very-large-app-threshold=_")
.WithType<unsigned int>()
+ .WithHelp("Specifies the minimum total dex file size in bytes to consider the input\n"
+ "\"very large\" and reduce compilation done.")
.IntoKey(M::VeryLargeAppThreshold)
.Define("--force-determinism")
+ .WithHelp("Force the compiler to emit a deterministic output")
.IntoKey(M::ForceDeterminism)
.Define("--check-linkage-conditions")
.IntoKey(M::CheckLinkageConditions)
@@ -236,34 +334,81 @@
.WithValueMap({{"true", linker::CopyOption::kOnlyIfCompressed},
{"false", linker::CopyOption::kNever},
{"always", linker::CopyOption::kAlways}})
+ .WithHelp("enable|disable copying the dex files into the output vdex.")
.IntoKey(M::CopyDexFiles)
.Define("--write-invocation-to=_")
+ .WithHelp("Write the invocation commandline to the given file for later use. Used to\n"
+ "test determinism with different args.")
.WithType<std::string>()
.IntoKey(M::InvocationFile)
.Define("--classpath-dir=_")
.WithType<std::string>()
+ .WithHelp("Directory used to resolve relative class paths.")
.IntoKey(M::ClasspathDir)
.Define("--class-loader-context=_")
.WithType<std::string>()
+ .WithHelp("a string specifying the intended runtime loading context for the compiled\n"
+ "dex files.")
.IntoKey(M::ClassLoaderContext)
.Define("--class-loader-context-fds=_")
.WithType<std::string>()
+ .WithHelp("a colon-separated list of file descriptors for dex files in\n"
+ "--class-loader-context. Their order must be the same as dex files in a\n"
+ "flattened class loader context")
.IntoKey(M::ClassLoaderContextFds)
.Define("--stored-class-loader-context=_")
.WithType<std::string>()
+ .WithHelp("a string specifying the intended runtime loading context that is stored\n"
+ "in the oat file. Overrides --class-loader-context. Note that this ignores\n"
+ "the classpath_dir arg.\n"
+ "\n"
+ "It describes how the class loader chain should be built in order to ensure\n"
+ "classes are resolved during dex2aot as they would be resolved at runtime.\n"
+ "This spec will be encoded in the oat file. If at runtime the dex file is\n"
+ "loaded in a different context, the oat file will be rejected.\n"
+ "\n"
+ "The chain is interpreted in the natural 'parent order', meaning that class\n"
+ "loader 'i+1' will be the parent of class loader 'i'.\n"
+ "The compilation sources will be appended to the classpath of the first class\n"
+ "loader.\n"
+ "\n"
+ "E.g. if the context is 'PCL[lib1.dex];DLC[lib2.dex]' and \n"
+ "--dex-file=src.dex then dex2oat will setup a PathClassLoader with classpath \n"
+ "'lib1.dex:src.dex' and set its parent to a DelegateLastClassLoader with \n"
+ "classpath 'lib2.dex'.\n"
+ "\n"
+ "Note that the compiler will be tolerant if the source dex files specified\n"
+ "with --dex-file are found in the classpath. The source dex files will be\n"
+ "removed from any class loader's classpath possibly resulting in empty\n"
+ "class loaders.\n"
+ "\n"
+ "Example: --class-loader-context=PCL[lib1.dex:lib2.dex];DLC[lib3.dex]")
.IntoKey(M::StoredClassLoaderContext)
.Define("--compact-dex-level=_")
.WithType<CompactDexLevel>()
.WithValueMap({{"none", CompactDexLevel::kCompactDexLevelNone},
{"fast", CompactDexLevel::kCompactDexLevelFast}})
+ .WithHelp("None avoids generating compact dex, fast generates compact dex with low\n"
+ "compile time. If speed-profile is specified as the compiler filter and the\n"
+ "profile is not empty, the default compact dex level is always used.")
.IntoKey(M::CompactDexLevel)
.Define("--runtime-arg _")
.WithType<std::vector<std::string>>().AppendValues()
+ .WithMetavar("{dalvikvm-arg}")
+ .WithHelp("used to specify various arguments for the runtime, such as initial heap\n"
+ "size, maximum heap size, and verbose output. Use a separate --runtime-arg\n"
+ "switch for each argument.\n"
+ "Example: --runtime-arg -Xms256m")
.IntoKey(M::RuntimeOptions)
.Define("--compilation-reason=_")
.WithType<std::string>()
+ .WithHelp("optional metadata specifying the reason for compiling the apk. If specified,\n"
+ "the string will be embedded verbatim in the key value store of the oat file.\n"
+ "Example: --compilation-reason=install")
.IntoKey(M::CompilationReason)
.Define("--compile-individually")
+ .WithHelp("Compiles dex files individually, unloading classes in between compiling each"
+ " file.")
.IntoKey(M::CompileIndividually);
AddCompilerOptionsArgumentParserOptions<Dex2oatArgumentMap>(*parser_builder);
@@ -276,7 +421,7 @@
std::unique_ptr<Dex2oatArgumentMap> Dex2oatArgumentMap::Parse(int argc,
const char** argv,
std::string* error_msg) {
- Parser parser = CreateArgumentParser();
+ Parser parser = CreateDex2oatArgumentParser();
CmdlineResult parse_result = parser.Parse(argv, argc);
if (!parse_result.IsSuccess()) {
*error_msg = parse_result.GetMessage();
diff --git a/dex2oat/dex2oat_options.h b/dex2oat/dex2oat_options.h
index 27d3d25..1da1ff9 100644
--- a/dex2oat/dex2oat_options.h
+++ b/dex2oat/dex2oat_options.h
@@ -72,6 +72,8 @@
#include "dex2oat_options.def"
};
+CmdlineParser<Dex2oatArgumentMap, Dex2oatArgumentMap::Key> CreateDex2oatArgumentParser();
+
extern template struct CompilerOptionsMap<Dex2oatArgumentMap, Dex2oatArgumentMapKey>;
} // namespace art
diff --git a/runtime/compiler_filter.cc b/runtime/compiler_filter.cc
index c086490..9ce2533 100644
--- a/runtime/compiler_filter.cc
+++ b/runtime/compiler_filter.cc
@@ -240,6 +240,11 @@
return true;
}
+const char* CompilerFilter::DescribeOptions() {
+ return "assume-verified|extract|verify|quicken|space{,-profile}|speed{,-profile}|"
+ "everything{,-profile}";
+}
+
std::ostream& operator<<(std::ostream& os, const CompilerFilter::Filter& rhs) {
return os << CompilerFilter::NameOfFilter(rhs);
}
diff --git a/runtime/compiler_filter.h b/runtime/compiler_filter.h
index c36e40f..a016683 100644
--- a/runtime/compiler_filter.h
+++ b/runtime/compiler_filter.h
@@ -101,6 +101,8 @@
// 'filter' must be non-null.
static bool ParseCompilerFilter(const char* name, /*out*/Filter* filter);
+ static const char* DescribeOptions();
+
private:
DISALLOW_COPY_AND_ASSIGN(CompilerFilter);
};