diff options
-rw-r--r-- | runtime/verifier/reg_type.cc | 11 | ||||
-rw-r--r-- | runtime/verifier/reg_type_cache-inl.h | 21 | ||||
-rw-r--r-- | runtime/verifier/reg_type_cache.cc | 96 | ||||
-rw-r--r-- | runtime/verifier/reg_type_cache.h | 63 |
4 files changed, 119 insertions, 72 deletions
diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc index 25f840cc56..857acb8743 100644 --- a/runtime/verifier/reg_type.cc +++ b/runtime/verifier/reg_type.cc @@ -99,7 +99,7 @@ std::string PreciseConstType::Dump() const { } std::string BooleanType::Dump() const { - return "boolean"; + return "Boolean"; } std::string ConflictType::Dump() const { @@ -111,7 +111,7 @@ std::string ByteType::Dump() const { } std::string ShortType::Dump() const { - return "short"; + return "Short"; } std::string CharType::Dump() const { @@ -119,15 +119,15 @@ std::string CharType::Dump() const { } std::string FloatType::Dump() const { - return "float"; + return "Float"; } std::string LongLoType::Dump() const { - return "long (Low Half)"; + return "Long (Low Half)"; } std::string LongHiType::Dump() const { - return "long (High Half)"; + return "Long (High Half)"; } std::string DoubleLoType::Dump() const { @@ -461,7 +461,6 @@ std::string ImpreciseConstType::Dump() const { std::stringstream result; uint32_t val = ConstantValue(); if (val == 0) { - CHECK(IsPreciseConstant()); result << "Zero/null"; } else { result << "Imprecise "; diff --git a/runtime/verifier/reg_type_cache-inl.h b/runtime/verifier/reg_type_cache-inl.h index 295e27198d..fc9e5c98f7 100644 --- a/runtime/verifier/reg_type_cache-inl.h +++ b/runtime/verifier/reg_type_cache-inl.h @@ -23,17 +23,6 @@ namespace art { namespace verifier { -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; -} inline const art::verifier::RegType& RegTypeCache::GetFromId(uint16_t id) const { DCHECK_LT(id, entries_.size()); @@ -41,6 +30,16 @@ inline const art::verifier::RegType& RegTypeCache::GetFromId(uint16_t id) const DCHECK(result != NULL); return *result; } + +inline const ConstantType& RegTypeCache::FromCat1Const(int32_t value, bool precise) { + // We only expect 0 to be a precise constant. + DCHECK(value != 0 || precise); + if (precise && (value >= kMinSmallConstant) && (value <= kMaxSmallConstant)) { + return *small_precise_constants_[value - kMinSmallConstant]; + } + return FromCat1NonSmallConstant(value, precise); +} + } // namespace verifier } // namespace art #endif // ART_RUNTIME_VERIFIER_REG_TYPE_CACHE_INL_H_ diff --git a/runtime/verifier/reg_type_cache.cc b/runtime/verifier/reg_type_cache.cc index 2c18132c0b..ce465a415d 100644 --- a/runtime/verifier/reg_type_cache.cc +++ b/runtime/verifier/reg_type_cache.cc @@ -26,8 +26,8 @@ namespace art { 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 @@ static bool MatchingPrecisionForClass(RegType* entry, bool precise) } } -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 @@ void RegTypeCache::FillPrimitiveTypes() { 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 @@ const RegType& RegTypeCache::FromClass(const char* descriptor, mirror::Class* kl 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 @@ void RegTypeCache::ShutDown() { 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 @@ void RegTypeCache::CreatePrimitiveTypes() { 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 @@ const RegType& RegTypeCache::FromUnresolvedSuperClass(const RegType& child) { 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 @@ const RegType& RegTypeCache::FromUninitialized(const RegType& uninit_type) { 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 @@ const RegType& RegTypeCache::UninitializedThisArgument(const RegType& type) { 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 @@ const RegType& RegTypeCache::UninitializedThisArgument(const RegType& type) { 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 @@ const RegType& RegTypeCache::FromCat1Const(int32_t value, bool precise) { 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 @@ const RegType& RegTypeCache::FromCat2ConstLo(int32_t value, bool precise) { 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 { diff --git a/runtime/verifier/reg_type_cache.h b/runtime/verifier/reg_type_cache.h index 77f58934da..a9f8bff784 100644 --- a/runtime/verifier/reg_type_cache.h +++ b/runtime/verifier/reg_type_cache.h @@ -35,19 +35,18 @@ namespace verifier { class RegType; -const size_t kNumPrimitives = 12; class RegTypeCache { public: explicit RegTypeCache(bool can_load_classes) : can_load_classes_(can_load_classes) { entries_.reserve(64); - FillPrimitiveTypes(); + FillPrimitiveAndSmallConstantTypes(); } ~RegTypeCache(); static void Init() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { if (!RegTypeCache::primitive_initialized_) { CHECK_EQ(RegTypeCache::primitive_count_, 0); - CreatePrimitiveTypes(); - CHECK_EQ(RegTypeCache::primitive_count_, kNumPrimitives); + CreatePrimitiveAndSmallConstantTypes(); + CHECK_EQ(RegTypeCache::primitive_count_, kNumPrimitivesAndSmallConstants); RegTypeCache::primitive_initialized_ = true; } } @@ -55,17 +54,13 @@ class RegTypeCache { const art::verifier::RegType& GetFromId(uint16_t id) const; const RegType& From(mirror::ClassLoader* loader, const char* descriptor, bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - template <class Type> - static Type* CreatePrimitiveTypeInstance(const std::string& descriptor) - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void FillPrimitiveTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); const RegType& FromClass(const char* descriptor, mirror::Class* klass, bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - const RegType& FromCat1Const(int32_t value, bool precise) + const ConstantType& FromCat1Const(int32_t value, bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - const RegType& FromCat2ConstLo(int32_t value, bool precise) + const ConstantType& FromCat2ConstLo(int32_t value, bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - const RegType& FromCat2ConstHi(int32_t value, bool precise) + const ConstantType& FromCat2ConstHi(int32_t value, bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); const RegType& FromDescriptor(mirror::ClassLoader* loader, const char* descriptor, bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -129,34 +124,56 @@ class RegTypeCache { const RegType& JavaLangObject(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { return From(NULL, "Ljava/lang/Object;", precise); } - const RegType& Uninitialized(const RegType& type, uint32_t allocation_pc) + const UninitializedType& Uninitialized(const RegType& type, uint32_t allocation_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Create an uninitialized 'this' argument for the given type. - const RegType& UninitializedThisArgument(const RegType& type) + const UninitializedType& UninitializedThisArgument(const RegType& type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); const RegType& FromUninitialized(const RegType& uninit_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - const RegType& ByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - const RegType& ShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - const RegType& IntConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const ImpreciseConstType& ByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const ImpreciseConstType& ShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const ImpreciseConstType& IntConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); const RegType& GetComponentType(const RegType& array, mirror::ClassLoader* loader) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void Dump(std::ostream& os) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); const RegType& RegTypeFromPrimitiveType(Primitive::Type) const; private: - std::vector<RegType*> entries_; - static bool primitive_initialized_; - static uint16_t primitive_start_; - static uint16_t primitive_count_; - static void CreatePrimitiveTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - // Whether or not we're allowed to load classes. - const bool can_load_classes_; + void FillPrimitiveAndSmallConstantTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); mirror::Class* ResolveClass(const char* descriptor, mirror::ClassLoader* loader) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void ClearException(); bool MatchDescriptor(size_t idx, const char* descriptor, bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const ConstantType& FromCat1NonSmallConstant(int32_t value, bool precise) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + + template <class Type> + static Type* CreatePrimitiveTypeInstance(const std::string& descriptor) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + static void CreatePrimitiveAndSmallConstantTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + + // The actual storage for the RegTypes. + std::vector<RegType*> entries_; + + // A quick look up for popular small constants. + static constexpr int32_t kMinSmallConstant = -1; + static constexpr int32_t kMaxSmallConstant = 4; + static PreciseConstType* small_precise_constants_[kMaxSmallConstant - kMinSmallConstant + 1]; + + static constexpr size_t kNumPrimitivesAndSmallConstants = + 12 + (kMaxSmallConstant - kMinSmallConstant + 1); + + // Have the well known global primitives been created? + static bool primitive_initialized_; + + // Number of well known primitives that will be copied into a RegTypeCache upon construction. + static uint16_t primitive_count_; + + // Whether or not we're allowed to load classes. + const bool can_load_classes_; + DISALLOW_COPY_AND_ASSIGN(RegTypeCache); }; |