Verifier improvements.
Make type hierarchy for unresolved and unitialized types explicit.
Tidy and comment code.
Add DexFile::FindStringId that takes UTF-16 to avoid unnecessary UTF-8
conversions during image writing.
Explicitly disable RTTI that causes problems in debug builds.
Change-Id: I701f1c3be8be5854fcabf5ec39e9f9c5d388aab0
diff --git a/src/verifier/reg_type_cache.cc b/src/verifier/reg_type_cache.cc
index 57a825b..a575f77 100644
--- a/src/verifier/reg_type_cache.cc
+++ b/src/verifier/reg_type_cache.cc
@@ -108,29 +108,14 @@
}
bool RegTypeCache::MatchDescriptor(size_t idx, const char* descriptor, bool precise) {
- RegType* cur_entry = entries_[idx];
- if (cur_entry->HasClass()) {
- // Check the descriptor in the reg_type if available.
- if(!cur_entry->descriptor_.empty()) {
- if (cur_entry->descriptor_ == descriptor && MatchingPrecisionForClass(cur_entry, precise)) {
- return true;
- }
- } else {
- // TODO: maintain an invariant that when we have a Class the descriptor is computed from that.
- // Descriptor not found in reg_type, maybe available in Class object.
- // So we might have cases where we have the class but not the descriptor
- // for that class we need the class helper to get the descriptor
- // and match it with the one we are given.
- ClassHelper kh(cur_entry->GetClass());
- if ((strcmp(descriptor, kh.GetDescriptor()) == 0) &&
- MatchingPrecisionForClass(cur_entry, precise)) {
- return true;
- }
- }
- } else if (cur_entry->IsUnresolvedReference() && cur_entry->GetDescriptor() == descriptor) {
+ RegType* entry = entries_[idx];
+ if (entry->descriptor_ != descriptor) {
+ return false;
+ }
+ if (entry->HasClass() && MatchingPrecisionForClass(entry, precise)) {
return true;
}
- return false;
+ return entry->IsUnresolvedReference();
}
mirror::Class* RegTypeCache::ResolveClass(const char* descriptor, mirror::ClassLoader* loader) {
@@ -206,24 +191,23 @@
}
}
-const RegType& RegTypeCache::FromClass(mirror::Class* klass, bool precise) {
+const RegType& RegTypeCache::FromClass(const char* descriptor, mirror::Class* klass, bool precise) {
if (klass->IsPrimitive()) {
return RegTypeFromPrimitiveType(klass->GetPrimitiveType());
} else {
// Look for the reference in the list of entries to have.
for (size_t i = primitive_count_; i < entries_.size(); i++) {
RegType* cur_entry = entries_[i];
- if ((cur_entry->HasClass()) && cur_entry->GetClass() == klass &&
- MatchingPrecisionForClass(cur_entry, precise)) {
+ if (cur_entry->klass_ == klass && MatchingPrecisionForClass(cur_entry, precise)) {
return *cur_entry;
}
}
// No reference to the class was found, create new reference.
RegType* entry;
if (precise) {
- entry = new PreciseReferenceType(klass, "", entries_.size());
+ entry = new PreciseReferenceType(klass, descriptor, entries_.size());
} else {
- entry = new ReferenceType(klass, "", entries_.size());
+ entry = new ReferenceType(klass, descriptor, entries_.size());
}
entries_.push_back(entry);
return *entry;
@@ -335,8 +319,8 @@
const RegType& RegTypeCache::Uninitialized(const RegType& type, uint32_t allocation_pc) {
RegType* entry = NULL;
RegType* cur_entry = NULL;
+ const std::string& descriptor(type.GetDescriptor());
if (type.IsUnresolvedTypes()) {
- const std::string& descriptor(type.GetDescriptor());
for (size_t i = primitive_count_; i < entries_.size(); i++) {
cur_entry = entries_[i];
if (cur_entry->IsUnresolvedAndUninitializedReference() &&
@@ -345,7 +329,7 @@
return *cur_entry;
}
}
- entry = new UnresolvedUninitializedRefType(descriptor.c_str(), allocation_pc, entries_.size());
+ entry = new UnresolvedUninitializedRefType(descriptor, allocation_pc, entries_.size());
} else {
mirror::Class* klass = type.GetClass();
for (size_t i = primitive_count_; i < entries_.size(); i++) {
@@ -357,7 +341,7 @@
return *cur_entry;
}
}
- entry = new UninitializedReferenceType(klass, "", allocation_pc, entries_.size());
+ entry = new UninitializedReferenceType(klass, descriptor, allocation_pc, entries_.size());
}
entries_.push_back(entry);
return *entry;
@@ -432,8 +416,8 @@
const RegType& RegTypeCache::UninitializedThisArgument(const RegType& type) {
RegType* entry;
+ const std::string& descriptor(type.GetDescriptor());
if (type.IsUnresolvedTypes()) {
- const std::string& descriptor(type.GetDescriptor());
for (size_t i = primitive_count_; i < entries_.size(); i++) {
RegType* cur_entry = entries_[i];
if (cur_entry->IsUnresolvedAndUninitializedThisReference() &&
@@ -451,7 +435,7 @@
return *cur_entry;
}
}
- entry = new UninitializedThisReferenceType(klass, "", entries_.size());
+ entry = new UninitializedThisReferenceType(klass, descriptor, entries_.size());
}
entries_.push_back(entry);
return *entry;
@@ -460,7 +444,8 @@
const RegType& RegTypeCache::FromCat1Const(int32_t value, bool precise) {
for (size_t i = primitive_count_; i < entries_.size(); i++) {
RegType* cur_entry = entries_[i];
- if (cur_entry->IsConstant() && cur_entry->IsPreciseConstant() == precise &&
+ if (cur_entry->klass_ == NULL && cur_entry->IsConstant() &&
+ cur_entry->IsPreciseConstant() == precise &&
(down_cast<ConstantType*>(cur_entry))->ConstantValue() == value) {
return *cur_entry;
}
@@ -519,7 +504,7 @@
return FromDescriptor(loader, component.c_str(), false);
} else {
mirror::Class* klass = array.GetClass()->GetComponentType();
- return FromClass(klass, klass->IsFinal());
+ return FromClass(ClassHelper(klass).GetDescriptor(), klass, klass->IsFinal());
}
}