diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/Android.bp | 4 | ||||
| -rw-r--r-- | compiler/driver/compiler_options.cc | 131 | ||||
| -rw-r--r-- | compiler/driver/compiler_options.h | 11 | ||||
| -rw-r--r-- | compiler/driver/compiler_options_map-inl.h | 159 | ||||
| -rw-r--r-- | compiler/driver/compiler_options_map-storage.h | 48 | ||||
| -rw-r--r-- | compiler/driver/compiler_options_map.def | 60 | ||||
| -rw-r--r-- | compiler/driver/compiler_options_map.h | 45 | ||||
| -rw-r--r-- | compiler/driver/simple_compiler_options_map.h | 64 | ||||
| -rw-r--r-- | compiler/jit/jit_compiler.cc | 21 | ||||
| -rw-r--r-- | compiler/utils/arm/jni_macro_assembler_arm_vixl.cc | 15 | ||||
| -rw-r--r-- | compiler/utils/arm64/jni_macro_assembler_arm64.cc | 15 | ||||
| -rw-r--r-- | compiler/utils/test_dex_file_builder.h | 9 |
12 files changed, 467 insertions, 115 deletions
diff --git a/compiler/Android.bp b/compiler/Android.bp index 59ca4c7abf..1e4cdf2bd5 100644 --- a/compiler/Android.bp +++ b/compiler/Android.bp @@ -193,6 +193,10 @@ art_cc_defaults { "liblzma", ], include_dirs: ["art/disassembler"], + header_libs: [ + "art_cmdlineparser_headers", // For compiler_options. + ], + export_include_dirs: ["."], } diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc index 538845de19..b6cedff28a 100644 --- a/compiler/driver/compiler_options.cc +++ b/compiler/driver/compiler_options.cc @@ -18,7 +18,13 @@ #include <fstream> +#include "android-base/stringprintf.h" + +#include "base/variant_map.h" +#include "cmdline_parser.h" +#include "compiler_options_map-inl.h" #include "runtime.h" +#include "simple_compiler_options_map.h" namespace art { @@ -71,115 +77,50 @@ bool CompilerOptions::EmitRunTimeChecksInDebugMode() const { (kIsTargetBuild || IsCoreImage() || Runtime::Current()->UseJitCompilation()); } -void CompilerOptions::ParseHugeMethodMax(const StringPiece& option, UsageFn Usage) { - ParseUintOption(option, "--huge-method-max", &huge_method_threshold_, Usage); -} - -void CompilerOptions::ParseLargeMethodMax(const StringPiece& option, UsageFn Usage) { - ParseUintOption(option, "--large-method-max", &large_method_threshold_, Usage); -} - -void CompilerOptions::ParseSmallMethodMax(const StringPiece& option, UsageFn Usage) { - ParseUintOption(option, "--small-method-max", &small_method_threshold_, Usage); -} - -void CompilerOptions::ParseTinyMethodMax(const StringPiece& option, UsageFn Usage) { - ParseUintOption(option, "--tiny-method-max", &tiny_method_threshold_, Usage); -} - -void CompilerOptions::ParseNumDexMethods(const StringPiece& option, UsageFn Usage) { - ParseUintOption(option, "--num-dex-methods", &num_dex_methods_threshold_, Usage); -} - -void CompilerOptions::ParseInlineMaxCodeUnits(const StringPiece& option, UsageFn Usage) { - ParseUintOption(option, "--inline-max-code-units", &inline_max_code_units_, Usage); -} - -void CompilerOptions::ParseDumpInitFailures(const StringPiece& option, - UsageFn Usage ATTRIBUTE_UNUSED) { - DCHECK(option.starts_with("--dump-init-failures=")); - std::string file_name = option.substr(strlen("--dump-init-failures=")).data(); - init_failure_output_.reset(new std::ofstream(file_name)); +bool CompilerOptions::ParseDumpInitFailures(const std::string& option, std::string* error_msg) { + init_failure_output_.reset(new std::ofstream(option)); if (init_failure_output_.get() == nullptr) { - LOG(ERROR) << "Failed to allocate ofstream"; + *error_msg = "Failed to construct std::ofstream"; + return false; } else if (init_failure_output_->fail()) { - LOG(ERROR) << "Failed to open " << file_name << " for writing the initialization " - << "failures."; + *error_msg = android::base::StringPrintf( + "Failed to open %s for writing the initialization failures.", option.c_str()); init_failure_output_.reset(); + return false; } + return true; } -void CompilerOptions::ParseRegisterAllocationStrategy(const StringPiece& option, - UsageFn Usage) { - DCHECK(option.starts_with("--register-allocation-strategy=")); - StringPiece choice = option.substr(strlen("--register-allocation-strategy=")).data(); - if (choice == "linear-scan") { +bool CompilerOptions::ParseRegisterAllocationStrategy(const std::string& option, + std::string* error_msg) { + if (option == "linear-scan") { register_allocation_strategy_ = RegisterAllocator::Strategy::kRegisterAllocatorLinearScan; - } else if (choice == "graph-color") { + } else if (option == "graph-color") { register_allocation_strategy_ = RegisterAllocator::Strategy::kRegisterAllocatorGraphColor; } else { - Usage("Unrecognized register allocation strategy. Try linear-scan, or graph-color."); + *error_msg = "Unrecognized register allocation strategy. Try linear-scan, or graph-color."; + return false; } + return true; } -bool CompilerOptions::ParseCompilerOption(const StringPiece& option, UsageFn Usage) { - if (option.starts_with("--compiler-filter=")) { - const char* compiler_filter_string = option.substr(strlen("--compiler-filter=")).data(); - if (!CompilerFilter::ParseCompilerFilter(compiler_filter_string, &compiler_filter_)) { - Usage("Unknown --compiler-filter value %s", compiler_filter_string); - } - } else if (option == "--compile-pic") { - compile_pic_ = true; - } else if (option.starts_with("--huge-method-max=")) { - ParseHugeMethodMax(option, Usage); - } else if (option.starts_with("--large-method-max=")) { - ParseLargeMethodMax(option, Usage); - } else if (option.starts_with("--small-method-max=")) { - ParseSmallMethodMax(option, Usage); - } else if (option.starts_with("--tiny-method-max=")) { - ParseTinyMethodMax(option, Usage); - } else if (option.starts_with("--num-dex-methods=")) { - ParseNumDexMethods(option, Usage); - } else if (option.starts_with("--inline-max-code-units=")) { - ParseInlineMaxCodeUnits(option, Usage); - } else if (option == "--generate-debug-info" || option == "-g") { - generate_debug_info_ = true; - } else if (option == "--no-generate-debug-info") { - generate_debug_info_ = false; - } else if (option == "--generate-mini-debug-info") { - generate_mini_debug_info_ = true; - } else if (option == "--no-generate-mini-debug-info") { - generate_mini_debug_info_ = false; - } else if (option == "--generate-build-id") { - generate_build_id_ = true; - } else if (option == "--no-generate-build-id") { - generate_build_id_ = false; - } else if (option == "--debuggable") { - debuggable_ = true; - } else if (option.starts_with("--top-k-profile-threshold=")) { - ParseDouble(option.data(), '=', 0.0, 100.0, &top_k_profile_threshold_, Usage); - } else if (option == "--abort-on-hard-verifier-error") { - abort_on_hard_verifier_failure_ = true; - } else if (option == "--no-abort-on-hard-verifier-error") { - abort_on_hard_verifier_failure_ = false; - } else if (option.starts_with("--dump-init-failures=")) { - ParseDumpInitFailures(option, Usage); - } else if (option.starts_with("--dump-cfg=")) { - dump_cfg_file_name_ = option.substr(strlen("--dump-cfg=")).data(); - } else if (option == "--dump-cfg-append") { - dump_cfg_append_ = true; - } else if (option.starts_with("--register-allocation-strategy=")) { - ParseRegisterAllocationStrategy(option, Usage); - } else if (option.starts_with("--verbose-methods=")) { - // TODO: rather than switch off compiler logging, make all VLOG(compiler) messages - // conditional on having verbose methods. - gLogVerbosity.compiler = false; - Split(option.substr(strlen("--verbose-methods=")).ToString(), ',', &verbose_methods_); - } else { - // Option not recognized. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wframe-larger-than=" + +bool CompilerOptions::ParseCompilerOptions(const std::vector<std::string>& options, + bool ignore_unrecognized, + std::string* error_msg) { + auto parser = CreateSimpleParser(ignore_unrecognized); + CmdlineResult parse_result = parser.Parse(options); + if (!parse_result.IsSuccess()) { + *error_msg = parse_result.GetMessage(); return false; } - return true; + + SimpleParseArgumentMap args = parser.ReleaseArgumentsMap(); + return ReadCompilerOptions(args, this, error_msg); } +#pragma GCC diagnostic pop + } // namespace art diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h index a9372c4844..311dbd569e 100644 --- a/compiler/driver/compiler_options.h +++ b/compiler/driver/compiler_options.h @@ -231,7 +231,9 @@ class CompilerOptions FINAL { return no_inline_from_; } - bool ParseCompilerOption(const StringPiece& option, UsageFn Usage); + bool ParseCompilerOptions(const std::vector<std::string>& options, + bool ignore_unrecognized, + std::string* error_msg); void SetNonPic() { compile_pic_ = false; @@ -258,7 +260,7 @@ class CompilerOptions FINAL { } private: - void ParseDumpInitFailures(const StringPiece& option, UsageFn Usage); + bool ParseDumpInitFailures(const std::string& option, std::string* error_msg); void ParseDumpCfgPasses(const StringPiece& option, UsageFn Usage); void ParseInlineMaxCodeUnits(const StringPiece& option, UsageFn Usage); void ParseNumDexMethods(const StringPiece& option, UsageFn Usage); @@ -266,7 +268,7 @@ class CompilerOptions FINAL { void ParseSmallMethodMax(const StringPiece& option, UsageFn Usage); void ParseLargeMethodMax(const StringPiece& option, UsageFn Usage); void ParseHugeMethodMax(const StringPiece& option, UsageFn Usage); - void ParseRegisterAllocationStrategy(const StringPiece& option, UsageFn Usage); + bool ParseRegisterAllocationStrategy(const std::string& option, std::string* error_msg); CompilerFilter::Filter compiler_filter_; size_t huge_method_threshold_; @@ -327,6 +329,9 @@ class CompilerOptions FINAL { friend class CommonCompilerTest; friend class verifier::VerifierDepsTest; + template <class Base> + friend bool ReadCompilerOptions(Base& map, CompilerOptions* options, std::string* error_msg); + DISALLOW_COPY_AND_ASSIGN(CompilerOptions); }; diff --git a/compiler/driver/compiler_options_map-inl.h b/compiler/driver/compiler_options_map-inl.h new file mode 100644 index 0000000000..9cb818a270 --- /dev/null +++ b/compiler/driver/compiler_options_map-inl.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_COMPILER_DRIVER_COMPILER_OPTIONS_MAP_INL_H_ +#define ART_COMPILER_DRIVER_COMPILER_OPTIONS_MAP_INL_H_ + +#include "compiler_options_map.h" + +#include <memory> + +#include "android-base/logging.h" +#include "android-base/macros.h" +#include "android-base/stringprintf.h" + +#include "base/macros.h" +#include "cmdline_parser.h" +#include "compiler_options.h" + +namespace art { + +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); + } + if (map.Exists(Base::PIC)) { + options->compile_pic_ = true; + } + map.AssignIfExists(Base::HugeMethodMaxThreshold, &options->huge_method_threshold_); + map.AssignIfExists(Base::LargeMethodMaxThreshold, &options->large_method_threshold_); + map.AssignIfExists(Base::SmallMethodMaxThreshold, &options->small_method_threshold_); + map.AssignIfExists(Base::TinyMethodMaxThreshold, &options->tiny_method_threshold_); + map.AssignIfExists(Base::NumDexMethodsThreshold, &options->num_dex_methods_threshold_); + map.AssignIfExists(Base::InlineMaxCodeUnitsThreshold, &options->inline_max_code_units_); + map.AssignIfExists(Base::GenerateDebugInfo, &options->generate_debug_info_); + map.AssignIfExists(Base::GenerateMiniDebugInfo, &options->generate_mini_debug_info_); + map.AssignIfExists(Base::GenerateBuildID, &options->generate_build_id_); + if (map.Exists(Base::Debuggable)) { + options->debuggable_ = true; + } + map.AssignIfExists(Base::TopKProfileThreshold, &options->top_k_profile_threshold_); + map.AssignIfExists(Base::AbortOnHardVerifierFailure, &options->abort_on_hard_verifier_failure_); + if (map.Exists(Base::DumpInitFailures)) { + if (!options->ParseDumpInitFailures(*map.Get(Base::DumpInitFailures), error_msg)) { + return false; + } + } + map.AssignIfExists(Base::DumpCFG, &options->dump_cfg_file_name_); + if (map.Exists(Base::DumpCFGAppend)) { + options->dump_cfg_append_ = true; + } + if (map.Exists(Base::RegisterAllocationStrategy)) { + if (!options->ParseRegisterAllocationStrategy(*map.Get(Base::DumpInitFailures), error_msg)) { + return false; + } + } + map.AssignIfExists(Base::VerboseMethods, &options->verbose_methods_); + + return true; +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wframe-larger-than=" + +template <typename Map, typename Builder> +inline void AddCompilerOptionsArgumentParserOptions(Builder& b) { + b. + Define("--compiler-filter=_") + .template WithType<std::string>() + .IntoKey(Map::CompilerFilter) + + .Define("--compile-pic") + .IntoKey(Map::PIC) + + .Define("--huge-method-max=_") + .template WithType<unsigned int>() + .IntoKey(Map::HugeMethodMaxThreshold) + .Define("--large-method-max=_") + .template WithType<unsigned int>() + .IntoKey(Map::LargeMethodMaxThreshold) + .Define("--small-method-max=_") + .template WithType<unsigned int>() + .IntoKey(Map::SmallMethodMaxThreshold) + .Define("--tiny-method-max=_") + .template WithType<unsigned int>() + .IntoKey(Map::TinyMethodMaxThreshold) + .Define("--num-dex-methods=_") + .template WithType<unsigned int>() + .IntoKey(Map::NumDexMethodsThreshold) + .Define("--inline-max-code-units=_") + .template WithType<unsigned int>() + .IntoKey(Map::InlineMaxCodeUnitsThreshold) + + .Define({"--generate-debug-info", "-g", "--no-generate-debug-info"}) + .WithValues({true, true, false}) + .IntoKey(Map::GenerateDebugInfo) + .Define({"--generate-mini-debug-info", "--no-generate-mini-debug-info"}) + .WithValues({true, false}) + .IntoKey(Map::GenerateMiniDebugInfo) + + .Define({"--generate-build-id", "--no-generate-build-id"}) + .WithValues({true, false}) + .IntoKey(Map::GenerateBuildID) + + .Define("--debuggable") + .IntoKey(Map::Debuggable) + + .Define("--top-k-profile-threshold=_") + .template WithType<double>().WithRange(0.0, 100.0) + .IntoKey(Map::TopKProfileThreshold) + + .Define({"--abort-on-hard-verifier-error", "--no-abort-on-hard-verifier-error"}) + .WithValues({true, false}) + .IntoKey(Map::AbortOnHardVerifierFailure) + + .Define("--dump-init-failures=_") + .template WithType<std::string>() + .IntoKey(Map::DumpInitFailures) + + .Define("--dump-cfg=_") + .template WithType<std::string>() + .IntoKey(Map::DumpCFG) + .Define("--dump-cfg-append") + .IntoKey(Map::DumpCFGAppend) + + .Define("--register-allocation-strategy=_") + .template WithType<std::string>() + .IntoKey(Map::RegisterAllocationStrategy) + + .Define("--verbose-methods=_") + .template WithType<ParseStringList<','>>() + .IntoKey(Map::VerboseMethods); +} + +#pragma GCC diagnostic pop + +} // namespace art + +#endif // ART_COMPILER_DRIVER_COMPILER_OPTIONS_MAP_INL_H_ diff --git a/compiler/driver/compiler_options_map-storage.h b/compiler/driver/compiler_options_map-storage.h new file mode 100644 index 0000000000..756598de05 --- /dev/null +++ b/compiler/driver/compiler_options_map-storage.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_COMPILER_DRIVER_COMPILER_OPTIONS_MAP_STORAGE_H_ +#define ART_COMPILER_DRIVER_COMPILER_OPTIONS_MAP_STORAGE_H_ + +// Assumes: +// * #include "compiler_options_map.h" +// * namespace art +// +// Usage: +// #define COMPILER_OPTIONS_MAP_TYPE TheTypeOfTheMap +// #define COMPILER_OPTIONS_MAP_KEY_TYPE TheTypeOfTheMapsKey +// #include "driver/compiler_options_map-storage.h + +#ifndef COMPILER_OPTIONS_MAP_TYPE +#error "Expected COMPILER_OPTIONS_MAP_TYPE" +#endif + +#ifndef COMPILER_OPTIONS_MAP_KEY_TYPE +#error "Expected COMPILER_OPTIONS_MAP_KEY_TYPE" +#endif + +#define COMPILER_OPTIONS_KEY(Type, Name, ...) \ + template <typename Base, template <typename TV> class KeyType> \ + const KeyType<Type> CompilerOptionsMap<Base, KeyType>::Name {__VA_ARGS__}; // NOLINT [readability/braces] [4] +#include <driver/compiler_options_map.def> + +template struct CompilerOptionsMap<COMPILER_OPTIONS_MAP_TYPE, COMPILER_OPTIONS_MAP_KEY_TYPE>; + +#undef COMPILER_OPTIONS_MAP_TYPE +#undef COMPILER_OPTIONS_MAP_KEY_TYPE + +#endif // ART_COMPILER_DRIVER_COMPILER_OPTIONS_MAP_STORAGE_H_ +#undef ART_COMPILER_DRIVER_COMPILER_OPTIONS_MAP_STORAGE_H_ // Guard is only for cpplint diff --git a/compiler/driver/compiler_options_map.def b/compiler/driver/compiler_options_map.def new file mode 100644 index 0000000000..570bc5aca7 --- /dev/null +++ b/compiler/driver/compiler_options_map.def @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef COMPILER_OPTIONS_KEY +#error "Please #define COMPILER_OPTIONS_KEY before #including this file" +#define COMPILER_OPTIONS_KEY(...) // Don't display errors in this file in IDEs. +#endif + +// This file defines the list of keys for CompilerOptionsMap. +// These can be used with CompilerOptionsMap.Get/Set/etc, once that template class has been +// instantiated. +// +// Column Descriptions: +// <<Type>> <<Key Name>> (<<Default Value>>) +// +// Default values are only used by Map::GetOrDefault(K<T>). +// If a default value is omitted here, T{} is used as the default value, which is +// almost-always the value of the type as if it was memset to all 0. +// +// Please keep the columns aligned if possible when adding new rows. +// + +// Parse-able keys from the command line. + +// TODO: Add type parser. +COMPILER_OPTIONS_KEY (std::string, CompilerFilter) +COMPILER_OPTIONS_KEY (Unit, PIC) +COMPILER_OPTIONS_KEY (unsigned int, HugeMethodMaxThreshold) +COMPILER_OPTIONS_KEY (unsigned int, LargeMethodMaxThreshold) +COMPILER_OPTIONS_KEY (unsigned int, SmallMethodMaxThreshold) +COMPILER_OPTIONS_KEY (unsigned int, TinyMethodMaxThreshold) +COMPILER_OPTIONS_KEY (unsigned int, NumDexMethodsThreshold) +COMPILER_OPTIONS_KEY (unsigned int, InlineMaxCodeUnitsThreshold) +COMPILER_OPTIONS_KEY (bool, GenerateDebugInfo) +COMPILER_OPTIONS_KEY (bool, GenerateMiniDebugInfo) +COMPILER_OPTIONS_KEY (bool, GenerateBuildID) +COMPILER_OPTIONS_KEY (Unit, Debuggable) +COMPILER_OPTIONS_KEY (double, TopKProfileThreshold) +COMPILER_OPTIONS_KEY (bool, AbortOnHardVerifierFailure) +COMPILER_OPTIONS_KEY (std::string, DumpInitFailures) +COMPILER_OPTIONS_KEY (std::string, DumpCFG) +COMPILER_OPTIONS_KEY (Unit, DumpCFGAppend) +// TODO: Add type parser. +COMPILER_OPTIONS_KEY (std::string, RegisterAllocationStrategy) +COMPILER_OPTIONS_KEY (ParseStringList<','>, VerboseMethods) + +#undef COMPILER_OPTIONS_KEY diff --git a/compiler/driver/compiler_options_map.h b/compiler/driver/compiler_options_map.h new file mode 100644 index 0000000000..b9bc8b6ea1 --- /dev/null +++ b/compiler/driver/compiler_options_map.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_COMPILER_DRIVER_COMPILER_OPTIONS_MAP_H_ +#define ART_COMPILER_DRIVER_COMPILER_OPTIONS_MAP_H_ + +#include <string> +#include <vector> + +#include "base/variant_map.h" +#include "cmdline_types.h" + +namespace art { + +// Defines a type-safe heterogeneous key->value map. This is to be used as the base for +// an extended map. +template <typename Base, template <typename TV> class KeyType> +struct CompilerOptionsMap : VariantMap<Base, KeyType> { + // Make the next many usages of Key slightly shorter to type. + template <typename TValue> + using Key = KeyType<TValue>; + + // List of key declarations, shorthand for 'static const Key<T> Name' +#define COMPILER_OPTIONS_KEY(Type, Name, ...) static const Key<Type> (Name); +#include "compiler_options_map.def" +}; + +#undef DECLARE_KEY + +} // namespace art + +#endif // ART_COMPILER_DRIVER_COMPILER_OPTIONS_MAP_H_ diff --git a/compiler/driver/simple_compiler_options_map.h b/compiler/driver/simple_compiler_options_map.h new file mode 100644 index 0000000000..3860da9f66 --- /dev/null +++ b/compiler/driver/simple_compiler_options_map.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// This file declares a completion of the CompilerOptionsMap and should be included into a +// .cc file, only. + +#ifndef ART_COMPILER_DRIVER_SIMPLE_COMPILER_OPTIONS_MAP_H_ +#define ART_COMPILER_DRIVER_SIMPLE_COMPILER_OPTIONS_MAP_H_ + +#include <memory> + +#include "compiler_options_map-inl.h" +#include "base/variant_map.h" + +namespace art { + +template <typename TValue> +struct SimpleParseArgumentMapKey : VariantMapKey<TValue> { + SimpleParseArgumentMapKey() {} + explicit SimpleParseArgumentMapKey(TValue default_value) + : VariantMapKey<TValue>(std::move(default_value)) {} + // Don't ODR-use constexpr default values, which means that Struct::Fields + // that are declared 'static constexpr T Name = Value' don't need to have a matching definition. +}; + +struct SimpleParseArgumentMap : CompilerOptionsMap<SimpleParseArgumentMap, + SimpleParseArgumentMapKey> { + // This 'using' line is necessary to inherit the variadic constructor. + using CompilerOptionsMap<SimpleParseArgumentMap, SimpleParseArgumentMapKey>::CompilerOptionsMap; +}; + +#define COMPILER_OPTIONS_MAP_TYPE SimpleParseArgumentMap +#define COMPILER_OPTIONS_MAP_KEY_TYPE SimpleParseArgumentMapKey +#include "compiler_options_map-storage.h" + +using Parser = CmdlineParser<SimpleParseArgumentMap, SimpleParseArgumentMapKey>; + +static inline Parser CreateSimpleParser(bool ignore_unrecognized) { + std::unique_ptr<Parser::Builder> parser_builder = + std::unique_ptr<Parser::Builder>(new Parser::Builder()); + + AddCompilerOptionsArgumentParserOptions<SimpleParseArgumentMap>(*parser_builder); + + parser_builder->IgnoreUnrecognized(ignore_unrecognized); + + return parser_builder->Build(); +} + +} // namespace art + +#endif // ART_COMPILER_DRIVER_SIMPLE_COMPILER_OPTIONS_MAP_H_ diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc index 511a44af04..5c89869e00 100644 --- a/compiler/jit/jit_compiler.cc +++ b/compiler/jit/jit_compiler.cc @@ -78,21 +78,16 @@ extern "C" void jit_types_loaded(void* handle, mirror::Class** types, size_t cou } } -// Callers of this method assume it has NO_RETURN. -NO_RETURN static void Usage(const char* fmt, ...) { - va_list ap; - va_start(ap, fmt); - std::string error; - android::base::StringAppendV(&error, fmt, ap); - LOG(FATAL) << error; - va_end(ap); - exit(EXIT_FAILURE); -} - JitCompiler::JitCompiler() { compiler_options_.reset(new CompilerOptions()); - for (const std::string& argument : Runtime::Current()->GetCompilerOptions()) { - compiler_options_->ParseCompilerOption(argument, Usage); + { + std::string error_msg; + if (!compiler_options_->ParseCompilerOptions(Runtime::Current()->GetCompilerOptions(), + true /* ignore_unrecognized */, + &error_msg)) { + LOG(FATAL) << error_msg; + UNREACHABLE(); + } } // JIT is never PIC, no matter what the runtime compiler options specify. compiler_options_->SetNonPic(); diff --git a/compiler/utils/arm/jni_macro_assembler_arm_vixl.cc b/compiler/utils/arm/jni_macro_assembler_arm_vixl.cc index edb3292ea7..0bae4d4b69 100644 --- a/compiler/utils/arm/jni_macro_assembler_arm_vixl.cc +++ b/compiler/utils/arm/jni_macro_assembler_arm_vixl.cc @@ -164,6 +164,21 @@ void ArmVIXLJNIMacroAssembler::RemoveFrame(size_t frame_size, // AAPCS calling convention. DCHECK_NE(core_spill_mask & (1 << MR), 0) << "core_spill_mask should contain Marking Register R" << MR; + + // The following condition is a compile-time one, so it does not have a run-time cost. + if (kIsDebugBuild) { + // The following condition is a run-time one; it is executed after the + // previous compile-time test, to avoid penalizing non-debug builds. + if (emit_run_time_checks_in_debug_mode_) { + // Emit a run-time check verifying that the Marking Register is up-to-date. + UseScratchRegisterScope temps(asm_.GetVIXLAssembler()); + vixl32::Register temp = temps.Acquire(); + // Ensure we are not clobbering a callee-save register that was restored before. + DCHECK_EQ(core_spill_mask & (1 << temp.GetCode()), 0) + << "core_spill_mask hould not contain scratch register R" << temp.GetCode(); + asm_.GenerateMarkingRegisterCheck(temp); + } + } } } diff --git a/compiler/utils/arm64/jni_macro_assembler_arm64.cc b/compiler/utils/arm64/jni_macro_assembler_arm64.cc index 43c0eff8fc..573bb6d4be 100644 --- a/compiler/utils/arm64/jni_macro_assembler_arm64.cc +++ b/compiler/utils/arm64/jni_macro_assembler_arm64.cc @@ -788,6 +788,21 @@ void Arm64JNIMacroAssembler::RemoveFrame(size_t frame_size, // AAPCS64 calling convention. DCHECK(core_reg_list.IncludesAliasOf(mr)) << "core_reg_list should contain Marking Register X" << mr.GetCode(); + + // The following condition is a compile-time one, so it does not have a run-time cost. + if (kIsDebugBuild) { + // The following condition is a run-time one; it is executed after the + // previous compile-time test, to avoid penalizing non-debug builds. + if (emit_run_time_checks_in_debug_mode_) { + // Emit a run-time check verifying that the Marking Register is up-to-date. + UseScratchRegisterScope temps(asm_.GetVIXLAssembler()); + Register temp = temps.AcquireW(); + // Ensure we are not clobbering a callee-save register that was restored before. + DCHECK(!core_reg_list.IncludesAliasOf(temp.X())) + << "core_reg_list should not contain scratch register X" << temp.GetCode(); + asm_.GenerateMarkingRegisterCheck(temp); + } + } } } diff --git a/compiler/utils/test_dex_file_builder.h b/compiler/utils/test_dex_file_builder.h index 9ba3903033..e6501e0b83 100644 --- a/compiler/utils/test_dex_file_builder.h +++ b/compiler/utils/test_dex_file_builder.h @@ -26,7 +26,8 @@ #include "base/bit_utils.h" #include "base/logging.h" -#include "dex_file.h" +#include "dex_file_loader.h" +#include "native_dex_file.h" namespace art { @@ -88,8 +89,8 @@ class TestDexFileBuilder { } header_data; std::memset(header_data.data, 0, sizeof(header_data.data)); DexFile::Header* header = reinterpret_cast<DexFile::Header*>(&header_data.data); - std::copy_n(DexFile::kDexMagic, 4u, header->magic_); - std::copy_n(DexFile::kDexMagicVersions[0], 4u, header->magic_ + 4u); + std::copy_n(NativeDexFile::kDexMagic, 4u, header->magic_); + std::copy_n(NativeDexFile::kDexMagicVersions[0], 4u, header->magic_ + 4u); header->header_size_ = sizeof(DexFile::Header); header->endian_tag_ = DexFile::kDexEndianConstant; header->link_size_ = 0u; // Unused. @@ -231,7 +232,7 @@ class TestDexFileBuilder { static constexpr bool kVerify = false; static constexpr bool kVerifyChecksum = false; std::string error_msg; - std::unique_ptr<const DexFile> dex_file(DexFile::Open( + std::unique_ptr<const DexFile> dex_file(DexFileLoader::Open( &dex_file_data_[0], dex_file_data_.size(), dex_location, |