ART: Clean up less in dex2oat
In non-debug builds, clean up even less. We already did not shut
down the runtime. Also skipping the compiler driver and the
verification results removes all major points of destructor
performance.
Tested with a common large app on Nexus 9. Time between dex2oat timing
message and executable exit (log from immediately-after log echo)
[w/o swap, w/ swap].
Before: 2.409s / 48.774s
After: 0.132s / 0.188s
Bug: 24199200
Change-Id: I5d8c17f8e28796545cfbb3887c07c92905f9b48d
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 8cbca0b..6cc9903 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -504,6 +504,7 @@
compiler_kind_(kUseOptimizingCompiler ? Compiler::kOptimizing : Compiler::kQuick),
instruction_set_(kRuntimeISA),
// Take the default set of instruction features from the build.
+ verification_results_(nullptr),
method_inliner_map_(),
runtime_(nullptr),
thread_count_(sysconf(_SC_NPROCESSORS_CONF)),
@@ -519,6 +520,7 @@
compiled_methods_filename_(nullptr),
image_(false),
is_host_(false),
+ driver_(nullptr),
dump_stats_(false),
dump_passes_(false),
dump_timing_(false),
@@ -539,6 +541,8 @@
if (kIsDebugBuild || (RUNNING_ON_MEMORY_TOOL && kMemoryToolDetectsLeaks)) {
delete runtime_; // See field declaration for why this is manual.
+ delete driver_;
+ delete verification_results_;
}
}
@@ -1240,9 +1244,9 @@
runtime_options.push_back(std::make_pair(runtime_args_[i], nullptr));
}
- verification_results_.reset(new VerificationResults(compiler_options_.get()));
+ verification_results_ = new VerificationResults(compiler_options_.get());
callbacks_.reset(new QuickCompilerCallbacks(
- verification_results_.get(),
+ verification_results_,
&method_inliner_map_,
image_ ?
CompilerCallbacks::CallbackMode::kCompileBootImage :
@@ -1467,24 +1471,24 @@
class_loader = class_linker->CreatePathClassLoader(self, class_path_files);
}
- driver_.reset(new CompilerDriver(compiler_options_.get(),
- verification_results_.get(),
- &method_inliner_map_,
- compiler_kind_,
- instruction_set_,
- instruction_set_features_.get(),
- image_,
- image_classes_.release(),
- compiled_classes_.release(),
- nullptr,
- thread_count_,
- dump_stats_,
- dump_passes_,
- dump_cfg_file_name_,
- dump_cfg_append_,
- compiler_phases_timings_.get(),
- swap_fd_,
- profile_file_));
+ driver_ = new CompilerDriver(compiler_options_.get(),
+ verification_results_,
+ &method_inliner_map_,
+ compiler_kind_,
+ instruction_set_,
+ instruction_set_features_.get(),
+ image_,
+ image_classes_.release(),
+ compiled_classes_.release(),
+ nullptr,
+ thread_count_,
+ dump_stats_,
+ dump_passes_,
+ dump_cfg_file_name_,
+ dump_cfg_append_,
+ compiler_phases_timings_.get(),
+ swap_fd_,
+ profile_file_);
driver_->CompileAll(class_loader, dex_files_, timings_);
}
@@ -1586,7 +1590,7 @@
oat_writer.reset(new OatWriter(dex_files_, image_file_location_oat_checksum,
image_file_location_oat_data_begin,
image_patch_delta,
- driver_.get(),
+ driver_,
image_writer_.get(),
timings_,
key_value_store_.get()));
@@ -1926,7 +1930,7 @@
// Note: driver creation can fail when loading an invalid dex file.
LOG(INFO) << "dex2oat took " << PrettyDuration(NanoTime() - start_ns_)
<< " (threads: " << thread_count_ << ") "
- << ((Runtime::Current() != nullptr && driver_.get() != nullptr) ?
+ << ((Runtime::Current() != nullptr && driver_ != nullptr) ?
driver_->GetMemoryUsageString(kIsDebugBuild || VLOG_IS_ON(compiler)) :
"");
}
@@ -1939,7 +1943,10 @@
std::unique_ptr<SafeMap<std::string, std::string> > key_value_store_;
- std::unique_ptr<VerificationResults> verification_results_;
+ // Not a unique_ptr as we want to just exit on non-debug builds, not bringing the compiler down
+ // in an orderly fashion. The destructor takes care of deleting this.
+ VerificationResults* verification_results_;
+
DexFileToMethodInlinerMap method_inliner_map_;
std::unique_ptr<QuickCompilerCallbacks> callbacks_;
@@ -1983,7 +1990,11 @@
std::vector<const DexFile*> dex_files_;
std::vector<jobject> dex_caches_;
std::vector<std::unique_ptr<const DexFile>> opened_dex_files_;
- std::unique_ptr<CompilerDriver> driver_;
+
+ // Not a unique_ptr as we want to just exit on non-debug builds, not bringing the driver down
+ // in an orderly fashion. The destructor takes care of deleting this.
+ CompilerDriver* driver_;
+
std::vector<std::string> verbose_methods_;
bool dump_stats_;
bool dump_passes_;