summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Marko <vmarko@google.com>2014-01-24 17:55:18 +0000
committerVladimir Marko <vmarko@google.com>2014-01-28 11:22:42 +0000
commitc7f832061fea59fd6abd125f26c8ca1faec695a5 (patch)
tree183afb5dfc1f4e6fb81f14707caffa558d31dbcc
parent7ea5dafc81b2bba7cabad26130bb75dc8f709803 (diff)
downloadart-c7f832061fea59fd6abd125f26c8ca1faec695a5.zip
art-c7f832061fea59fd6abd125f26c8ca1faec695a5.tar.gz
art-c7f832061fea59fd6abd125f26c8ca1faec695a5.tar.bz2
Refactor verification results.
Rename VerificationMethodsData to VerificationResults. Create new class VerifiedMethod to hold all the data for a given method. Change-Id: Ife1ac67cede20f3a2f9c7f5345f08a851cf1ed20
-rw-r--r--compiler/Android.mk3
-rw-r--r--compiler/dex/quick/codegen_util.cc4
-rw-r--r--compiler/dex/verification_results.cc128
-rw-r--r--compiler/dex/verification_results.h80
-rw-r--r--compiler/dex/verified_method.cc (renamed from compiler/dex/verified_methods_data.cc)352
-rw-r--r--compiler/dex/verified_method.h98
-rw-r--r--compiler/dex/verified_methods_data.h117
-rw-r--r--compiler/driver/compiler_driver.cc14
-rw-r--r--compiler/driver/compiler_driver.h10
-rw-r--r--compiler/llvm/compiler_llvm.cc4
-rw-r--r--compiler/oat_test.cc6
-rw-r--r--compiler/oat_writer.cc6
-rw-r--r--dex2oat/dex2oat.cc20
-rw-r--r--runtime/common_test.h26
-rw-r--r--runtime/method_reference.h2
15 files changed, 460 insertions, 410 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;
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 26fac23..97df199 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -32,7 +32,7 @@
#include "class_linker.h"
#include "compiler_callbacks.h"
#include "dex_file-inl.h"
-#include "dex/verified_methods_data.h"
+#include "dex/verification_results.h"
#include "driver/compiler_driver.h"
#include "elf_fixup.h"
#include "elf_stripper.h"
@@ -268,7 +268,7 @@ class Dex2Oat {
Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path_files);
}
- UniquePtr<CompilerDriver> driver(new CompilerDriver(verified_methods_data_.get(),
+ UniquePtr<CompilerDriver> driver(new CompilerDriver(verification_results_.get(),
method_inliner_map_.get(),
compiler_backend_,
instruction_set_,
@@ -348,15 +348,15 @@ class Dex2Oat {
private:
class Dex2OatCompilerCallbacks : public CompilerCallbacks {
public:
- Dex2OatCompilerCallbacks(VerifiedMethodsData* verified_methods_data,
+ Dex2OatCompilerCallbacks(VerificationResults* verification_results,
DexFileToMethodInlinerMap* method_inliner_map)
- : verified_methods_data_(verified_methods_data),
+ : verification_results_(verification_results),
method_inliner_map_(method_inliner_map) { }
virtual ~Dex2OatCompilerCallbacks() { }
virtual bool MethodVerified(verifier::MethodVerifier* verifier)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- bool result = verified_methods_data_->ProcessVerifiedMethod(verifier);
+ bool result = verification_results_->ProcessVerifiedMethod(verifier);
if (result && method_inliner_map_ != nullptr) {
MethodReference ref = verifier->GetMethodReference();
method_inliner_map_->GetMethodInliner(ref.dex_file)
@@ -365,11 +365,11 @@ class Dex2Oat {
return result;
}
virtual void ClassRejected(ClassReference ref) {
- verified_methods_data_->AddRejectedClass(ref);
+ verification_results_->AddRejectedClass(ref);
}
private:
- VerifiedMethodsData* verified_methods_data_;
+ VerificationResults* verification_results_;
DexFileToMethodInlinerMap* method_inliner_map_;
};
@@ -380,9 +380,9 @@ class Dex2Oat {
: compiler_backend_(compiler_backend),
instruction_set_(instruction_set),
instruction_set_features_(instruction_set_features),
- verified_methods_data_(new VerifiedMethodsData),
+ verification_results_(new VerificationResults),
method_inliner_map_(compiler_backend == kQuick ? new DexFileToMethodInlinerMap : nullptr),
- callbacks_(verified_methods_data_.get(), method_inliner_map_.get()),
+ callbacks_(verification_results_.get(), method_inliner_map_.get()),
runtime_(nullptr),
thread_count_(thread_count),
start_ns_(NanoTime()) {
@@ -446,7 +446,7 @@ class Dex2Oat {
const InstructionSet instruction_set_;
const InstructionSetFeatures instruction_set_features_;
- UniquePtr<VerifiedMethodsData> verified_methods_data_;
+ UniquePtr<VerificationResults> verification_results_;
UniquePtr<DexFileToMethodInlinerMap> method_inliner_map_;
Dex2OatCompilerCallbacks callbacks_;
Runtime* runtime_;
diff --git a/runtime/common_test.h b/runtime/common_test.h
index ee95d5b..5e6354e 100644
--- a/runtime/common_test.h
+++ b/runtime/common_test.h
@@ -26,7 +26,7 @@
#include "../../external/icu4c/common/unicode/uvernum.h"
#include "../compiler/dex/quick/dex_file_to_method_inliner_map.h"
-#include "../compiler/dex/verified_methods_data.h"
+#include "../compiler/dex/verification_results.h"
#include "../compiler/driver/compiler_driver.h"
#include "base/macros.h"
#include "base/stl_util.h"
@@ -425,9 +425,9 @@ class CommonTest : public testing::Test {
CompilerBackend compiler_backend = kQuick;
#endif
- 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());
+ callbacks_.Reset(verification_results_.get(), method_inliner_map_.get());
Runtime::Options options;
options.push_back(std::make_pair("compilercallbacks", static_cast<CompilerCallbacks*>(&callbacks_)));
options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
@@ -474,7 +474,7 @@ class CommonTest : public testing::Test {
}
}
class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
- compiler_driver_.reset(new CompilerDriver(verified_methods_data_.get(),
+ compiler_driver_.reset(new CompilerDriver(verification_results_.get(),
method_inliner_map_.get(),
compiler_backend, instruction_set,
instruction_set_features,
@@ -526,7 +526,7 @@ class CommonTest : public testing::Test {
compiler_driver_.reset();
callbacks_.Reset(nullptr, nullptr);
method_inliner_map_.reset();
- verified_methods_data_.reset();
+ verification_results_.reset();
STLDeleteElements(&opened_dex_files_);
Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
@@ -654,18 +654,18 @@ class CommonTest : public testing::Test {
class TestCompilerCallbacks : public CompilerCallbacks {
public:
- TestCompilerCallbacks() : verified_methods_data_(nullptr), method_inliner_map_(nullptr) { }
+ TestCompilerCallbacks() : verification_results_(nullptr), method_inliner_map_(nullptr) { }
- void Reset(VerifiedMethodsData* verified_methods_data,
+ void Reset(VerificationResults* verification_results,
DexFileToMethodInlinerMap* method_inliner_map) {
- verified_methods_data_ = verified_methods_data;
+ verification_results_ = verification_results;
method_inliner_map_ = method_inliner_map;
}
virtual bool MethodVerified(verifier::MethodVerifier* verifier)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- CHECK(verified_methods_data_);
- bool result = verified_methods_data_->ProcessVerifiedMethod(verifier);
+ CHECK(verification_results_);
+ bool result = verification_results_->ProcessVerifiedMethod(verifier);
if (result && method_inliner_map_ != nullptr) {
MethodReference ref = verifier->GetMethodReference();
method_inliner_map_->GetMethodInliner(ref.dex_file)
@@ -674,11 +674,11 @@ class CommonTest : public testing::Test {
return result;
}
virtual void ClassRejected(ClassReference ref) {
- verified_methods_data_->AddRejectedClass(ref);
+ verification_results_->AddRejectedClass(ref);
}
private:
- VerifiedMethodsData* verified_methods_data_;
+ VerificationResults* verification_results_;
DexFileToMethodInlinerMap* method_inliner_map_;
};
@@ -689,7 +689,7 @@ class CommonTest : public testing::Test {
UniquePtr<Runtime> runtime_;
// Owned by the runtime
ClassLinker* class_linker_;
- UniquePtr<VerifiedMethodsData> verified_methods_data_;
+ UniquePtr<VerificationResults> verification_results_;
UniquePtr<DexFileToMethodInlinerMap> method_inliner_map_;
TestCompilerCallbacks callbacks_;
UniquePtr<CompilerDriver> compiler_driver_;
diff --git a/runtime/method_reference.h b/runtime/method_reference.h
index 1ff4ea0..8e46d7e 100644
--- a/runtime/method_reference.h
+++ b/runtime/method_reference.h
@@ -17,6 +17,8 @@
#ifndef ART_RUNTIME_METHOD_REFERENCE_H_
#define ART_RUNTIME_METHOD_REFERENCE_H_
+#include <stdint.h>
+
namespace art {
class DexFile;