diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/Android.mk | 3 | ||||
-rw-r--r-- | compiler/dex/quick/codegen_util.cc | 4 | ||||
-rw-r--r-- | compiler/dex/verification_results.cc | 128 | ||||
-rw-r--r-- | compiler/dex/verification_results.h | 80 | ||||
-rw-r--r-- | compiler/dex/verified_method.cc (renamed from compiler/dex/verified_methods_data.cc) | 352 | ||||
-rw-r--r-- | compiler/dex/verified_method.h | 98 | ||||
-rw-r--r-- | compiler/dex/verified_methods_data.h | 117 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.cc | 14 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.h | 10 | ||||
-rw-r--r-- | compiler/llvm/compiler_llvm.cc | 4 | ||||
-rw-r--r-- | compiler/oat_test.cc | 6 | ||||
-rw-r--r-- | compiler/oat_writer.cc | 6 |
12 files changed, 435 insertions, 387 deletions
diff --git a/compiler/Android.mk b/compiler/Android.mk index 25dfb0a..c6662c2 100644 --- a/compiler/Android.mk +++ b/compiler/Android.mk @@ -59,7 +59,8 @@ LIBART_COMPILER_SRC_FILES := \ dex/frontend.cc \ dex/mir_graph.cc \ dex/mir_analysis.cc \ - dex/verified_methods_data.cc \ + dex/verified_method.cc \ + dex/verification_results.cc \ dex/vreg_analysis.cc \ dex/ssa_transformation.cc \ driver/compiler_driver.cc \ diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc index 1eb79c9..cb36813 100644 --- a/compiler/dex/quick/codegen_util.cc +++ b/compiler/dex/quick/codegen_util.cc @@ -21,7 +21,7 @@ #include "mir_to_lir-inl.h" #include "dex/quick/dex_file_method_inliner.h" #include "dex/quick/dex_file_to_method_inliner_map.h" -#include "dex/verified_methods_data.h" +#include "dex/verification_results.h" #include "verifier/dex_gc_map.h" #include "verifier/method_verifier.h" @@ -764,7 +764,7 @@ void Mir2Lir::CreateNativeGcMap() { } MethodReference method_ref(cu_->dex_file, cu_->method_idx); const std::vector<uint8_t>* gc_map_raw = - cu_->compiler_driver->GetVerifiedMethodsData()->GetDexGcMap(method_ref); + 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()); // Compute native offset to references size. diff --git a/compiler/dex/verification_results.cc b/compiler/dex/verification_results.cc new file mode 100644 index 0000000..8b4fa1a --- /dev/null +++ b/compiler/dex/verification_results.cc @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "verification_results.h" + +#include "base/stl_util.h" +#include "base/mutex.h" +#include "base/mutex-inl.h" +#include "thread.h" +#include "thread-inl.h" +#include "verified_method.h" +#include "verifier/method_verifier.h" +#include "verifier/method_verifier-inl.h" + +namespace art { + +VerificationResults::VerificationResults() + : verified_methods_lock_("compiler verified methods lock"), + verified_methods_(), + rejected_classes_lock_("compiler rejected classes lock"), + rejected_classes_() { +} + +VerificationResults::~VerificationResults() { + Thread* self = Thread::Current(); + { + WriterMutexLock mu(self, verified_methods_lock_); + STLDeleteValues(&verified_methods_); + } +} + +bool VerificationResults::ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier) { + MethodReference ref = method_verifier->GetMethodReference(); + bool compile = IsCandidateForCompilation(ref, method_verifier->GetAccessFlags()); + // TODO: Check also for virtual/interface invokes when DEX-to-DEX supports devirtualization. + if (!compile && !method_verifier->HasCheckCasts()) { + return true; + } + + const VerifiedMethod* verified_method = VerifiedMethod::Create(method_verifier, compile); + if (verified_method == nullptr) { + DCHECK(method_verifier->HasFailures()); + return false; + } + + WriterMutexLock mu(Thread::Current(), verified_methods_lock_); + auto it = verified_methods_.find(ref); + if (it != verified_methods_.end()) { + // TODO: Investigate why are we doing the work again for this method and try to avoid it. + LOG(WARNING) << "Method processed more than once: " + << PrettyMethod(ref.dex_method_index, *ref.dex_file); + DCHECK_EQ(it->second->GetDevirtMap().size(), verified_method->GetDevirtMap().size()); + DCHECK_EQ(it->second->GetSafeCastSet().size(), verified_method->GetSafeCastSet().size()); + DCHECK_EQ(it->second->GetDexGcMap().size(), verified_method->GetDexGcMap().size()); + delete it->second; + verified_methods_.erase(it); + } + verified_methods_.Put(ref, verified_method); + DCHECK(verified_methods_.find(ref) != verified_methods_.end()); + return true; +} + +const VerifiedMethod* VerificationResults::GetVerifiedMethod(MethodReference ref) { + ReaderMutexLock mu(Thread::Current(), verified_methods_lock_); + auto it = verified_methods_.find(ref); + 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_); + rejected_classes_.insert(ref); + } + DCHECK(IsClassRejected(ref)); +} + +bool VerificationResults::IsClassRejected(ClassReference ref) { + ReaderMutexLock mu(Thread::Current(), rejected_classes_lock_); + return (rejected_classes_.find(ref) != rejected_classes_.end()); +} + +bool VerificationResults::IsCandidateForCompilation(MethodReference& method_ref, + const uint32_t access_flags) { +#ifdef ART_SEA_IR_MODE + bool use_sea = Runtime::Current()->IsSeaIRMode(); + use_sea = use_sea && (std::string::npos != PrettyMethod( + method_ref.dex_method_index, *(method_ref.dex_file)).find("fibonacci")); + if (use_sea) return true; +#endif + // Don't compile class initializers, ever. + if (((access_flags & kAccConstructor) != 0) && ((access_flags & kAccStatic) != 0)) { + return false; + } + return (Runtime::Current()->GetCompilerFilter() != Runtime::kInterpretOnly); +} + +} // namespace art diff --git a/compiler/dex/verification_results.h b/compiler/dex/verification_results.h new file mode 100644 index 0000000..e9cdb53 --- /dev/null +++ b/compiler/dex/verification_results.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_COMPILER_DEX_VERIFICATION_RESULTS_H_ +#define ART_COMPILER_DEX_VERIFICATION_RESULTS_H_ + +#include <stdint.h> +#include <set> +#include <vector> + +#include "base/macros.h" +#include "base/mutex.h" +#include "class_reference.h" +#include "method_reference.h" +#include "safe_map.h" + +namespace art { + +namespace verifier { +class MethodVerifier; +} // namespace verifier + +class VerifiedMethod; + +class VerificationResults { + public: + VerificationResults(); + ~VerificationResults(); + + bool ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) + LOCKS_EXCLUDED(verified_methods_lock_); + + 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_); + + static bool IsCandidateForCompilation(MethodReference& method_ref, + const uint32_t access_flags); + + private: + // Verified methods. + typedef SafeMap<MethodReference, const VerifiedMethod*, + MethodReferenceComparator> VerifiedMethodMap; + ReaderWriterMutex verified_methods_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; + VerifiedMethodMap verified_methods_; + + // Rejected classes. + ReaderWriterMutex rejected_classes_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; + std::set<ClassReference> rejected_classes_ GUARDED_BY(rejected_classes_lock_); +}; + +} // namespace art + +#endif // ART_COMPILER_DEX_VERIFICATION_RESULTS_H_ diff --git a/compiler/dex/verified_methods_data.cc b/compiler/dex/verified_method.cc index e6c4dda..0f812a4 100644 --- a/compiler/dex/verified_methods_data.cc +++ b/compiler/dex/verified_method.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,6 +14,12 @@ * limitations under the License. */ +#include "verified_method.h" + +#include <algorithm> +#include <vector> + +#include "base/logging.h" #include "base/stl_util.h" #include "dex_file.h" #include "dex_instruction.h" @@ -28,7 +34,7 @@ #include "mirror/dex_cache-inl.h" #include "mirror/object.h" #include "mirror/object-inl.h" -#include "verified_methods_data.h" +#include "UniquePtr.h" #include "verifier/dex_gc_map.h" #include "verifier/method_verifier.h" #include "verifier/method_verifier-inl.h" @@ -37,150 +43,58 @@ namespace art { -VerifiedMethodsData::VerifiedMethodsData() - : dex_gc_maps_lock_("compiler GC maps lock"), - dex_gc_maps_(), - safecast_map_lock_("compiler Cast Elision lock"), - safecast_map_(), - devirt_maps_lock_("compiler Devirtualization lock"), - devirt_maps_(), - rejected_classes_lock_("compiler rejected classes lock"), - rejected_classes_() { -} - -VerifiedMethodsData::~VerifiedMethodsData() { - Thread* self = Thread::Current(); - { - WriterMutexLock mu(self, dex_gc_maps_lock_); - STLDeleteValues(&dex_gc_maps_); - } - { - WriterMutexLock mu(self, safecast_map_lock_); - STLDeleteValues(&safecast_map_); - } - { - WriterMutexLock mu(self, devirt_maps_lock_); - STLDeleteValues(&devirt_maps_); - } -} - -bool VerifiedMethodsData::ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier) { - MethodReference ref = method_verifier->GetMethodReference(); - bool compile = IsCandidateForCompilation(ref, method_verifier->GetAccessFlags()); +const VerifiedMethod* VerifiedMethod::Create(verifier::MethodVerifier* method_verifier, + bool compile) { + UniquePtr<VerifiedMethod> verified_method(new VerifiedMethod); if (compile) { - /* Generate a register map and add it to the method. */ - const std::vector<uint8_t>* dex_gc_map = GenerateGcMap(method_verifier); - if (dex_gc_map == NULL) { - DCHECK(method_verifier->HasFailures()); - return false; // Not a real failure, but a failure to encode + /* Generate a register map. */ + if (!verified_method->GenerateGcMap(method_verifier)) { + CHECK(method_verifier->HasFailures()); + return nullptr; // Not a real failure, but a failure to encode. } if (kIsDebugBuild) { - VerifyGcMap(method_verifier, *dex_gc_map); + VerifyGcMap(method_verifier, verified_method->dex_gc_map_); } - SetDexGcMap(ref, dex_gc_map); // TODO: move this out when DEX-to-DEX supports devirtualization. if (method_verifier->HasVirtualOrInterfaceInvokes()) { - PcToConcreteMethodMap* pc_to_concrete_method = GenerateDevirtMap(method_verifier); - if (pc_to_concrete_method != NULL) { - SetDevirtMap(ref, pc_to_concrete_method); - } + verified_method->GenerateDevirtMap(method_verifier); } } if (method_verifier->HasCheckCasts()) { - MethodSafeCastSet* method_to_safe_casts = GenerateSafeCastSet(method_verifier); - if (method_to_safe_casts != NULL) { - SetSafeCastMap(ref, method_to_safe_casts); - } - } - return true; -} - -const std::vector<uint8_t>* VerifiedMethodsData::GetDexGcMap(MethodReference ref) { - ReaderMutexLock mu(Thread::Current(), dex_gc_maps_lock_); - DexGcMapTable::const_iterator it = dex_gc_maps_.find(ref); - CHECK(it != dex_gc_maps_.end()) - << "Didn't find GC map for: " << PrettyMethod(ref.dex_method_index, *ref.dex_file); - CHECK(it->second != NULL); - return it->second; -} - -const MethodReference* VerifiedMethodsData::GetDevirtMap(const MethodReference& ref, - uint32_t dex_pc) { - ReaderMutexLock mu(Thread::Current(), devirt_maps_lock_); - DevirtualizationMapTable::const_iterator it = devirt_maps_.find(ref); - if (it == devirt_maps_.end()) { - return NULL; - } - - // Look up the PC in the map, get the concrete method to execute and return its reference. - PcToConcreteMethodMap::const_iterator pc_to_concrete_method = it->second->find(dex_pc); - if (pc_to_concrete_method != it->second->end()) { - return &(pc_to_concrete_method->second); - } else { - return NULL; - } -} - -bool VerifiedMethodsData::IsSafeCast(MethodReference ref, uint32_t pc) { - ReaderMutexLock mu(Thread::Current(), safecast_map_lock_); - SafeCastMap::const_iterator it = safecast_map_.find(ref); - if (it == safecast_map_.end()) { - return false; + verified_method->GenerateSafeCastSet(method_verifier); } - - // Look up the cast address in the set of safe casts - // Use binary_search for lookup in the sorted vector. - return std::binary_search(it->second->begin(), it->second->end(), pc); -} - -void VerifiedMethodsData::AddRejectedClass(ClassReference ref) { - { - WriterMutexLock mu(Thread::Current(), rejected_classes_lock_); - rejected_classes_.insert(ref); - } - DCHECK(IsClassRejected(ref)); + return verified_method.release(); } -bool VerifiedMethodsData::IsClassRejected(ClassReference ref) { - ReaderMutexLock mu(Thread::Current(), rejected_classes_lock_); - return (rejected_classes_.find(ref) != rejected_classes_.end()); +const MethodReference* VerifiedMethod::GetDevirtTarget(uint32_t dex_pc) const { + auto it = devirt_map_.find(dex_pc); + return (it != devirt_map_.end()) ? &it->second : nullptr; } -bool VerifiedMethodsData::IsCandidateForCompilation(MethodReference& method_ref, - const uint32_t access_flags) { -#ifdef ART_SEA_IR_MODE - bool use_sea = Runtime::Current()->IsSeaIRMode(); - use_sea = use_sea && (std::string::npos != PrettyMethod( - method_ref.dex_method_index, *(method_ref.dex_file)).find("fibonacci")); - if (use_sea) return true; -#endif - // Don't compile class initializers, ever. - if (((access_flags & kAccConstructor) != 0) && ((access_flags & kAccStatic) != 0)) { - return false; - } - return (Runtime::Current()->GetCompilerFilter() != Runtime::kInterpretOnly); +bool VerifiedMethod::IsSafeCast(uint32_t pc) const { + return std::binary_search(safe_cast_set_.begin(), safe_cast_set_.end(), pc); } -const std::vector<uint8_t>* VerifiedMethodsData::GenerateGcMap( - verifier::MethodVerifier* method_verifier) { +bool VerifiedMethod::GenerateGcMap(verifier::MethodVerifier* method_verifier) { + DCHECK(dex_gc_map_.empty()); size_t num_entries, ref_bitmap_bits, pc_bits; ComputeGcMapSizes(method_verifier, &num_entries, &ref_bitmap_bits, &pc_bits); - // There's a single byte to encode the size of each bitmap + // There's a single byte to encode the size of each bitmap. if (ref_bitmap_bits >= (8 /* bits per byte */ * 8192 /* 13-bit size */ )) { // TODO: either a better GC map format or per method failures method_verifier->Fail(verifier::VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot encode GC map for method with " << ref_bitmap_bits << " registers"; - return NULL; + return false; } size_t ref_bitmap_bytes = (ref_bitmap_bits + 7) / 8; - // There are 2 bytes to encode the number of entries + // There are 2 bytes to encode the number of entries. if (num_entries >= 65536) { - // TODO: either a better GC map format or per method failures + // TODO: Either a better GC map format or per method failures. method_verifier->Fail(verifier::VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot encode GC map for method with " << num_entries << " entries"; - return NULL; + return false; } size_t pc_bytes; verifier::RegisterMapFormat format; @@ -191,45 +105,39 @@ const std::vector<uint8_t>* VerifiedMethodsData::GenerateGcMap( format = verifier::kRegMapFormatCompact16; pc_bytes = 2; } else { - // TODO: either a better GC map format or per method failures + // TODO: Either a better GC map format or per method failures. method_verifier->Fail(verifier::VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot encode GC map for method with " << (1 << pc_bits) << " instructions (number is rounded up to nearest power of 2)"; - return NULL; + return false; } size_t table_size = ((pc_bytes + ref_bitmap_bytes) * num_entries) + 4; - std::vector<uint8_t>* table = new std::vector<uint8_t>; - if (table == NULL) { - method_verifier->Fail(verifier::VERIFY_ERROR_BAD_CLASS_HARD) - << "Failed to encode GC map (size=" << table_size << ")"; - return NULL; - } - table->reserve(table_size); - // Write table header - table->push_back(format | ((ref_bitmap_bytes & ~0xFF) >> 5)); - table->push_back(ref_bitmap_bytes & 0xFF); - table->push_back(num_entries & 0xFF); - table->push_back((num_entries >> 8) & 0xFF); - // Write table data + dex_gc_map_.reserve(table_size); + // Write table header. + dex_gc_map_.push_back(format | ((ref_bitmap_bytes & ~0xFF) >> 5)); + dex_gc_map_.push_back(ref_bitmap_bytes & 0xFF); + dex_gc_map_.push_back(num_entries & 0xFF); + dex_gc_map_.push_back((num_entries >> 8) & 0xFF); + // Write table data. const DexFile::CodeItem* code_item = method_verifier->CodeItem(); for (size_t i = 0; i < code_item->insns_size_in_code_units_; i++) { if (method_verifier->GetInstructionFlags(i).IsCompileTimeInfoPoint()) { - table->push_back(i & 0xFF); + dex_gc_map_.push_back(i & 0xFF); if (pc_bytes == 2) { - table->push_back((i >> 8) & 0xFF); + dex_gc_map_.push_back((i >> 8) & 0xFF); } verifier::RegisterLine* line = method_verifier->GetRegLine(i); - line->WriteReferenceBitMap(*table, ref_bitmap_bytes); + line->WriteReferenceBitMap(dex_gc_map_, ref_bitmap_bytes); } } - DCHECK_EQ(table->size(), table_size); - return table; + DCHECK_EQ(dex_gc_map_.size(), table_size); + return true; } -void VerifiedMethodsData::VerifyGcMap(verifier::MethodVerifier* method_verifier, - const std::vector<uint8_t>& data) { +void VerifiedMethod::VerifyGcMap(verifier::MethodVerifier* method_verifier, + const std::vector<uint8_t>& data) { // Check that for every GC point there is a map entry, there aren't entries for non-GC points, - // that the table data is well formed and all references are marked (or not) in the bitmap + // that the table data is well formed and all references are marked (or not) in the bitmap. verifier::DexPcToReferenceMap map(&data[0]); DCHECK_EQ(data.size(), map.RawSize()); size_t map_index = 0; @@ -237,30 +145,30 @@ void VerifiedMethodsData::VerifyGcMap(verifier::MethodVerifier* method_verifier, for (size_t i = 0; i < code_item->insns_size_in_code_units_; i++) { const uint8_t* reg_bitmap = map.FindBitMap(i, false); if (method_verifier->GetInstructionFlags(i).IsCompileTimeInfoPoint()) { - CHECK_LT(map_index, map.NumEntries()); - CHECK_EQ(map.GetDexPc(map_index), i); - CHECK_EQ(map.GetBitMap(map_index), reg_bitmap); + DCHECK_LT(map_index, map.NumEntries()); + DCHECK_EQ(map.GetDexPc(map_index), i); + DCHECK_EQ(map.GetBitMap(map_index), reg_bitmap); map_index++; verifier::RegisterLine* line = method_verifier->GetRegLine(i); for (size_t j = 0; j < code_item->registers_size_; j++) { if (line->GetRegisterType(j).IsNonZeroReferenceTypes()) { - CHECK_LT(j / 8, map.RegWidth()); - CHECK_EQ((reg_bitmap[j / 8] >> (j % 8)) & 1, 1); + DCHECK_LT(j / 8, map.RegWidth()); + DCHECK_EQ((reg_bitmap[j / 8] >> (j % 8)) & 1, 1); } else if ((j / 8) < map.RegWidth()) { - CHECK_EQ((reg_bitmap[j / 8] >> (j % 8)) & 1, 0); + DCHECK_EQ((reg_bitmap[j / 8] >> (j % 8)) & 1, 0); } else { - // If a register doesn't contain a reference then the bitmap may be shorter than the line + // If a register doesn't contain a reference then the bitmap may be shorter than the line. } } } else { - CHECK(reg_bitmap == NULL); + DCHECK(reg_bitmap == NULL); } } } -void VerifiedMethodsData::ComputeGcMapSizes(verifier::MethodVerifier* method_verifier, - size_t* gc_points, size_t* ref_bitmap_bits, - size_t* log2_max_gc_pc) { +void VerifiedMethod::ComputeGcMapSizes(verifier::MethodVerifier* method_verifier, + size_t* gc_points, size_t* ref_bitmap_bits, + size_t* log2_max_gc_pc) { size_t local_gc_points = 0; size_t max_insn = 0; size_t max_ref_reg = -1; @@ -274,7 +182,7 @@ void VerifiedMethodsData::ComputeGcMapSizes(verifier::MethodVerifier* method_ver } } *gc_points = local_gc_points; - *ref_bitmap_bits = max_ref_reg + 1; // if max register is 0 we need 1 bit to encode (ie +1) + *ref_bitmap_bits = max_ref_reg + 1; // If max register is 0 we need 1 bit to encode (ie +1). size_t i = 0; while ((1U << i) <= max_insn) { i++; @@ -282,92 +190,13 @@ void VerifiedMethodsData::ComputeGcMapSizes(verifier::MethodVerifier* method_ver *log2_max_gc_pc = i; } -void VerifiedMethodsData::SetDexGcMap(MethodReference ref, const std::vector<uint8_t>* gc_map) { - DCHECK(Runtime::Current()->IsCompiler()); - { - WriterMutexLock mu(Thread::Current(), dex_gc_maps_lock_); - DexGcMapTable::iterator it = dex_gc_maps_.find(ref); - if (it != dex_gc_maps_.end()) { - delete it->second; - dex_gc_maps_.erase(it); - } - dex_gc_maps_.Put(ref, gc_map); - } - DCHECK(GetDexGcMap(ref) != NULL); -} - -VerifiedMethodsData::MethodSafeCastSet* VerifiedMethodsData::GenerateSafeCastSet( - verifier::MethodVerifier* method_verifier) { - /* - * Walks over the method code and adds any cast instructions in which - * the type cast is implicit to a set, which is used in the code generation - * to elide these casts. - */ - if (method_verifier->HasFailures()) { - return NULL; - } - UniquePtr<MethodSafeCastSet> mscs; - const DexFile::CodeItem* code_item = method_verifier->CodeItem(); - const Instruction* inst = Instruction::At(code_item->insns_); - const Instruction* end = Instruction::At(code_item->insns_ + - code_item->insns_size_in_code_units_); - - for (; inst < end; inst = inst->Next()) { - Instruction::Code code = inst->Opcode(); - if ((code == Instruction::CHECK_CAST) || (code == Instruction::APUT_OBJECT)) { - uint32_t dex_pc = inst->GetDexPc(code_item->insns_); - const verifier::RegisterLine* line = method_verifier->GetRegLine(dex_pc); - bool is_safe_cast = false; - if (code == Instruction::CHECK_CAST) { - const verifier::RegType& reg_type(line->GetRegisterType(inst->VRegA_21c())); - const verifier::RegType& cast_type = - method_verifier->ResolveCheckedClass(inst->VRegB_21c()); - is_safe_cast = cast_type.IsStrictlyAssignableFrom(reg_type); - } else { - const verifier::RegType& array_type(line->GetRegisterType(inst->VRegB_23x())); - // We only know its safe to assign to an array if the array type is precise. For example, - // an Object[] can have any type of object stored in it, but it may also be assigned a - // String[] in which case the stores need to be of Strings. - if (array_type.IsPreciseReference()) { - const verifier::RegType& value_type(line->GetRegisterType(inst->VRegA_23x())); - const verifier::RegType& component_type = method_verifier->GetRegTypeCache() - ->GetComponentType(array_type, method_verifier->GetClassLoader()); - is_safe_cast = component_type.IsStrictlyAssignableFrom(value_type); - } - } - if (is_safe_cast) { - if (mscs.get() == nullptr) { - mscs.reset(new MethodSafeCastSet()); - } else { - DCHECK_LT(mscs->back(), dex_pc); // Verify ordering for push_back() to the sorted vector. - } - mscs->push_back(dex_pc); - } - } - } - return mscs.release(); -} - -void VerifiedMethodsData::SetSafeCastMap(MethodReference ref, const MethodSafeCastSet* cast_set) { - WriterMutexLock mu(Thread::Current(), safecast_map_lock_); - SafeCastMap::iterator it = safecast_map_.find(ref); - if (it != safecast_map_.end()) { - delete it->second; - safecast_map_.erase(it); - } - safecast_map_.Put(ref, cast_set); - DCHECK(safecast_map_.find(ref) != safecast_map_.end()); -} - -VerifiedMethodsData::PcToConcreteMethodMap* VerifiedMethodsData::GenerateDevirtMap( - verifier::MethodVerifier* method_verifier) { +void VerifiedMethod::GenerateDevirtMap(verifier::MethodVerifier* method_verifier) { // It is risky to rely on reg_types for sharpening in cases of soft // verification, we might end up sharpening to a wrong implementation. Just abort. if (method_verifier->HasFailures()) { - return NULL; + return; } - UniquePtr<PcToConcreteMethodMap> pc_to_concrete_method_map; const DexFile::CodeItem* code_item = method_verifier->CodeItem(); const uint16_t* insns = code_item->insns_; const Instruction* inst = Instruction::At(insns); @@ -426,29 +255,58 @@ VerifiedMethodsData::PcToConcreteMethodMap* VerifiedMethodsData::GenerateDevirtM concrete_method->GetDeclaringClass()->IsFinal()) { // If we knew exactly the class being dispatched upon, or if the target method cannot be // overridden record the target to be used in the compiler driver. - if (pc_to_concrete_method_map.get() == NULL) { - pc_to_concrete_method_map.reset(new PcToConcreteMethodMap()); - } MethodReference concrete_ref( concrete_method->GetDeclaringClass()->GetDexCache()->GetDexFile(), concrete_method->GetDexMethodIndex()); - pc_to_concrete_method_map->Put(dex_pc, concrete_ref); + devirt_map_.Put(dex_pc, concrete_ref); } } - return pc_to_concrete_method_map.release(); } -void VerifiedMethodsData::SetDevirtMap(MethodReference ref, - const PcToConcreteMethodMap* devirt_map) { - WriterMutexLock mu(Thread::Current(), devirt_maps_lock_); - DevirtualizationMapTable::iterator it = devirt_maps_.find(ref); - if (it != devirt_maps_.end()) { - delete it->second; - devirt_maps_.erase(it); +void VerifiedMethod::GenerateSafeCastSet(verifier::MethodVerifier* method_verifier) { + /* + * Walks over the method code and adds any cast instructions in which + * the type cast is implicit to a set, which is used in the code generation + * to elide these casts. + */ + if (method_verifier->HasFailures()) { + return; } + const DexFile::CodeItem* code_item = method_verifier->CodeItem(); + const Instruction* inst = Instruction::At(code_item->insns_); + const Instruction* end = Instruction::At(code_item->insns_ + + code_item->insns_size_in_code_units_); - devirt_maps_.Put(ref, devirt_map); - DCHECK(devirt_maps_.find(ref) != devirt_maps_.end()); + for (; inst < end; inst = inst->Next()) { + Instruction::Code code = inst->Opcode(); + if ((code == Instruction::CHECK_CAST) || (code == Instruction::APUT_OBJECT)) { + uint32_t dex_pc = inst->GetDexPc(code_item->insns_); + const verifier::RegisterLine* line = method_verifier->GetRegLine(dex_pc); + bool is_safe_cast = false; + if (code == Instruction::CHECK_CAST) { + const verifier::RegType& reg_type(line->GetRegisterType(inst->VRegA_21c())); + const verifier::RegType& cast_type = + method_verifier->ResolveCheckedClass(inst->VRegB_21c()); + is_safe_cast = cast_type.IsStrictlyAssignableFrom(reg_type); + } else { + const verifier::RegType& array_type(line->GetRegisterType(inst->VRegB_23x())); + // We only know its safe to assign to an array if the array type is precise. For example, + // an Object[] can have any type of object stored in it, but it may also be assigned a + // String[] in which case the stores need to be of Strings. + if (array_type.IsPreciseReference()) { + const verifier::RegType& value_type(line->GetRegisterType(inst->VRegA_23x())); + const verifier::RegType& component_type = method_verifier->GetRegTypeCache() + ->GetComponentType(array_type, method_verifier->GetClassLoader()); + is_safe_cast = component_type.IsStrictlyAssignableFrom(value_type); + } + } + if (is_safe_cast) { + // Verify ordering for push_back() to the sorted vector. + DCHECK(safe_cast_set_.empty() || safe_cast_set_.back() < dex_pc); + safe_cast_set_.push_back(dex_pc); + } + } + } } } // namespace art diff --git a/compiler/dex/verified_method.h b/compiler/dex/verified_method.h new file mode 100644 index 0000000..aa0e72a --- /dev/null +++ b/compiler/dex/verified_method.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_COMPILER_DEX_VERIFIED_METHOD_H_ +#define ART_COMPILER_DEX_VERIFIED_METHOD_H_ + +#include <vector> + +#include "method_reference.h" +#include "safe_map.h" + +namespace art { + +namespace verifier { +class MethodVerifier; +} // namespace verifier + +class VerifiedMethod { + public: + // Cast elision set type. + // Since we're adding the dex PCs to the set in increasing order, a sorted vector + // is better for performance (not just memory usage), especially for large sets. + typedef std::vector<uint32_t> SafeCastSet; + + // Devirtualization map type maps dex offset to concrete method reference. + typedef SafeMap<uint32_t, MethodReference> DevirtualizationMap; + + static const VerifiedMethod* Create(verifier::MethodVerifier* method_verifier, bool compile) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + ~VerifiedMethod() = default; + + const std::vector<uint8_t>& GetDexGcMap() const { + return dex_gc_map_; + } + + const DevirtualizationMap& GetDevirtMap() const { + return devirt_map_; + } + + const SafeCastSet& GetSafeCastSet() const { + return safe_cast_set_; + } + + // Returns the devirtualization target method, or nullptr if none. + const MethodReference* GetDevirtTarget(uint32_t dex_pc) const; + + // 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(uint32_t pc) const; + + private: + VerifiedMethod() = default; + + /* + * Generate the GC map for a method that has just been verified (i.e. we're doing this as part of + * verification). For type-precise determination we have all the data we need, so we just need to + * encode it in some clever fashion. + * Stores the data in dex_gc_map_, returns true on success and false on failure. + */ + bool GenerateGcMap(verifier::MethodVerifier* method_verifier); + + // Verify that the GC map associated with method_ is well formed. + static void VerifyGcMap(verifier::MethodVerifier* method_verifier, + const std::vector<uint8_t>& data); + + // Compute sizes for GC map data. + static void ComputeGcMapSizes(verifier::MethodVerifier* method_verifier, + size_t* gc_points, size_t* ref_bitmap_bits, size_t* log2_max_gc_pc); + + // Generate devirtualizaion map into devirt_map_. + void GenerateDevirtMap(verifier::MethodVerifier* method_verifier) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + + // Generate safe case set into safe_cast_set_. + void GenerateSafeCastSet(verifier::MethodVerifier* method_verifier) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + + std::vector<uint8_t> dex_gc_map_; + DevirtualizationMap devirt_map_; + SafeCastSet safe_cast_set_; +}; + +} // namespace art + +#endif // ART_COMPILER_DEX_VERIFIED_METHOD_H_ diff --git a/compiler/dex/verified_methods_data.h b/compiler/dex/verified_methods_data.h deleted file mode 100644 index d495dff..0000000 --- a/compiler/dex/verified_methods_data.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ART_COMPILER_DEX_VERIFIED_METHODS_DATA_H_ -#define ART_COMPILER_DEX_VERIFIED_METHODS_DATA_H_ - -#include <stdint.h> -#include <set> -#include <vector> - -#include "base/macros.h" -#include "base/mutex.h" -#include "class_reference.h" -#include "method_reference.h" -#include "safe_map.h" - -namespace art { - -namespace verifier { -class MethodVerifier; -} // namespace verifier - -class VerifiedMethodsData { - public: - VerifiedMethodsData(); - ~VerifiedMethodsData(); - - bool ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier) - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) - LOCKS_EXCLUDED(dex_gc_maps_lock_, devirt_maps_lock_, safecast_map_lock_); - - const std::vector<uint8_t>* GetDexGcMap(MethodReference ref) - LOCKS_EXCLUDED(dex_gc_maps_lock_); - - const MethodReference* GetDevirtMap(const MethodReference& ref, uint32_t dex_pc) - LOCKS_EXCLUDED(devirt_maps_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_); - - static bool IsCandidateForCompilation(MethodReference& method_ref, - const uint32_t access_flags); - - private: - /* - * Generate the GC map for a method that has just been verified (i.e. we're doing this as part of - * verification). For type-precise determination we have all the data we need, so we just need to - * encode it in some clever fashion. - * Returns a pointer to a newly-allocated RegisterMap, or NULL on failure. - */ - const std::vector<uint8_t>* GenerateGcMap(verifier::MethodVerifier* method_verifier); - - // Verify that the GC map associated with method_ is well formed - void VerifyGcMap(verifier::MethodVerifier* method_verifier, const std::vector<uint8_t>& data); - - // Compute sizes for GC map data - void ComputeGcMapSizes(verifier::MethodVerifier* method_verifier, - size_t* gc_points, size_t* ref_bitmap_bits, size_t* log2_max_gc_pc); - - // All the GC maps that the verifier has created - typedef SafeMap<const MethodReference, const std::vector<uint8_t>*, - MethodReferenceComparator> DexGcMapTable; - ReaderWriterMutex dex_gc_maps_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; - DexGcMapTable dex_gc_maps_ GUARDED_BY(dex_gc_maps_lock_); - void SetDexGcMap(MethodReference ref, const std::vector<uint8_t>* dex_gc_map) - LOCKS_EXCLUDED(dex_gc_maps_lock_); - - // Cast elision types. - // Since we're adding the dex PCs to the set in increasing order, a sorted vector - // is better for performance (not just memory usage), especially for large sets. - typedef std::vector<uint32_t> MethodSafeCastSet; - typedef SafeMap<MethodReference, const MethodSafeCastSet*, - MethodReferenceComparator> SafeCastMap; - MethodSafeCastSet* GenerateSafeCastSet(verifier::MethodVerifier* method_verifier) - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void SetSafeCastMap(MethodReference ref, const MethodSafeCastSet* mscs) - LOCKS_EXCLUDED(safecast_map_lock_); - ReaderWriterMutex safecast_map_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; - SafeCastMap safecast_map_ GUARDED_BY(safecast_map_lock_); - - // Devirtualization map. - typedef SafeMap<uint32_t, MethodReference> PcToConcreteMethodMap; - typedef SafeMap<MethodReference, const PcToConcreteMethodMap*, - MethodReferenceComparator> DevirtualizationMapTable; - PcToConcreteMethodMap* GenerateDevirtMap(verifier::MethodVerifier* method_verifier) - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - ReaderWriterMutex devirt_maps_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; - DevirtualizationMapTable devirt_maps_ GUARDED_BY(devirt_maps_lock_); - void SetDevirtMap(MethodReference ref, const PcToConcreteMethodMap* pc_method_map) - LOCKS_EXCLUDED(devirt_maps_lock_); - - // Rejected classes - typedef std::set<ClassReference> RejectedClassesTable; - ReaderWriterMutex rejected_classes_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; - RejectedClassesTable rejected_classes_ GUARDED_BY(rejected_classes_lock_); -}; - -} // namespace art - -#endif // ART_COMPILER_DEX_VERIFIED_METHODS_DATA_H_ diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index f390b41..f84e01f 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -27,7 +27,7 @@ #include "class_linker.h" #include "dex_compilation_unit.h" #include "dex_file-inl.h" -#include "dex/verified_methods_data.h" +#include "dex/verification_results.h" #include "jni_internal.h" #include "object_utils.h" #include "runtime.h" @@ -336,13 +336,13 @@ extern "C" art::CompiledMethod* ArtQuickJniCompileMethod(art::CompilerDriver& co extern "C" void compilerLLVMSetBitcodeFileName(art::CompilerDriver& driver, std::string const& filename); -CompilerDriver::CompilerDriver(VerifiedMethodsData* verified_methods_data, +CompilerDriver::CompilerDriver(VerificationResults* verification_results, DexFileToMethodInlinerMap* method_inliner_map, CompilerBackend compiler_backend, InstructionSet instruction_set, InstructionSetFeatures instruction_set_features, bool image, DescriptorSet* image_classes, size_t thread_count, bool dump_stats) - : verified_methods_data_(verified_methods_data), + : verification_results_(verification_results), method_inliner_map_(method_inliner_map), compiler_backend_(compiler_backend), instruction_set_(instruction_set), @@ -1274,7 +1274,7 @@ bool CompilerDriver::ComputeInvokeInfo(const DexCompilationUnit* mUnit, const ui // Did the verifier record a more precise invoke target based on its type information? const MethodReference caller_method(mUnit->GetDexFile(), mUnit->GetDexMethodIndex()); const MethodReference* devirt_map_target = - verified_methods_data_->GetDevirtMap(caller_method, dex_pc); + verification_results_->GetDevirtMap(caller_method, dex_pc); if (devirt_map_target != NULL) { SirtRef<mirror::DexCache> target_dex_cache(soa.Self(), mUnit->GetClassLinker()->FindDexCache(*devirt_map_target->dex_file)); SirtRef<mirror::ClassLoader> class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())); @@ -1322,7 +1322,7 @@ bool CompilerDriver::ComputeInvokeInfo(const DexCompilationUnit* mUnit, const ui } bool CompilerDriver::IsSafeCast(const MethodReference& mr, uint32_t dex_pc) { - bool result = verified_methods_data_->IsSafeCast(mr, dex_pc); + bool result = verification_results_->IsSafeCast(mr, dex_pc); if (result) { stats_->SafeCast(); } else { @@ -2268,7 +2268,7 @@ void CompilerDriver::CompileClass(const ParallelCompilationManager* manager, siz } ClassReference ref(&dex_file, class_def_index); // Skip compiling classes with generic verifier failures since they will still fail at runtime - if (manager->GetCompiler()->verified_methods_data_->IsClassRejected(ref)) { + if (manager->GetCompiler()->verification_results_->IsClassRejected(ref)) { return; } const byte* class_data = dex_file.GetClassData(class_def); @@ -2351,7 +2351,7 @@ void CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t } else if ((access_flags & kAccAbstract) != 0) { } else { MethodReference method_ref(&dex_file, method_idx); - bool compile = VerifiedMethodsData::IsCandidateForCompilation(method_ref, access_flags); + bool compile = VerificationResults::IsCandidateForCompilation(method_ref, access_flags); if (compile) { CompilerFn compiler = compiler_; diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index eef94a1..f8aa868 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -44,7 +44,7 @@ class DexCompilationUnit; class DexFileToMethodInlinerMap; class OatWriter; class TimingLogger; -class VerifiedMethodsData; +class VerificationResults; enum CompilerBackend { kQuick, @@ -92,7 +92,7 @@ class CompilerDriver { // enabled. "image_classes" lets the compiler know what classes it // can assume will be in the image, with NULL implying all available // classes. - explicit CompilerDriver(VerifiedMethodsData* verified_methods_data, + explicit CompilerDriver(VerificationResults* verification_results, DexFileToMethodInlinerMap* method_inliner_map, CompilerBackend compiler_backend, InstructionSet instruction_set, InstructionSetFeatures instruction_set_features, @@ -109,8 +109,8 @@ class CompilerDriver { void CompileOne(const mirror::ArtMethod* method, TimingLogger& timings) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - VerifiedMethodsData* GetVerifiedMethodsData() const { - return verified_methods_data_; + VerificationResults* GetVerificationResults() const { + return verification_results_; } DexFileToMethodInlinerMap* GetMethodInlinerMap() const { @@ -486,7 +486,7 @@ class CompilerDriver { std::vector<const CallPatchInformation*> methods_to_patch_; std::vector<const TypePatchInformation*> classes_to_patch_; - VerifiedMethodsData* verified_methods_data_; + VerificationResults* verification_results_; DexFileToMethodInlinerMap* method_inliner_map_; CompilerBackend compiler_backend_; diff --git a/compiler/llvm/compiler_llvm.cc b/compiler/llvm/compiler_llvm.cc index 35d1ecd..8f996fa 100644 --- a/compiler/llvm/compiler_llvm.cc +++ b/compiler/llvm/compiler_llvm.cc @@ -20,7 +20,7 @@ #include "base/stl_util.h" #include "class_linker.h" #include "compiled_method.h" -#include "dex/verified_methods_data.h" +#include "dex/verification_results.h" #include "driver/compiler_driver.h" #include "driver/dex_compilation_unit.h" #include "globals.h" @@ -157,7 +157,7 @@ CompileDexMethod(DexCompilationUnit* dex_compilation_unit, InvokeType invoke_typ dex_compilation_unit->GetDexMethodIndex()); return new CompiledMethod(*compiler_driver_, compiler_driver_->GetInstructionSet(), cunit->GetElfObject(), - *compiler_driver_->GetVerifiedMethodsData()->GetDexGcMap(mref), + *compiler_driver_->GetVerificationResults()->GetDexGcMap(mref), cunit->GetDexCompilationUnit()->GetSymbol()); } diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc index 2434262..fc45412 100644 --- a/compiler/oat_test.cc +++ b/compiler/oat_test.cc @@ -79,10 +79,10 @@ TEST_F(OatTest, WriteRead) { InstructionSet insn_set = kIsTargetBuild ? kThumb2 : kX86; InstructionSetFeatures insn_features; - verified_methods_data_.reset(new VerifiedMethodsData); + verification_results_.reset(new VerificationResults); method_inliner_map_.reset(compiler_backend == kQuick ? new DexFileToMethodInlinerMap : nullptr); - callbacks_.Reset(verified_methods_data_.get(), method_inliner_map_.get()); - compiler_driver_.reset(new CompilerDriver(verified_methods_data_.get(), + callbacks_.Reset(verification_results_.get(), method_inliner_map_.get()); + compiler_driver_.reset(new CompilerDriver(verification_results_.get(), method_inliner_map_.get(), compiler_backend, insn_set, insn_features, false, NULL, 2, true)); diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index 199a2b8..7a902d8 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -23,7 +23,7 @@ #include "base/unix_file/fd_file.h" #include "class_linker.h" #include "dex_file-inl.h" -#include "dex/verified_methods_data.h" +#include "dex/verification_results.h" #include "gc/space/space.h" #include "mirror/art_method-inl.h" #include "mirror/array.h" @@ -218,7 +218,7 @@ size_t OatWriter::InitOatClasses(size_t offset) { mirror::Class::Status status; if (compiled_class != NULL) { status = compiled_class->GetStatus(); - } else if (compiler_driver_->GetVerifiedMethodsData()->IsClassRejected(class_ref)) { + } else if (compiler_driver_->GetVerificationResults()->IsClassRejected(class_ref)) { status = mirror::Class::kStatusError; } else { status = mirror::Class::kStatusNotReady; @@ -433,7 +433,7 @@ size_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, mirror::Class::Status status; if (compiled_class != NULL) { status = compiled_class->GetStatus(); - } else if (compiler_driver_->GetVerifiedMethodsData()->IsClassRejected(class_ref)) { + } else if (compiler_driver_->GetVerificationResults()->IsClassRejected(class_ref)) { status = mirror::Class::kStatusError; } else { status = mirror::Class::kStatusNotReady; |