diff options
| author | Mathieu Chartier <mathieuc@google.com> | 2018-10-15 09:44:35 -0700 |
|---|---|---|
| committer | Mathieu Chartier <mathieuc@google.com> | 2018-10-16 13:13:26 -0700 |
| commit | cd0f38fcbda3e578ac27e483a1ffb7718f83fb7a (patch) | |
| tree | 5a8a89ca8cb04ae22d2c43aff38ab50717801581 /compiler/driver | |
| parent | 8677e4bd3a091588c3b8058439f7022edab57f6e (diff) | |
| download | art-cd0f38fcbda3e578ac27e483a1ffb7718f83fb7a.tar.gz art-cd0f38fcbda3e578ac27e483a1ffb7718f83fb7a.tar.bz2 art-cd0f38fcbda3e578ac27e483a1ffb7718f83fb7a.zip | |
Add logic to eagerly resolve const-string for startup methods
Added dex2oat option --resolve-startup-const-strings=<true|false>
If true, this option causes the compiler driver to resolve all
const-strings that are referenced from methods marked as "startup" in
the profile.
Bug: 116059983
Test: test-art-host
Change-Id: I61cf9e945c125671fc4ab4b50458a911318a837f
Diffstat (limited to 'compiler/driver')
| -rw-r--r-- | compiler/driver/compiler_driver.cc | 18 | ||||
| -rw-r--r-- | compiler/driver/compiler_driver.h | 6 | ||||
| -rw-r--r-- | compiler/driver/compiler_options.cc | 1 | ||||
| -rw-r--r-- | compiler/driver/compiler_options.h | 8 | ||||
| -rw-r--r-- | compiler/driver/compiler_options_map-inl.h | 6 | ||||
| -rw-r--r-- | compiler/driver/compiler_options_map.def | 3 |
6 files changed, 36 insertions, 6 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index c5416d5a3d..89ac308fed 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -708,9 +708,9 @@ void CompilerDriver::Resolve(jobject class_loader, } } -static void ResolveConstStrings(CompilerDriver* driver, - const std::vector<const DexFile*>& dex_files, - TimingLogger* timings) { +void CompilerDriver::ResolveConstStrings(const std::vector<const DexFile*>& dex_files, + bool only_startup_strings, + TimingLogger* timings) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<1> hs(soa.Self()); ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); @@ -721,12 +721,18 @@ static void ResolveConstStrings(CompilerDriver* driver, TimingLogger::ScopedTiming t("Resolve const-string Strings", timings); for (ClassAccessor accessor : dex_file->GetClasses()) { - if (!driver->IsClassToCompile(accessor.GetDescriptor())) { + if (!IsClassToCompile(accessor.GetDescriptor())) { // Compilation is skipped, do not resolve const-string in code of this class. // FIXME: Make sure that inlining honors this. b/26687569 continue; } for (const ClassAccessor::Method& method : accessor.GetMethods()) { + if (only_startup_strings && + profile_compilation_info_ != nullptr && + !profile_compilation_info_->GetMethodHotness(method.GetReference()).IsStartup()) { + continue; + } + // Resolve const-strings in the code. Done to have deterministic allocation behavior. Right // now this is single-threaded for simplicity. // TODO: Collect the relevant string indices in parallel, then allocate them sequentially @@ -897,8 +903,10 @@ void CompilerDriver::PreCompile(jobject class_loader, if (GetCompilerOptions().IsForceDeterminism() && GetCompilerOptions().IsBootImage()) { // Resolve strings from const-string. Do this now to have a deterministic image. - ResolveConstStrings(this, dex_files, timings); + ResolveConstStrings(dex_files, /*only_startup_strings=*/ false, timings); VLOG(compiler) << "Resolve const-strings: " << GetMemoryUsageString(false); + } else if (GetCompilerOptions().ResolveStartupConstStrings()) { + ResolveConstStrings(dex_files, /*only_startup_strings=*/ true, timings); } Verify(class_loader, dex_files, timings); diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index 343f67c6d5..9a83e55c96 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -430,6 +430,12 @@ class CompilerDriver { typedef AtomicDexRefMap<MethodReference, CompiledMethod*> MethodTable; private: + // Resolve const string literals that are loaded from dex code. If only_startup_strings is + // specified, only methods that are marked startup in the profile are resolved. + void ResolveConstStrings(const std::vector<const DexFile*>& dex_files, + bool only_startup_strings, + /*inout*/ TimingLogger* timings); + // All method references that this compiler has compiled. MethodTable compiled_methods_; diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc index 3ab9afc5d6..6b0e45629b 100644 --- a/compiler/driver/compiler_options.cc +++ b/compiler/driver/compiler_options.cc @@ -69,6 +69,7 @@ CompilerOptions::CompilerOptions() force_determinism_(false), deduplicate_code_(true), count_hotness_in_compiled_code_(false), + resolve_startup_const_strings_(false), register_allocation_strategy_(RegisterAllocator::kRegisterAllocatorDefault), passes_to_run_(nullptr) { } diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h index e9cbf74428..4a6bbfaae6 100644 --- a/compiler/driver/compiler_options.h +++ b/compiler/driver/compiler_options.h @@ -313,6 +313,10 @@ class CompilerOptions final { return count_hotness_in_compiled_code_; } + bool ResolveStartupConstStrings() const { + return resolve_startup_const_strings_; + } + private: bool ParseDumpInitFailures(const std::string& option, std::string* error_msg); void ParseDumpCfgPasses(const StringPiece& option, UsageFn Usage); @@ -392,6 +396,10 @@ class CompilerOptions final { // won't be atomic for performance reasons, so we accept races, just like in interpreter. bool count_hotness_in_compiled_code_; + // Whether we eagerly resolve all of the const strings that are loaded from startup methods in the + // profile. + bool resolve_startup_const_strings_; + RegisterAllocator::Strategy register_allocation_strategy_; // If not null, specifies optimization passes which will be run instead of defaults. diff --git a/compiler/driver/compiler_options_map-inl.h b/compiler/driver/compiler_options_map-inl.h index d4a582fb35..5a844959c4 100644 --- a/compiler/driver/compiler_options_map-inl.h +++ b/compiler/driver/compiler_options_map-inl.h @@ -80,6 +80,7 @@ inline bool ReadCompilerOptions(Base& map, CompilerOptions* options, std::string if (map.Exists(Base::CountHotnessInCompiledCode)) { options->count_hotness_in_compiled_code_ = true; } + map.AssignIfExists(Base::ResolveStartupConstStrings, &options->resolve_startup_const_strings_); if (map.Exists(Base::DumpTimings)) { options->dump_timings_ = true; @@ -184,6 +185,11 @@ inline void AddCompilerOptionsArgumentParserOptions(Builder& b) { .template WithType<std::string>() .IntoKey(Map::RegisterAllocationStrategy) + .Define("--resolve-startup-const-strings=_") + .template WithType<bool>() + .WithValueMap({{"false", false}, {"true", true}}) + .IntoKey(Map::ResolveStartupConstStrings) + .Define("--verbose-methods=_") .template WithType<ParseStringList<','>>() .IntoKey(Map::VerboseMethods); diff --git a/compiler/driver/compiler_options_map.def b/compiler/driver/compiler_options_map.def index 238cd465df..a593240365 100644 --- a/compiler/driver/compiler_options_map.def +++ b/compiler/driver/compiler_options_map.def @@ -52,13 +52,14 @@ COMPILER_OPTIONS_KEY (Unit, Baseline) COMPILER_OPTIONS_KEY (double, TopKProfileThreshold) COMPILER_OPTIONS_KEY (bool, AbortOnHardVerifierFailure) COMPILER_OPTIONS_KEY (bool, AbortOnSoftVerifierFailure) +COMPILER_OPTIONS_KEY (bool, ResolveStartupConstStrings, false) COMPILER_OPTIONS_KEY (std::string, DumpInitFailures) COMPILER_OPTIONS_KEY (std::string, DumpCFG) COMPILER_OPTIONS_KEY (Unit, DumpCFGAppend) // TODO: Add type parser. COMPILER_OPTIONS_KEY (std::string, RegisterAllocationStrategy) COMPILER_OPTIONS_KEY (ParseStringList<','>, VerboseMethods) -COMPILER_OPTIONS_KEY (bool, DeduplicateCode, true) +COMPILER_OPTIONS_KEY (bool, DeduplicateCode, true) COMPILER_OPTIONS_KEY (Unit, CountHotnessInCompiledCode) COMPILER_OPTIONS_KEY (Unit, DumpTimings) COMPILER_OPTIONS_KEY (Unit, DumpPassTimings) |
