diff options
57 files changed, 467 insertions, 620 deletions
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc index 52c767f935..22720ce524 100644 --- a/compiler/common_compiler_test.cc +++ b/compiler/common_compiler_test.cc @@ -153,11 +153,7 @@ void CommonCompilerTest::SetUp() { { ScopedObjectAccess soa(Thread::Current()); - const InstructionSet instruction_set = kRuntimeISA; - // Take the default set of instruction features from the build. - instruction_set_features_ = InstructionSetFeatures::FromCppDefines(); - - runtime_->SetInstructionSet(instruction_set); + runtime_->SetInstructionSet(instruction_set_); for (uint32_t i = 0; i < static_cast<uint32_t>(CalleeSaveType::kLastCalleeSaveType); ++i) { CalleeSaveType type = CalleeSaveType(i); if (!runtime_->HasCalleeSaveMethod(type)) { @@ -165,23 +161,48 @@ void CommonCompilerTest::SetUp() { } } - CreateCompilerDriver(compiler_kind_, instruction_set); + CreateCompilerDriver(); + } +} + +void CommonCompilerTest::ApplyInstructionSet() { + // Copy local instruction_set_ and instruction_set_features_ to *compiler_options_; + CHECK(instruction_set_features_ != nullptr); + if (instruction_set_ == InstructionSet::kThumb2) { + CHECK_EQ(InstructionSet::kArm, instruction_set_features_->GetInstructionSet()); + } else { + CHECK_EQ(instruction_set_, instruction_set_features_->GetInstructionSet()); } + compiler_options_->instruction_set_ = instruction_set_; + compiler_options_->instruction_set_features_ = + InstructionSetFeatures::FromBitmap(instruction_set_, instruction_set_features_->AsBitmap()); + CHECK(compiler_options_->instruction_set_features_->Equals(instruction_set_features_.get())); } -void CommonCompilerTest::CreateCompilerDriver(Compiler::Kind kind, - InstructionSet isa, - size_t number_of_threads) { +void CommonCompilerTest::OverrideInstructionSetFeatures(InstructionSet instruction_set, + const std::string& variant) { + instruction_set_ = instruction_set; + std::string error_msg; + instruction_set_features_ = + InstructionSetFeatures::FromVariant(instruction_set, variant, &error_msg); + CHECK(instruction_set_features_ != nullptr) << error_msg; + + if (compiler_options_ != nullptr) { + ApplyInstructionSet(); + } +} + +void CommonCompilerTest::CreateCompilerDriver() { + ApplyInstructionSet(); + compiler_options_->boot_image_ = true; compiler_options_->SetCompilerFilter(GetCompilerFilter()); compiler_options_->image_classes_.swap(*GetImageClasses()); compiler_driver_.reset(new CompilerDriver(compiler_options_.get(), verification_results_.get(), - kind, - isa, - instruction_set_features_.get(), + compiler_kind_, &compiler_options_->image_classes_, - number_of_threads, + number_of_threads_, /* swap_fd */ -1, GetProfileCompilationInfo())); // We typically don't generate an image in unit tests, disable this optimization by default. @@ -207,11 +228,6 @@ void CommonCompilerTest::SetCompilerKind(Compiler::Kind compiler_kind) { compiler_kind_ = compiler_kind; } -InstructionSet CommonCompilerTest::GetInstructionSet() const { - DCHECK(compiler_driver_.get() != nullptr); - return compiler_driver_->GetInstructionSet(); -} - void CommonCompilerTest::TearDown() { compiler_driver_.reset(); callbacks_.reset(); @@ -339,4 +355,8 @@ void CommonCompilerTest::SetDexFilesForOatFile(const std::vector<const DexFile*> compiler_driver_->dex_to_dex_compiler_.SetDexFiles(dex_files); } +void CommonCompilerTest::ClearBootImageOption() { + compiler_options_->boot_image_ = false; +} + } // namespace art diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h index f070bbbeb8..db38110400 100644 --- a/compiler/common_compiler_test.h +++ b/compiler/common_compiler_test.h @@ -20,6 +20,8 @@ #include <list> #include <vector> +#include "arch/instruction_set.h" +#include "arch/instruction_set_features.h" #include "base/hash_set.h" #include "common_runtime_test.h" #include "compiler.h" @@ -55,15 +57,13 @@ class CommonCompilerTest : public CommonRuntimeTest { REQUIRES_SHARED(Locks::mutator_lock_); protected: - virtual void SetUp(); + void SetUp() OVERRIDE; - virtual void SetUpRuntimeOptions(RuntimeOptions* options); + void SetUpRuntimeOptions(RuntimeOptions* options) OVERRIDE; Compiler::Kind GetCompilerKind() const; void SetCompilerKind(Compiler::Kind compiler_kind); - InstructionSet GetInstructionSet() const; - // Get the set of image classes given to the compiler-driver in SetUp. virtual std::unique_ptr<HashSet<std::string>> GetImageClasses(); @@ -73,7 +73,7 @@ class CommonCompilerTest : public CommonRuntimeTest { return CompilerFilter::kDefaultCompilerFilter; } - virtual void TearDown(); + void TearDown() OVERRIDE; void CompileClass(mirror::ClassLoader* class_loader, const char* class_name) REQUIRES_SHARED(Locks::mutator_lock_); @@ -88,7 +88,10 @@ class CommonCompilerTest : public CommonRuntimeTest { const char* method_name, const char* signature) REQUIRES_SHARED(Locks::mutator_lock_); - void CreateCompilerDriver(Compiler::Kind kind, InstructionSet isa, size_t number_of_threads = 2U); + void ApplyInstructionSet(); + void OverrideInstructionSetFeatures(InstructionSet instruction_set, const std::string& variant); + + void CreateCompilerDriver(); void ReserveImageSpace(); @@ -96,12 +99,20 @@ class CommonCompilerTest : public CommonRuntimeTest { void SetDexFilesForOatFile(const std::vector<const DexFile*>& dex_files); + void ClearBootImageOption(); + Compiler::Kind compiler_kind_ = Compiler::kOptimizing; + size_t number_of_threads_ = 2u; + + InstructionSet instruction_set_ = + (kRuntimeISA == InstructionSet::kArm) ? InstructionSet::kThumb2 : kRuntimeISA; + // Take the default set of instruction features from the build. + std::unique_ptr<const InstructionSetFeatures> instruction_set_features_ + = InstructionSetFeatures::FromCppDefines(); + std::unique_ptr<CompilerOptions> compiler_options_; std::unique_ptr<VerificationResults> verification_results_; std::unique_ptr<CompilerDriver> compiler_driver_; - std::unique_ptr<const InstructionSetFeatures> instruction_set_features_; - private: std::unique_ptr<MemMap> image_reservation_; diff --git a/compiler/debug/dwarf/dwarf_test.h b/compiler/debug/dwarf/dwarf_test.h index 9a7c604ca1..6b039a7b5f 100644 --- a/compiler/debug/dwarf/dwarf_test.h +++ b/compiler/debug/dwarf/dwarf_test.h @@ -28,7 +28,7 @@ #include "base/os.h" #include "base/unix_file/fd_file.h" -#include "common_runtime_test.h" +#include "common_compiler_test.h" #include "gtest/gtest.h" #include "linker/elf_builder.h" #include "linker/file_output_stream.h" @@ -39,7 +39,7 @@ namespace dwarf { #define DW_CHECK(substring) Check(substring, false, __FILE__, __LINE__) #define DW_CHECK_NEXT(substring) Check(substring, true, __FILE__, __LINE__) -class DwarfTest : public CommonRuntimeTest { +class DwarfTest : public CommonCompilerTest { public: static constexpr bool kPrintObjdumpOutput = false; // debugging. diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc index fb6a72b1c5..fcaa0cdd07 100644 --- a/compiler/dex/dex_to_dex_compiler.cc +++ b/compiler/dex/dex_to_dex_compiler.cc @@ -31,6 +31,7 @@ #include "dex/dex_instruction-inl.h" #include "dex_to_dex_decompiler.h" #include "driver/compiler_driver.h" +#include "driver/compiler_options.h" #include "driver/dex_compilation_unit.h" #include "mirror/dex_cache.h" #include "quicken_info.h" @@ -609,7 +610,7 @@ CompiledMethod* DexToDexCompiler::CompileMethod( } // Create a `CompiledMethod`, with the quickened information in the vmap table. - InstructionSet instruction_set = driver_->GetInstructionSet(); + InstructionSet instruction_set = driver_->GetCompilerOptions().GetInstructionSet(); if (instruction_set == InstructionSet::kThumb2) { // Don't use the thumb2 instruction set to avoid the one off code delta. instruction_set = InstructionSet::kArm; diff --git a/compiler/driver/compiled_method_storage_test.cc b/compiler/driver/compiled_method_storage_test.cc index 42fbba5109..aed04f9c75 100644 --- a/compiler/driver/compiled_method_storage_test.cc +++ b/compiler/driver/compiled_method_storage_test.cc @@ -31,8 +31,6 @@ TEST(CompiledMethodStorage, Deduplicate) { CompilerDriver driver(&compiler_options, &verification_results, Compiler::kOptimizing, - /* instruction_set_ */ InstructionSet::kNone, - /* instruction_set_features */ nullptr, /* image_classes */ nullptr, /* thread_count */ 1u, /* swap_fd */ -1, diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 66a8a57b36..7c13894a2c 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -261,8 +261,6 @@ CompilerDriver::CompilerDriver( const CompilerOptions* compiler_options, VerificationResults* verification_results, Compiler::Kind compiler_kind, - InstructionSet instruction_set, - const InstructionSetFeatures* instruction_set_features, HashSet<std::string>* image_classes, size_t thread_count, int swap_fd, @@ -271,9 +269,6 @@ CompilerDriver::CompilerDriver( verification_results_(verification_results), compiler_(Compiler::Create(this, compiler_kind)), compiler_kind_(compiler_kind), - instruction_set_( - instruction_set == InstructionSet::kArm ? InstructionSet::kThumb2 : instruction_set), - instruction_set_features_(instruction_set_features), requires_constructor_barrier_lock_("constructor barrier lock"), non_relative_linker_patch_count_(0u), image_classes_(std::move(image_classes)), @@ -309,13 +304,15 @@ CompilerDriver::~CompilerDriver() { } -#define CREATE_TRAMPOLINE(type, abi, offset) \ - if (Is64BitInstructionSet(instruction_set_)) { \ - return CreateTrampoline64(instruction_set_, abi, \ - type ## _ENTRYPOINT_OFFSET(PointerSize::k64, offset)); \ - } else { \ - return CreateTrampoline32(instruction_set_, abi, \ - type ## _ENTRYPOINT_OFFSET(PointerSize::k32, offset)); \ +#define CREATE_TRAMPOLINE(type, abi, offset) \ + if (Is64BitInstructionSet(GetCompilerOptions().GetInstructionSet())) { \ + return CreateTrampoline64(GetCompilerOptions().GetInstructionSet(), \ + abi, \ + type ## _ENTRYPOINT_OFFSET(PointerSize::k64, offset)); \ + } else { \ + return CreateTrampoline32(GetCompilerOptions().GetInstructionSet(), \ + abi, \ + type ## _ENTRYPOINT_OFFSET(PointerSize::k32, offset)); \ } std::unique_ptr<const std::vector<uint8_t>> CompilerDriver::CreateJniDlsymLookup() const { @@ -601,7 +598,7 @@ static void CompileMethodQuick( if ((access_flags & kAccNative) != 0) { // Are we extracting only and have support for generic JNI down calls? if (!driver->GetCompilerOptions().IsJniCompilationEnabled() && - InstructionSetHasGenericJniStub(driver->GetInstructionSet())) { + InstructionSetHasGenericJniStub(driver->GetCompilerOptions().GetInstructionSet())) { // Leaving this empty will trigger the generic JNI version } else { // Query any JNI optimization annotations such as @FastNative or @CriticalNative. @@ -2146,8 +2143,9 @@ class SetVerifiedClassVisitor : public CompilationVisitor { mirror::Class::SetStatus(klass, ClassStatus::kVerified, soa.Self()); // Mark methods as pre-verified. If we don't do this, the interpreter will run with // access checks. - klass->SetSkipAccessChecksFlagOnAllMethods( - GetInstructionSetPointerSize(manager_->GetCompiler()->GetInstructionSet())); + InstructionSet instruction_set = + manager_->GetCompiler()->GetCompilerOptions().GetInstructionSet(); + klass->SetSkipAccessChecksFlagOnAllMethods(GetInstructionSetPointerSize(instruction_set)); klass->SetVerificationAttempted(); } // Record the final class status if necessary. diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index 54e1f3747f..8739dc3a35 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -97,8 +97,6 @@ class CompilerDriver { CompilerDriver(const CompilerOptions* compiler_options, VerificationResults* verification_results, Compiler::Kind compiler_kind, - InstructionSet instruction_set, - const InstructionSetFeatures* instruction_set_features, HashSet<std::string>* image_classes, size_t thread_count, int swap_fd, @@ -129,14 +127,6 @@ class CompilerDriver { VerificationResults* GetVerificationResults() const; - InstructionSet GetInstructionSet() const { - return instruction_set_; - } - - const InstructionSetFeatures* GetInstructionSetFeatures() const { - return instruction_set_features_; - } - const CompilerOptions& GetCompilerOptions() const { return *compiler_options_; } @@ -451,9 +441,6 @@ class CompilerDriver { std::unique_ptr<Compiler> compiler_; Compiler::Kind compiler_kind_; - const InstructionSet instruction_set_; - const InstructionSetFeatures* const instruction_set_features_; - // All class references that require constructor barriers. If the class reference is not in the // set then the result has not yet been computed. mutable ReaderWriterMutex requires_constructor_barrier_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc index cc1af3e108..62d547de44 100644 --- a/compiler/driver/compiler_options.cc +++ b/compiler/driver/compiler_options.cc @@ -20,6 +20,8 @@ #include "android-base/stringprintf.h" +#include "arch/instruction_set.h" +#include "arch/instruction_set_features.h" #include "base/runtime_debug.h" #include "base/variant_map.h" #include "cmdline_parser.h" @@ -37,13 +39,14 @@ CompilerOptions::CompilerOptions() tiny_method_threshold_(kDefaultTinyMethodThreshold), num_dex_methods_threshold_(kDefaultNumDexMethodsThreshold), inline_max_code_units_(kUnsetInlineMaxCodeUnits), + instruction_set_(kRuntimeISA == InstructionSet::kArm ? InstructionSet::kThumb2 : kRuntimeISA), + instruction_set_features_(nullptr), no_inline_from_(), dex_files_for_oat_file_(), image_classes_(), boot_image_(false), core_image_(false), app_image_(false), - top_k_profile_threshold_(kDefaultTopKProfileThreshold), debuggable_(false), generate_debug_info_(kDefaultGenerateDebugInfo), generate_mini_debug_info_(kDefaultGenerateMiniDebugInfo), @@ -55,6 +58,7 @@ CompilerOptions::CompilerOptions() dump_timings_(false), dump_pass_timings_(false), dump_stats_(false), + top_k_profile_threshold_(kDefaultTopKProfileThreshold), verbose_methods_(), abort_on_hard_verifier_failure_(false), abort_on_soft_verifier_failure_(false), diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h index 908ff3302c..601c9140dd 100644 --- a/compiler/driver/compiler_options.h +++ b/compiler/driver/compiler_options.h @@ -17,6 +17,7 @@ #ifndef ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_ #define ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_ +#include <memory> #include <ostream> #include <string> #include <vector> @@ -30,11 +31,17 @@ namespace art { +namespace jit { +class JitCompiler; +} // namespace jit + namespace verifier { class VerifierDepsTest; } // namespace verifier class DexFile; +enum class InstructionSet; +class InstructionSetFeatures; class CompilerOptions FINAL { public: @@ -231,6 +238,15 @@ class CompilerOptions FINAL { return abort_on_soft_verifier_failure_; } + InstructionSet GetInstructionSet() const { + return instruction_set_; + } + + const InstructionSetFeatures* GetInstructionSetFeatures() const { + return instruction_set_features_.get(); + } + + const std::vector<const DexFile*>& GetNoInlineFromDexFile() const { return no_inline_from_; } @@ -312,6 +328,9 @@ class CompilerOptions FINAL { size_t num_dex_methods_threshold_; size_t inline_max_code_units_; + InstructionSet instruction_set_; + std::unique_ptr<const InstructionSetFeatures> instruction_set_features_; + // Dex files from which we should not inline code. Does not own the dex files. // This is usually a very short list (i.e. a single dex file), so we // prefer vector<> over a lookup-oriented container, such as set<>. @@ -327,8 +346,6 @@ class CompilerOptions FINAL { bool boot_image_; bool core_image_; bool app_image_; - // When using a profile file only the top K% of the profiled samples will be compiled. - double top_k_profile_threshold_; bool debuggable_; bool generate_debug_info_; bool generate_mini_debug_info_; @@ -341,6 +358,9 @@ class CompilerOptions FINAL { bool dump_pass_timings_; bool dump_stats_; + // When using a profile file only the top K% of the profiled samples will be compiled. + double top_k_profile_threshold_; + // Vector of methods to have verbose output enabled for. std::vector<std::string> verbose_methods_; @@ -380,6 +400,7 @@ class CompilerOptions FINAL { friend class Dex2Oat; friend class DexToDexDecompilerTest; friend class CommonCompilerTest; + friend class jit::JitCompiler; friend class verifier::VerifierDepsTest; template <class Base> diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc index 0de00a82fa..d7bd828f80 100644 --- a/compiler/jit/jit_compiler.cc +++ b/compiler/jit/jit_compiler.cc @@ -33,6 +33,7 @@ #include "jit/debugger_interface.h" #include "jit/jit.h" #include "jit/jit_code_cache.h" +#include "jit/jit_logger.h" #include "oat_file-inl.h" #include "oat_quick_method_header.h" #include "object_lock.h" @@ -50,7 +51,7 @@ extern "C" void* jit_load(bool* generate_debug_info) { VLOG(jit) << "loading jit compiler"; auto* const jit_compiler = JitCompiler::Create(); CHECK(jit_compiler != nullptr); - *generate_debug_info = jit_compiler->GetCompilerOptions()->GetGenerateDebugInfo(); + *generate_debug_info = jit_compiler->GetCompilerOptions().GetGenerateDebugInfo(); VLOG(jit) << "Done loading jit compiler"; return jit_compiler; } @@ -72,10 +73,11 @@ extern "C" void jit_types_loaded(void* handle, mirror::Class** types, size_t cou REQUIRES_SHARED(Locks::mutator_lock_) { auto* jit_compiler = reinterpret_cast<JitCompiler*>(handle); DCHECK(jit_compiler != nullptr); - if (jit_compiler->GetCompilerOptions()->GetGenerateDebugInfo()) { + const CompilerOptions& compiler_options = jit_compiler->GetCompilerOptions(); + if (compiler_options.GetGenerateDebugInfo()) { const ArrayRef<mirror::Class*> types_array(types, count); std::vector<uint8_t> elf_file = debug::WriteDebugElfFileForClasses( - kRuntimeISA, jit_compiler->GetCompilerDriver()->GetInstructionSetFeatures(), types_array); + kRuntimeISA, compiler_options.GetInstructionSetFeatures(), types_array); MutexLock mu(Thread::Current(), *Locks::native_debug_interface_lock_); // We never free debug info for types, so we don't need to provide a handle // (which would have been otherwise used as identifier to remove it later). @@ -103,44 +105,50 @@ JitCompiler::JitCompiler() { // Set debuggability based on the runtime value. compiler_options_->SetDebuggable(Runtime::Current()->IsJavaDebuggable()); - const InstructionSet instruction_set = kRuntimeISA; + const InstructionSet instruction_set = compiler_options_->GetInstructionSet(); + if (kRuntimeISA == InstructionSet::kArm) { + DCHECK_EQ(instruction_set, InstructionSet::kThumb2); + } else { + DCHECK_EQ(instruction_set, kRuntimeISA); + } + std::unique_ptr<const InstructionSetFeatures> instruction_set_features; for (const StringPiece option : Runtime::Current()->GetCompilerOptions()) { VLOG(compiler) << "JIT compiler option " << option; std::string error_msg; if (option.starts_with("--instruction-set-variant=")) { StringPiece str = option.substr(strlen("--instruction-set-variant=")).data(); VLOG(compiler) << "JIT instruction set variant " << str; - instruction_set_features_ = InstructionSetFeatures::FromVariant( + instruction_set_features = InstructionSetFeatures::FromVariant( instruction_set, str.as_string(), &error_msg); - if (instruction_set_features_ == nullptr) { + if (instruction_set_features == nullptr) { LOG(WARNING) << "Error parsing " << option << " message=" << error_msg; } } else if (option.starts_with("--instruction-set-features=")) { StringPiece str = option.substr(strlen("--instruction-set-features=")).data(); VLOG(compiler) << "JIT instruction set features " << str; - if (instruction_set_features_ == nullptr) { - instruction_set_features_ = InstructionSetFeatures::FromVariant( + if (instruction_set_features == nullptr) { + instruction_set_features = InstructionSetFeatures::FromVariant( instruction_set, "default", &error_msg); - if (instruction_set_features_ == nullptr) { + if (instruction_set_features == nullptr) { LOG(WARNING) << "Error parsing " << option << " message=" << error_msg; } } - instruction_set_features_ = - instruction_set_features_->AddFeaturesFromString(str.as_string(), &error_msg); - if (instruction_set_features_ == nullptr) { + instruction_set_features = + instruction_set_features->AddFeaturesFromString(str.as_string(), &error_msg); + if (instruction_set_features == nullptr) { LOG(WARNING) << "Error parsing " << option << " message=" << error_msg; } } } - if (instruction_set_features_ == nullptr) { - instruction_set_features_ = InstructionSetFeatures::FromCppDefines(); + if (instruction_set_features == nullptr) { + instruction_set_features = InstructionSetFeatures::FromCppDefines(); } + compiler_options_->instruction_set_features_ = std::move(instruction_set_features); + compiler_driver_.reset(new CompilerDriver( compiler_options_.get(), /* verification_results */ nullptr, Compiler::kOptimizing, - instruction_set, - instruction_set_features_.get(), /* image_classes */ nullptr, /* thread_count */ 1, /* swap_fd */ -1, diff --git a/compiler/jit/jit_compiler.h b/compiler/jit/jit_compiler.h index 31dc9e2fe5..5840fece2e 100644 --- a/compiler/jit/jit_compiler.h +++ b/compiler/jit/jit_compiler.h @@ -18,18 +18,19 @@ #define ART_COMPILER_JIT_JIT_COMPILER_H_ #include "base/mutex.h" -#include "compiled_method.h" -#include "driver/compiler_driver.h" -#include "driver/compiler_options.h" -#include "jit_logger.h" namespace art { class ArtMethod; -class InstructionSetFeatures; +class CompiledMethod; +class CompilerDriver; +class CompilerOptions; +class Thread; namespace jit { +class JitLogger; + class JitCompiler { public: static JitCompiler* Create(); @@ -39,8 +40,8 @@ class JitCompiler { bool CompileMethod(Thread* self, ArtMethod* method, bool osr) REQUIRES_SHARED(Locks::mutator_lock_); - CompilerOptions* GetCompilerOptions() const { - return compiler_options_.get(); + const CompilerOptions& GetCompilerOptions() const { + return *compiler_options_.get(); } CompilerDriver* GetCompilerDriver() const { return compiler_driver_.get(); @@ -49,7 +50,6 @@ class JitCompiler { private: std::unique_ptr<CompilerOptions> compiler_options_; std::unique_ptr<CompilerDriver> compiler_driver_; - std::unique_ptr<const InstructionSetFeatures> instruction_set_features_; std::unique_ptr<JitLogger> jit_logger_; JitCompiler(); diff --git a/compiler/jni/quick/jni_compiler.cc b/compiler/jni/quick/jni_compiler.cc index 0902bf2bce..62e8e0264f 100644 --- a/compiler/jni/quick/jni_compiler.cc +++ b/compiler/jni/quick/jni_compiler.cc @@ -34,7 +34,6 @@ #include "class_linker.h" #include "debug/dwarf/debug_frame_opcode_writer.h" #include "dex/dex_file-inl.h" -#include "driver/compiler_driver.h" #include "driver/compiler_options.h" #include "entrypoints/quick/quick_entrypoints.h" #include "jni/jni_env_ext.h" @@ -115,7 +114,7 @@ static ThreadOffset<kPointerSize> GetJniEntrypointThreadOffset(JniEntrypoint whi // convention. // template <PointerSize kPointerSize> -static JniCompiledMethod ArtJniCompileMethodInternal(CompilerDriver* driver, +static JniCompiledMethod ArtJniCompileMethodInternal(const CompilerOptions& compiler_options, uint32_t access_flags, uint32_t method_idx, const DexFile& dex_file) { @@ -124,8 +123,9 @@ static JniCompiledMethod ArtJniCompileMethodInternal(CompilerDriver* driver, const bool is_static = (access_flags & kAccStatic) != 0; const bool is_synchronized = (access_flags & kAccSynchronized) != 0; const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx)); - InstructionSet instruction_set = driver->GetInstructionSet(); - const InstructionSetFeatures* instruction_set_features = driver->GetInstructionSetFeatures(); + InstructionSet instruction_set = compiler_options.GetInstructionSet(); + const InstructionSetFeatures* instruction_set_features = + compiler_options.GetInstructionSetFeatures(); // i.e. if the method was annotated with @FastNative const bool is_fast_native = (access_flags & kAccFastNative) != 0u; @@ -216,7 +216,6 @@ static JniCompiledMethod ArtJniCompileMethodInternal(CompilerDriver* driver, // Assembler that holds generated instructions std::unique_ptr<JNIMacroAssembler<kPointerSize>> jni_asm = GetMacroAssembler<kPointerSize>(&allocator, instruction_set, instruction_set_features); - const CompilerOptions& compiler_options = driver->GetCompilerOptions(); jni_asm->cfi().SetEnabled(compiler_options.GenerateAnyDebugInfo()); jni_asm->SetEmitRunTimeChecksInDebugMode(compiler_options.EmitRunTimeChecksInDebugMode()); @@ -771,16 +770,16 @@ static void SetNativeParameter(JNIMacroAssembler<kPointerSize>* jni_asm, } } -JniCompiledMethod ArtQuickJniCompileMethod(CompilerDriver* compiler, +JniCompiledMethod ArtQuickJniCompileMethod(const CompilerOptions& compiler_options, uint32_t access_flags, uint32_t method_idx, const DexFile& dex_file) { - if (Is64BitInstructionSet(compiler->GetInstructionSet())) { + if (Is64BitInstructionSet(compiler_options.GetInstructionSet())) { return ArtJniCompileMethodInternal<PointerSize::k64>( - compiler, access_flags, method_idx, dex_file); + compiler_options, access_flags, method_idx, dex_file); } else { return ArtJniCompileMethodInternal<PointerSize::k32>( - compiler, access_flags, method_idx, dex_file); + compiler_options, access_flags, method_idx, dex_file); } } diff --git a/compiler/jni/quick/jni_compiler.h b/compiler/jni/quick/jni_compiler.h index 11419947a0..313fcd361e 100644 --- a/compiler/jni/quick/jni_compiler.h +++ b/compiler/jni/quick/jni_compiler.h @@ -25,7 +25,7 @@ namespace art { class ArtMethod; -class CompilerDriver; +class CompilerOptions; class DexFile; class JniCompiledMethod { @@ -62,7 +62,7 @@ class JniCompiledMethod { std::vector<uint8_t> cfi_; }; -JniCompiledMethod ArtQuickJniCompileMethod(CompilerDriver* compiler, +JniCompiledMethod ArtQuickJniCompileMethod(const CompilerOptions& compiler_options, uint32_t access_flags, uint32_t method_idx, const DexFile& dex_file); diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 2589869859..f53e60b9ff 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -877,53 +877,45 @@ void CodeGenerator::AllocateLocations(HInstruction* instruction) { } std::unique_ptr<CodeGenerator> CodeGenerator::Create(HGraph* graph, - InstructionSet instruction_set, - const InstructionSetFeatures& isa_features, const CompilerOptions& compiler_options, OptimizingCompilerStats* stats) { ArenaAllocator* allocator = graph->GetAllocator(); - switch (instruction_set) { + switch (compiler_options.GetInstructionSet()) { #ifdef ART_ENABLE_CODEGEN_arm case InstructionSet::kArm: case InstructionSet::kThumb2: { return std::unique_ptr<CodeGenerator>( - new (allocator) arm::CodeGeneratorARMVIXL( - graph, *isa_features.AsArmInstructionSetFeatures(), compiler_options, stats)); + new (allocator) arm::CodeGeneratorARMVIXL(graph, compiler_options, stats)); } #endif #ifdef ART_ENABLE_CODEGEN_arm64 case InstructionSet::kArm64: { return std::unique_ptr<CodeGenerator>( - new (allocator) arm64::CodeGeneratorARM64( - graph, *isa_features.AsArm64InstructionSetFeatures(), compiler_options, stats)); + new (allocator) arm64::CodeGeneratorARM64(graph, compiler_options, stats)); } #endif #ifdef ART_ENABLE_CODEGEN_mips case InstructionSet::kMips: { return std::unique_ptr<CodeGenerator>( - new (allocator) mips::CodeGeneratorMIPS( - graph, *isa_features.AsMipsInstructionSetFeatures(), compiler_options, stats)); + new (allocator) mips::CodeGeneratorMIPS(graph, compiler_options, stats)); } #endif #ifdef ART_ENABLE_CODEGEN_mips64 case InstructionSet::kMips64: { return std::unique_ptr<CodeGenerator>( - new (allocator) mips64::CodeGeneratorMIPS64( - graph, *isa_features.AsMips64InstructionSetFeatures(), compiler_options, stats)); + new (allocator) mips64::CodeGeneratorMIPS64(graph, compiler_options, stats)); } #endif #ifdef ART_ENABLE_CODEGEN_x86 case InstructionSet::kX86: { return std::unique_ptr<CodeGenerator>( - new (allocator) x86::CodeGeneratorX86( - graph, *isa_features.AsX86InstructionSetFeatures(), compiler_options, stats)); + new (allocator) x86::CodeGeneratorX86(graph, compiler_options, stats)); } #endif #ifdef ART_ENABLE_CODEGEN_x86_64 case InstructionSet::kX86_64: { return std::unique_ptr<CodeGenerator>( - new (allocator) x86_64::CodeGeneratorX86_64( - graph, *isa_features.AsX86_64InstructionSetFeatures(), compiler_options, stats)); + new (allocator) x86_64::CodeGeneratorX86_64(graph, compiler_options, stats)); } #endif default: diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h index 03ae4983d4..59f858ea52 100644 --- a/compiler/optimizing/code_generator.h +++ b/compiler/optimizing/code_generator.h @@ -188,8 +188,6 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> { // Compiles the graph to executable instructions. void Compile(CodeAllocator* allocator); static std::unique_ptr<CodeGenerator> Create(HGraph* graph, - InstructionSet instruction_set, - const InstructionSetFeatures& isa_features, const CompilerOptions& compiler_options, OptimizingCompilerStats* stats = nullptr); virtual ~CodeGenerator(); diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 85c5659b83..979a5d4b2c 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -1374,7 +1374,6 @@ Location InvokeDexCallingConventionVisitorARM64::GetMethodLocation() const { } CodeGeneratorARM64::CodeGeneratorARM64(HGraph* graph, - const Arm64InstructionSetFeatures& isa_features, const CompilerOptions& compiler_options, OptimizingCompilerStats* stats) : CodeGenerator(graph, @@ -1391,7 +1390,6 @@ CodeGeneratorARM64::CodeGeneratorARM64(HGraph* graph, instruction_visitor_(graph, this), move_resolver_(graph->GetAllocator(), this), assembler_(graph->GetAllocator()), - isa_features_(isa_features), uint32_literals_(std::less<uint32_t>(), graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)), uint64_literals_(std::less<uint64_t>(), @@ -1729,6 +1727,10 @@ void CodeGeneratorARM64::DumpFloatingPointRegister(std::ostream& stream, int reg stream << DRegister(reg); } +const Arm64InstructionSetFeatures& CodeGeneratorARM64::GetInstructionSetFeatures() const { + return *GetCompilerOptions().GetInstructionSetFeatures()->AsArm64InstructionSetFeatures(); +} + void CodeGeneratorARM64::MoveConstant(CPURegister destination, HConstant* constant) { if (constant->IsIntConstant()) { __ Mov(Register(destination), constant->AsIntConstant()->GetValue()); diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h index 11ff78b021..e62c16c414 100644 --- a/compiler/optimizing/code_generator_arm64.h +++ b/compiler/optimizing/code_generator_arm64.h @@ -399,7 +399,6 @@ class ParallelMoveResolverARM64 : public ParallelMoveResolverNoSwap { class CodeGeneratorARM64 : public CodeGenerator { public: CodeGeneratorARM64(HGraph* graph, - const Arm64InstructionSetFeatures& isa_features, const CompilerOptions& compiler_options, OptimizingCompilerStats* stats = nullptr); virtual ~CodeGeneratorARM64() {} @@ -472,9 +471,7 @@ class CodeGeneratorARM64 : public CodeGenerator { return InstructionSet::kArm64; } - const Arm64InstructionSetFeatures& GetInstructionSetFeatures() const { - return isa_features_; - } + const Arm64InstructionSetFeatures& GetInstructionSetFeatures() const; void Initialize() OVERRIDE { block_labels_.resize(GetGraph()->GetBlocks().size()); @@ -890,7 +887,6 @@ class CodeGeneratorARM64 : public CodeGenerator { InstructionCodeGeneratorARM64 instruction_visitor_; ParallelMoveResolverARM64 move_resolver_; Arm64Assembler assembler_; - const Arm64InstructionSetFeatures& isa_features_; // Deduplication map for 32-bit literals, used for non-patchable boot image addresses. Uint32ToLiteralMap uint32_literals_; diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 6804340cd4..6c8d5636d5 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -1502,6 +1502,10 @@ void CodeGeneratorARMVIXL::DumpFloatingPointRegister(std::ostream& stream, int r stream << vixl32::SRegister(reg); } +const ArmInstructionSetFeatures& CodeGeneratorARMVIXL::GetInstructionSetFeatures() const { + return *GetCompilerOptions().GetInstructionSetFeatures()->AsArmInstructionSetFeatures(); +} + static uint32_t ComputeSRegisterListMask(const SRegisterList& regs) { uint32_t mask = 0; for (uint32_t i = regs.GetFirstSRegister().GetCode(); @@ -2319,7 +2323,6 @@ vixl32::Label* CodeGeneratorARMVIXL::GetFinalLabel(HInstruction* instruction, } CodeGeneratorARMVIXL::CodeGeneratorARMVIXL(HGraph* graph, - const ArmInstructionSetFeatures& isa_features, const CompilerOptions& compiler_options, OptimizingCompilerStats* stats) : CodeGenerator(graph, @@ -2336,7 +2339,6 @@ CodeGeneratorARMVIXL::CodeGeneratorARMVIXL(HGraph* graph, instruction_visitor_(graph, this), move_resolver_(graph->GetAllocator(), this), assembler_(graph->GetAllocator()), - isa_features_(isa_features), uint32_literals_(std::less<uint32_t>(), graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)), boot_image_method_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)), diff --git a/compiler/optimizing/code_generator_arm_vixl.h b/compiler/optimizing/code_generator_arm_vixl.h index 4893d3c25e..ae19cdbc50 100644 --- a/compiler/optimizing/code_generator_arm_vixl.h +++ b/compiler/optimizing/code_generator_arm_vixl.h @@ -428,7 +428,6 @@ class InstructionCodeGeneratorARMVIXL : public InstructionCodeGenerator { class CodeGeneratorARMVIXL : public CodeGenerator { public: CodeGeneratorARMVIXL(HGraph* graph, - const ArmInstructionSetFeatures& isa_features, const CompilerOptions& compiler_options, OptimizingCompilerStats* stats = nullptr); virtual ~CodeGeneratorARMVIXL() {} @@ -475,6 +474,9 @@ class CodeGeneratorARMVIXL : public CodeGenerator { ParallelMoveResolver* GetMoveResolver() OVERRIDE { return &move_resolver_; } InstructionSet GetInstructionSet() const OVERRIDE { return InstructionSet::kThumb2; } + + const ArmInstructionSetFeatures& GetInstructionSetFeatures() const; + // Helper method to move a 32-bit value between two locations. void Move32(Location destination, Location source); @@ -523,8 +525,6 @@ class CodeGeneratorARMVIXL : public CodeGenerator { void Finalize(CodeAllocator* allocator) OVERRIDE; - const ArmInstructionSetFeatures& GetInstructionSetFeatures() const { return isa_features_; } - bool NeedsTwoRegisters(DataType::Type type) const OVERRIDE { return type == DataType::Type::kFloat64 || type == DataType::Type::kInt64; } @@ -888,7 +888,6 @@ class CodeGeneratorARMVIXL : public CodeGenerator { ParallelMoveResolverARMVIXL move_resolver_; ArmVIXLAssembler assembler_; - const ArmInstructionSetFeatures& isa_features_; // Deduplication map for 32-bit literals, used for non-patchable boot image addresses. Uint32ToLiteralMap uint32_literals_; diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index 112eb517b5..8c38824d12 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -997,7 +997,6 @@ class ReadBarrierForRootSlowPathMIPS : public SlowPathCodeMIPS { }; CodeGeneratorMIPS::CodeGeneratorMIPS(HGraph* graph, - const MipsInstructionSetFeatures& isa_features, const CompilerOptions& compiler_options, OptimizingCompilerStats* stats) : CodeGenerator(graph, @@ -1014,8 +1013,8 @@ CodeGeneratorMIPS::CodeGeneratorMIPS(HGraph* graph, location_builder_(graph, this), instruction_visitor_(graph, this), move_resolver_(graph->GetAllocator(), this), - assembler_(graph->GetAllocator(), &isa_features), - isa_features_(isa_features), + assembler_(graph->GetAllocator(), + compiler_options.GetInstructionSetFeatures()->AsMipsInstructionSetFeatures()), uint32_literals_(std::less<uint32_t>(), graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)), boot_image_method_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)), @@ -1912,6 +1911,10 @@ void CodeGeneratorMIPS::DumpFloatingPointRegister(std::ostream& stream, int reg) stream << FRegister(reg); } +const MipsInstructionSetFeatures& CodeGeneratorMIPS::GetInstructionSetFeatures() const { + return *GetCompilerOptions().GetInstructionSetFeatures()->AsMipsInstructionSetFeatures(); +} + constexpr size_t kMipsDirectEntrypointRuntimeOffset = 16; void CodeGeneratorMIPS::InvokeRuntime(QuickEntrypointEnum entrypoint, diff --git a/compiler/optimizing/code_generator_mips.h b/compiler/optimizing/code_generator_mips.h index 9fdb385ce6..9758d35335 100644 --- a/compiler/optimizing/code_generator_mips.h +++ b/compiler/optimizing/code_generator_mips.h @@ -370,7 +370,6 @@ class InstructionCodeGeneratorMIPS : public InstructionCodeGenerator { class CodeGeneratorMIPS : public CodeGenerator { public: CodeGeneratorMIPS(HGraph* graph, - const MipsInstructionSetFeatures& isa_features, const CompilerOptions& compiler_options, OptimizingCompilerStats* stats = nullptr); virtual ~CodeGeneratorMIPS() {} @@ -509,9 +508,7 @@ class CodeGeneratorMIPS : public CodeGenerator { InstructionSet GetInstructionSet() const OVERRIDE { return InstructionSet::kMips; } - const MipsInstructionSetFeatures& GetInstructionSetFeatures() const { - return isa_features_; - } + const MipsInstructionSetFeatures& GetInstructionSetFeatures() const; MipsLabel* GetLabelOf(HBasicBlock* block) const { return CommonGetLabelOf<MipsLabel>(block_labels_, block); @@ -695,7 +692,6 @@ class CodeGeneratorMIPS : public CodeGenerator { InstructionCodeGeneratorMIPS instruction_visitor_; ParallelMoveResolverMIPS move_resolver_; MipsAssembler assembler_; - const MipsInstructionSetFeatures& isa_features_; // Deduplication map for 32-bit literals, used for non-patchable boot image addresses. Uint32ToLiteralMap uint32_literals_; diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index 9f863640d5..9682377f5e 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -940,7 +940,6 @@ class ReadBarrierForRootSlowPathMIPS64 : public SlowPathCodeMIPS64 { }; CodeGeneratorMIPS64::CodeGeneratorMIPS64(HGraph* graph, - const Mips64InstructionSetFeatures& isa_features, const CompilerOptions& compiler_options, OptimizingCompilerStats* stats) : CodeGenerator(graph, @@ -957,8 +956,8 @@ CodeGeneratorMIPS64::CodeGeneratorMIPS64(HGraph* graph, location_builder_(graph, this), instruction_visitor_(graph, this), move_resolver_(graph->GetAllocator(), this), - assembler_(graph->GetAllocator(), &isa_features), - isa_features_(isa_features), + assembler_(graph->GetAllocator(), + compiler_options.GetInstructionSetFeatures()->AsMips64InstructionSetFeatures()), uint32_literals_(std::less<uint32_t>(), graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)), uint64_literals_(std::less<uint64_t>(), @@ -1772,6 +1771,10 @@ void CodeGeneratorMIPS64::DumpFloatingPointRegister(std::ostream& stream, int re stream << FpuRegister(reg); } +const Mips64InstructionSetFeatures& CodeGeneratorMIPS64::GetInstructionSetFeatures() const { + return *GetCompilerOptions().GetInstructionSetFeatures()->AsMips64InstructionSetFeatures(); +} + void CodeGeneratorMIPS64::InvokeRuntime(QuickEntrypointEnum entrypoint, HInstruction* instruction, uint32_t dex_pc, diff --git a/compiler/optimizing/code_generator_mips64.h b/compiler/optimizing/code_generator_mips64.h index 25c886f55d..96306d12c4 100644 --- a/compiler/optimizing/code_generator_mips64.h +++ b/compiler/optimizing/code_generator_mips64.h @@ -352,7 +352,6 @@ class InstructionCodeGeneratorMIPS64 : public InstructionCodeGenerator { class CodeGeneratorMIPS64 : public CodeGenerator { public: CodeGeneratorMIPS64(HGraph* graph, - const Mips64InstructionSetFeatures& isa_features, const CompilerOptions& compiler_options, OptimizingCompilerStats* stats = nullptr); virtual ~CodeGeneratorMIPS64() {} @@ -484,9 +483,7 @@ class CodeGeneratorMIPS64 : public CodeGenerator { InstructionSet GetInstructionSet() const OVERRIDE { return InstructionSet::kMips64; } - const Mips64InstructionSetFeatures& GetInstructionSetFeatures() const { - return isa_features_; - } + const Mips64InstructionSetFeatures& GetInstructionSetFeatures() const; Mips64Label* GetLabelOf(HBasicBlock* block) const { return CommonGetLabelOf<Mips64Label>(block_labels_, block); @@ -657,7 +654,6 @@ class CodeGeneratorMIPS64 : public CodeGenerator { InstructionCodeGeneratorMIPS64 instruction_visitor_; ParallelMoveResolverMIPS64 move_resolver_; Mips64Assembler assembler_; - const Mips64InstructionSetFeatures& isa_features_; // Deduplication map for 32-bit literals, used for non-patchable boot image addresses. Uint32ToLiteralMap uint32_literals_; diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 12872edd0d..b03d72c0f3 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -958,6 +958,10 @@ void CodeGeneratorX86::DumpFloatingPointRegister(std::ostream& stream, int reg) stream << XmmRegister(reg); } +const X86InstructionSetFeatures& CodeGeneratorX86::GetInstructionSetFeatures() const { + return *GetCompilerOptions().GetInstructionSetFeatures()->AsX86InstructionSetFeatures(); +} + size_t CodeGeneratorX86::SaveCoreRegister(size_t stack_index, uint32_t reg_id) { __ movl(Address(ESP, stack_index), static_cast<Register>(reg_id)); return kX86WordSize; @@ -1009,7 +1013,6 @@ void CodeGeneratorX86::GenerateInvokeRuntime(int32_t entry_point_offset) { } CodeGeneratorX86::CodeGeneratorX86(HGraph* graph, - const X86InstructionSetFeatures& isa_features, const CompilerOptions& compiler_options, OptimizingCompilerStats* stats) : CodeGenerator(graph, @@ -1027,7 +1030,6 @@ CodeGeneratorX86::CodeGeneratorX86(HGraph* graph, instruction_visitor_(graph, this), move_resolver_(graph->GetAllocator(), this), assembler_(graph->GetAllocator()), - isa_features_(isa_features), boot_image_method_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)), method_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)), boot_image_type_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)), diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h index 7d18e2b4f3..e947b9dfc8 100644 --- a/compiler/optimizing/code_generator_x86.h +++ b/compiler/optimizing/code_generator_x86.h @@ -316,7 +316,6 @@ class JumpTableRIPFixup; class CodeGeneratorX86 : public CodeGenerator { public: CodeGeneratorX86(HGraph* graph, - const X86InstructionSetFeatures& isa_features, const CompilerOptions& compiler_options, OptimizingCompilerStats* stats = nullptr); virtual ~CodeGeneratorX86() {} @@ -390,6 +389,8 @@ class CodeGeneratorX86 : public CodeGenerator { return InstructionSet::kX86; } + const X86InstructionSetFeatures& GetInstructionSetFeatures() const; + // Helper method to move a 32bits value between two locations. void Move32(Location destination, Location source); // Helper method to move a 64bits value between two locations. @@ -474,10 +475,6 @@ class CodeGeneratorX86 : public CodeGenerator { Label* GetFrameEntryLabel() { return &frame_entry_label_; } - const X86InstructionSetFeatures& GetInstructionSetFeatures() const { - return isa_features_; - } - void AddMethodAddressOffset(HX86ComputeBaseMethodAddress* method_base, int32_t offset) { method_address_offset_.Put(method_base->GetId(), offset); } @@ -640,7 +637,6 @@ class CodeGeneratorX86 : public CodeGenerator { InstructionCodeGeneratorX86 instruction_visitor_; ParallelMoveResolverX86 move_resolver_; X86Assembler assembler_; - const X86InstructionSetFeatures& isa_features_; // PC-relative method patch info for kBootImageLinkTimePcRelative/kBootImageRelRo. // Also used for type/string patches for kBootImageRelRo (same linker patch as for methods). diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 9631c15668..28f3abff79 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -1185,6 +1185,10 @@ void CodeGeneratorX86_64::DumpFloatingPointRegister(std::ostream& stream, int re stream << FloatRegister(reg); } +const X86_64InstructionSetFeatures& CodeGeneratorX86_64::GetInstructionSetFeatures() const { + return *GetCompilerOptions().GetInstructionSetFeatures()->AsX86_64InstructionSetFeatures(); +} + size_t CodeGeneratorX86_64::SaveCoreRegister(size_t stack_index, uint32_t reg_id) { __ movq(Address(CpuRegister(RSP), stack_index), CpuRegister(reg_id)); return kX86_64WordSize; @@ -1239,7 +1243,6 @@ static constexpr int kNumberOfCpuRegisterPairs = 0; // Use a fake return address register to mimic Quick. static constexpr Register kFakeReturnRegister = Register(kLastCpuRegister + 1); CodeGeneratorX86_64::CodeGeneratorX86_64(HGraph* graph, - const X86_64InstructionSetFeatures& isa_features, const CompilerOptions& compiler_options, OptimizingCompilerStats* stats) : CodeGenerator(graph, @@ -1258,7 +1261,6 @@ CodeGeneratorX86_64::CodeGeneratorX86_64(HGraph* graph, instruction_visitor_(graph, this), move_resolver_(graph->GetAllocator(), this), assembler_(graph->GetAllocator()), - isa_features_(isa_features), constant_area_start_(0), boot_image_method_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)), method_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)), diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h index cf862d3f34..0937f55899 100644 --- a/compiler/optimizing/code_generator_x86_64.h +++ b/compiler/optimizing/code_generator_x86_64.h @@ -296,7 +296,6 @@ class JumpTableRIPFixup; class CodeGeneratorX86_64 : public CodeGenerator { public: CodeGeneratorX86_64(HGraph* graph, - const X86_64InstructionSetFeatures& isa_features, const CompilerOptions& compiler_options, OptimizingCompilerStats* stats = nullptr); virtual ~CodeGeneratorX86_64() {} @@ -370,6 +369,8 @@ class CodeGeneratorX86_64 : public CodeGenerator { return InstructionSet::kX86_64; } + const X86_64InstructionSetFeatures& GetInstructionSetFeatures() const; + // Emit a write barrier. void MarkGCCard(CpuRegister temp, CpuRegister card, @@ -440,10 +441,6 @@ class CodeGeneratorX86_64 : public CodeGenerator { void EmitJitRootPatches(uint8_t* code, const uint8_t* roots_data) OVERRIDE; - const X86_64InstructionSetFeatures& GetInstructionSetFeatures() const { - return isa_features_; - } - // Fast path implementation of ReadBarrier::Barrier for a heap // reference field load when Baker's read barriers are used. void GenerateFieldLoadWithBakerReadBarrier(HInstruction* instruction, @@ -606,7 +603,6 @@ class CodeGeneratorX86_64 : public CodeGenerator { InstructionCodeGeneratorX86_64 instruction_visitor_; ParallelMoveResolverX86_64 move_resolver_; X86_64Assembler assembler_; - const X86_64InstructionSetFeatures& isa_features_; // Offset to the start of the constant area in the assembled code. // Used for fixups to the constant area. diff --git a/compiler/optimizing/codegen_test.cc b/compiler/optimizing/codegen_test.cc index a0fd5ffcb1..86687e60a9 100644 --- a/compiler/optimizing/codegen_test.cc +++ b/compiler/optimizing/codegen_test.cc @@ -89,7 +89,8 @@ void CodegenTest::TestCode(const std::vector<uint16_t>& data, bool has_result, i HGraph* graph = CreateCFG(data); // Remove suspend checks, they cannot be executed in this context. RemoveSuspendChecks(graph); - RunCode(target_config, graph, [](HGraph*) {}, has_result, expected); + OverrideInstructionSetFeatures(target_config.GetInstructionSet(), "default"); + RunCode(target_config, *compiler_options_, graph, [](HGraph*) {}, has_result, expected); } } @@ -100,7 +101,8 @@ void CodegenTest::TestCodeLong(const std::vector<uint16_t>& data, HGraph* graph = CreateCFG(data, DataType::Type::kInt64); // Remove suspend checks, they cannot be executed in this context. RemoveSuspendChecks(graph); - RunCode(target_config, graph, [](HGraph*) {}, has_result, expected); + OverrideInstructionSetFeatures(target_config.GetInstructionSet(), "default"); + RunCode(target_config, *compiler_options_, graph, [](HGraph*) {}, has_result, expected); } } @@ -460,7 +462,8 @@ TEST_F(CodegenTest, NonMaterializedCondition) { block->InsertInstructionBefore(move, block->GetLastInstruction()); }; - RunCode(target_config, graph, hook_before_codegen, true, 0); + OverrideInstructionSetFeatures(target_config.GetInstructionSet(), "default"); + RunCode(target_config, *compiler_options_, graph, hook_before_codegen, true, 0); } } @@ -506,7 +509,8 @@ TEST_F(CodegenTest, MaterializedCondition1) { new (graph_in->GetAllocator()) HParallelMove(graph_in->GetAllocator()); block->InsertInstructionBefore(move, block->GetLastInstruction()); }; - RunCode(target_config, graph, hook_before_codegen, true, lhs[i] < rhs[i]); + OverrideInstructionSetFeatures(target_config.GetInstructionSet(), "default"); + RunCode(target_config, *compiler_options_, graph, hook_before_codegen, true, lhs[i] < rhs[i]); } } } @@ -573,7 +577,8 @@ TEST_F(CodegenTest, MaterializedCondition2) { new (graph_in->GetAllocator()) HParallelMove(graph_in->GetAllocator()); block->InsertInstructionBefore(move, block->GetLastInstruction()); }; - RunCode(target_config, graph, hook_before_codegen, true, lhs[i] < rhs[i]); + OverrideInstructionSetFeatures(target_config.GetInstructionSet(), "default"); + RunCode(target_config, *compiler_options_, graph, hook_before_codegen, true, lhs[i] < rhs[i]); } } } @@ -682,7 +687,8 @@ void CodegenTest::TestComparison(IfCondition condition, block->AddInstruction(new (GetAllocator()) HReturn(comparison)); graph->BuildDominatorTree(); - RunCode(target_config, graph, [](HGraph*) {}, true, expected_result); + OverrideInstructionSetFeatures(target_config.GetInstructionSet(), "default"); + RunCode(target_config, *compiler_options_, graph, [](HGraph*) {}, true, expected_result); } TEST_F(CodegenTest, ComparisonsInt) { @@ -713,10 +719,9 @@ TEST_F(CodegenTest, ComparisonsLong) { #ifdef ART_ENABLE_CODEGEN_arm TEST_F(CodegenTest, ARMVIXLParallelMoveResolver) { - std::unique_ptr<const ArmInstructionSetFeatures> features( - ArmInstructionSetFeatures::FromCppDefines()); + OverrideInstructionSetFeatures(InstructionSet::kThumb2, "default"); HGraph* graph = CreateGraph(); - arm::CodeGeneratorARMVIXL codegen(graph, *features.get(), CompilerOptions()); + arm::CodeGeneratorARMVIXL codegen(graph, *compiler_options_); codegen.Initialize(); @@ -737,10 +742,9 @@ TEST_F(CodegenTest, ARMVIXLParallelMoveResolver) { #ifdef ART_ENABLE_CODEGEN_arm64 // Regression test for b/34760542. TEST_F(CodegenTest, ARM64ParallelMoveResolverB34760542) { - std::unique_ptr<const Arm64InstructionSetFeatures> features( - Arm64InstructionSetFeatures::FromCppDefines()); + OverrideInstructionSetFeatures(InstructionSet::kArm64, "default"); HGraph* graph = CreateGraph(); - arm64::CodeGeneratorARM64 codegen(graph, *features.get(), CompilerOptions()); + arm64::CodeGeneratorARM64 codegen(graph, *compiler_options_); codegen.Initialize(); @@ -787,10 +791,9 @@ TEST_F(CodegenTest, ARM64ParallelMoveResolverB34760542) { // Check that ParallelMoveResolver works fine for ARM64 for both cases when SIMD is on and off. TEST_F(CodegenTest, ARM64ParallelMoveResolverSIMD) { - std::unique_ptr<const Arm64InstructionSetFeatures> features( - Arm64InstructionSetFeatures::FromCppDefines()); + OverrideInstructionSetFeatures(InstructionSet::kArm64, "default"); HGraph* graph = CreateGraph(); - arm64::CodeGeneratorARM64 codegen(graph, *features.get(), CompilerOptions()); + arm64::CodeGeneratorARM64 codegen(graph, *compiler_options_); codegen.Initialize(); @@ -824,9 +827,9 @@ TEST_F(CodegenTest, ARM64ParallelMoveResolverSIMD) { #ifdef ART_ENABLE_CODEGEN_mips TEST_F(CodegenTest, MipsClobberRA) { - std::unique_ptr<const MipsInstructionSetFeatures> features_mips( - MipsInstructionSetFeatures::FromCppDefines()); - if (!CanExecute(InstructionSet::kMips) || features_mips->IsR6()) { + OverrideInstructionSetFeatures(InstructionSet::kMips, "mips32r"); + CHECK(!instruction_set_features_->AsMipsInstructionSetFeatures()->IsR6()); + if (!CanExecute(InstructionSet::kMips)) { // HMipsComputeBaseMethodAddress and the NAL instruction behind it // should only be generated on non-R6. return; @@ -860,7 +863,7 @@ TEST_F(CodegenTest, MipsClobberRA) { graph->BuildDominatorTree(); - mips::CodeGeneratorMIPS codegenMIPS(graph, *features_mips.get(), CompilerOptions()); + mips::CodeGeneratorMIPS codegenMIPS(graph, *compiler_options_); // Since there isn't HLoadClass or HLoadString, we need to manually indicate // that RA is clobbered and the method entry code should generate a stack frame // and preserve RA in it. And this is what we're testing here. diff --git a/compiler/optimizing/codegen_test_utils.h b/compiler/optimizing/codegen_test_utils.h index 792cfb539a..91811262de 100644 --- a/compiler/optimizing/codegen_test_utils.h +++ b/compiler/optimizing/codegen_test_utils.h @@ -17,17 +17,11 @@ #ifndef ART_COMPILER_OPTIMIZING_CODEGEN_TEST_UTILS_H_ #define ART_COMPILER_OPTIMIZING_CODEGEN_TEST_UTILS_H_ -#include "arch/arm/instruction_set_features_arm.h" #include "arch/arm/registers_arm.h" -#include "arch/arm64/instruction_set_features_arm64.h" #include "arch/instruction_set.h" -#include "arch/mips/instruction_set_features_mips.h" #include "arch/mips/registers_mips.h" -#include "arch/mips64/instruction_set_features_mips64.h" #include "arch/mips64/registers_mips64.h" -#include "arch/x86/instruction_set_features_x86.h" #include "arch/x86/registers_x86.h" -#include "arch/x86_64/instruction_set_features_x86_64.h" #include "code_simulator.h" #include "code_simulator_container.h" #include "common_compiler_test.h" @@ -101,10 +95,8 @@ class CodegenTargetConfig { // to just overwrite the code generator. class TestCodeGeneratorARMVIXL : public arm::CodeGeneratorARMVIXL { public: - TestCodeGeneratorARMVIXL(HGraph* graph, - const ArmInstructionSetFeatures& isa_features, - const CompilerOptions& compiler_options) - : arm::CodeGeneratorARMVIXL(graph, isa_features, compiler_options) { + TestCodeGeneratorARMVIXL(HGraph* graph, const CompilerOptions& compiler_options) + : arm::CodeGeneratorARMVIXL(graph, compiler_options) { AddAllocatedRegister(Location::RegisterLocation(arm::R6)); AddAllocatedRegister(Location::RegisterLocation(arm::R7)); } @@ -145,10 +137,8 @@ class TestCodeGeneratorARMVIXL : public arm::CodeGeneratorARMVIXL { // function. class TestCodeGeneratorARM64 : public arm64::CodeGeneratorARM64 { public: - TestCodeGeneratorARM64(HGraph* graph, - const Arm64InstructionSetFeatures& isa_features, - const CompilerOptions& compiler_options) - : arm64::CodeGeneratorARM64(graph, isa_features, compiler_options) {} + TestCodeGeneratorARM64(HGraph* graph, const CompilerOptions& compiler_options) + : arm64::CodeGeneratorARM64(graph, compiler_options) {} void MaybeGenerateMarkingRegisterCheck(int codem ATTRIBUTE_UNUSED, Location temp_loc ATTRIBUTE_UNUSED) OVERRIDE { @@ -165,10 +155,8 @@ class TestCodeGeneratorARM64 : public arm64::CodeGeneratorARM64 { #ifdef ART_ENABLE_CODEGEN_x86 class TestCodeGeneratorX86 : public x86::CodeGeneratorX86 { public: - TestCodeGeneratorX86(HGraph* graph, - const X86InstructionSetFeatures& isa_features, - const CompilerOptions& compiler_options) - : x86::CodeGeneratorX86(graph, isa_features, compiler_options) { + TestCodeGeneratorX86(HGraph* graph, const CompilerOptions& compiler_options) + : x86::CodeGeneratorX86(graph, compiler_options) { // Save edi, we need it for getting enough registers for long multiplication. AddAllocatedRegister(Location::RegisterLocation(x86::EDI)); } @@ -324,11 +312,11 @@ static void RunCode(CodeGenerator* codegen, template <typename Expected> static void RunCode(CodegenTargetConfig target_config, + const CompilerOptions& compiler_options, HGraph* graph, std::function<void(HGraph*)> hook_before_codegen, bool has_result, Expected expected) { - CompilerOptions compiler_options; std::unique_ptr<CodeGenerator> codegen(target_config.CreateCodeGenerator(graph, compiler_options)); RunCode(codegen.get(), graph, hook_before_codegen, has_result, expected); @@ -336,55 +324,37 @@ static void RunCode(CodegenTargetConfig target_config, #ifdef ART_ENABLE_CODEGEN_arm CodeGenerator* create_codegen_arm_vixl32(HGraph* graph, const CompilerOptions& compiler_options) { - std::unique_ptr<const ArmInstructionSetFeatures> features_arm( - ArmInstructionSetFeatures::FromCppDefines()); - return new (graph->GetAllocator()) - TestCodeGeneratorARMVIXL(graph, *features_arm.get(), compiler_options); + return new (graph->GetAllocator()) TestCodeGeneratorARMVIXL(graph, compiler_options); } #endif #ifdef ART_ENABLE_CODEGEN_arm64 CodeGenerator* create_codegen_arm64(HGraph* graph, const CompilerOptions& compiler_options) { - std::unique_ptr<const Arm64InstructionSetFeatures> features_arm64( - Arm64InstructionSetFeatures::FromCppDefines()); - return new (graph->GetAllocator()) - TestCodeGeneratorARM64(graph, *features_arm64.get(), compiler_options); + return new (graph->GetAllocator()) TestCodeGeneratorARM64(graph, compiler_options); } #endif #ifdef ART_ENABLE_CODEGEN_x86 CodeGenerator* create_codegen_x86(HGraph* graph, const CompilerOptions& compiler_options) { - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - return new (graph->GetAllocator()) TestCodeGeneratorX86( - graph, *features_x86.get(), compiler_options); + return new (graph->GetAllocator()) TestCodeGeneratorX86(graph, compiler_options); } #endif #ifdef ART_ENABLE_CODEGEN_x86_64 CodeGenerator* create_codegen_x86_64(HGraph* graph, const CompilerOptions& compiler_options) { - std::unique_ptr<const X86_64InstructionSetFeatures> features_x86_64( - X86_64InstructionSetFeatures::FromCppDefines()); - return new (graph->GetAllocator()) - x86_64::CodeGeneratorX86_64(graph, *features_x86_64.get(), compiler_options); + return new (graph->GetAllocator()) x86_64::CodeGeneratorX86_64(graph, compiler_options); } #endif #ifdef ART_ENABLE_CODEGEN_mips CodeGenerator* create_codegen_mips(HGraph* graph, const CompilerOptions& compiler_options) { - std::unique_ptr<const MipsInstructionSetFeatures> features_mips( - MipsInstructionSetFeatures::FromCppDefines()); - return new (graph->GetAllocator()) - mips::CodeGeneratorMIPS(graph, *features_mips.get(), compiler_options); + return new (graph->GetAllocator()) mips::CodeGeneratorMIPS(graph, compiler_options); } #endif #ifdef ART_ENABLE_CODEGEN_mips64 CodeGenerator* create_codegen_mips64(HGraph* graph, const CompilerOptions& compiler_options) { - std::unique_ptr<const Mips64InstructionSetFeatures> features_mips64( - Mips64InstructionSetFeatures::FromCppDefines()); - return new (graph->GetAllocator()) - mips64::CodeGeneratorMIPS64(graph, *features_mips64.get(), compiler_options); + return new (graph->GetAllocator()) mips64::CodeGeneratorMIPS64(graph, compiler_options); } #endif diff --git a/compiler/optimizing/constant_folding_test.cc b/compiler/optimizing/constant_folding_test.cc index d27104752b..b1436f863c 100644 --- a/compiler/optimizing/constant_folding_test.cc +++ b/compiler/optimizing/constant_folding_test.cc @@ -16,8 +16,6 @@ #include <functional> -#include "arch/x86/instruction_set_features_x86.h" -#include "code_generator_x86.h" #include "constant_folding.h" #include "dead_code_elimination.h" #include "driver/compiler_options.h" @@ -60,9 +58,6 @@ class ConstantFoldingTest : public OptimizingUnitTest { std::string actual_before = printer_before.str(); EXPECT_EQ(expected_before, actual_before); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegenX86(graph_, *features_x86.get(), CompilerOptions()); HConstantFolding(graph_, "constant_folding").Run(); GraphChecker graph_checker_cf(graph_); graph_checker_cf.Run(); diff --git a/compiler/optimizing/dead_code_elimination_test.cc b/compiler/optimizing/dead_code_elimination_test.cc index adb6ce1187..277453545a 100644 --- a/compiler/optimizing/dead_code_elimination_test.cc +++ b/compiler/optimizing/dead_code_elimination_test.cc @@ -16,8 +16,6 @@ #include "dead_code_elimination.h" -#include "arch/x86/instruction_set_features_x86.h" -#include "code_generator_x86.h" #include "driver/compiler_options.h" #include "graph_checker.h" #include "optimizing_unit_test.h" @@ -45,9 +43,6 @@ void DeadCodeEliminationTest::TestCode(const std::vector<uint16_t>& data, std::string actual_before = printer_before.str(); ASSERT_EQ(actual_before, expected_before); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegenX86(graph, *features_x86.get(), CompilerOptions()); HDeadCodeElimination(graph, nullptr /* stats */, "dead_code_elimination").Run(); GraphChecker graph_checker(graph); graph_checker.Run(); diff --git a/compiler/optimizing/emit_swap_mips_test.cc b/compiler/optimizing/emit_swap_mips_test.cc index b63914faf7..293c1ab3f3 100644 --- a/compiler/optimizing/emit_swap_mips_test.cc +++ b/compiler/optimizing/emit_swap_mips_test.cc @@ -28,11 +28,12 @@ namespace art { class EmitSwapMipsTest : public OptimizingUnitTest { public: void SetUp() OVERRIDE { + instruction_set_ = InstructionSet::kMips; + instruction_set_features_ = MipsInstructionSetFeatures::FromCppDefines(); + OptimizingUnitTest::SetUp(); graph_ = CreateGraph(); - isa_features_ = MipsInstructionSetFeatures::FromCppDefines(); - codegen_ = new (graph_->GetAllocator()) mips::CodeGeneratorMIPS(graph_, - *isa_features_.get(), - CompilerOptions()); + codegen_.reset( + new (graph_->GetAllocator()) mips::CodeGeneratorMIPS(graph_, *compiler_options_)); moves_ = new (GetAllocator()) HParallelMove(GetAllocator()); test_helper_.reset( new AssemblerTestInfrastructure(GetArchitectureString(), @@ -47,8 +48,10 @@ class EmitSwapMipsTest : public OptimizingUnitTest { void TearDown() OVERRIDE { test_helper_.reset(); - isa_features_.reset(); + codegen_.reset(); + graph_ = nullptr; ResetPoolAndAllocator(); + OptimizingUnitTest::TearDown(); } // Get the typically used name for this architecture. @@ -106,10 +109,9 @@ class EmitSwapMipsTest : public OptimizingUnitTest { protected: HGraph* graph_; HParallelMove* moves_; - mips::CodeGeneratorMIPS* codegen_; + std::unique_ptr<mips::CodeGeneratorMIPS> codegen_; mips::MipsAssembler* assembler_; std::unique_ptr<AssemblerTestInfrastructure> test_helper_; - std::unique_ptr<const MipsInstructionSetFeatures> isa_features_; }; TEST_F(EmitSwapMipsTest, TwoRegisters) { diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 72d53d28cf..a104070dd3 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -1783,7 +1783,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, graph_->GetArenaStack(), callee_dex_file, method_index, - compiler_driver_->GetInstructionSet(), + codegen_->GetCompilerOptions().GetInstructionSet(), invoke_type, graph_->IsDebuggable(), /* osr */ false, @@ -1820,8 +1820,8 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, return false; } - if (!RegisterAllocator::CanAllocateRegistersFor(*callee_graph, - compiler_driver_->GetInstructionSet())) { + if (!RegisterAllocator::CanAllocateRegistersFor( + *callee_graph, codegen_->GetCompilerOptions().GetInstructionSet())) { LOG_FAIL(stats_, MethodCompilationStat::kNotInlinedRegisterAllocator) << "Method " << callee_dex_file.PrettyMethod(method_index) << " cannot be inlined because of the register allocator"; diff --git a/compiler/optimizing/linearize_test.cc b/compiler/optimizing/linearize_test.cc index 9fa5b74c62..50bfe843b5 100644 --- a/compiler/optimizing/linearize_test.cc +++ b/compiler/optimizing/linearize_test.cc @@ -16,11 +16,9 @@ #include <fstream> -#include "arch/x86/instruction_set_features_x86.h" #include "base/arena_allocator.h" #include "builder.h" #include "code_generator.h" -#include "code_generator_x86.h" #include "dex/dex_file.h" #include "dex/dex_instruction.h" #include "driver/compiler_options.h" @@ -43,10 +41,8 @@ template <size_t number_of_blocks> void LinearizeTest::TestCode(const std::vector<uint16_t>& data, const uint32_t (&expected_order)[number_of_blocks]) { HGraph* graph = CreateCFG(data); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); - SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); + std::unique_ptr<CodeGenerator> codegen = CodeGenerator::Create(graph, *compiler_options_); + SsaLivenessAnalysis liveness(graph, codegen.get(), GetScopedAllocator()); liveness.Analyze(); ASSERT_EQ(graph->GetLinearOrder().size(), number_of_blocks); diff --git a/compiler/optimizing/live_ranges_test.cc b/compiler/optimizing/live_ranges_test.cc index 66660662e4..0fb90fb370 100644 --- a/compiler/optimizing/live_ranges_test.cc +++ b/compiler/optimizing/live_ranges_test.cc @@ -14,11 +14,9 @@ * limitations under the License. */ -#include "arch/x86/instruction_set_features_x86.h" #include "base/arena_allocator.h" #include "builder.h" #include "code_generator.h" -#include "code_generator_x86.h" #include "dex/dex_file.h" #include "dex/dex_instruction.h" #include "driver/compiler_options.h" @@ -63,10 +61,8 @@ TEST_F(LiveRangesTest, CFG1) { HGraph* graph = BuildGraph(data); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); - SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); + std::unique_ptr<CodeGenerator> codegen = CodeGenerator::Create(graph, *compiler_options_); + SsaLivenessAnalysis liveness(graph, codegen.get(), GetScopedAllocator()); liveness.Analyze(); LiveInterval* interval = liveness.GetInstructionFromSsaIndex(0)->GetLiveInterval(); @@ -109,10 +105,8 @@ TEST_F(LiveRangesTest, CFG2) { Instruction::RETURN | 0 << 8); HGraph* graph = BuildGraph(data); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); - SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); + std::unique_ptr<CodeGenerator> codegen = CodeGenerator::Create(graph, *compiler_options_); + SsaLivenessAnalysis liveness(graph, codegen.get(), GetScopedAllocator()); liveness.Analyze(); LiveInterval* interval = liveness.GetInstructionFromSsaIndex(0)->GetLiveInterval(); @@ -158,10 +152,8 @@ TEST_F(LiveRangesTest, CFG3) { Instruction::RETURN | 0 << 8); HGraph* graph = BuildGraph(data); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); - SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); + std::unique_ptr<CodeGenerator> codegen = CodeGenerator::Create(graph, *compiler_options_); + SsaLivenessAnalysis liveness(graph, codegen.get(), GetScopedAllocator()); liveness.Analyze(); // Test for the 4 constant. @@ -235,10 +227,8 @@ TEST_F(LiveRangesTest, Loop1) { HGraph* graph = BuildGraph(data); RemoveSuspendChecks(graph); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); - SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); + std::unique_ptr<CodeGenerator> codegen = CodeGenerator::Create(graph, *compiler_options_); + SsaLivenessAnalysis liveness(graph, codegen.get(), GetScopedAllocator()); liveness.Analyze(); // Test for the 0 constant. @@ -312,10 +302,8 @@ TEST_F(LiveRangesTest, Loop2) { Instruction::RETURN | 0 << 8); HGraph* graph = BuildGraph(data); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); - SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); + std::unique_ptr<CodeGenerator> codegen = CodeGenerator::Create(graph, *compiler_options_); + SsaLivenessAnalysis liveness(graph, codegen.get(), GetScopedAllocator()); liveness.Analyze(); // Test for the 0 constant. @@ -388,10 +376,8 @@ TEST_F(LiveRangesTest, CFG4) { Instruction::RETURN); HGraph* graph = BuildGraph(data); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); - SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); + std::unique_ptr<CodeGenerator> codegen = CodeGenerator::Create(graph, *compiler_options_); + SsaLivenessAnalysis liveness(graph, codegen.get(), GetScopedAllocator()); liveness.Analyze(); // Test for the 0 constant. diff --git a/compiler/optimizing/liveness_test.cc b/compiler/optimizing/liveness_test.cc index 6621a03568..72f995e773 100644 --- a/compiler/optimizing/liveness_test.cc +++ b/compiler/optimizing/liveness_test.cc @@ -14,11 +14,9 @@ * limitations under the License. */ -#include "arch/x86/instruction_set_features_x86.h" #include "base/arena_allocator.h" #include "builder.h" #include "code_generator.h" -#include "code_generator_x86.h" #include "dex/dex_file.h" #include "dex/dex_instruction.h" #include "driver/compiler_options.h" @@ -50,10 +48,8 @@ void LivenessTest::TestCode(const std::vector<uint16_t>& data, const char* expec HGraph* graph = CreateCFG(data); // `Inline` conditions into ifs. PrepareForRegisterAllocation(graph).Run(); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); - SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); + std::unique_ptr<CodeGenerator> codegen = CodeGenerator::Create(graph, *compiler_options_); + SsaLivenessAnalysis liveness(graph, codegen.get(), GetScopedAllocator()); liveness.Analyze(); std::ostringstream buffer; diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc index eda6bd1e86..72aa25302e 100644 --- a/compiler/optimizing/loop_optimization.cc +++ b/compiler/optimizing/loop_optimization.cc @@ -23,7 +23,7 @@ #include "arch/mips64/instruction_set_features_mips64.h" #include "arch/x86/instruction_set_features_x86.h" #include "arch/x86_64/instruction_set_features_x86_64.h" -#include "driver/compiler_driver.h" +#include "driver/compiler_options.h" #include "linear_order.h" #include "mirror/array-inl.h" #include "mirror/string.h" @@ -427,12 +427,12 @@ static void TryToEvaluateIfCondition(HIf* instruction, HGraph* graph) { // HLoopOptimization::HLoopOptimization(HGraph* graph, - CompilerDriver* compiler_driver, + const CompilerOptions* compiler_options, HInductionVarAnalysis* induction_analysis, OptimizingCompilerStats* stats, const char* name) : HOptimization(graph, name, stats), - compiler_driver_(compiler_driver), + compiler_options_(compiler_options), induction_range_(induction_analysis), loop_allocator_(nullptr), global_allocator_(graph_->GetAllocator()), @@ -454,8 +454,8 @@ HLoopOptimization::HLoopOptimization(HGraph* graph, vector_header_(nullptr), vector_body_(nullptr), vector_index_(nullptr), - arch_loop_helper_(ArchNoOptsLoopHelper::Create(compiler_driver_ != nullptr - ? compiler_driver_->GetInstructionSet() + arch_loop_helper_(ArchNoOptsLoopHelper::Create(compiler_options_ != nullptr + ? compiler_options_->GetInstructionSet() : InstructionSet::kNone, global_allocator_)) { } @@ -756,9 +756,9 @@ bool HLoopOptimization::OptimizeInnerLoop(LoopNode* node) { // bool HLoopOptimization::TryUnrollingForBranchPenaltyReduction(LoopNode* node) { - // Don't run peeling/unrolling if compiler_driver_ is nullptr (i.e., running under tests) + // Don't run peeling/unrolling if compiler_options_ is nullptr (i.e., running under tests) // as InstructionSet is needed. - if (compiler_driver_ == nullptr) { + if (compiler_options_ == nullptr) { return false; } @@ -802,9 +802,9 @@ bool HLoopOptimization::TryUnrollingForBranchPenaltyReduction(LoopNode* node) { } bool HLoopOptimization::TryPeelingForLoopInvariantExitsElimination(LoopNode* node) { - // Don't run peeling/unrolling if compiler_driver_ is nullptr (i.e., running under tests) + // Don't run peeling/unrolling if compiler_options_ is nullptr (i.e., running under tests) // as InstructionSet is needed. - if (compiler_driver_ == nullptr) { + if (compiler_options_ == nullptr) { return false; } @@ -1459,7 +1459,7 @@ bool HLoopOptimization::VectorizeUse(LoopNode* node, } uint32_t HLoopOptimization::GetVectorSizeInBytes() { - switch (compiler_driver_->GetInstructionSet()) { + switch (compiler_options_->GetInstructionSet()) { case InstructionSet::kArm: case InstructionSet::kThumb2: return 8; // 64-bit SIMD @@ -1469,8 +1469,8 @@ uint32_t HLoopOptimization::GetVectorSizeInBytes() { } bool HLoopOptimization::TrySetVectorType(DataType::Type type, uint64_t* restrictions) { - const InstructionSetFeatures* features = compiler_driver_->GetInstructionSetFeatures(); - switch (compiler_driver_->GetInstructionSet()) { + const InstructionSetFeatures* features = compiler_options_->GetInstructionSetFeatures(); + switch (compiler_options_->GetInstructionSet()) { case InstructionSet::kArm: case InstructionSet::kThumb2: // Allow vectorization for all ARM devices, because Android assumes that diff --git a/compiler/optimizing/loop_optimization.h b/compiler/optimizing/loop_optimization.h index 191a93da26..9743b25259 100644 --- a/compiler/optimizing/loop_optimization.h +++ b/compiler/optimizing/loop_optimization.h @@ -27,7 +27,7 @@ namespace art { -class CompilerDriver; +class CompilerOptions; class ArchNoOptsLoopHelper; /** @@ -38,7 +38,7 @@ class ArchNoOptsLoopHelper; class HLoopOptimization : public HOptimization { public: HLoopOptimization(HGraph* graph, - CompilerDriver* compiler_driver, + const CompilerOptions* compiler_options, HInductionVarAnalysis* induction_analysis, OptimizingCompilerStats* stats, const char* name = kLoopOptimizationPassName); @@ -243,8 +243,8 @@ class HLoopOptimization : public HOptimization { void RemoveDeadInstructions(const HInstructionList& list); bool CanRemoveCycle(); // Whether the current 'iset_' is removable. - // Compiler driver (to query ISA features). - const CompilerDriver* compiler_driver_; + // Compiler options (to query ISA features). + const CompilerOptions* compiler_options_; // Range information based on prior induction variable analysis. InductionVarRange induction_range_; diff --git a/compiler/optimizing/loop_optimization_test.cc b/compiler/optimizing/loop_optimization_test.cc index c21bd65d97..c7cc661303 100644 --- a/compiler/optimizing/loop_optimization_test.cc +++ b/compiler/optimizing/loop_optimization_test.cc @@ -29,7 +29,8 @@ class LoopOptimizationTest : public OptimizingUnitTest { LoopOptimizationTest() : graph_(CreateGraph()), iva_(new (GetAllocator()) HInductionVarAnalysis(graph_)), - loop_opt_(new (GetAllocator()) HLoopOptimization(graph_, nullptr, iva_, nullptr)) { + loop_opt_(new (GetAllocator()) HLoopOptimization( + graph_, /* compiler_options */ nullptr, iva_, /* stats */ nullptr)) { BuildGraph(); } diff --git a/compiler/optimizing/optimization.cc b/compiler/optimizing/optimization.cc index d37c43db81..a38bd2464d 100644 --- a/compiler/optimizing/optimization.cc +++ b/compiler/optimizing/optimization.cc @@ -40,6 +40,7 @@ #include "constructor_fence_redundancy_elimination.h" #include "dead_code_elimination.h" #include "dex/code_item_accessors-inl.h" +#include "driver/compiler_options.h" #include "driver/dex_compilation_unit.h" #include "gvn.h" #include "induction_var_analysis.h" @@ -224,7 +225,7 @@ ArenaVector<HOptimization*> ConstructOptimizations( case OptimizationPass::kLoopOptimization: CHECK(most_recent_induction != nullptr); opt = new (allocator) HLoopOptimization( - graph, driver, most_recent_induction, stats, pass_name); + graph, &codegen->GetCompilerOptions(), most_recent_induction, stats, pass_name); break; case OptimizationPass::kBoundsCheckElimination: CHECK(most_recent_side_effects != nullptr && most_recent_induction != nullptr); @@ -286,7 +287,7 @@ ArenaVector<HOptimization*> ConstructOptimizations( break; case OptimizationPass::kScheduling: opt = new (allocator) HInstructionScheduling( - graph, driver->GetInstructionSet(), codegen, pass_name); + graph, codegen->GetCompilerOptions().GetInstructionSet(), codegen, pass_name); break; // // Arch-specific passes. diff --git a/compiler/optimizing/optimizing_cfi_test.cc b/compiler/optimizing/optimizing_cfi_test.cc index 2e189fdd14..1c1cf28294 100644 --- a/compiler/optimizing/optimizing_cfi_test.cc +++ b/compiler/optimizing/optimizing_cfi_test.cc @@ -47,25 +47,20 @@ class OptimizingCFITest : public CFITest, public OptimizingUnitTestHelper { static constexpr bool kGenerateExpected = false; OptimizingCFITest() - : pool_and_allocator_(), - opts_(), - isa_features_(), - graph_(nullptr), + : graph_(nullptr), code_gen_(), blocks_(GetAllocator()->Adapter()) {} - ArenaAllocator* GetAllocator() { return pool_and_allocator_.GetAllocator(); } - void SetUpFrame(InstructionSet isa) { + OverrideInstructionSetFeatures(isa, "default"); + // Ensure that slow-debug is off, so that there is no unexpected read-barrier check emitted. SetRuntimeDebugFlagsEnabled(false); // Setup simple context. - std::string error; - isa_features_ = InstructionSetFeatures::FromVariant(isa, "default", &error); graph_ = CreateGraph(); // Generate simple frame with some spills. - code_gen_ = CodeGenerator::Create(graph_, isa, *isa_features_, opts_); + code_gen_ = CodeGenerator::Create(graph_, *compiler_options_); code_gen_->GetAssembler()->cfi().SetEnabled(true); code_gen_->InitializeCodeGenerationData(); const int frame_size = 64; @@ -148,9 +143,6 @@ class OptimizingCFITest : public CFITest, public OptimizingUnitTestHelper { DISALLOW_COPY_AND_ASSIGN(InternalCodeAllocator); }; - ArenaPoolAndAllocator pool_and_allocator_; - CompilerOptions opts_; - std::unique_ptr<const InstructionSetFeatures> isa_features_; HGraph* graph_; std::unique_ptr<CodeGenerator> code_gen_; ArenaVector<HBasicBlock*> blocks_; diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 79ac6b9b9d..84863e4357 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -287,7 +287,7 @@ class OptimizingCompiler FINAL : public Compiler { uintptr_t GetEntryPointOf(ArtMethod* method) const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) { return reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCodePtrSize( - InstructionSetPointerSize(GetCompilerDriver()->GetInstructionSet()))); + InstructionSetPointerSize(GetCompilerDriver()->GetCompilerOptions().GetInstructionSet()))); } void Init() OVERRIDE; @@ -460,7 +460,7 @@ bool OptimizingCompiler::RunArchOptimizations(HGraph* graph, const DexCompilationUnit& dex_compilation_unit, PassObserver* pass_observer, VariableSizedHandleScope* handles) const { - switch (GetCompilerDriver()->GetInstructionSet()) { + switch (codegen->GetCompilerOptions().GetInstructionSet()) { #if defined(ART_ENABLE_CODEGEN_arm) case InstructionSet::kThumb2: case InstructionSet::kArm: { @@ -758,7 +758,8 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* allocator, VariableSizedHandleScope* handles) const { MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kAttemptBytecodeCompilation); CompilerDriver* compiler_driver = GetCompilerDriver(); - InstructionSet instruction_set = compiler_driver->GetInstructionSet(); + const CompilerOptions& compiler_options = compiler_driver->GetCompilerOptions(); + InstructionSet instruction_set = compiler_options.GetInstructionSet(); const DexFile& dex_file = *dex_compilation_unit.GetDexFile(); uint32_t method_idx = dex_compilation_unit.GetDexMethodIndex(); const DexFile::CodeItem* code_item = dex_compilation_unit.GetCodeItem(); @@ -782,7 +783,6 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* allocator, // Implementation of the space filter: do not compile a code item whose size in // code units is bigger than 128. static constexpr size_t kSpaceFilterOptimizingThreshold = 128; - const CompilerOptions& compiler_options = compiler_driver->GetCompilerOptions(); if ((compiler_options.GetCompilerFilter() == CompilerFilter::kSpace) && (CodeItemInstructionAccessor(dex_file, code_item).InsnsSizeInCodeUnits() > kSpaceFilterOptimizingThreshold)) { @@ -796,7 +796,7 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* allocator, arena_stack, dex_file, method_idx, - compiler_driver->GetInstructionSet(), + compiler_options.GetInstructionSet(), kInvalidInvokeType, compiler_driver->GetCompilerOptions().GetDebuggable(), osr); @@ -813,9 +813,7 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* allocator, std::unique_ptr<CodeGenerator> codegen( CodeGenerator::Create(graph, - instruction_set, - *compiler_driver->GetInstructionSetFeatures(), - compiler_driver->GetCompilerOptions(), + compiler_options, compilation_stats_.get())); if (codegen.get() == nullptr) { MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kNotCompiledNoCodegen); @@ -903,7 +901,8 @@ CodeGenerator* OptimizingCompiler::TryCompileIntrinsic( VariableSizedHandleScope* handles) const { MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kAttemptIntrinsicCompilation); CompilerDriver* compiler_driver = GetCompilerDriver(); - InstructionSet instruction_set = compiler_driver->GetInstructionSet(); + const CompilerOptions& compiler_options = compiler_driver->GetCompilerOptions(); + InstructionSet instruction_set = compiler_options.GetInstructionSet(); const DexFile& dex_file = *dex_compilation_unit.GetDexFile(); uint32_t method_idx = dex_compilation_unit.GetDexMethodIndex(); @@ -921,7 +920,7 @@ CodeGenerator* OptimizingCompiler::TryCompileIntrinsic( arena_stack, dex_file, method_idx, - compiler_driver->GetInstructionSet(), + compiler_driver->GetCompilerOptions().GetInstructionSet(), kInvalidInvokeType, compiler_driver->GetCompilerOptions().GetDebuggable(), /* osr */ false); @@ -932,15 +931,12 @@ CodeGenerator* OptimizingCompiler::TryCompileIntrinsic( std::unique_ptr<CodeGenerator> codegen( CodeGenerator::Create(graph, - instruction_set, - *compiler_driver->GetInstructionSetFeatures(), - compiler_driver->GetCompilerOptions(), + compiler_options, compilation_stats_.get())); if (codegen.get() == nullptr) { return nullptr; } - codegen->GetAssembler()->cfi().SetEnabled( - compiler_driver->GetCompilerOptions().GenerateAnyDebugInfo()); + codegen->GetAssembler()->cfi().SetEnabled(compiler_options.GenerateAnyDebugInfo()); PassObserver pass_observer(graph, codegen.get(), @@ -1095,7 +1091,7 @@ CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item, if (kIsDebugBuild && IsCompilingWithCoreImage() && - IsInstructionSetSupported(compiler_driver->GetInstructionSet())) { + IsInstructionSetSupported(compiler_driver->GetCompilerOptions().GetInstructionSet())) { // For testing purposes, we put a special marker on method names // that should be compiled with this compiler (when the // instruction set is supported). This makes sure we're not @@ -1112,7 +1108,8 @@ CompiledMethod* OptimizingCompiler::JniCompile(uint32_t access_flags, uint32_t method_idx, const DexFile& dex_file, Handle<mirror::DexCache> dex_cache) const { - if (GetCompilerDriver()->GetCompilerOptions().IsBootImage()) { + const CompilerOptions& compiler_options = GetCompilerDriver()->GetCompilerOptions(); + if (compiler_options.IsBootImage()) { ScopedObjectAccess soa(Thread::Current()); Runtime* runtime = Runtime::Current(); ArtMethod* method = runtime->GetClassLinker()->LookupResolvedMethod( @@ -1154,7 +1151,7 @@ CompiledMethod* OptimizingCompiler::JniCompile(uint32_t access_flags, } JniCompiledMethod jni_compiled_method = ArtQuickJniCompileMethod( - GetCompilerDriver(), access_flags, method_idx, dex_file); + compiler_options, access_flags, method_idx, dex_file); MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kCompiledNativeStub); return CompiledMethod::SwapAllocCompiledMethod( GetCompilerDriver(), @@ -1218,8 +1215,9 @@ bool OptimizingCompiler::JitCompile(Thread* self, ArenaAllocator allocator(runtime->GetJitArenaPool()); if (UNLIKELY(method->IsNative())) { + const CompilerOptions& compiler_options = GetCompilerDriver()->GetCompilerOptions(); JniCompiledMethod jni_compiled_method = ArtQuickJniCompileMethod( - GetCompilerDriver(), access_flags, method_idx, *dex_file); + compiler_options, access_flags, method_idx, *dex_file); ScopedNullHandle<mirror::ObjectArray<mirror::Object>> roots; ArenaSet<ArtMethod*, std::less<ArtMethod*>> cha_single_implementation_list( allocator.Adapter(kArenaAllocCHA)); @@ -1243,7 +1241,6 @@ bool OptimizingCompiler::JitCompile(Thread* self, return false; } - const CompilerOptions& compiler_options = GetCompilerDriver()->GetCompilerOptions(); if (compiler_options.GenerateAnyDebugInfo()) { const auto* method_header = reinterpret_cast<const OatQuickMethodHeader*>(code); const uintptr_t code_address = reinterpret_cast<uintptr_t>(method_header->GetCode()); @@ -1420,8 +1417,8 @@ void OptimizingCompiler::GenerateJitDebugInfo(ArtMethod* method, debug::MethodDe // Create entry for the single method that we just compiled. std::vector<uint8_t> elf_file = debug::MakeElfFileForJIT( - GetCompilerDriver()->GetInstructionSet(), - GetCompilerDriver()->GetInstructionSetFeatures(), + compiler_options.GetInstructionSet(), + compiler_options.GetInstructionSetFeatures(), mini_debug_info, ArrayRef<const debug::MethodDebugInfo>(&info, 1)); MutexLock mu(Thread::Current(), *Locks::native_debug_interface_lock_); diff --git a/compiler/optimizing/register_allocator_test.cc b/compiler/optimizing/register_allocator_test.cc index a70b0664dc..7144775c2b 100644 --- a/compiler/optimizing/register_allocator_test.cc +++ b/compiler/optimizing/register_allocator_test.cc @@ -40,6 +40,12 @@ using Strategy = RegisterAllocator::Strategy; class RegisterAllocatorTest : public OptimizingUnitTest { protected: + void SetUp() OVERRIDE { + // This test is using the x86 ISA. + OverrideInstructionSetFeatures(InstructionSet::kX86, "default"); + OptimizingUnitTest::SetUp(); + } + // These functions need to access private variables of LocationSummary, so we declare it // as a member of RegisterAllocatorTest, which we make a friend class. void SameAsFirstInputHint(Strategy strategy); @@ -81,9 +87,7 @@ TEST_F(RegisterAllocatorTest, test_name##_GraphColor) {\ bool RegisterAllocatorTest::Check(const std::vector<uint16_t>& data, Strategy strategy) { HGraph* graph = CreateCFG(data); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); + x86::CodeGeneratorX86 codegen(graph, *compiler_options_); SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); std::unique_ptr<RegisterAllocator> register_allocator = @@ -98,9 +102,7 @@ bool RegisterAllocatorTest::Check(const std::vector<uint16_t>& data, Strategy st */ TEST_F(RegisterAllocatorTest, ValidateIntervals) { HGraph* graph = CreateGraph(); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); + x86::CodeGeneratorX86 codegen(graph, *compiler_options_); ScopedArenaVector<LiveInterval*> intervals(GetScopedAllocator()->Adapter()); // Test with two intervals of the same range. @@ -324,9 +326,7 @@ void RegisterAllocatorTest::Loop3(Strategy strategy) { Instruction::GOTO | 0xF900); HGraph* graph = CreateCFG(data); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); + x86::CodeGeneratorX86 codegen(graph, *compiler_options_); SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); std::unique_ptr<RegisterAllocator> register_allocator = @@ -359,9 +359,7 @@ TEST_F(RegisterAllocatorTest, FirstRegisterUse) { Instruction::RETURN_VOID); HGraph* graph = CreateCFG(data); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); + x86::CodeGeneratorX86 codegen(graph, *compiler_options_); SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); @@ -412,9 +410,7 @@ void RegisterAllocatorTest::DeadPhi(Strategy strategy) { HGraph* graph = CreateCFG(data); SsaDeadPhiElimination(graph).Run(); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); + x86::CodeGeneratorX86 codegen(graph, *compiler_options_); SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); std::unique_ptr<RegisterAllocator> register_allocator = @@ -438,9 +434,7 @@ TEST_F(RegisterAllocatorTest, FreeUntil) { HGraph* graph = CreateCFG(data); SsaDeadPhiElimination(graph).Run(); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); + x86::CodeGeneratorX86 codegen(graph, *compiler_options_); SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); RegisterAllocatorLinearScan register_allocator(GetScopedAllocator(), &codegen, liveness); @@ -566,9 +560,7 @@ void RegisterAllocatorTest::PhiHint(Strategy strategy) { { HGraph* graph = BuildIfElseWithPhi(&phi, &input1, &input2); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); + x86::CodeGeneratorX86 codegen(graph, *compiler_options_); SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); @@ -584,9 +576,7 @@ void RegisterAllocatorTest::PhiHint(Strategy strategy) { { HGraph* graph = BuildIfElseWithPhi(&phi, &input1, &input2); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); + x86::CodeGeneratorX86 codegen(graph, *compiler_options_); SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); @@ -604,9 +594,7 @@ void RegisterAllocatorTest::PhiHint(Strategy strategy) { { HGraph* graph = BuildIfElseWithPhi(&phi, &input1, &input2); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); + x86::CodeGeneratorX86 codegen(graph, *compiler_options_); SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); @@ -624,9 +612,7 @@ void RegisterAllocatorTest::PhiHint(Strategy strategy) { { HGraph* graph = BuildIfElseWithPhi(&phi, &input1, &input2); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); + x86::CodeGeneratorX86 codegen(graph, *compiler_options_); SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); @@ -689,9 +675,7 @@ void RegisterAllocatorTest::ExpectedInRegisterHint(Strategy strategy) { { HGraph* graph = BuildFieldReturn(&field, &ret); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); + x86::CodeGeneratorX86 codegen(graph, *compiler_options_); SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); @@ -705,9 +689,7 @@ void RegisterAllocatorTest::ExpectedInRegisterHint(Strategy strategy) { { HGraph* graph = BuildFieldReturn(&field, &ret); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); + x86::CodeGeneratorX86 codegen(graph, *compiler_options_); SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); @@ -761,9 +743,7 @@ void RegisterAllocatorTest::SameAsFirstInputHint(Strategy strategy) { { HGraph* graph = BuildTwoSubs(&first_sub, &second_sub); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); + x86::CodeGeneratorX86 codegen(graph, *compiler_options_); SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); @@ -778,9 +758,7 @@ void RegisterAllocatorTest::SameAsFirstInputHint(Strategy strategy) { { HGraph* graph = BuildTwoSubs(&first_sub, &second_sub); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); + x86::CodeGeneratorX86 codegen(graph, *compiler_options_); SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); @@ -834,9 +812,7 @@ HGraph* RegisterAllocatorTest::BuildDiv(HInstruction** div) { void RegisterAllocatorTest::ExpectedExactInRegisterAndSameOutputHint(Strategy strategy) { HInstruction *div; HGraph* graph = BuildDiv(&div); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); + x86::CodeGeneratorX86 codegen(graph, *compiler_options_); SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); @@ -934,9 +910,7 @@ TEST_F(RegisterAllocatorTest, SpillInactive) { new (GetAllocator()) LocationSummary(fourth->GetDefinedBy(), LocationSummary::kNoCall); locations->SetOut(Location::RequiresRegister()); - std::unique_ptr<const X86InstructionSetFeatures> features_x86( - X86InstructionSetFeatures::FromCppDefines()); - x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions()); + x86::CodeGeneratorX86 codegen(graph, *compiler_options_); SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); // Populate the instructions in the liveness object, to please the register allocator. for (size_t i = 0; i < 32; ++i) { diff --git a/compiler/optimizing/scheduler_test.cc b/compiler/optimizing/scheduler_test.cc index d4cae72c7e..7079e07ae1 100644 --- a/compiler/optimizing/scheduler_test.cc +++ b/compiler/optimizing/scheduler_test.cc @@ -192,7 +192,9 @@ class SchedulerTest : public OptimizingUnitTest { HInstructionScheduling scheduling(graph, target_config.GetInstructionSet()); scheduling.Run(/*only_optimize_loop_blocks*/ false, /*schedule_randomly*/ true); + OverrideInstructionSetFeatures(target_config.GetInstructionSet(), "default"); RunCode(target_config, + *compiler_options_, graph, [](HGraph* graph_arg) { RemoveSuspendChecks(graph_arg); }, has_result, expected); diff --git a/compiler/optimizing/ssa_liveness_analysis_test.cc b/compiler/optimizing/ssa_liveness_analysis_test.cc index ae5e4e7176..a683c698d9 100644 --- a/compiler/optimizing/ssa_liveness_analysis_test.cc +++ b/compiler/optimizing/ssa_liveness_analysis_test.cc @@ -28,18 +28,11 @@ namespace art { class SsaLivenessAnalysisTest : public OptimizingUnitTest { - public: - SsaLivenessAnalysisTest() - : graph_(CreateGraph()), - compiler_options_(), - instruction_set_(kRuntimeISA) { - std::string error_msg; - instruction_set_features_ = - InstructionSetFeatures::FromVariant(instruction_set_, "default", &error_msg); - codegen_ = CodeGenerator::Create(graph_, - instruction_set_, - *instruction_set_features_, - compiler_options_); + protected: + void SetUp() OVERRIDE { + OptimizingUnitTest::SetUp(); + graph_ = CreateGraph(); + codegen_ = CodeGenerator::Create(graph_, *compiler_options_); CHECK(codegen_ != nullptr) << instruction_set_ << " is not a supported target architecture."; // Create entry block. entry_ = new (GetAllocator()) HBasicBlock(graph_); @@ -57,9 +50,6 @@ class SsaLivenessAnalysisTest : public OptimizingUnitTest { } HGraph* graph_; - CompilerOptions compiler_options_; - InstructionSet instruction_set_; - std::unique_ptr<const InstructionSetFeatures> instruction_set_features_; std::unique_ptr<CodeGenerator> codegen_; HBasicBlock* entry_; }; diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 708f6ffcac..a8024425d8 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -610,7 +610,6 @@ class Dex2Oat FINAL { public: explicit Dex2Oat(TimingLogger* timings) : compiler_kind_(Compiler::kOptimizing), - instruction_set_(kRuntimeISA == InstructionSet::kArm ? InstructionSet::kThumb2 : kRuntimeISA), // Take the default set of instruction features from the build. image_file_location_oat_checksum_(0), image_file_location_oat_data_begin_(0), @@ -700,25 +699,26 @@ class Dex2Oat FINAL { } void ParseInstructionSetVariant(const std::string& option, ParserOptions* parser_options) { - instruction_set_features_ = InstructionSetFeatures::FromVariant( - instruction_set_, option, &parser_options->error_msg); - if (instruction_set_features_.get() == nullptr) { + compiler_options_->instruction_set_features_ = InstructionSetFeatures::FromVariant( + compiler_options_->instruction_set_, option, &parser_options->error_msg); + if (compiler_options_->instruction_set_features_ == nullptr) { Usage("%s", parser_options->error_msg.c_str()); } } void ParseInstructionSetFeatures(const std::string& option, ParserOptions* parser_options) { - if (instruction_set_features_ == nullptr) { - instruction_set_features_ = InstructionSetFeatures::FromVariant( - instruction_set_, "default", &parser_options->error_msg); - if (instruction_set_features_.get() == nullptr) { + if (compiler_options_->instruction_set_features_ == nullptr) { + compiler_options_->instruction_set_features_ = InstructionSetFeatures::FromVariant( + compiler_options_->instruction_set_, "default", &parser_options->error_msg); + if (compiler_options_->instruction_set_features_ == nullptr) { Usage("Problem initializing default instruction set features variant: %s", parser_options->error_msg.c_str()); } } - instruction_set_features_ = - instruction_set_features_->AddFeaturesFromString(option, &parser_options->error_msg); - if (instruction_set_features_ == nullptr) { + compiler_options_->instruction_set_features_ = + compiler_options_->instruction_set_features_->AddFeaturesFromString( + option, &parser_options->error_msg); + if (compiler_options_->instruction_set_features_ == nullptr) { Usage("Error parsing '%s': %s", option.c_str(), parser_options->error_msg.c_str()); } } @@ -870,23 +870,23 @@ class Dex2Oat FINAL { // If no instruction set feature was given, use the default one for the target // instruction set. - if (instruction_set_features_.get() == nullptr) { - instruction_set_features_ = InstructionSetFeatures::FromVariant( - instruction_set_, "default", &parser_options->error_msg); - if (instruction_set_features_.get() == nullptr) { + if (compiler_options_->instruction_set_features_.get() == nullptr) { + compiler_options_->instruction_set_features_ = InstructionSetFeatures::FromVariant( + compiler_options_->instruction_set_, "default", &parser_options->error_msg); + if (compiler_options_->instruction_set_features_ == nullptr) { Usage("Problem initializing default instruction set features variant: %s", parser_options->error_msg.c_str()); } } - if (instruction_set_ == kRuntimeISA) { + if (compiler_options_->instruction_set_ == kRuntimeISA) { std::unique_ptr<const InstructionSetFeatures> runtime_features( InstructionSetFeatures::FromCppDefines()); - if (!instruction_set_features_->Equals(runtime_features.get())) { + if (!compiler_options_->GetInstructionSetFeatures()->Equals(runtime_features.get())) { LOG(WARNING) << "Mismatch between dex2oat instruction set features (" - << *instruction_set_features_ << ") and those of dex2oat executable (" - << *runtime_features <<") for the command line:\n" - << CommandLine(); + << *compiler_options_->GetInstructionSetFeatures() + << ") and those of dex2oat executable (" << *runtime_features + << ") for the command line:\n" << CommandLine(); } } @@ -896,7 +896,7 @@ class Dex2Oat FINAL { // Checks are all explicit until we know the architecture. // Set the compilation target's implicit checks options. - switch (instruction_set_) { + switch (compiler_options_->GetInstructionSet()) { case InstructionSet::kArm: case InstructionSet::kThumb2: case InstructionSet::kArm64: @@ -1215,10 +1215,10 @@ class Dex2Oat FINAL { AssignIfExists(args, M::Backend, &compiler_kind_); parser_options->requested_specific_compiler = args.Exists(M::Backend); - AssignIfExists(args, M::TargetInstructionSet, &instruction_set_); + AssignIfExists(args, M::TargetInstructionSet, &compiler_options_->instruction_set_); // arm actually means thumb2. - if (instruction_set_ == InstructionSet::kArm) { - instruction_set_ = InstructionSet::kThumb2; + if (compiler_options_->instruction_set_ == InstructionSet::kArm) { + compiler_options_->instruction_set_ = InstructionSet::kThumb2; } AssignTrueIfExists(args, M::Host, &is_host_); @@ -1628,8 +1628,6 @@ class Dex2Oat FINAL { if (!oat_writers_[i]->WriteAndOpenDexFiles( vdex_files_[i].get(), rodata_.back(), - instruction_set_, - instruction_set_features_.get(), key_value_store_.get(), verify, update_input_vdex_, @@ -1847,8 +1845,6 @@ class Dex2Oat FINAL { driver_.reset(new CompilerDriver(compiler_options_.get(), verification_results_.get(), compiler_kind_, - instruction_set_, - instruction_set_features_.get(), &compiler_options_->image_classes_, thread_count_, swap_fd_, @@ -2021,7 +2017,7 @@ class Dex2Oat FINAL { VLOG(compiler) << "App image base=" << reinterpret_cast<void*>(image_base_); } - image_writer_.reset(new linker::ImageWriter(*driver_, + image_writer_.reset(new linker::ImageWriter(*compiler_options_, image_base_, compiler_options_->GetCompilePic(), IsAppImage(), @@ -2076,8 +2072,8 @@ class Dex2Oat FINAL { { TimingLogger::ScopedTiming t2("dex2oat Write ELF", timings_); - linker::MultiOatRelativePatcher patcher(instruction_set_, - instruction_set_features_.get(), + linker::MultiOatRelativePatcher patcher(compiler_options_->GetInstructionSet(), + compiler_options_->GetInstructionSetFeatures(), driver_->GetCompiledMethodStorage()); for (size_t i = 0, size = oat_files_.size(); i != size; ++i) { std::unique_ptr<linker::ElfWriter>& elf_writer = elf_writers_[i]; @@ -2486,17 +2482,14 @@ class Dex2Oat FINAL { elf_writers_.reserve(oat_files_.size()); oat_writers_.reserve(oat_files_.size()); for (const std::unique_ptr<File>& oat_file : oat_files_) { - elf_writers_.emplace_back(linker::CreateElfWriterQuick(instruction_set_, - instruction_set_features_.get(), - compiler_options_.get(), - oat_file.get())); + elf_writers_.emplace_back(linker::CreateElfWriterQuick(*compiler_options_, oat_file.get())); elf_writers_.back()->Start(); bool do_oat_writer_layout = DoDexLayoutOptimizations() || DoOatLayoutOptimizations(); if (profile_compilation_info_ != nullptr && profile_compilation_info_->IsEmpty()) { do_oat_writer_layout = false; } oat_writers_.emplace_back(new linker::OatWriter( - IsBootImage(), + *compiler_options_, timings_, do_oat_writer_layout ? profile_compilation_info_.get() : nullptr, compact_dex_level_)); @@ -2544,7 +2537,8 @@ class Dex2Oat FINAL { raw_options.push_back(std::make_pair("compilercallbacks", callbacks)); raw_options.push_back( - std::make_pair("imageinstructionset", GetInstructionSetString(instruction_set_))); + std::make_pair("imageinstructionset", + GetInstructionSetString(compiler_options_->GetInstructionSet()))); // Only allow no boot image for the runtime if we're compiling one. When we compile an app, // we don't want fallback mode, it will abort as we do not push a boot classpath (it might @@ -2607,7 +2601,7 @@ class Dex2Oat FINAL { SetThreadName(kIsDebugBuild ? "dex2oatd" : "dex2oat"); runtime_.reset(Runtime::Current()); - runtime_->SetInstructionSet(instruction_set_); + runtime_->SetInstructionSet(compiler_options_->GetInstructionSet()); for (uint32_t i = 0; i < static_cast<uint32_t>(CalleeSaveType::kLastCalleeSaveType); ++i) { CalleeSaveType type = CalleeSaveType(i); if (!runtime_->HasCalleeSaveMethod(type)) { @@ -2802,9 +2796,6 @@ class Dex2Oat FINAL { std::unique_ptr<CompilerOptions> compiler_options_; Compiler::Kind compiler_kind_; - InstructionSet instruction_set_; - std::unique_ptr<const InstructionSetFeatures> instruction_set_features_; - uint32_t image_file_location_oat_checksum_; uintptr_t image_file_location_oat_data_begin_; int32_t image_patch_delta_; diff --git a/dex2oat/linker/arm/relative_patcher_thumb2_test.cc b/dex2oat/linker/arm/relative_patcher_thumb2_test.cc index 3fe97e146c..3d7277aab3 100644 --- a/dex2oat/linker/arm/relative_patcher_thumb2_test.cc +++ b/dex2oat/linker/arm/relative_patcher_thumb2_test.cc @@ -197,10 +197,7 @@ class Thumb2RelativePatcherTest : public RelativePatcherTest { OptimizingUnitTestHelper helper; HGraph* graph = helper.CreateGraph(); std::string error_msg; - ArmFeaturesUniquePtr features = - ArmInstructionSetFeatures::FromVariant("default", &error_msg); - CompilerOptions options; - arm::CodeGeneratorARMVIXL codegen(graph, *features, options); + arm::CodeGeneratorARMVIXL codegen(graph, *compiler_options_); ArenaVector<uint8_t> code(helper.GetAllocator()->Adapter()); codegen.EmitThunkCode(patch, &code, debug_name); return std::vector<uint8_t>(code.begin(), code.end()); diff --git a/dex2oat/linker/arm64/relative_patcher_arm64_test.cc b/dex2oat/linker/arm64/relative_patcher_arm64_test.cc index 393733dd0c..07e6860f9c 100644 --- a/dex2oat/linker/arm64/relative_patcher_arm64_test.cc +++ b/dex2oat/linker/arm64/relative_patcher_arm64_test.cc @@ -176,10 +176,7 @@ class Arm64RelativePatcherTest : public RelativePatcherTest { OptimizingUnitTestHelper helper; HGraph* graph = helper.CreateGraph(); std::string error_msg; - Arm64FeaturesUniquePtr features = - Arm64InstructionSetFeatures::FromVariant("default", &error_msg); - CompilerOptions options; - arm64::CodeGeneratorARM64 codegen(graph, *features, options); + arm64::CodeGeneratorARM64 codegen(graph, *compiler_options_); ArenaVector<uint8_t> code(helper.GetAllocator()->Adapter()); codegen.EmitThunkCode(patch, &code, debug_name); return std::vector<uint8_t>(code.begin(), code.end()); diff --git a/dex2oat/linker/elf_writer_quick.cc b/dex2oat/linker/elf_writer_quick.cc index 58bd1b0f1f..8f6ff702cc 100644 --- a/dex2oat/linker/elf_writer_quick.cc +++ b/dex2oat/linker/elf_writer_quick.cc @@ -96,9 +96,7 @@ class DebugInfoTask : public Task { template <typename ElfTypes> class ElfWriterQuick FINAL : public ElfWriter { public: - ElfWriterQuick(InstructionSet instruction_set, - const InstructionSetFeatures* features, - const CompilerOptions* compiler_options, + ElfWriterQuick(const CompilerOptions& compiler_options, File* elf_file); ~ElfWriterQuick(); @@ -129,8 +127,7 @@ class ElfWriterQuick FINAL : public ElfWriter { std::vector<uint8_t>* buffer); private: - const InstructionSetFeatures* instruction_set_features_; - const CompilerOptions* const compiler_options_; + const CompilerOptions& compiler_options_; File* const elf_file_; size_t rodata_size_; size_t text_size_; @@ -147,30 +144,18 @@ class ElfWriterQuick FINAL : public ElfWriter { DISALLOW_IMPLICIT_CONSTRUCTORS(ElfWriterQuick); }; -std::unique_ptr<ElfWriter> CreateElfWriterQuick(InstructionSet instruction_set, - const InstructionSetFeatures* features, - const CompilerOptions* compiler_options, +std::unique_ptr<ElfWriter> CreateElfWriterQuick(const CompilerOptions& compiler_options, File* elf_file) { - if (Is64BitInstructionSet(instruction_set)) { - return std::make_unique<ElfWriterQuick<ElfTypes64>>(instruction_set, - features, - compiler_options, - elf_file); + if (Is64BitInstructionSet(compiler_options.GetInstructionSet())) { + return std::make_unique<ElfWriterQuick<ElfTypes64>>(compiler_options, elf_file); } else { - return std::make_unique<ElfWriterQuick<ElfTypes32>>(instruction_set, - features, - compiler_options, - elf_file); + return std::make_unique<ElfWriterQuick<ElfTypes32>>(compiler_options, elf_file); } } template <typename ElfTypes> -ElfWriterQuick<ElfTypes>::ElfWriterQuick(InstructionSet instruction_set, - const InstructionSetFeatures* features, - const CompilerOptions* compiler_options, - File* elf_file) +ElfWriterQuick<ElfTypes>::ElfWriterQuick(const CompilerOptions& compiler_options, File* elf_file) : ElfWriter(), - instruction_set_features_(features), compiler_options_(compiler_options), elf_file_(elf_file), rodata_size_(0u), @@ -180,7 +165,9 @@ ElfWriterQuick<ElfTypes>::ElfWriterQuick(InstructionSet instruction_set, dex_section_size_(0u), output_stream_( std::make_unique<BufferedOutputStream>(std::make_unique<FileOutputStream>(elf_file))), - builder_(new ElfBuilder<ElfTypes>(instruction_set, features, output_stream_.get())) {} + builder_(new ElfBuilder<ElfTypes>(compiler_options_.GetInstructionSet(), + compiler_options_.GetInstructionSetFeatures(), + output_stream_.get())) {} template <typename ElfTypes> ElfWriterQuick<ElfTypes>::~ElfWriterQuick() {} @@ -188,7 +175,7 @@ ElfWriterQuick<ElfTypes>::~ElfWriterQuick() {} template <typename ElfTypes> void ElfWriterQuick<ElfTypes>::Start() { builder_->Start(); - if (compiler_options_->GetGenerateBuildId()) { + if (compiler_options_.GetGenerateBuildId()) { builder_->GetBuildId()->AllocateVirtualMemory(builder_->GetBuildId()->GetSize()); builder_->WriteBuildIdSection(); } @@ -272,12 +259,12 @@ void ElfWriterQuick<ElfTypes>::WriteDynamicSection() { template <typename ElfTypes> void ElfWriterQuick<ElfTypes>::PrepareDebugInfo(const debug::DebugInfo& debug_info) { - if (!debug_info.Empty() && compiler_options_->GetGenerateMiniDebugInfo()) { + if (!debug_info.Empty() && compiler_options_.GetGenerateMiniDebugInfo()) { // Prepare the mini-debug-info in background while we do other I/O. Thread* self = Thread::Current(); debug_info_task_ = std::unique_ptr<DebugInfoTask>( new DebugInfoTask(builder_->GetIsa(), - instruction_set_features_, + compiler_options_.GetInstructionSetFeatures(), builder_->GetText()->GetAddress(), text_size_, builder_->GetDex()->Exists() ? builder_->GetDex()->GetAddress() : 0, @@ -293,11 +280,11 @@ void ElfWriterQuick<ElfTypes>::PrepareDebugInfo(const debug::DebugInfo& debug_in template <typename ElfTypes> void ElfWriterQuick<ElfTypes>::WriteDebugInfo(const debug::DebugInfo& debug_info) { if (!debug_info.Empty()) { - if (compiler_options_->GetGenerateDebugInfo()) { + if (compiler_options_.GetGenerateDebugInfo()) { // Generate all the debug information we can. debug::WriteDebugInfo(builder_.get(), debug_info, kCFIFormat, true /* write_oat_patches */); } - if (compiler_options_->GetGenerateMiniDebugInfo()) { + if (compiler_options_.GetGenerateMiniDebugInfo()) { // Wait for the mini-debug-info generation to finish and write it to disk. Thread* self = Thread::Current(); DCHECK(debug_info_thread_pool_ != nullptr); @@ -310,7 +297,7 @@ void ElfWriterQuick<ElfTypes>::WriteDebugInfo(const debug::DebugInfo& debug_info template <typename ElfTypes> bool ElfWriterQuick<ElfTypes>::End() { builder_->End(); - if (compiler_options_->GetGenerateBuildId()) { + if (compiler_options_.GetGenerateBuildId()) { uint8_t build_id[ElfBuilder<ElfTypes>::kBuildIdLen]; ComputeFileBuildId(&build_id); builder_->WriteBuildId(build_id); diff --git a/dex2oat/linker/elf_writer_quick.h b/dex2oat/linker/elf_writer_quick.h index 274d18b858..333c6e3b06 100644 --- a/dex2oat/linker/elf_writer_quick.h +++ b/dex2oat/linker/elf_writer_quick.h @@ -30,9 +30,7 @@ class InstructionSetFeatures; namespace linker { -std::unique_ptr<ElfWriter> CreateElfWriterQuick(InstructionSet instruction_set, - const InstructionSetFeatures* features, - const CompilerOptions* compiler_options, +std::unique_ptr<ElfWriter> CreateElfWriterQuick(const CompilerOptions& compiler_options, File* elf_file); } // namespace linker diff --git a/dex2oat/linker/image_test.h b/dex2oat/linker/image_test.h index 66b37fb08d..fa8c7784f5 100644 --- a/dex2oat/linker/image_test.h +++ b/dex2oat/linker/image_test.h @@ -35,6 +35,7 @@ #include "compiler_callbacks.h" #include "debug/method_debug_info.h" #include "dex/quick_compiler_callbacks.h" +#include "driver/compiler_driver.h" #include "driver/compiler_options.h" #include "gc/space/image_space.h" #include "image_writer.h" @@ -211,7 +212,7 @@ inline void ImageTest::DoCompile(ImageHeader::StorageMode storage_mode, ++image_idx; } // TODO: compile_pic should be a test argument. - std::unique_ptr<ImageWriter> writer(new ImageWriter(*driver, + std::unique_ptr<ImageWriter> writer(new ImageWriter(*compiler_options_, kRequestedImageBase, /*compile_pic*/false, /*compile_app_image*/false, @@ -242,12 +243,9 @@ inline void ImageTest::DoCompile(ImageHeader::StorageMode storage_mode, std::vector<std::unique_ptr<ElfWriter>> elf_writers; std::vector<std::unique_ptr<OatWriter>> oat_writers; for (ScratchFile& oat_file : out_helper.oat_files) { - elf_writers.emplace_back(CreateElfWriterQuick(driver->GetInstructionSet(), - driver->GetInstructionSetFeatures(), - &driver->GetCompilerOptions(), - oat_file.GetFile())); + elf_writers.emplace_back(CreateElfWriterQuick(*compiler_options_, oat_file.GetFile())); elf_writers.back()->Start(); - oat_writers.emplace_back(new OatWriter(/*compiling_boot_image*/true, + oat_writers.emplace_back(new OatWriter(*compiler_options_, &timings, /*profile_compilation_info*/nullptr, CompactDexLevel::kCompactDexLevelNone)); @@ -272,8 +270,6 @@ inline void ImageTest::DoCompile(ImageHeader::StorageMode storage_mode, bool dex_files_ok = oat_writers[i]->WriteAndOpenDexFiles( out_helper.vdex_files[i].GetFile(), rodata.back(), - driver->GetInstructionSet(), - driver->GetInstructionSetFeatures(), &key_value_store, /* verify */ false, // Dex files may be dex-to-dex-ed, don't verify. /* update_input_vdex */ false, @@ -299,8 +295,8 @@ inline void ImageTest::DoCompile(ImageHeader::StorageMode storage_mode, DCHECK_EQ(out_helper.vdex_files.size(), out_helper.oat_files.size()); for (size_t i = 0, size = out_helper.oat_files.size(); i != size; ++i) { - MultiOatRelativePatcher patcher(driver->GetInstructionSet(), - driver->GetInstructionSetFeatures(), + MultiOatRelativePatcher patcher(compiler_options_->GetInstructionSet(), + compiler_options_->GetInstructionSetFeatures(), driver->GetCompiledMethodStorage()); OatWriter* const oat_writer = oat_writers[i].get(); ElfWriter* const elf_writer = elf_writers[i].get(); @@ -381,7 +377,8 @@ inline void ImageTest::Compile(ImageHeader::StorageMode storage_mode, for (const std::string& image_class : image_classes) { image_classes_.insert(image_class); } - CreateCompilerDriver(Compiler::kOptimizing, kRuntimeISA, kIsTargetBuild ? 2U : 16U); + number_of_threads_ = kIsTargetBuild ? 2U : 16U; + CreateCompilerDriver(); // Set inline filter values. compiler_options_->SetInlineMaxCodeUnits(CompilerOptions::kDefaultInlineMaxCodeUnits); image_classes_.clear(); diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc index bb730d3374..8778cd8adc 100644 --- a/dex2oat/linker/image_writer.cc +++ b/dex2oat/linker/image_writer.cc @@ -37,7 +37,6 @@ #include "compiled_method.h" #include "dex/dex_file-inl.h" #include "dex/dex_file_types.h" -#include "driver/compiler_driver.h" #include "driver/compiler_options.h" #include "elf_file.h" #include "elf_utils.h" @@ -137,7 +136,7 @@ static void ClearDexFileCookies() REQUIRES_SHARED(Locks::mutator_lock_) { } bool ImageWriter::PrepareImageAddressSpace(TimingLogger* timings) { - target_ptr_size_ = InstructionSetPointerSize(compiler_driver_.GetInstructionSet()); + target_ptr_size_ = InstructionSetPointerSize(compiler_options_.GetInstructionSet()); gc::Heap* const heap = Runtime::Current()->GetHeap(); { ScopedObjectAccess soa(Thread::Current()); @@ -439,10 +438,10 @@ void ImageWriter::SetImageBinSlot(mirror::Object* object, BinSlot bin_slot) { } void ImageWriter::PrepareDexCacheArraySlots() { - // Prepare dex cache array starts based on the ordering specified in the CompilerDriver. + // Prepare dex cache array starts based on the ordering specified in the CompilerOptions. // Set the slot size early to avoid DCHECK() failures in IsImageBinSlotAssigned() // when AssignImageBinSlot() assigns their indexes out or order. - for (const DexFile* dex_file : compiler_driver_.GetCompilerOptions().GetDexFilesForOatFile()) { + for (const DexFile* dex_file : compiler_options_.GetDexFilesForOatFile()) { auto it = dex_file_oat_index_map_.find(dex_file); DCHECK(it != dex_file_oat_index_map_.end()) << dex_file->GetLocation(); ImageInfo& image_info = GetImageInfo(it->second); @@ -852,8 +851,7 @@ bool ImageWriter::PruneAppImageClassInternal( std::string temp; // Prune if not an image class, this handles any broken sets of image classes such as having a // class in the set but not it's superclass. - result = result || - !compiler_driver_.GetCompilerOptions().IsImageClass(klass->GetDescriptor(&temp)); + result = result || !compiler_options_.IsImageClass(klass->GetDescriptor(&temp)); bool my_early_exit = false; // Only for ourselves, ignore caller. // Remove classes that failed to verify since we don't want to have java.lang.VerifyError in the // app image. @@ -943,7 +941,7 @@ bool ImageWriter::KeepClass(ObjPtr<mirror::Class> klass) { return true; } std::string temp; - if (!compiler_driver_.GetCompilerOptions().IsImageClass(klass->GetDescriptor(&temp))) { + if (!compiler_options_.IsImageClass(klass->GetDescriptor(&temp))) { return false; } if (compile_app_image_) { @@ -1229,7 +1227,7 @@ void ImageWriter::CheckNonImageClassesRemoved() { } void ImageWriter::DumpImageClasses() { - for (const std::string& image_class : compiler_driver_.GetCompilerOptions().GetImageClasses()) { + for (const std::string& image_class : compiler_options_.GetImageClasses()) { LOG(INFO) << " " << image_class; } } @@ -1738,7 +1736,7 @@ void ImageWriter::CalculateNewObjectOffsets() { WorkStack work_stack; // Special case interned strings to put them in the image they are likely to be resolved from. - for (const DexFile* dex_file : compiler_driver_.GetCompilerOptions().GetDexFilesForOatFile()) { + for (const DexFile* dex_file : compiler_options_.GetDexFilesForOatFile()) { auto it = dex_file_oat_index_map_.find(dex_file); DCHECK(it != dex_file_oat_index_map_.end()) << dex_file->GetLocation(); const size_t oat_index = it->second; @@ -2819,7 +2817,7 @@ void ImageWriter::UpdateOatFileHeader(size_t oat_index, const OatHeader& oat_hea } ImageWriter::ImageWriter( - const CompilerDriver& compiler_driver, + const CompilerOptions& compiler_options, uintptr_t image_begin, bool compile_pic, bool compile_app_image, @@ -2827,12 +2825,12 @@ ImageWriter::ImageWriter( const std::vector<const char*>& oat_filenames, const std::unordered_map<const DexFile*, size_t>& dex_file_oat_index_map, const HashSet<std::string>* dirty_image_objects) - : compiler_driver_(compiler_driver), + : compiler_options_(compiler_options), global_image_begin_(reinterpret_cast<uint8_t*>(image_begin)), image_objects_offset_begin_(0), compile_pic_(compile_pic), compile_app_image_(compile_app_image), - target_ptr_size_(InstructionSetPointerSize(compiler_driver_.GetInstructionSet())), + target_ptr_size_(InstructionSetPointerSize(compiler_options.GetInstructionSet())), image_infos_(oat_filenames.size()), dirty_methods_(0u), clean_methods_(0u), diff --git a/dex2oat/linker/image_writer.h b/dex2oat/linker/image_writer.h index 2fcf5fd56a..4111e84df2 100644 --- a/dex2oat/linker/image_writer.h +++ b/dex2oat/linker/image_writer.h @@ -39,7 +39,6 @@ #include "base/safe_map.h" #include "base/utils.h" #include "class_table.h" -#include "driver/compiler_driver.h" #include "image.h" #include "intern_table.h" #include "lock_word.h" @@ -63,6 +62,7 @@ class ClassLoader; } // namespace mirror class ClassLoaderVisitor; +class CompilerOptions; class ImTable; class ImtConflictTable; class TimingLogger; @@ -74,7 +74,7 @@ namespace linker { // Write a Space built during compilation for use during execution. class ImageWriter FINAL { public: - ImageWriter(const CompilerDriver& compiler_driver, + ImageWriter(const CompilerOptions& compiler_options, uintptr_t image_begin, bool compile_pic, bool compile_app_image, @@ -511,9 +511,8 @@ class ImageWriter FINAL { // classes since we do not want any boot class loader classes in the image. This means that // we also cannot have any classes which refer to these boot class loader non image classes. // PruneAppImageClass also prunes if klass depends on a non-image class according to the compiler - // driver. - bool PruneAppImageClass(ObjPtr<mirror::Class> klass) - REQUIRES_SHARED(Locks::mutator_lock_); + // options. + bool PruneAppImageClass(ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_); // early_exit is true if we had a cyclic dependency anywhere down the chain. bool PruneAppImageClassInternal(ObjPtr<mirror::Class> klass, @@ -575,7 +574,7 @@ class ImageWriter FINAL { void CopyAndFixupPointer(void** target, void* value); - const CompilerDriver& compiler_driver_; + const CompilerOptions& compiler_options_; // Beginning target image address for the first image. uint8_t* global_image_begin_; diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc index 0ed9579aed..154f9ca677 100644 --- a/dex2oat/linker/oat_writer.cc +++ b/dex2oat/linker/oat_writer.cc @@ -355,7 +355,7 @@ class OatWriter::OatDexFile { DCHECK_EQ(static_cast<off_t>(file_offset + offset_), out->Seek(0, kSeekCurrent)) \ << "file_offset=" << file_offset << " offset_=" << offset_ -OatWriter::OatWriter(bool compiling_boot_image, +OatWriter::OatWriter(const CompilerOptions& compiler_options, TimingLogger* timings, ProfileCompilationInfo* info, CompactDexLevel compact_dex_level) @@ -366,9 +366,8 @@ OatWriter::OatWriter(bool compiling_boot_image, zipped_dex_files_(), zipped_dex_file_locations_(), compiler_driver_(nullptr), - compiler_options_(nullptr), + compiler_options_(compiler_options), image_writer_(nullptr), - compiling_boot_image_(compiling_boot_image), extract_dex_files_into_vdex_(true), dex_files_(nullptr), vdex_size_(0u), @@ -649,8 +648,6 @@ bool OatWriter::MayHaveCompiledMethods() const { bool OatWriter::WriteAndOpenDexFiles( File* vdex_file, OutputStream* oat_rodata, - InstructionSet instruction_set, - const InstructionSetFeatures* instruction_set_features, SafeMap<std::string, std::string>* key_value_store, bool verify, bool update_input_vdex, @@ -672,9 +669,7 @@ bool OatWriter::WriteAndOpenDexFiles( // Reserve space for Vdex header and checksums. vdex_size_ = sizeof(VdexFile::VerifierDepsHeader) + oat_dex_files_.size() * sizeof(VdexFile::VdexChecksum); - oat_size_ = InitOatHeader(instruction_set, - instruction_set_features, - dchecked_integral_cast<uint32_t>(oat_dex_files_.size()), + oat_size_ = InitOatHeader(dchecked_integral_cast<uint32_t>(oat_dex_files_.size()), key_value_store); ChecksumUpdatingOutputStream checksum_updating_rodata(oat_rodata, oat_header_.get()); @@ -708,7 +703,6 @@ void OatWriter::Initialize(const CompilerDriver* compiler_driver, ImageWriter* image_writer, const std::vector<const DexFile*>& dex_files) { compiler_driver_ = compiler_driver; - compiler_options_ = &compiler_driver->GetCompilerOptions(); image_writer_ = image_writer; dex_files_ = &dex_files; } @@ -719,10 +713,10 @@ void OatWriter::PrepareLayout(MultiOatRelativePatcher* relative_patcher) { relative_patcher_ = relative_patcher; SetMultiOatRelativePatcherAdjustment(); - if (compiling_boot_image_) { + if (GetCompilerOptions().IsBootImage()) { CHECK(image_writer_ != nullptr); } - InstructionSet instruction_set = compiler_driver_->GetInstructionSet(); + InstructionSet instruction_set = compiler_options_.GetInstructionSet(); CHECK_EQ(instruction_set, oat_header_->GetInstructionSet()); { @@ -769,7 +763,7 @@ void OatWriter::PrepareLayout(MultiOatRelativePatcher* relative_patcher) { bss_start_ = (bss_size_ != 0u) ? RoundUp(oat_size_, kPageSize) : 0u; CHECK_EQ(dex_files_->size(), oat_dex_files_.size()); - if (compiling_boot_image_) { + if (GetCompilerOptions().IsBootImage()) { CHECK_EQ(image_writer_ != nullptr, oat_header_->GetStoreValueByKey(OatHeader::kImageLocationKey) == nullptr); } @@ -1551,7 +1545,7 @@ class OatWriter::InitImageMethodVisitor : public OatDexMethodVisitor { size_t offset, const std::vector<const DexFile*>* dex_files) : OatDexMethodVisitor(writer, offset), - pointer_size_(GetInstructionSetPointerSize(writer_->compiler_driver_->GetInstructionSet())), + pointer_size_(GetInstructionSetPointerSize(writer_->compiler_options_.GetInstructionSet())), class_loader_(writer->HasImage() ? writer->image_writer_->GetClassLoader() : nullptr), dex_files_(dex_files), class_linker_(Runtime::Current()->GetClassLinker()) {} @@ -1619,7 +1613,7 @@ class OatWriter::InitImageMethodVisitor : public OatDexMethodVisitor { Thread* self = Thread::Current(); ObjPtr<mirror::DexCache> dex_cache = class_linker_->FindDexCache(self, *dex_file_); ArtMethod* method; - if (writer_->HasBootImage()) { + if (writer_->GetCompilerOptions().IsBootImage()) { const InvokeType invoke_type = it.GetMethodInvokeType( dex_file_->GetClassDef(class_def_index_)); // Unchecked as we hold mutator_lock_ on entry. @@ -1702,7 +1696,7 @@ class OatWriter::WriteCodeMethodVisitor : public OrderedMethodVisitor { writer_(writer), offset_(relative_offset), dex_file_(nullptr), - pointer_size_(GetInstructionSetPointerSize(writer_->compiler_driver_->GetInstructionSet())), + pointer_size_(GetInstructionSetPointerSize(writer_->compiler_options_.GetInstructionSet())), class_loader_(writer->HasImage() ? writer->image_writer_->GetClassLoader() : nullptr), out_(out), file_offset_(file_offset), @@ -1710,7 +1704,7 @@ class OatWriter::WriteCodeMethodVisitor : public OrderedMethodVisitor { dex_cache_(nullptr), no_thread_suspension_("OatWriter patching") { patched_code_.reserve(16 * KB); - if (writer_->HasBootImage()) { + if (writer_->GetCompilerOptions().IsBootImage()) { // If we're creating the image, the address space must be ready so that we can apply patches. CHECK(writer_->image_writer_->IsImageAddressSpaceReady()); } @@ -1958,7 +1952,7 @@ class OatWriter::WriteCodeMethodVisitor : public OrderedMethodVisitor { const void* oat_code_offset = target->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size_); if (oat_code_offset != 0) { - DCHECK(!writer_->HasBootImage()); + DCHECK(!writer_->GetCompilerOptions().IsBootImage()); DCHECK(!Runtime::Current()->GetClassLinker()->IsQuickResolutionStub(oat_code_offset)); DCHECK(!Runtime::Current()->GetClassLinker()->IsQuickToInterpreterBridge(oat_code_offset)); DCHECK(!Runtime::Current()->GetClassLinker()->IsQuickGenericJniStub(oat_code_offset)); @@ -1995,13 +1989,13 @@ class OatWriter::WriteCodeMethodVisitor : public OrderedMethodVisitor { ObjPtr<mirror::String> string = linker->LookupString(patch.TargetStringIndex(), GetDexCache(patch.TargetStringDexFile())); DCHECK(string != nullptr); - DCHECK(writer_->HasBootImage() || + DCHECK(writer_->GetCompilerOptions().IsBootImage() || Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(string)); return string; } uint32_t GetTargetMethodOffset(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) { - DCHECK(writer_->HasBootImage()); + DCHECK(writer_->GetCompilerOptions().IsBootImage()); method = writer_->image_writer_->GetImageMethodAddress(method); size_t oat_index = writer_->image_writer_->GetOatIndexForDexFile(dex_file_); uintptr_t oat_data_begin = writer_->image_writer_->GetOatDataBegin(oat_index); @@ -2011,7 +2005,7 @@ class OatWriter::WriteCodeMethodVisitor : public OrderedMethodVisitor { uint32_t GetTargetObjectOffset(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_) { - DCHECK(writer_->HasBootImage()); + DCHECK(writer_->GetCompilerOptions().IsBootImage()); object = writer_->image_writer_->GetImageAddress(object.Ptr()); size_t oat_index = writer_->image_writer_->GetOatIndexForDexFile(dex_file_); uintptr_t oat_data_begin = writer_->image_writer_->GetOatDataBegin(oat_index); @@ -2021,7 +2015,7 @@ class OatWriter::WriteCodeMethodVisitor : public OrderedMethodVisitor { void PatchObjectAddress(std::vector<uint8_t>* code, uint32_t offset, mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_) { - if (writer_->HasBootImage()) { + if (writer_->GetCompilerOptions().IsBootImage()) { object = writer_->image_writer_->GetImageAddress(object); } else { // NOTE: We're using linker patches for app->boot references when the image can @@ -2042,7 +2036,7 @@ class OatWriter::WriteCodeMethodVisitor : public OrderedMethodVisitor { void PatchCodeAddress(std::vector<uint8_t>* code, uint32_t offset, uint32_t target_offset) REQUIRES_SHARED(Locks::mutator_lock_) { uint32_t address = target_offset; - if (writer_->HasBootImage()) { + if (writer_->GetCompilerOptions().IsBootImage()) { size_t oat_index = writer_->image_writer_->GetOatIndexForDexCache(dex_cache_); // TODO: Clean up offset types. // The target_offset must be treated as signed for cross-oat patching. @@ -2212,13 +2206,11 @@ bool OatWriter::VisitDexMethods(DexMethodVisitor* visitor) { return true; } -size_t OatWriter::InitOatHeader(InstructionSet instruction_set, - const InstructionSetFeatures* instruction_set_features, - uint32_t num_dex_files, +size_t OatWriter::InitOatHeader(uint32_t num_dex_files, SafeMap<std::string, std::string>* key_value_store) { TimingLogger::ScopedTiming split("InitOatHeader", timings_); - oat_header_.reset(OatHeader::Create(instruction_set, - instruction_set_features, + oat_header_.reset(OatHeader::Create(GetCompilerOptions().GetInstructionSet(), + GetCompilerOptions().GetInstructionSetFeatures(), num_dex_files, key_value_store)); size_oat_header_ += sizeof(OatHeader); @@ -2399,7 +2391,7 @@ size_t OatWriter::InitOatCode(size_t offset) { oat_header_->SetInterpreterToInterpreterBridgeOffset(0); oat_header_->SetInterpreterToCompiledCodeBridgeOffset(0); if (GetCompilerOptions().IsBootImage()) { - InstructionSet instruction_set = compiler_driver_->GetInstructionSet(); + InstructionSet instruction_set = compiler_options_.GetInstructionSet(); const bool generate_debug_info = GetCompilerOptions().GenerateAnyDebugInfo(); size_t adjusted_offset = offset; @@ -2522,7 +2514,7 @@ void OatWriter::InitBssLayout(InstructionSet instruction_set) { } DCHECK_EQ(bss_size_, 0u); - if (HasBootImage()) { + if (GetCompilerOptions().IsBootImage()) { DCHECK(bss_string_entries_.empty()); } if (bss_method_entries_.empty() && @@ -3294,7 +3286,7 @@ size_t OatWriter::WriteOatDexFiles(OutputStream* out, size_t file_offset, size_t size_t OatWriter::WriteCode(OutputStream* out, size_t file_offset, size_t relative_offset) { if (GetCompilerOptions().IsBootImage()) { - InstructionSet instruction_set = compiler_driver_->GetInstructionSet(); + InstructionSet instruction_set = compiler_options_.GetInstructionSet(); #define DO_TRAMPOLINE(field) \ do { \ @@ -3652,7 +3644,7 @@ bool OatWriter::LayoutAndWriteDexFile(OutputStream* out, OatDexFile* oat_dex_fil dex_file = dex_file_loader.Open(location, zip_entry->GetCrc32(), std::move(mem_map), - /* verify */ !compiling_boot_image_, + /* verify */ !GetCompilerOptions().IsBootImage(), /* verify_checksum */ true, &error_msg); } else if (oat_dex_file->source_.IsRawFile()) { @@ -3664,7 +3656,7 @@ bool OatWriter::LayoutAndWriteDexFile(OutputStream* out, OatDexFile* oat_dex_fil } TimingLogger::ScopedTiming extract("Open", timings_); dex_file = dex_file_loader.OpenDex(dup_fd, location, - /* verify */ !compiling_boot_image_, + /* verify */ !GetCompilerOptions().IsBootImage(), /* verify_checksum */ true, /* mmap_shared */ false, &error_msg); diff --git a/dex2oat/linker/oat_writer.h b/dex2oat/linker/oat_writer.h index ccafe05544..63fe57fd18 100644 --- a/dex2oat/linker/oat_writer.h +++ b/dex2oat/linker/oat_writer.h @@ -119,7 +119,7 @@ class OatWriter { kDefault = kCreate }; - OatWriter(bool compiling_boot_image, + OatWriter(const CompilerOptions& compiler_options, TimingLogger* timings, ProfileCompilationInfo* info, CompactDexLevel compact_dex_level); @@ -173,8 +173,6 @@ class OatWriter { // and the compiler will just re-use the existing vdex file. bool WriteAndOpenDexFiles(File* vdex_file, OutputStream* oat_rodata, - InstructionSet instruction_set, - const InstructionSetFeatures* instruction_set_features, SafeMap<std::string, std::string>* key_value_store, bool verify, bool update_input_vdex, @@ -212,10 +210,6 @@ class OatWriter { return image_writer_ != nullptr; } - bool HasBootImage() const { - return compiling_boot_image_; - } - const OatHeader& GetOatHeader() const { return *oat_header_; } @@ -261,8 +255,7 @@ class OatWriter { } const CompilerOptions& GetCompilerOptions() const { - DCHECK(compiler_options_ != nullptr); - return *compiler_options_; + return compiler_options_; } private: @@ -327,10 +320,7 @@ class OatWriter { /*out*/ std::vector<std::unique_ptr<MemMap>>* opened_dex_files_map, /*out*/ std::vector<std::unique_ptr<const DexFile>>* opened_dex_files); - size_t InitOatHeader(InstructionSet instruction_set, - const InstructionSetFeatures* instruction_set_features, - uint32_t num_dex_files, - SafeMap<std::string, std::string>* key_value_store); + size_t InitOatHeader(uint32_t num_dex_files, SafeMap<std::string, std::string>* key_value_store); size_t InitClassOffsets(size_t offset); size_t InitOatClasses(size_t offset); size_t InitOatMaps(size_t offset); @@ -390,9 +380,8 @@ class OatWriter { dchecked_vector<debug::MethodDebugInfo> method_info_; const CompilerDriver* compiler_driver_; - const CompilerOptions* compiler_options_; + const CompilerOptions& compiler_options_; ImageWriter* image_writer_; - const bool compiling_boot_image_; // Whether the dex files being compiled are going to be extracted to the vdex. bool extract_dex_files_into_vdex_; diff --git a/dex2oat/linker/oat_writer_test.cc b/dex2oat/linker/oat_writer_test.cc index e43a7f3d0c..85eaa844d2 100644 --- a/dex2oat/linker/oat_writer_test.cc +++ b/dex2oat/linker/oat_writer_test.cc @@ -86,33 +86,17 @@ class OatTest : public CommonCompilerTest { } } - void SetupCompiler(Compiler::Kind compiler_kind, - InstructionSet insn_set, - const std::vector<std::string>& compiler_options, - /*out*/std::string* error_msg) { - ASSERT_TRUE(error_msg != nullptr); - insn_features_ = InstructionSetFeatures::FromVariant(insn_set, "default", error_msg); - ASSERT_TRUE(insn_features_ != nullptr) << *error_msg; - compiler_options_.reset(new CompilerOptions); + void SetupCompiler(const std::vector<std::string>& compiler_options) { + std::string error_msg; if (!compiler_options_->ParseCompilerOptions(compiler_options, false /* ignore_unrecognized */, - error_msg)) { - LOG(FATAL) << *error_msg; + &error_msg)) { + LOG(FATAL) << error_msg; UNREACHABLE(); } - verification_results_.reset(new VerificationResults(compiler_options_.get())); callbacks_.reset(new QuickCompilerCallbacks(CompilerCallbacks::CallbackMode::kCompileApp)); callbacks_->SetVerificationResults(verification_results_.get()); Runtime::Current()->SetCompilerCallbacks(callbacks_.get()); - compiler_driver_.reset(new CompilerDriver(compiler_options_.get(), - verification_results_.get(), - compiler_kind, - insn_set, - insn_features_.get(), - /* image_classes */ nullptr, - /* thread_count */ 2, - /* swap_fd */ -1, - /* profile_compilation_info */ nullptr)); } bool WriteElf(File* vdex_file, @@ -121,7 +105,8 @@ class OatTest : public CommonCompilerTest { SafeMap<std::string, std::string>& key_value_store, bool verify) { TimingLogger timings("WriteElf", false, false); - OatWriter oat_writer(/*compiling_boot_image*/false, + ClearBootImageOption(); + OatWriter oat_writer(*compiler_options_, &timings, /*profile_compilation_info*/nullptr, CompactDexLevel::kCompactDexLevelNone); @@ -145,7 +130,8 @@ class OatTest : public CommonCompilerTest { bool verify, ProfileCompilationInfo* profile_compilation_info) { TimingLogger timings("WriteElf", false, false); - OatWriter oat_writer(/*compiling_boot_image*/false, + ClearBootImageOption(); + OatWriter oat_writer(*compiler_options_, &timings, profile_compilation_info, CompactDexLevel::kCompactDexLevelNone); @@ -164,7 +150,8 @@ class OatTest : public CommonCompilerTest { SafeMap<std::string, std::string>& key_value_store, bool verify) { TimingLogger timings("WriteElf", false, false); - OatWriter oat_writer(/*compiling_boot_image*/false, + ClearBootImageOption(); + OatWriter oat_writer(*compiler_options_, &timings, /*profile_compilation_info*/nullptr, CompactDexLevel::kCompactDexLevelNone); @@ -180,9 +167,7 @@ class OatTest : public CommonCompilerTest { SafeMap<std::string, std::string>& key_value_store, bool verify) { std::unique_ptr<ElfWriter> elf_writer = CreateElfWriterQuick( - compiler_driver_->GetInstructionSet(), - compiler_driver_->GetInstructionSetFeatures(), - &compiler_driver_->GetCompilerOptions(), + compiler_driver_->GetCompilerOptions(), oat_file); elf_writer->Start(); OutputStream* oat_rodata = elf_writer->StartRoData(); @@ -191,8 +176,6 @@ class OatTest : public CommonCompilerTest { if (!oat_writer.WriteAndOpenDexFiles( vdex_file, oat_rodata, - compiler_driver_->GetInstructionSet(), - compiler_driver_->GetInstructionSetFeatures(), &key_value_store, verify, /* update_input_vdex */ false, @@ -210,8 +193,8 @@ class OatTest : public CommonCompilerTest { ScopedObjectAccess soa(Thread::Current()); class_linker->RegisterDexFile(*dex_file, nullptr); } - MultiOatRelativePatcher patcher(compiler_driver_->GetInstructionSet(), - instruction_set_features_.get(), + MultiOatRelativePatcher patcher(compiler_options_->GetInstructionSet(), + compiler_options_->GetInstructionSetFeatures(), compiler_driver_->GetCompiledMethodStorage()); oat_writer.Initialize(compiler_driver_.get(), nullptr, dex_files); oat_writer.PrepareLayout(&patcher); @@ -278,7 +261,6 @@ class OatTest : public CommonCompilerTest { void TestZipFileInput(bool verify); void TestZipFileInputWithEmptyDex(); - std::unique_ptr<const InstructionSetFeatures> insn_features_; std::unique_ptr<QuickCompilerCallbacks> callbacks_; std::vector<std::unique_ptr<MemMap>> opened_dex_files_maps_; @@ -400,11 +382,8 @@ TEST_F(OatTest, WriteRead) { TimingLogger timings("OatTest::WriteRead", false, false); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - // TODO: make selectable. - Compiler::Kind compiler_kind = Compiler::kQuick; - InstructionSet insn_set = kIsTargetBuild ? InstructionSet::kThumb2 : InstructionSet::kX86; std::string error_msg; - SetupCompiler(compiler_kind, insn_set, std::vector<std::string>(), /*out*/ &error_msg); + SetupCompiler(std::vector<std::string>()); jobject class_loader = nullptr; if (kCompile) { @@ -524,14 +503,9 @@ TEST_F(OatTest, OatHeaderIsValid) { TEST_F(OatTest, EmptyTextSection) { TimingLogger timings("OatTest::EmptyTextSection", false, false); - // TODO: make selectable. - Compiler::Kind compiler_kind = Compiler::kQuick; - InstructionSet insn_set = kRuntimeISA; - if (insn_set == InstructionSet::kArm) insn_set = InstructionSet::kThumb2; - std::string error_msg; std::vector<std::string> compiler_options; compiler_options.push_back("--compiler-filter=extract"); - SetupCompiler(compiler_kind, insn_set, compiler_options, /*out*/ &error_msg); + SetupCompiler(compiler_options); jobject class_loader; { @@ -560,6 +534,7 @@ TEST_F(OatTest, EmptyTextSection) { /* verify */ false); ASSERT_TRUE(success); + std::string error_msg; std::unique_ptr<OatFile> oat_file(OatFile::Open(/* zip_fd */ -1, tmp_oat.GetFilename(), tmp_oat.GetFilename(), diff --git a/dex2oat/linker/relative_patcher_test.h b/dex2oat/linker/relative_patcher_test.h index b4123eea3e..b913c7c827 100644 --- a/dex2oat/linker/relative_patcher_test.h +++ b/dex2oat/linker/relative_patcher_test.h @@ -22,6 +22,7 @@ #include "base/array_ref.h" #include "base/globals.h" #include "base/macros.h" +#include "common_compiler_test.h" #include "compiled_method-inl.h" #include "dex/verification_results.h" #include "dex/method_reference.h" @@ -38,38 +39,39 @@ namespace art { namespace linker { // Base class providing infrastructure for architecture-specific tests. -class RelativePatcherTest : public testing::Test { +class RelativePatcherTest : public CommonCompilerTest { protected: RelativePatcherTest(InstructionSet instruction_set, const std::string& variant) - : compiler_options_(), - verification_results_(&compiler_options_), - driver_(&compiler_options_, - &verification_results_, - Compiler::kQuick, - instruction_set, - /* instruction_set_features*/ nullptr, - /* image_classes */ nullptr, - /* thread_count */ 1u, - /* swap_fd */ -1, - /* profile_compilation_info */ nullptr), - error_msg_(), - instruction_set_(instruction_set), - features_(InstructionSetFeatures::FromVariant(instruction_set, variant, &error_msg_)), + : variant_(variant), method_offset_map_(), - patcher_(RelativePatcher::Create(instruction_set, - features_.get(), - &thunk_provider_, - &method_offset_map_)), + patcher_(nullptr), bss_begin_(0u), compiled_method_refs_(), compiled_methods_(), patched_code_(), output_(), out_("test output stream", &output_) { - CHECK(error_msg_.empty()) << instruction_set << "/" << variant; + // Override CommonCompilerTest's defaults. + instruction_set_ = instruction_set; + number_of_threads_ = 1u; patched_code_.reserve(16 * KB); } + void SetUp() OVERRIDE { + OverrideInstructionSetFeatures(instruction_set_, variant_); + CommonCompilerTest::SetUp(); + + patcher_ = RelativePatcher::Create(compiler_options_->GetInstructionSet(), + compiler_options_->GetInstructionSetFeatures(), + &thunk_provider_, + &method_offset_map_); + } + + void TearDown() OVERRIDE { + patcher_.reset(); + CommonCompilerTest::TearDown(); + } + MethodReference MethodRef(uint32_t method_idx) { CHECK_NE(method_idx, 0u); return MethodReference(nullptr, method_idx); @@ -81,7 +83,7 @@ class RelativePatcherTest : public testing::Test { const ArrayRef<const LinkerPatch>& patches = ArrayRef<const LinkerPatch>()) { compiled_method_refs_.push_back(method_ref); compiled_methods_.emplace_back(new CompiledMethod( - &driver_, + compiler_driver_.get(), instruction_set_, code, /* frame_size_in_bytes */ 0u, @@ -333,12 +335,7 @@ class RelativePatcherTest : public testing::Test { static const uint32_t kTrampolineSize = 4u; static const uint32_t kTrampolineOffset = 0u; - CompilerOptions compiler_options_; - VerificationResults verification_results_; - CompilerDriver driver_; // Needed for constructing CompiledMethod. - std::string error_msg_; - InstructionSet instruction_set_; - std::unique_ptr<const InstructionSetFeatures> features_; + std::string variant_; ThunkProvider thunk_provider_; MethodOffsetMap method_offset_map_; std::unique_ptr<RelativePatcher> patcher_; |