Add VerfiedMethod to DexCompilationUnit.
Avoid some mutex locking and map lookups.
Change-Id: I8e0486af77e38dcd065569572a6b985eb57f4f63
diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc
index 3368132..ff8fea0 100644
--- a/compiler/dex/dex_to_dex_compiler.cc
+++ b/compiler/dex/dex_to_dex_compiler.cc
@@ -176,8 +176,7 @@
if (!kEnableCheckCastEllision || !PerformOptimizations()) {
return inst;
}
- MethodReference referrer(&GetDexFile(), unit_.GetDexMethodIndex());
- if (!driver_.IsSafeCast(referrer, dex_pc)) {
+ if (!driver_.IsSafeCast(&unit_, dex_pc)) {
return inst;
}
// Ok, this is a safe cast. Since the "check-cast" instruction size is 2 code
@@ -272,15 +271,16 @@
} // namespace optimizer
} // namespace art
-extern "C" void ArtCompileDEX(art::CompilerDriver& compiler, const art::DexFile::CodeItem* code_item,
+extern "C" void ArtCompileDEX(art::CompilerDriver& driver, const art::DexFile::CodeItem* code_item,
uint32_t access_flags, art::InvokeType invoke_type,
uint16_t class_def_idx, uint32_t method_idx, jobject class_loader,
const art::DexFile& dex_file,
art::DexToDexCompilationLevel dex_to_dex_compilation_level) {
if (dex_to_dex_compilation_level != art::kDontDexToDexCompile) {
art::DexCompilationUnit unit(NULL, class_loader, art::Runtime::Current()->GetClassLinker(),
- dex_file, code_item, class_def_idx, method_idx, access_flags);
- art::optimizer::DexCompiler dex_compiler(compiler, unit, dex_to_dex_compilation_level);
+ dex_file, code_item, class_def_idx, method_idx, access_flags,
+ driver.GetVerifiedMethod(&dex_file, method_idx));
+ art::optimizer::DexCompiler dex_compiler(driver, unit, dex_to_dex_compilation_level);
dex_compiler.Compile();
}
}
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc
index 8c90edb..9dbb341 100644
--- a/compiler/dex/mir_graph.cc
+++ b/compiler/dex/mir_graph.cc
@@ -529,7 +529,8 @@
current_offset_ = 0;
// TODO: will need to snapshot stack image and use that as the mir context identification.
m_units_.push_back(new DexCompilationUnit(cu_, class_loader, Runtime::Current()->GetClassLinker(),
- dex_file, current_code_item_, class_def_idx, method_idx, access_flags));
+ dex_file, current_code_item_, class_def_idx, method_idx, access_flags,
+ cu_->compiler_driver->GetVerifiedMethod(&dex_file, method_idx)));
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/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc
index cb36813..7f19ea1 100644
--- a/compiler/dex/quick/codegen_util.cc
+++ b/compiler/dex/quick/codegen_util.cc
@@ -22,6 +22,7 @@
#include "dex/quick/dex_file_method_inliner.h"
#include "dex/quick/dex_file_to_method_inliner_map.h"
#include "dex/verification_results.h"
+#include "dex/verified_method.h"
#include "verifier/dex_gc_map.h"
#include "verifier/method_verifier.h"
@@ -763,10 +764,10 @@
}
}
MethodReference method_ref(cu_->dex_file, cu_->method_idx);
- const std::vector<uint8_t>* gc_map_raw =
- cu_->compiler_driver->GetVerificationResults()->GetDexGcMap(method_ref);
- verifier::DexPcToReferenceMap dex_gc_map(&(*gc_map_raw)[0]);
- DCHECK_EQ(gc_map_raw->size(), dex_gc_map.RawSize());
+ const std::vector<uint8_t>& gc_map_raw =
+ mir_graph_->GetCurrentDexCompilationUnit()->GetVerifiedMethod()->GetDexGcMap();
+ verifier::DexPcToReferenceMap dex_gc_map(&(gc_map_raw)[0]);
+ DCHECK_EQ(gc_map_raw.size(), dex_gc_map.RawSize());
// Compute native offset to references size.
NativePcToReferenceMapBuilder native_gc_map_builder(&native_gc_map_,
mapping_table.PcToDexSize(),
diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc
index d8b9869..746c1db 100644
--- a/compiler/dex/quick/gen_common.cc
+++ b/compiler/dex/quick/gen_common.cc
@@ -1133,8 +1133,7 @@
// Note: currently type_known_final is unused, as optimizing will only improve the performance
// of the exception throw path.
DexCompilationUnit* cu = mir_graph_->GetCurrentDexCompilationUnit();
- const MethodReference mr(cu->GetDexFile(), cu->GetDexMethodIndex());
- if (!needs_access_check && cu_->compiler_driver->IsSafeCast(mr, insn_idx)) {
+ if (!needs_access_check && cu_->compiler_driver->IsSafeCast(cu, insn_idx)) {
// Verifier type analysis proved this check cast would never cause an exception.
return;
}
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index 0a470a5..1f4122d 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -342,8 +342,8 @@
bool is_safe = is_null; // Always safe to store null.
if (!is_safe) {
// Check safety from verifier type information.
- const MethodReference mr(cu_->dex_file, cu_->method_idx);
- is_safe = cu_->compiler_driver->IsSafeCast(mr, mir->offset);
+ const DexCompilationUnit* unit = mir_graph_->GetCurrentDexCompilationUnit();
+ is_safe = cu_->compiler_driver->IsSafeCast(unit, mir->offset);
}
if (is_null || is_safe) {
// Store of constant null doesn't require an assignability test and can be generated inline
diff --git a/compiler/dex/verification_results.cc b/compiler/dex/verification_results.cc
index 8b4fa1a..edccec5 100644
--- a/compiler/dex/verification_results.cc
+++ b/compiler/dex/verification_results.cc
@@ -79,24 +79,6 @@
return (it != verified_methods_.end()) ? it->second : nullptr;
}
-const std::vector<uint8_t>* VerificationResults::GetDexGcMap(MethodReference ref) {
- const VerifiedMethod* verified_method = GetVerifiedMethod(ref);
- CHECK(verified_method != nullptr)
- << "Didn't find GC map for: " << PrettyMethod(ref.dex_method_index, *ref.dex_file);
- return &verified_method->GetDexGcMap();
-}
-
-const MethodReference* VerificationResults::GetDevirtMap(const MethodReference& ref,
- uint32_t dex_pc) {
- const VerifiedMethod* verified_method = GetVerifiedMethod(ref);
- return (verified_method != nullptr) ? verified_method->GetDevirtTarget(dex_pc) : nullptr;
-}
-
-bool VerificationResults::IsSafeCast(MethodReference ref, uint32_t pc) {
- const VerifiedMethod* verified_method = GetVerifiedMethod(ref);
- return (verified_method != nullptr) && (verified_method->IsSafeCast(pc));
-}
-
void VerificationResults::AddRejectedClass(ClassReference ref) {
{
WriterMutexLock mu(Thread::Current(), rejected_classes_lock_);
diff --git a/compiler/dex/verification_results.h b/compiler/dex/verification_results.h
index e9cdb53..2eb0713 100644
--- a/compiler/dex/verification_results.h
+++ b/compiler/dex/verification_results.h
@@ -47,16 +47,6 @@
const VerifiedMethod* GetVerifiedMethod(MethodReference ref)
LOCKS_EXCLUDED(verified_methods_lock_);
- const std::vector<uint8_t>* GetDexGcMap(MethodReference ref)
- LOCKS_EXCLUDED(verified_methods_lock_);
-
- const MethodReference* GetDevirtMap(const MethodReference& ref, uint32_t dex_pc)
- LOCKS_EXCLUDED(verified_methods_lock_);
-
- // Returns true if the cast can statically be verified to be redundant
- // by using the check-cast elision peephole optimization in the verifier.
- bool IsSafeCast(MethodReference ref, uint32_t pc) LOCKS_EXCLUDED(safecast_map_lock_);
-
void AddRejectedClass(ClassReference ref) LOCKS_EXCLUDED(rejected_classes_lock_);
bool IsClassRejected(ClassReference ref) LOCKS_EXCLUDED(rejected_classes_lock_);