Avoid cases of deriving information from unresolved types giving conflict.
Previously non-trivial merges of unresolved types resulted in conflict
(bottom), introduce a new type to represent this case. Similarly
implement a type for unresolved super classes.
Change-Id: Ib84ba082cb9409ad3acaa49dafbc6b1dd1c7772d
diff --git a/src/verifier/reg_type_cache.cc b/src/verifier/reg_type_cache.cc
index bb05e7e..37086c9 100644
--- a/src/verifier/reg_type_cache.cc
+++ b/src/verifier/reg_type_cache.cc
@@ -143,6 +143,60 @@
}
}
+const RegType& RegTypeCache::FromUnresolvedMerge(const RegType& left, const RegType& right) {
+ std::set<uint16_t> types;
+ if (left.IsUnresolvedMergedReference()) {
+ types = left.GetMergedTypes(this);
+ } else {
+ types.insert(left.GetId());
+ }
+ if (right.IsUnresolvedMergedReference()) {
+ std::set<uint16_t> right_types = right.GetMergedTypes(this);
+ types.insert(right_types.begin(), right_types.end());
+ } else {
+ types.insert(right.GetId());
+ }
+ // Check if entry already exists.
+ for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
+ RegType* cur_entry = entries_[i];
+ if (cur_entry->IsUnresolvedMergedReference()) {
+ std::set<uint16_t> cur_entry_types = cur_entry->GetMergedTypes(this);
+ if (cur_entry_types == types) {
+ return *cur_entry;
+ }
+ }
+ }
+ // Create entry.
+ uint32_t merged_ids = static_cast<uint32_t>(left.GetId()) << 16 |
+ static_cast<uint32_t>(right.GetId());
+ RegType* entry = new RegType(RegType::kRegTypeUnresolvedMergedReference, NULL, merged_ids,
+ entries_.size());
+ entries_.push_back(entry);
+#ifndef DEBUG
+ std::set<uint16_t> check_types = entry->GetMergedTypes(this);
+ CHECK(check_types == types);
+#endif
+ return *entry;
+}
+
+const RegType& RegTypeCache::FromUnresolvedSuperClass(const RegType& child) {
+ // Check if entry already exists.
+ for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
+ RegType* cur_entry = entries_[i];
+ if (cur_entry->IsUnresolvedSuperClass()) {
+ uint16_t unresolved_super_child_id = cur_entry->GetUnresolvedSuperClassChildId();
+ if (unresolved_super_child_id == child.GetId()) {
+ return *cur_entry;
+ }
+ }
+ }
+ // Create entry.
+ RegType* entry = new RegType(RegType::kRegTypeUnresolvedSuperClass, NULL, child.GetId(),
+ entries_.size());
+ entries_.push_back(entry);
+ return *entry;
+}
+
const RegType& RegTypeCache::Uninitialized(const RegType& type, uint32_t allocation_pc) {
RegType* entry;
if (type.IsUnresolvedTypes()) {