Add a pool of small cat1 constants to the verifier.
This avoids creating constants in roughly half the cases seen in boot/core.
Also, strengthen the types on a few of the RegTypeCache routines, add some
documentation and move methods to the appropriate location and out of being
public when possible.
Change-Id: I384189d51d8f097bb7f744c0f6275dee4bb11302
diff --git a/runtime/verifier/reg_type_cache.cc b/runtime/verifier/reg_type_cache.cc
index 2c18132..ce465a4 100644
--- a/runtime/verifier/reg_type_cache.cc
+++ b/runtime/verifier/reg_type_cache.cc
@@ -26,8 +26,8 @@
namespace verifier {
bool RegTypeCache::primitive_initialized_ = false;
-uint16_t RegTypeCache::primitive_start_ = 0;
uint16_t RegTypeCache::primitive_count_ = 0;
+PreciseConstType* RegTypeCache::small_precise_constants_[kMaxSmallConstant - kMinSmallConstant + 1];
static bool MatchingPrecisionForClass(RegType* entry, bool precise)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -44,7 +44,7 @@
}
}
-void RegTypeCache::FillPrimitiveTypes() {
+void RegTypeCache::FillPrimitiveAndSmallConstantTypes() {
entries_.push_back(UndefinedType::GetInstance());
entries_.push_back(ConflictType::GetInstance());
entries_.push_back(BooleanType::GetInstance());
@@ -57,6 +57,11 @@
entries_.push_back(FloatType::GetInstance());
entries_.push_back(DoubleLoType::GetInstance());
entries_.push_back(DoubleHiType::GetInstance());
+ for (int32_t value = kMinSmallConstant; value <= kMaxSmallConstant; ++value) {
+ int32_t i = value - kMinSmallConstant;
+ DCHECK_EQ(entries_.size(), small_precise_constants_[i]->GetId());
+ entries_.push_back(small_precise_constants_[i]);
+ }
DCHECK_EQ(entries_.size(), primitive_count_);
}
@@ -232,12 +237,12 @@
RegTypeCache::~RegTypeCache() {
CHECK_LE(primitive_count_, entries_.size());
// Delete only the non primitive types.
- if (entries_.size() == kNumPrimitives) {
- // All entries are primitive, nothing to delete.
+ if (entries_.size() == kNumPrimitivesAndSmallConstants) {
+ // All entries are from the global pool, nothing to delete.
return;
}
std::vector<RegType*>::iterator non_primitive_begin = entries_.begin();
- std::advance(non_primitive_begin, kNumPrimitives);
+ std::advance(non_primitive_begin, kNumPrimitivesAndSmallConstants);
STLDeleteContainerPointers(non_primitive_begin, entries_.end());
}
@@ -255,12 +260,29 @@
FloatType::Destroy();
DoubleLoType::Destroy();
DoubleHiType::Destroy();
+ for (uint16_t value = kMinSmallConstant; value <= kMaxSmallConstant; ++value) {
+ PreciseConstType* type = small_precise_constants_[value - kMinSmallConstant];
+ delete type;
+ }
+
RegTypeCache::primitive_initialized_ = false;
RegTypeCache::primitive_count_ = 0;
}
}
-void RegTypeCache::CreatePrimitiveTypes() {
+template <class Type>
+Type* RegTypeCache::CreatePrimitiveTypeInstance(const std::string& descriptor) {
+ mirror::Class* klass = NULL;
+ // Try loading the class from linker.
+ if (!descriptor.empty()) {
+ klass = art::Runtime::Current()->GetClassLinker()->FindSystemClass(descriptor.c_str());
+ }
+ Type* entry = Type::CreateInstance(klass, descriptor, RegTypeCache::primitive_count_);
+ RegTypeCache::primitive_count_++;
+ return entry;
+}
+
+void RegTypeCache::CreatePrimitiveAndSmallConstantTypes() {
CreatePrimitiveTypeInstance<UndefinedType>("");
CreatePrimitiveTypeInstance<ConflictType>("");
CreatePrimitiveTypeInstance<BooleanType>("Z");
@@ -273,6 +295,11 @@
CreatePrimitiveTypeInstance<FloatType>("F");
CreatePrimitiveTypeInstance<DoubleLoType>("D");
CreatePrimitiveTypeInstance<DoubleHiType>("D");
+ for (int32_t value = kMinSmallConstant; value <= kMaxSmallConstant; ++value) {
+ PreciseConstType* type = new PreciseConstType(value, primitive_count_);
+ small_precise_constants_[value - kMinSmallConstant] = type;
+ primitive_count_++;
+ }
}
const RegType& RegTypeCache::FromUnresolvedMerge(const RegType& left, const RegType& right) {
@@ -331,29 +358,28 @@
return *entry;
}
-const RegType& RegTypeCache::Uninitialized(const RegType& type, uint32_t allocation_pc) {
- RegType* entry = NULL;
- RegType* cur_entry = NULL;
+const UninitializedType& RegTypeCache::Uninitialized(const RegType& type, uint32_t allocation_pc) {
+ UninitializedType* entry = NULL;
const std::string& descriptor(type.GetDescriptor());
if (type.IsUnresolvedTypes()) {
for (size_t i = primitive_count_; i < entries_.size(); i++) {
- cur_entry = entries_[i];
+ RegType* cur_entry = entries_[i];
if (cur_entry->IsUnresolvedAndUninitializedReference() &&
down_cast<UnresolvedUninitializedRefType*>(cur_entry)->GetAllocationPc() == allocation_pc &&
(cur_entry->GetDescriptor() == descriptor)) {
- return *cur_entry;
+ return *down_cast<UnresolvedUninitializedRefType*>(cur_entry);
}
}
entry = new UnresolvedUninitializedRefType(descriptor, allocation_pc, entries_.size());
} else {
mirror::Class* klass = type.GetClass();
for (size_t i = primitive_count_; i < entries_.size(); i++) {
- cur_entry = entries_[i];
+ RegType* cur_entry = entries_[i];
if (cur_entry->IsUninitializedReference() &&
down_cast<UninitializedReferenceType*>(cur_entry)
->GetAllocationPc() == allocation_pc &&
cur_entry->GetClass() == klass) {
- return *cur_entry;
+ return *down_cast<UninitializedReferenceType*>(cur_entry);
}
}
entry = new UninitializedReferenceType(klass, descriptor, allocation_pc, entries_.size());
@@ -404,27 +430,33 @@
return *entry;
}
-const RegType& RegTypeCache::ByteConstant() {
- return FromCat1Const(std::numeric_limits<jbyte>::min(), false);
+const ImpreciseConstType& RegTypeCache::ByteConstant() {
+ const ConstantType& result = FromCat1Const(std::numeric_limits<jbyte>::min(), false);
+ DCHECK(result.IsImpreciseConstant());
+ return *down_cast<const ImpreciseConstType*>(&result);
}
-const RegType& RegTypeCache::ShortConstant() {
- return FromCat1Const(std::numeric_limits<jshort>::min(), false);
+const ImpreciseConstType& RegTypeCache::ShortConstant() {
+ const ConstantType& result = FromCat1Const(std::numeric_limits<jshort>::min(), false);
+ DCHECK(result.IsImpreciseConstant());
+ return *down_cast<const ImpreciseConstType*>(&result);
}
-const RegType& RegTypeCache::IntConstant() {
- return FromCat1Const(std::numeric_limits<jint>::max(), false);
+const ImpreciseConstType& RegTypeCache::IntConstant() {
+ const ConstantType& result = FromCat1Const(std::numeric_limits<jint>::max(), false);
+ DCHECK(result.IsImpreciseConstant());
+ return *down_cast<const ImpreciseConstType*>(&result);
}
-const RegType& RegTypeCache::UninitializedThisArgument(const RegType& type) {
- RegType* entry;
+const UninitializedType& RegTypeCache::UninitializedThisArgument(const RegType& type) {
+ UninitializedType* entry;
const std::string& descriptor(type.GetDescriptor());
if (type.IsUnresolvedTypes()) {
for (size_t i = primitive_count_; i < entries_.size(); i++) {
RegType* cur_entry = entries_[i];
if (cur_entry->IsUnresolvedAndUninitializedThisReference() &&
cur_entry->GetDescriptor() == descriptor) {
- return *cur_entry;
+ return *down_cast<UninitializedType*>(cur_entry);
}
}
entry = new UnresolvedUninitializedThisRefType(descriptor, entries_.size());
@@ -433,7 +465,7 @@
for (size_t i = primitive_count_; i < entries_.size(); i++) {
RegType* cur_entry = entries_[i];
if (cur_entry->IsUninitializedThisReference() && cur_entry->GetClass() == klass) {
- return *cur_entry;
+ return *down_cast<UninitializedType*>(cur_entry);
}
}
entry = new UninitializedThisReferenceType(klass, descriptor, entries_.size());
@@ -442,16 +474,16 @@
return *entry;
}
-const RegType& RegTypeCache::FromCat1Const(int32_t value, bool precise) {
+const ConstantType& RegTypeCache::FromCat1NonSmallConstant(int32_t value, bool precise) {
for (size_t i = primitive_count_; i < entries_.size(); i++) {
RegType* cur_entry = entries_[i];
if (cur_entry->klass_ == NULL && cur_entry->IsConstant() &&
cur_entry->IsPreciseConstant() == precise &&
(down_cast<ConstantType*>(cur_entry))->ConstantValue() == value) {
- return *cur_entry;
+ return *down_cast<ConstantType*>(cur_entry);
}
}
- RegType* entry;
+ ConstantType* entry;
if (precise) {
entry = new PreciseConstType(value, entries_.size());
} else {
@@ -461,15 +493,15 @@
return *entry;
}
-const RegType& RegTypeCache::FromCat2ConstLo(int32_t value, bool precise) {
+const ConstantType& RegTypeCache::FromCat2ConstLo(int32_t value, bool precise) {
for (size_t i = primitive_count_; i < entries_.size(); i++) {
RegType* cur_entry = entries_[i];
if (cur_entry->IsConstantLo() && (cur_entry->IsPrecise() == precise) &&
(down_cast<ConstantType*>(cur_entry))->ConstantValueLo() == value) {
- return *cur_entry;
+ return *down_cast<ConstantType*>(cur_entry);
}
}
- RegType* entry;
+ ConstantType* entry;
if (precise) {
entry = new PreciseConstLoType(value, entries_.size());
} else {
@@ -479,15 +511,15 @@
return *entry;
}
-const RegType& RegTypeCache::FromCat2ConstHi(int32_t value, bool precise) {
+const ConstantType& RegTypeCache::FromCat2ConstHi(int32_t value, bool precise) {
for (size_t i = primitive_count_; i < entries_.size(); i++) {
RegType* cur_entry = entries_[i];
if (cur_entry->IsConstantHi() && (cur_entry->IsPrecise() == precise) &&
(down_cast<ConstantType*>(cur_entry))->ConstantValueHi() == value) {
- return *cur_entry;
+ return *down_cast<ConstantType*>(cur_entry);
}
}
- RegType* entry;
+ ConstantType* entry;
if (precise) {
entry = new PreciseConstHiType(value, entries_.size());
} else {