diff options
author | 2020-08-25 09:16:34 -0700 | |
---|---|---|
committer | 2020-09-02 17:21:58 +0000 | |
commit | 0d47a82b11ea666fc3ef971b32be5a03ffadc452 (patch) | |
tree | 2bd3e50b0dae701470f92a713a875ab594b3d344 | |
parent | 6624d58c11b43a10c802037bf1c5754ca276156c (diff) |
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
-rw-r--r-- | cmdline/cmdline_parser.h | 10 | ||||
-rw-r--r-- | cmdline/detail/cmdline_parse_argument_detail.h | 2 | ||||
-rw-r--r-- | compiler/driver/compiler_options_map-inl.h | 65 | ||||
-rw-r--r-- | compiler/driver/compiler_options_map.def | 2 | ||||
-rw-r--r-- | compiler/driver/compiler_options_map.h | 1 | ||||
-rw-r--r-- | dex2oat/dex2oat.cc | 307 | ||||
-rw-r--r-- | dex2oat/dex2oat_options.cc | 149 | ||||
-rw-r--r-- | dex2oat/dex2oat_options.h | 2 | ||||
-rw-r--r-- | runtime/compiler_filter.cc | 5 | ||||
-rw-r--r-- | runtime/compiler_filter.h | 2 |
10 files changed, 228 insertions, 317 deletions
diff --git a/cmdline/cmdline_parser.h b/cmdline/cmdline_parser.h index 86e3b2c7df..22eb44c211 100644 --- a/cmdline/cmdline_parser.h +++ b/cmdline/cmdline_parser.h @@ -755,10 +755,12 @@ void CmdlineParser<TVariantMap, TVariantMapKey>::DumpHelp(VariableIndentationOut 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 f5cbda9a73..0f73a76b72 100644 --- a/cmdline/detail/cmdline_parse_argument_detail.h +++ b/cmdline/detail/cmdline_parse_argument_detail.h @@ -145,6 +145,8 @@ struct CmdlineParserArgumentInfo { 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 e80fb46503..fcbc0f2f5c 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 @@ template <typename Map, typename Builder> 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 @@ inline void AddCompilerOptionsArgumentParserOptions(Builder& b) { .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 @@ inline void AddCompilerOptionsArgumentParserOptions(Builder& b) { .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 @@ inline void AddCompilerOptionsArgumentParserOptions(Builder& b) { .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 @@ inline void AddCompilerOptionsArgumentParserOptions(Builder& b) { .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 @@ inline void AddCompilerOptionsArgumentParserOptions(Builder& b) { .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 40a62843dc..b1398c9a33 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 af212d66a1..14f511286a 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 3e0bb8827d..fe826c1353 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -230,307 +230,12 @@ NO_RETURN static void Usage(const char* fmt, ...) { 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 81b9c987dd..c7c62d7865 100644 --- a/dex2oat/dex2oat_options.cc +++ b/dex2oat/dex2oat_options.cc @@ -34,6 +34,7 @@ struct CmdlineType<InstructionSet> : CmdlineTypeParser<InstructionSet> { } 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 @@ static void AddInputMappings(Builder& builder) { 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 @@ static void AddGeneratedArtifactMappings(Builder& builder) { 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 @@ static void AddImageMappings(Builder& builder) { 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 @@ static void AddSwapMappings(Builder& builder) { 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 @@ static void AddCompilerMappings(Builder& builder) { .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 @@ static void AddTargetMappings(Builder& builder) { 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 @@ static Parser CreateArgumentParser() { 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 @@ static Parser CreateArgumentParser() { .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 @@ static Parser CreateArgumentParser() { 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 27d3d25f2a..1da1ff9a0a 100644 --- a/dex2oat/dex2oat_options.h +++ b/dex2oat/dex2oat_options.h @@ -72,6 +72,8 @@ struct Dex2oatArgumentMap : CompilerOptionsMap<Dex2oatArgumentMap, Dex2oatArgume #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 c0864901cf..9ce25333cb 100644 --- a/runtime/compiler_filter.cc +++ b/runtime/compiler_filter.cc @@ -240,6 +240,11 @@ bool CompilerFilter::ParseCompilerFilter(const char* option, Filter* filter) { 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 c36e40fc0a..a0166833d3 100644 --- a/runtime/compiler_filter.h +++ b/runtime/compiler_filter.h @@ -101,6 +101,8 @@ class CompilerFilter final { // 'filter' must be non-null. static bool ParseCompilerFilter(const char* name, /*out*/Filter* filter); + static const char* DescribeOptions(); + private: DISALLOW_COPY_AND_ASSIGN(CompilerFilter); }; |