Reduce how often we call FindDexCache
Before host boot.oat -j4 optimizing compile:
real 1m17.792s
user 3m26.140s
sys 0m8.340s
After:
real 1m12.324s
user 3m22.718s
sys 0m8.320s
Change-Id: If18e9e79e06cdf1676692e5efacb682bf93889c3
diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc
index 603130a..850cca0 100644
--- a/compiler/dex/dex_to_dex_compiler.cc
+++ b/compiler/dex/dex_to_dex_compiler.cc
@@ -324,9 +324,13 @@
DexToDexCompilationLevel dex_to_dex_compilation_level) {
DCHECK(driver != nullptr);
if (dex_to_dex_compilation_level != DexToDexCompilationLevel::kDontDexToDexCompile) {
- art::DexCompilationUnit unit(nullptr, class_loader, art::Runtime::Current()->GetClassLinker(),
+ ScopedObjectAccess soa(Thread::Current());
+ StackHandleScope<1> hs(soa.Self());
+ ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
+ art::DexCompilationUnit unit(nullptr, class_loader, class_linker,
dex_file, code_item, class_def_idx, method_idx, access_flags,
- driver->GetVerifiedMethod(&dex_file, method_idx));
+ driver->GetVerifiedMethod(&dex_file, method_idx),
+ hs.NewHandle(class_linker->FindDexCache(soa.Self(), dex_file)));
art::optimizer::DexCompiler dex_compiler(*driver, unit, dex_to_dex_compilation_level);
dex_compiler.Compile();
if (dex_compiler.GetQuickenedInfo().empty()) {
diff --git a/compiler/dex/mir_analysis.cc b/compiler/dex/mir_analysis.cc
index 1cff8dc..39f8ee8 100644
--- a/compiler/dex/mir_analysis.cc
+++ b/compiler/dex/mir_analysis.cc
@@ -30,6 +30,7 @@
#include "driver/compiler_driver.h"
#include "driver/compiler_options.h"
#include "driver/dex_compilation_unit.h"
+#include "scoped_thread_state_change.h"
#include "utils.h"
namespace art {
@@ -1283,8 +1284,12 @@
ifield_lowering_infos_.push_back(
MirIFieldLoweringInfo(masked_field_idx, field_types[pos], is_quickened));
}
- MirIFieldLoweringInfo::Resolve(cu_->compiler_driver, GetCurrentDexCompilationUnit(),
- ifield_lowering_infos_.data(), ifield_pos);
+ ScopedObjectAccess soa(Thread::Current());
+ MirIFieldLoweringInfo::Resolve(soa,
+ cu_->compiler_driver,
+ GetCurrentDexCompilationUnit(),
+ ifield_lowering_infos_.data(),
+ ifield_pos);
}
if (sfield_pos != max_refs) {
diff --git a/compiler/dex/mir_field_info.cc b/compiler/dex/mir_field_info.cc
index 4dfec17..13bbc3e 100644
--- a/compiler/dex/mir_field_info.cc
+++ b/compiler/dex/mir_field_info.cc
@@ -29,7 +29,8 @@
namespace art {
-void MirIFieldLoweringInfo::Resolve(CompilerDriver* compiler_driver,
+void MirIFieldLoweringInfo::Resolve(const ScopedObjectAccess& soa,
+ CompilerDriver* compiler_driver,
const DexCompilationUnit* mUnit,
MirIFieldLoweringInfo* field_infos, size_t count) {
if (kIsDebugBuild) {
@@ -44,7 +45,6 @@
// We're going to resolve fields and check access in a tight loop. It's better to hold
// the lock and needed references once than re-acquiring them again and again.
- ScopedObjectAccess soa(Thread::Current());
StackHandleScope<3> hs(soa.Self());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(compiler_driver->GetDexCache(mUnit)));
Handle<mirror::ClassLoader> class_loader(
diff --git a/compiler/dex/mir_field_info.h b/compiler/dex/mir_field_info.h
index 053029d..b6dc27d 100644
--- a/compiler/dex/mir_field_info.h
+++ b/compiler/dex/mir_field_info.h
@@ -26,6 +26,7 @@
class CompilerDriver;
class DexCompilationUnit;
+class ScopedObjectAccess;
/*
* Field info is calculated from the perspective of the compilation unit that accesses
@@ -133,9 +134,12 @@
// For each requested instance field retrieve the field's declaring location (dex file, class
// index and field index) and volatility and compute whether we can fast path the access
// with IGET/IPUT. For fast path fields, retrieve the field offset.
- static void Resolve(CompilerDriver* compiler_driver, const DexCompilationUnit* mUnit,
- MirIFieldLoweringInfo* field_infos, size_t count)
- REQUIRES(!Locks::mutator_lock_);
+ static void Resolve(const ScopedObjectAccess& soa,
+ CompilerDriver* compiler_driver,
+ const DexCompilationUnit* mUnit,
+ MirIFieldLoweringInfo* field_infos,
+ size_t count)
+ SHARED_REQUIRES(Locks::mutator_lock_);
// Construct an unresolved instance field lowering info.
MirIFieldLoweringInfo(uint16_t field_idx, DexMemAccessType type, bool is_quickened)
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc
index 3834242..7976a9a 100644
--- a/compiler/dex/mir_graph.cc
+++ b/compiler/dex/mir_graph.cc
@@ -699,16 +699,17 @@
/* Parse a Dex method and insert it into the MIRGraph at the current insert point. */
void MIRGraph::InlineMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
InvokeType invoke_type ATTRIBUTE_UNUSED, uint16_t class_def_idx,
- uint32_t method_idx, jobject class_loader, const DexFile& dex_file) {
+ uint32_t method_idx, jobject class_loader, const DexFile& dex_file,
+ Handle<mirror::DexCache> dex_cache) {
current_code_item_ = code_item;
method_stack_.push_back(std::make_pair(current_method_, current_offset_));
current_method_ = m_units_.size();
current_offset_ = 0;
// TODO: will need to snapshot stack image and use that as the mir context identification.
m_units_.push_back(new (arena_) DexCompilationUnit(
- cu_, class_loader, Runtime::Current()->GetClassLinker(), dex_file,
- current_code_item_, class_def_idx, method_idx, access_flags,
- cu_->compiler_driver->GetVerifiedMethod(&dex_file, method_idx)));
+ cu_, class_loader, Runtime::Current()->GetClassLinker(), dex_file, current_code_item_,
+ class_def_idx, method_idx, access_flags,
+ cu_->compiler_driver->GetVerifiedMethod(&dex_file, method_idx), dex_cache));
const uint16_t* code_ptr = current_code_item_->insns_;
const uint16_t* code_end =
current_code_item_->insns_ + current_code_item_->insns_size_in_code_units_;
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index 8bf709a..a9ebe9c 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -572,9 +572,14 @@
* Parse dex method and add MIR at current insert point. Returns id (which is
* actually the index of the method in the m_units_ array).
*/
- void InlineMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
- InvokeType invoke_type, uint16_t class_def_idx,
- uint32_t method_idx, jobject class_loader, const DexFile& dex_file);
+ void InlineMethod(const DexFile::CodeItem* code_item,
+ uint32_t access_flags,
+ InvokeType invoke_type,
+ uint16_t class_def_idx,
+ uint32_t method_idx,
+ jobject class_loader,
+ const DexFile& dex_file,
+ Handle<mirror::DexCache> dex_cache);
/* Find existing block */
BasicBlock* FindBlock(DexOffset code_offset,
diff --git a/compiler/dex/mir_method_info.cc b/compiler/dex/mir_method_info.cc
index 31c3808..658e7d6 100644
--- a/compiler/dex/mir_method_info.cc
+++ b/compiler/dex/mir_method_info.cc
@@ -112,7 +112,8 @@
mUnit->GetCompilationUnit(), mUnit->GetClassLoader(), mUnit->GetClassLinker(),
*it->target_dex_file_, nullptr /* code_item not used */, 0u /* class_def_idx not used */,
it->target_method_idx_, 0u /* access_flags not used */,
- nullptr /* verified_method not used */);
+ nullptr /* verified_method not used */,
+ current_dex_cache);
resolved_method = compiler_driver->ResolveMethod(soa, current_dex_cache, class_loader, &cu,
it->target_method_idx_, invoke_type, false);
if (resolved_method == nullptr) {
diff --git a/compiler/dex/mir_optimization.cc b/compiler/dex/mir_optimization.cc
index 80b7ac1..eb4915b 100644
--- a/compiler/dex/mir_optimization.cc
+++ b/compiler/dex/mir_optimization.cc
@@ -17,6 +17,7 @@
#include "base/bit_vector-inl.h"
#include "base/logging.h"
#include "base/scoped_arena_containers.h"
+#include "class_linker-inl.h"
#include "dataflow_iterator-inl.h"
#include "dex/verified_method.h"
#include "dex_flags.h"
@@ -30,6 +31,7 @@
#include "quick/dex_file_method_inliner.h"
#include "quick/dex_file_to_method_inliner_map.h"
#include "stack.h"
+#include "thread-inl.h"
#include "type_inference.h"
#include "utils.h"
@@ -1469,13 +1471,23 @@
const MirMethodLoweringInfo& method_info = GetMethodLoweringInfo(invoke);
MethodReference target = method_info.GetTargetMethod();
- DexCompilationUnit inlined_unit(
- cu_, cu_->class_loader, cu_->class_linker, *target.dex_file,
- nullptr /* code_item not used */, 0u /* class_def_idx not used */, target.dex_method_index,
- 0u /* access_flags not used */, nullptr /* verified_method not used */);
+ ScopedObjectAccess soa(Thread::Current());
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::DexCache> dex_cache(
+ hs.NewHandle(cu_->class_linker->FindDexCache(hs.Self(), *target.dex_file)));
+ DexCompilationUnit inlined_unit(cu_,
+ cu_->class_loader,
+ cu_->class_linker,
+ *target.dex_file,
+ nullptr /* code_item not used */,
+ 0u /* class_def_idx not used */,
+ target.dex_method_index,
+ 0u /* access_flags not used */,
+ nullptr /* verified_method not used */,
+ dex_cache);
DexMemAccessType type = IGetOrIPutMemAccessType(iget_or_iput->dalvikInsn.opcode);
MirIFieldLoweringInfo inlined_field_info(field_idx, type, false);
- MirIFieldLoweringInfo::Resolve(cu_->compiler_driver, &inlined_unit, &inlined_field_info, 1u);
+ MirIFieldLoweringInfo::Resolve(soa, cu_->compiler_driver, &inlined_unit, &inlined_field_info, 1u);
DCHECK(inlined_field_info.IsResolved());
uint32_t field_info_index = ifield_lowering_infos_.size();
diff --git a/compiler/dex/quick/quick_compiler.cc b/compiler/dex/quick/quick_compiler.cc
index 3642b82..b5ecf9c 100644
--- a/compiler/dex/quick/quick_compiler.cc
+++ b/compiler/dex/quick/quick_compiler.cc
@@ -663,7 +663,8 @@
uint16_t class_def_idx,
uint32_t method_idx,
jobject class_loader,
- const DexFile& dex_file) const {
+ const DexFile& dex_file,
+ Handle<mirror::DexCache> dex_cache) const {
if (kPoisonHeapReferences) {
VLOG(compiler) << "Skipping method : " << PrettyMethod(method_idx, dex_file)
<< " Reason = Quick does not support heap poisoning.";
@@ -749,7 +750,7 @@
/* Build the raw MIR graph */
cu.mir_graph->InlineMethod(code_item, access_flags, invoke_type, class_def_idx, method_idx,
- class_loader, dex_file);
+ class_loader, dex_file, dex_cache);
if (!CanCompileMethod(method_idx, dex_file, &cu)) {
VLOG(compiler) << cu.instruction_set << ": Cannot compile method : "
diff --git a/compiler/dex/quick/quick_compiler.h b/compiler/dex/quick/quick_compiler.h
index 4a39ab3..d512b25 100644
--- a/compiler/dex/quick/quick_compiler.h
+++ b/compiler/dex/quick/quick_compiler.h
@@ -21,6 +21,10 @@
namespace art {
+namespace mirror {
+class DexCache;
+}
+
class Compiler;
class CompilerDriver;
class Mir2Lir;
@@ -43,7 +47,8 @@
uint16_t class_def_idx,
uint32_t method_idx,
jobject class_loader,
- const DexFile& dex_file) const OVERRIDE;
+ const DexFile& dex_file,
+ Handle<mirror::DexCache> dex_cache) const OVERRIDE;
CompiledMethod* JniCompile(uint32_t access_flags,
uint32_t method_idx,
diff --git a/compiler/dex/type_inference_test.cc b/compiler/dex/type_inference_test.cc
index eaa2bfa..872a8d6 100644
--- a/compiler/dex/type_inference_test.cc
+++ b/compiler/dex/type_inference_test.cc
@@ -252,7 +252,8 @@
cu_.mir_graph->m_units_.push_back(new (cu_.mir_graph->arena_) DexCompilationUnit(
&cu_, cu_.class_loader, cu_.class_linker, *cu_.dex_file, nullptr /* code_item not used */,
0u /* class_def_idx not used */, 0u /* method_index not used */,
- cu_.access_flags, nullptr /* verified_method not used */));
+ cu_.access_flags, nullptr /* verified_method not used */,
+ NullHandle<mirror::DexCache>()));
cu_.mir_graph->current_method_ = 0u;
code_item_ = static_cast<DexFile::CodeItem*>(
cu_.arena.Alloc(sizeof(DexFile::CodeItem), kArenaAllocMisc));