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/compiler.h b/compiler/compiler.h
index 01ca46e..9b4dbe0 100644
--- a/compiler/compiler.h
+++ b/compiler/compiler.h
@@ -51,7 +51,8 @@
uint16_t class_def_idx,
uint32_t method_idx,
jobject class_loader,
- const DexFile& dex_file) const = 0;
+ const DexFile& dex_file,
+ Handle<mirror::DexCache> dex_cache) const = 0;
virtual CompiledMethod* JniCompile(uint32_t access_flags,
uint32_t method_idx,
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));
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h
index 8f1987a..e535afd 100644
--- a/compiler/driver/compiler_driver-inl.h
+++ b/compiler/driver/compiler_driver-inl.h
@@ -34,7 +34,7 @@
return mUnit->GetClassLinker()->FindDexCache(Thread::Current(), *mUnit->GetDexFile(), false);
}
-inline mirror::ClassLoader* CompilerDriver::GetClassLoader(ScopedObjectAccess& soa,
+inline mirror::ClassLoader* CompilerDriver::GetClassLoader(const ScopedObjectAccess& soa,
const DexCompilationUnit* mUnit) {
return soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader());
}
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 6d3a960..ded70cd 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -571,7 +571,8 @@
jobject class_loader,
const DexFile& dex_file,
optimizer::DexToDexCompilationLevel dex_to_dex_compilation_level,
- bool compilation_enabled)
+ bool compilation_enabled,
+ Handle<mirror::DexCache> dex_cache)
REQUIRES(!driver->compiled_methods_lock_) {
DCHECK(driver != nullptr);
CompiledMethod* compiled_method = nullptr;
@@ -608,7 +609,7 @@
// NOTE: if compiler declines to compile this method, it will return null.
compiled_method = driver->GetCompiler()->Compile(code_item, access_flags, invoke_type,
class_def_idx, method_idx, class_loader,
- dex_file);
+ dex_file, dex_cache);
}
if (compiled_method == nullptr &&
dex_to_dex_compilation_level != optimizer::DexToDexCompilationLevel::kDontDexToDexCompile) {
@@ -673,6 +674,8 @@
uint32_t method_idx = method->GetDexMethodIndex();
uint32_t access_flags = method->GetAccessFlags();
InvokeType invoke_type = method->GetInvokeType();
+ StackHandleScope<1> hs(self);
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
{
ScopedObjectAccessUnchecked soa(self);
ScopedLocalRef<jobject> local_class_loader(
@@ -683,6 +686,8 @@
class_def_idx = method->GetClassDefIndex();
}
const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset());
+
+ // Go to native so that we don't block GC during compilation.
self->TransitionFromRunnableToSuspended(kNative);
std::vector<const DexFile*> dex_files;
@@ -709,7 +714,8 @@
jclass_loader,
*dex_file,
dex_to_dex_compilation_level,
- true);
+ true,
+ dex_cache);
self->GetJniEnv()->DeleteGlobalRef(jclass_loader);
self->TransitionFromSuspendedToRunnable();
@@ -719,9 +725,10 @@
const uint32_t method_idx = method->GetDexMethodIndex();
const uint32_t access_flags = method->GetAccessFlags();
const InvokeType invoke_type = method->GetInvokeType();
- StackHandleScope<1> hs(self);
+ StackHandleScope<2> hs(self);
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
method->GetDeclaringClass()->GetClassLoader()));
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
jobject jclass_loader = class_loader.ToJObject();
const DexFile* dex_file = method->GetDexFile();
const uint16_t class_def_idx = method->GetClassDefIndex();
@@ -729,6 +736,7 @@
optimizer::DexToDexCompilationLevel dex_to_dex_compilation_level =
GetDexToDexCompilationLevel(self, *this, class_loader, *dex_file, class_def);
const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset());
+ // Go to native so that we don't block GC during compilation.
self->TransitionFromRunnableToSuspended(kNative);
CompileMethod(self,
this,
@@ -740,7 +748,8 @@
jclass_loader,
*dex_file,
dex_to_dex_compilation_level,
- true);
+ true,
+ dex_cache);
auto* compiled_method = GetCompiledMethod(MethodReference(dex_file, method_idx));
self->TransitionFromSuspendedToRunnable();
return compiled_method;
@@ -1422,24 +1431,19 @@
// Try to resolve the field and compiling method's class.
ArtField* resolved_field;
mirror::Class* referrer_class;
- mirror::DexCache* dex_cache;
+ Handle<mirror::DexCache> dex_cache(mUnit->GetDexCache());
{
- StackHandleScope<2> hs(soa.Self());
- Handle<mirror::DexCache> dex_cache_handle(
- hs.NewHandle(mUnit->GetClassLinker()->FindDexCache(
- soa.Self(), *mUnit->GetDexFile(), false)));
+ StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader_handle(
hs.NewHandle(soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())));
- resolved_field =
- ResolveField(soa, dex_cache_handle, class_loader_handle, mUnit, field_idx, false);
+ resolved_field = ResolveField(soa, dex_cache, class_loader_handle, mUnit, field_idx, false);
referrer_class = resolved_field != nullptr
- ? ResolveCompilingMethodsClass(soa, dex_cache_handle, class_loader_handle, mUnit) : nullptr;
- dex_cache = dex_cache_handle.Get();
+ ? ResolveCompilingMethodsClass(soa, dex_cache, class_loader_handle, mUnit) : nullptr;
}
bool can_link = false;
if (resolved_field != nullptr && referrer_class != nullptr) {
std::pair<bool, bool> fast_path = IsFastInstanceField(
- dex_cache, referrer_class, resolved_field, field_idx);
+ dex_cache.Get(), referrer_class, resolved_field, field_idx);
can_link = is_put ? fast_path.second : fast_path.first;
}
ProcessedInstanceField(can_link);
@@ -1473,25 +1477,21 @@
// Try to resolve the field and compiling method's class.
ArtField* resolved_field;
mirror::Class* referrer_class;
- mirror::DexCache* dex_cache;
+ Handle<mirror::DexCache> dex_cache(mUnit->GetDexCache());
{
- StackHandleScope<2> hs(soa.Self());
- Handle<mirror::DexCache> dex_cache_handle(
- hs.NewHandle(mUnit->GetClassLinker()->FindDexCache(
- soa.Self(), *mUnit->GetDexFile(), false)));
+ StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader_handle(
hs.NewHandle(soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())));
resolved_field =
- ResolveField(soa, dex_cache_handle, class_loader_handle, mUnit, field_idx, true);
+ ResolveField(soa, dex_cache, class_loader_handle, mUnit, field_idx, true);
referrer_class = resolved_field != nullptr
- ? ResolveCompilingMethodsClass(soa, dex_cache_handle, class_loader_handle, mUnit) : nullptr;
- dex_cache = dex_cache_handle.Get();
+ ? ResolveCompilingMethodsClass(soa, dex_cache, class_loader_handle, mUnit) : nullptr;
}
bool result = false;
if (resolved_field != nullptr && referrer_class != nullptr) {
*is_volatile = IsFieldVolatile(resolved_field);
std::pair<bool, bool> fast_path = IsFastStaticField(
- dex_cache, referrer_class, resolved_field, field_idx, storage_index);
+ dex_cache.Get(), referrer_class, resolved_field, field_idx, storage_index);
result = is_put ? fast_path.second : fast_path.first;
}
if (result) {
@@ -1662,10 +1662,8 @@
int stats_flags = 0;
ScopedObjectAccess soa(Thread::Current());
// Try to resolve the method and compiling method's class.
- StackHandleScope<3> hs(soa.Self());
- Handle<mirror::DexCache> dex_cache(
- hs.NewHandle(mUnit->GetClassLinker()->FindDexCache(
- soa.Self(), *mUnit->GetDexFile(), false)));
+ StackHandleScope<2> hs(soa.Self());
+ Handle<mirror::DexCache> dex_cache(mUnit->GetDexCache());
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())));
uint32_t method_idx = target_method->dex_method_index;
@@ -2353,39 +2351,44 @@
const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
ClassLinker* class_linker = manager_->GetClassLinker();
jobject jclass_loader = manager_->GetClassLoader();
- Thread* self = Thread::Current();
- {
- // Use a scoped object access to perform to the quick SkipClass check.
- const char* descriptor = dex_file.GetClassDescriptor(class_def);
- ScopedObjectAccess soa(self);
- StackHandleScope<3> hs(soa.Self());
- Handle<mirror::ClassLoader> class_loader(
- hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
- Handle<mirror::Class> klass(
- hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
- if (klass.Get() == nullptr) {
- CHECK(soa.Self()->IsExceptionPending());
- soa.Self()->ClearException();
- } else if (SkipClass(jclass_loader, dex_file, klass.Get())) {
- return;
- }
- }
ClassReference ref(&dex_file, class_def_index);
// Skip compiling classes with generic verifier failures since they will still fail at runtime
if (manager_->GetCompiler()->verification_results_->IsClassRejected(ref)) {
return;
}
+ // Use a scoped object access to perform to the quick SkipClass check.
+ const char* descriptor = dex_file.GetClassDescriptor(class_def);
+ ScopedObjectAccess soa(Thread::Current());
+ StackHandleScope<3> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader(
+ hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
+ Handle<mirror::Class> klass(
+ hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
+ Handle<mirror::DexCache> dex_cache;
+ if (klass.Get() == nullptr) {
+ soa.Self()->AssertPendingException();
+ soa.Self()->ClearException();
+ dex_cache = hs.NewHandle(class_linker->FindDexCache(soa.Self(), dex_file));
+ } else if (SkipClass(jclass_loader, dex_file, klass.Get())) {
+ return;
+ } else {
+ dex_cache = hs.NewHandle(klass->GetDexCache());
+ }
+
const uint8_t* class_data = dex_file.GetClassData(class_def);
if (class_data == nullptr) {
// empty class, probably a marker interface
return;
}
+ // Go to native so that we don't block GC during compilation.
+ soa.Self()->TransitionFromRunnableToSuspended(kNative);
+
CompilerDriver* const driver = manager_->GetCompiler();
// Can we run DEX-to-DEX compiler on this class ?
optimizer::DexToDexCompilationLevel dex_to_dex_compilation_level =
- GetDexToDexCompilationLevel(self, *driver, jclass_loader, dex_file, class_def);
+ GetDexToDexCompilationLevel(soa.Self(), *driver, jclass_loader, dex_file, class_def);
ClassDataItemIterator it(dex_file, class_data);
// Skip fields
@@ -2410,10 +2413,10 @@
continue;
}
previous_direct_method_idx = method_idx;
- CompileMethod(self, driver, it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
+ CompileMethod(soa.Self(), driver, it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
it.GetMethodInvokeType(class_def), class_def_index,
method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
- compilation_enabled);
+ compilation_enabled, dex_cache);
it.Next();
}
// Compile virtual methods
@@ -2427,13 +2430,15 @@
continue;
}
previous_virtual_method_idx = method_idx;
- CompileMethod(self, driver, it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
+ CompileMethod(soa.Self(), driver, it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
it.GetMethodInvokeType(class_def), class_def_index,
method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
- compilation_enabled);
+ compilation_enabled, dex_cache);
it.Next();
}
DCHECK(!it.HasNext());
+
+ soa.Self()->TransitionFromSuspendedToRunnable();
}
private:
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 5718be9..b229184 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -226,7 +226,8 @@
mirror::DexCache* GetDexCache(const DexCompilationUnit* mUnit)
SHARED_REQUIRES(Locks::mutator_lock_);
- mirror::ClassLoader* GetClassLoader(ScopedObjectAccess& soa, const DexCompilationUnit* mUnit)
+ mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa,
+ const DexCompilationUnit* mUnit)
SHARED_REQUIRES(Locks::mutator_lock_);
// Resolve compiling method's class. Returns null on failure.
diff --git a/compiler/driver/dex_compilation_unit.cc b/compiler/driver/dex_compilation_unit.cc
index e6c8c18..cfaa01b 100644
--- a/compiler/driver/dex_compilation_unit.cc
+++ b/compiler/driver/dex_compilation_unit.cc
@@ -18,6 +18,7 @@
#include "base/stringprintf.h"
#include "dex/compiler_ir.h"
+#include "mirror/dex_cache.h"
#include "utils.h"
namespace art {
@@ -30,7 +31,8 @@
uint16_t class_def_idx,
uint32_t method_idx,
uint32_t access_flags,
- const VerifiedMethod* verified_method)
+ const VerifiedMethod* verified_method,
+ Handle<mirror::DexCache> dex_cache)
: cu_(cu),
class_loader_(class_loader),
class_linker_(class_linker),
@@ -39,7 +41,8 @@
class_def_idx_(class_def_idx),
dex_method_idx_(method_idx),
access_flags_(access_flags),
- verified_method_(verified_method) {
+ verified_method_(verified_method),
+ dex_cache_(dex_cache) {
}
const std::string& DexCompilationUnit::GetSymbol() {
diff --git a/compiler/driver/dex_compilation_unit.h b/compiler/driver/dex_compilation_unit.h
index 3983006..16872f4 100644
--- a/compiler/driver/dex_compilation_unit.h
+++ b/compiler/driver/dex_compilation_unit.h
@@ -19,9 +19,10 @@
#include <stdint.h>
-#include "dex_file.h"
-#include "jni.h"
#include "base/arena_object.h"
+#include "dex_file.h"
+#include "handle.h"
+#include "jni.h"
namespace art {
namespace mirror {
@@ -36,10 +37,16 @@
public:
explicit DexCompilationUnit(CompilationUnit* cu);
- DexCompilationUnit(CompilationUnit* cu, jobject class_loader, ClassLinker* class_linker,
- const DexFile& dex_file, const DexFile::CodeItem* code_item,
- uint16_t class_def_idx, uint32_t method_idx, uint32_t access_flags,
- const VerifiedMethod* verified_method);
+ DexCompilationUnit(CompilationUnit* cu,
+ jobject class_loader,
+ ClassLinker* class_linker,
+ const DexFile& dex_file,
+ const DexFile::CodeItem* code_item,
+ uint16_t class_def_idx,
+ uint32_t method_idx,
+ uint32_t access_flags,
+ const VerifiedMethod* verified_method,
+ Handle<mirror::DexCache> dex_cache);
CompilationUnit* GetCompilationUnit() const {
return cu_;
@@ -109,6 +116,10 @@
const std::string& GetSymbol();
+ Handle<mirror::DexCache> GetDexCache() const {
+ return dex_cache_;
+ }
+
private:
CompilationUnit* const cu_;
@@ -124,6 +135,8 @@
const uint32_t access_flags_;
const VerifiedMethod* verified_method_;
+ Handle<mirror::DexCache> dex_cache_;
+
std::string symbol_;
};
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 23ab94e..1650fd1 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -1205,7 +1205,8 @@
resolved_field->GetOffset(),
resolved_field->IsVolatile(),
field_index,
- *dex_file_));
+ *dex_file_,
+ dex_compilation_unit_->GetDexCache()));
} else {
current_block_->AddInstruction(new (arena_) HInstanceFieldGet(
current_block_->GetLastInstruction(),
@@ -1213,7 +1214,8 @@
resolved_field->GetOffset(),
resolved_field->IsVolatile(),
field_index,
- *dex_file_));
+ *dex_file_,
+ dex_compilation_unit_->GetDexCache()));
UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction());
}
@@ -1334,14 +1336,16 @@
resolved_field->GetOffset(),
resolved_field->IsVolatile(),
field_index,
- *dex_file_));
+ *dex_file_,
+ dex_cache_));
} else {
current_block_->AddInstruction(new (arena_) HStaticFieldGet(cls,
field_type,
resolved_field->GetOffset(),
resolved_field->IsVolatile(),
field_index,
- *dex_file_));
+ *dex_file_,
+ dex_cache_));
UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction());
}
return true;
diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h
index d6b25ee..560ed86 100644
--- a/compiler/optimizing/builder.h
+++ b/compiler/optimizing/builder.h
@@ -40,7 +40,8 @@
const DexFile* dex_file,
CompilerDriver* driver,
OptimizingCompilerStats* compiler_stats,
- const uint8_t* interpreter_metadata)
+ const uint8_t* interpreter_metadata,
+ Handle<mirror::DexCache> dex_cache)
: arena_(graph->GetArena()),
branch_targets_(graph->GetArena(), 0),
locals_(graph->GetArena(), 0),
@@ -57,7 +58,8 @@
latest_result_(nullptr),
can_use_baseline_for_string_init_(true),
compilation_stats_(compiler_stats),
- interpreter_metadata_(interpreter_metadata) {}
+ interpreter_metadata_(interpreter_metadata),
+ dex_cache_(dex_cache) {}
// Only for unit testing.
HGraphBuilder(HGraph* graph, Primitive::Type return_type = Primitive::kPrimInt)
@@ -77,7 +79,8 @@
latest_result_(nullptr),
can_use_baseline_for_string_init_(true),
compilation_stats_(nullptr),
- interpreter_metadata_(nullptr) {}
+ interpreter_metadata_(nullptr),
+ dex_cache_(NullHandle<mirror::DexCache>()) {}
bool BuildGraph(const DexFile::CodeItem& code);
@@ -334,6 +337,9 @@
const uint8_t* interpreter_metadata_;
+ // Dex cache for dex_file_.
+ Handle<mirror::DexCache> dex_cache_;
+
DISALLOW_COPY_AND_ASSIGN(HGraphBuilder);
};
diff --git a/compiler/optimizing/gvn_test.cc b/compiler/optimizing/gvn_test.cc
index 42ef3ff..32f45b5 100644
--- a/compiler/optimizing/gvn_test.cc
+++ b/compiler/optimizing/gvn_test.cc
@@ -28,6 +28,7 @@
TEST(GVNTest, LocalFieldElimination) {
ArenaPool pool;
ArenaAllocator allocator(&pool);
+ NullHandle<mirror::DexCache> dex_cache;
HGraph* graph = CreateGraph(&allocator);
HBasicBlock* entry = new (&allocator) HBasicBlock(graph);
@@ -45,20 +46,23 @@
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile()));
+ graph->GetDexFile(),
+ dex_cache));
block->AddInstruction(new (&allocator) HInstanceFieldGet(parameter,
Primitive::kPrimNot,
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile()));
+ graph->GetDexFile(),
+ dex_cache));
HInstruction* to_remove = block->GetLastInstruction();
block->AddInstruction(new (&allocator) HInstanceFieldGet(parameter,
Primitive::kPrimNot,
MemberOffset(43),
false,
kUnknownFieldIndex,
- graph->GetDexFile()));
+ graph->GetDexFile(),
+ dex_cache));
HInstruction* different_offset = block->GetLastInstruction();
// Kill the value.
block->AddInstruction(new (&allocator) HInstanceFieldSet(parameter,
@@ -67,13 +71,15 @@
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile()));
+ graph->GetDexFile(),
+ dex_cache));
block->AddInstruction(new (&allocator) HInstanceFieldGet(parameter,
Primitive::kPrimNot,
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile()));
+ graph->GetDexFile(),
+ dex_cache));
HInstruction* use_after_kill = block->GetLastInstruction();
block->AddInstruction(new (&allocator) HExit());
@@ -94,6 +100,7 @@
TEST(GVNTest, GlobalFieldElimination) {
ArenaPool pool;
ArenaAllocator allocator(&pool);
+ NullHandle<mirror::DexCache> dex_cache;
HGraph* graph = CreateGraph(&allocator);
HBasicBlock* entry = new (&allocator) HBasicBlock(graph);
@@ -110,7 +117,8 @@
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile()));
+ graph->GetDexFile(),
+ dex_cache));
block->AddInstruction(new (&allocator) HIf(block->GetLastInstruction()));
HBasicBlock* then = new (&allocator) HBasicBlock(graph);
@@ -130,21 +138,24 @@
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile()));
+ graph->GetDexFile(),
+ dex_cache));
then->AddInstruction(new (&allocator) HGoto());
else_->AddInstruction(new (&allocator) HInstanceFieldGet(parameter,
Primitive::kPrimBoolean,
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile()));
+ graph->GetDexFile(),
+ dex_cache));
else_->AddInstruction(new (&allocator) HGoto());
join->AddInstruction(new (&allocator) HInstanceFieldGet(parameter,
Primitive::kPrimBoolean,
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile()));
+ graph->GetDexFile(),
+ dex_cache));
join->AddInstruction(new (&allocator) HExit());
graph->TryBuildingSsa();
@@ -161,6 +172,7 @@
TEST(GVNTest, LoopFieldElimination) {
ArenaPool pool;
ArenaAllocator allocator(&pool);
+ NullHandle<mirror::DexCache> dex_cache;
HGraph* graph = CreateGraph(&allocator);
HBasicBlock* entry = new (&allocator) HBasicBlock(graph);
@@ -178,7 +190,8 @@
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile()));
+ graph->GetDexFile(),
+ dex_cache));
block->AddInstruction(new (&allocator) HGoto());
HBasicBlock* loop_header = new (&allocator) HBasicBlock(graph);
@@ -198,7 +211,8 @@
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile()));
+ graph->GetDexFile(),
+ dex_cache));
HInstruction* field_get_in_loop_header = loop_header->GetLastInstruction();
loop_header->AddInstruction(new (&allocator) HIf(block->GetLastInstruction()));
@@ -210,14 +224,16 @@
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile()));
+ graph->GetDexFile(),
+ dex_cache));
HInstruction* field_set = loop_body->GetLastInstruction();
loop_body->AddInstruction(new (&allocator) HInstanceFieldGet(parameter,
Primitive::kPrimBoolean,
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile()));
+ graph->GetDexFile(),
+ dex_cache));
HInstruction* field_get_in_loop_body = loop_body->GetLastInstruction();
loop_body->AddInstruction(new (&allocator) HGoto());
@@ -226,7 +242,8 @@
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile()));
+ graph->GetDexFile(),
+ dex_cache));
HInstruction* field_get_in_exit = exit->GetLastInstruction();
exit->AddInstruction(new (&allocator) HExit());
@@ -265,6 +282,7 @@
TEST(GVNTest, LoopSideEffects) {
ArenaPool pool;
ArenaAllocator allocator(&pool);
+ NullHandle<mirror::DexCache> dex_cache;
static const SideEffects kCanTriggerGC = SideEffects::CanTriggerGC();
@@ -320,7 +338,8 @@
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile()));
+ graph->GetDexFile(),
+ dex_cache));
SideEffectsAnalysis side_effects(graph);
side_effects.Run();
@@ -342,7 +361,8 @@
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile()),
+ graph->GetDexFile(),
+ dex_cache),
outer_loop_body->GetLastInstruction());
SideEffectsAnalysis side_effects(graph);
@@ -365,7 +385,8 @@
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile()),
+ graph->GetDexFile(),
+ dex_cache),
inner_loop_body->GetLastInstruction());
SideEffectsAnalysis side_effects(graph);
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 112d42e..b5870ae 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -182,10 +182,13 @@
ArtMethod* resolved_method;
if (invoke_instruction->IsInvokeStaticOrDirect()) {
MethodReference ref = invoke_instruction->AsInvokeStaticOrDirect()->GetTargetMethod();
- resolved_method = class_linker->FindDexCache(soa.Self(), *ref.dex_file)->GetResolvedMethod(
+ mirror::DexCache* const dex_cache = (&caller_dex_file == ref.dex_file)
+ ? caller_compilation_unit_.GetDexCache().Get()
+ : class_linker->FindDexCache(soa.Self(), *ref.dex_file);
+ resolved_method = dex_cache->GetResolvedMethod(
ref.dex_method_index, class_linker->GetImagePointerSize());
} else {
- resolved_method = class_linker->FindDexCache(soa.Self(), caller_dex_file)->GetResolvedMethod(
+ resolved_method = caller_compilation_unit_.GetDexCache().Get()->GetResolvedMethod(
method_index, class_linker->GetImagePointerSize());
}
@@ -273,6 +276,7 @@
const DexFile& callee_dex_file = *resolved_method->GetDexFile();
uint32_t method_index = resolved_method->GetDexMethodIndex();
ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker();
+ Handle<mirror::DexCache> dex_cache(handles_->NewHandle(resolved_method->GetDexCache()));
DexCompilationUnit dex_compilation_unit(
nullptr,
caller_compilation_unit_.GetClassLoader(),
@@ -282,7 +286,8 @@
resolved_method->GetDeclaringClass()->GetDexClassDefIndex(),
method_index,
resolved_method->GetAccessFlags(),
- compiler_driver_->GetVerifiedMethod(&callee_dex_file, method_index));
+ compiler_driver_->GetVerifiedMethod(&callee_dex_file, method_index),
+ dex_cache);
bool requires_ctor_barrier = false;
@@ -326,7 +331,8 @@
resolved_method->GetDexFile(),
compiler_driver_,
&inline_stats,
- resolved_method->GetQuickenedInfo());
+ resolved_method->GetQuickenedInfo(),
+ dex_cache);
if (!builder.BuildGraph(*code_item)) {
VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
diff --git a/compiler/optimizing/licm_test.cc b/compiler/optimizing/licm_test.cc
index 2fc66e6d..bc4a663 100644
--- a/compiler/optimizing/licm_test.cc
+++ b/compiler/optimizing/licm_test.cc
@@ -120,13 +120,14 @@
BuildLoop();
// Populate the loop with instructions: set/get field with different types.
+ NullHandle<mirror::DexCache> dex_cache;
HInstruction* get_field = new (&allocator_) HInstanceFieldGet(
parameter_, Primitive::kPrimLong, MemberOffset(10),
- false, kUnknownFieldIndex, graph_->GetDexFile());
+ false, kUnknownFieldIndex, graph_->GetDexFile(), dex_cache);
loop_body_->InsertInstructionBefore(get_field, loop_body_->GetLastInstruction());
HInstruction* set_field = new (&allocator_) HInstanceFieldSet(
parameter_, constant_, Primitive::kPrimInt, MemberOffset(20),
- false, kUnknownFieldIndex, graph_->GetDexFile());
+ false, kUnknownFieldIndex, graph_->GetDexFile(), dex_cache);
loop_body_->InsertInstructionBefore(set_field, loop_body_->GetLastInstruction());
EXPECT_EQ(get_field->GetBlock(), loop_body_);
@@ -140,13 +141,14 @@
BuildLoop();
// Populate the loop with instructions: set/get field with same types.
+ NullHandle<mirror::DexCache> dex_cache;
HInstruction* get_field = new (&allocator_) HInstanceFieldGet(
parameter_, Primitive::kPrimLong, MemberOffset(10),
- false, kUnknownFieldIndex, graph_->GetDexFile());
+ false, kUnknownFieldIndex, graph_->GetDexFile(), dex_cache);
loop_body_->InsertInstructionBefore(get_field, loop_body_->GetLastInstruction());
HInstruction* set_field = new (&allocator_) HInstanceFieldSet(
parameter_, get_field, Primitive::kPrimLong, MemberOffset(10),
- false, kUnknownFieldIndex, graph_->GetDexFile());
+ false, kUnknownFieldIndex, graph_->GetDexFile(), dex_cache);
loop_body_->InsertInstructionBefore(set_field, loop_body_->GetLastInstruction());
EXPECT_EQ(get_field->GetBlock(), loop_body_);
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 2ed2d9a..1470e10 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -58,6 +58,10 @@
class SlowPathCode;
class SsaBuilder;
+namespace mirror {
+class DexCache;
+} // namespace mirror
+
static const int kDefaultNumberOfBlocks = 8;
static const int kDefaultNumberOfSuccessors = 2;
static const int kDefaultNumberOfPredecessors = 2;
@@ -4020,25 +4024,29 @@
Primitive::Type field_type,
bool is_volatile,
uint32_t index,
- const DexFile& dex_file)
+ const DexFile& dex_file,
+ Handle<mirror::DexCache> dex_cache)
: field_offset_(field_offset),
field_type_(field_type),
is_volatile_(is_volatile),
index_(index),
- dex_file_(dex_file) {}
+ dex_file_(dex_file),
+ dex_cache_(dex_cache) {}
MemberOffset GetFieldOffset() const { return field_offset_; }
Primitive::Type GetFieldType() const { return field_type_; }
uint32_t GetFieldIndex() const { return index_; }
const DexFile& GetDexFile() const { return dex_file_; }
bool IsVolatile() const { return is_volatile_; }
+ Handle<mirror::DexCache> GetDexCache() const { return dex_cache_; }
private:
const MemberOffset field_offset_;
const Primitive::Type field_type_;
const bool is_volatile_;
- uint32_t index_;
+ const uint32_t index_;
const DexFile& dex_file_;
+ const Handle<mirror::DexCache> dex_cache_;
};
class HInstanceFieldGet : public HExpression<1> {
@@ -4048,11 +4056,12 @@
MemberOffset field_offset,
bool is_volatile,
uint32_t field_idx,
- const DexFile& dex_file)
+ const DexFile& dex_file,
+ Handle<mirror::DexCache> dex_cache)
: HExpression(
field_type,
SideEffects::FieldReadOfType(field_type, is_volatile)),
- field_info_(field_offset, field_type, is_volatile, field_idx, dex_file) {
+ field_info_(field_offset, field_type, is_volatile, field_idx, dex_file, dex_cache) {
SetRawInputAt(0, value);
}
@@ -4092,10 +4101,11 @@
MemberOffset field_offset,
bool is_volatile,
uint32_t field_idx,
- const DexFile& dex_file)
+ const DexFile& dex_file,
+ Handle<mirror::DexCache> dex_cache)
: HTemplateInstruction(
SideEffects::FieldWriteOfType(field_type, is_volatile)),
- field_info_(field_offset, field_type, is_volatile, field_idx, dex_file),
+ field_info_(field_offset, field_type, is_volatile, field_idx, dex_file, dex_cache),
value_can_be_null_(true) {
SetRawInputAt(0, object);
SetRawInputAt(1, value);
@@ -4510,11 +4520,12 @@
MemberOffset field_offset,
bool is_volatile,
uint32_t field_idx,
- const DexFile& dex_file)
+ const DexFile& dex_file,
+ Handle<mirror::DexCache> dex_cache)
: HExpression(
field_type,
SideEffects::FieldReadOfType(field_type, is_volatile)),
- field_info_(field_offset, field_type, is_volatile, field_idx, dex_file) {
+ field_info_(field_offset, field_type, is_volatile, field_idx, dex_file, dex_cache) {
SetRawInputAt(0, cls);
}
@@ -4551,10 +4562,11 @@
MemberOffset field_offset,
bool is_volatile,
uint32_t field_idx,
- const DexFile& dex_file)
+ const DexFile& dex_file,
+ Handle<mirror::DexCache> dex_cache)
: HTemplateInstruction(
SideEffects::FieldWriteOfType(field_type, is_volatile)),
- field_info_(field_offset, field_type, is_volatile, field_idx, dex_file),
+ field_info_(field_offset, field_type, is_volatile, field_idx, dex_file, dex_cache),
value_can_be_null_(true) {
SetRawInputAt(0, cls);
SetRawInputAt(1, value);
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 6f251e8..7044a87 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -243,7 +243,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* TryCompile(const DexFile::CodeItem* code_item,
uint32_t access_flags,
@@ -251,7 +252,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;
CompiledMethod* JniCompile(uint32_t access_flags,
uint32_t method_idx,
@@ -638,7 +640,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 {
UNUSED(invoke_type);
std::string method_name = PrettyMethod(method_idx, dex_file);
MaybeRecordStat(MethodCompilationStat::kAttemptCompilation);
@@ -674,7 +677,7 @@
DexCompilationUnit dex_compilation_unit(
nullptr, class_loader, Runtime::Current()->GetClassLinker(), dex_file, code_item,
class_def_idx, method_idx, access_flags,
- compiler_driver->GetVerifiedMethod(&dex_file, method_idx));
+ compiler_driver->GetVerifiedMethod(&dex_file, method_idx), dex_cache);
bool requires_barrier = dex_compilation_unit.IsConstructor()
&& compiler_driver->RequiresConstructorBarrier(Thread::Current(),
@@ -712,10 +715,7 @@
const uint8_t* interpreter_metadata = nullptr;
{
ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<4> hs(soa.Self());
- ClassLinker* class_linker = dex_compilation_unit.GetClassLinker();
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(
- soa.Self(), dex_file)));
+ StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> loader(hs.NewHandle(
soa.Decode<mirror::ClassLoader*>(class_loader)));
ArtMethod* art_method = compiler_driver->ResolveMethod(
@@ -732,7 +732,8 @@
&dex_file,
compiler_driver,
compilation_stats_.get(),
- interpreter_metadata);
+ interpreter_metadata,
+ dex_cache);
VLOG(compiler) << "Building " << method_name;
@@ -798,13 +799,14 @@
uint16_t class_def_idx,
uint32_t method_idx,
jobject jclass_loader,
- const DexFile& dex_file) const {
+ const DexFile& dex_file,
+ Handle<mirror::DexCache> dex_cache) const {
CompilerDriver* compiler_driver = GetCompilerDriver();
CompiledMethod* method = nullptr;
DCHECK(!compiler_driver->GetVerifiedMethod(&dex_file, method_idx)->HasRuntimeThrow());
if (compiler_driver->IsMethodVerifiedWithoutFailures(method_idx, class_def_idx, dex_file)) {
method = TryCompile(code_item, access_flags, invoke_type, class_def_idx,
- method_idx, jclass_loader, dex_file);
+ method_idx, jclass_loader, dex_file, dex_cache);
} else {
if (compiler_driver->GetCompilerOptions().VerifyAtRuntime()) {
MaybeRecordStat(MethodCompilationStat::kNotCompiledVerifyAtRuntime);
@@ -817,7 +819,7 @@
return method;
}
method = delegate_->Compile(code_item, access_flags, invoke_type, class_def_idx, method_idx,
- jclass_loader, dex_file);
+ jclass_loader, dex_file, dex_cache);
if (method != nullptr) {
MaybeRecordStat(MethodCompilationStat::kCompiledQuick);
diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc
index 516638b..b887b89 100644
--- a/compiler/optimizing/reference_type_propagation.cc
+++ b/compiler/optimizing/reference_type_propagation.cc
@@ -434,8 +434,7 @@
ScopedObjectAccess soa(Thread::Current());
ClassLinker* cl = Runtime::Current()->GetClassLinker();
- mirror::DexCache* dex_cache = cl->FindDexCache(soa.Self(), info.GetDexFile(), false);
- ArtField* field = cl->GetResolvedField(info.GetFieldIndex(), dex_cache);
+ ArtField* field = cl->GetResolvedField(info.GetFieldIndex(), info.GetDexCache().Get());
// TODO: There are certain cases where we can't resolve the field.
// b/21914925 is open to keep track of a repro case for this issue.
mirror::Class* klass = (field == nullptr) ? nullptr : field->GetType<false>();
diff --git a/compiler/optimizing/register_allocator_test.cc b/compiler/optimizing/register_allocator_test.cc
index b7da362..965a8df 100644
--- a/compiler/optimizing/register_allocator_test.cc
+++ b/compiler/optimizing/register_allocator_test.cc
@@ -472,6 +472,7 @@
HInstruction** input2) {
HGraph* graph = CreateGraph(allocator);
HBasicBlock* entry = new (allocator) HBasicBlock(graph);
+ NullHandle<mirror::DexCache> dex_cache;
graph->AddBlock(entry);
graph->SetEntryBlock(entry);
HInstruction* parameter = new (allocator) HParameterValue(0, Primitive::kPrimNot);
@@ -486,7 +487,8 @@
MemberOffset(22),
false,
kUnknownFieldIndex,
- graph->GetDexFile());
+ graph->GetDexFile(),
+ dex_cache);
block->AddInstruction(test);
block->AddInstruction(new (allocator) HIf(test));
HBasicBlock* then = new (allocator) HBasicBlock(graph);
@@ -510,13 +512,15 @@
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile());
+ graph->GetDexFile(),
+ dex_cache);
*input2 = new (allocator) HInstanceFieldGet(parameter,
Primitive::kPrimInt,
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile());
+ graph->GetDexFile(),
+ dex_cache);
then->AddInstruction(*input1);
else_->AddInstruction(*input2);
join->AddInstruction(new (allocator) HExit());
@@ -613,6 +617,7 @@
HInstruction** field,
HInstruction** ret) {
HGraph* graph = CreateGraph(allocator);
+ NullHandle<mirror::DexCache> dex_cache;
HBasicBlock* entry = new (allocator) HBasicBlock(graph);
graph->AddBlock(entry);
graph->SetEntryBlock(entry);
@@ -628,7 +633,8 @@
MemberOffset(42),
false,
kUnknownFieldIndex,
- graph->GetDexFile());
+ graph->GetDexFile(),
+ dex_cache);
block->AddInstruction(*field);
*ret = new (allocator) HReturn(*field);
block->AddInstruction(*ret);