diff options
Diffstat (limited to 'runtime')
50 files changed, 586 insertions, 360 deletions
diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc index bbf9a8b93c..6665897c9d 100644 --- a/runtime/arch/stub_test.cc +++ b/runtime/arch/stub_test.cc @@ -1063,7 +1063,7 @@ TEST_F(StubTest, AllocObject) { EXPECT_FALSE(self->IsExceptionPending()); { // Use an arbitrary method from c to use as referrer - size_t result = Invoke3(static_cast<size_t>(c->GetDexTypeIndex()), // type_idx + size_t result = Invoke3(static_cast<size_t>(c->GetDexTypeIndex().index_), // type_idx // arbitrary reinterpret_cast<size_t>(c->GetVirtualMethod(0, kRuntimePointerSize)), 0U, @@ -1197,7 +1197,7 @@ TEST_F(StubTest, AllocObjectArray) { if ((false)) { // Use an arbitrary method from c to use as referrer size_t result = Invoke3( - static_cast<size_t>(c->GetDexTypeIndex()), // type_idx + static_cast<size_t>(c->GetDexTypeIndex().index_), // type_idx 10U, // arbitrary reinterpret_cast<size_t>(c_obj->GetVirtualMethod(0, kRuntimePointerSize)), diff --git a/runtime/art_field.cc b/runtime/art_field.cc index b46b058b16..25b8ed295b 100644 --- a/runtime/art_field.cc +++ b/runtime/art_field.cc @@ -48,7 +48,7 @@ ObjPtr<mirror::Class> ArtField::ProxyFindSystemClass(const char* descriptor) { return Runtime::Current()->GetClassLinker()->FindSystemClass(Thread::Current(), descriptor); } -ObjPtr<mirror::Class> ArtField::ResolveGetType(uint32_t type_idx) { +ObjPtr<mirror::Class> ArtField::ResolveGetType(dex::TypeIndex type_idx) { return Runtime::Current()->GetClassLinker()->ResolveType(type_idx, this); } diff --git a/runtime/art_field.h b/runtime/art_field.h index 7c2f490706..cacb32450b 100644 --- a/runtime/art_field.h +++ b/runtime/art_field.h @@ -19,6 +19,7 @@ #include <jni.h> +#include "dex_file_types.h" #include "gc_root.h" #include "modifiers.h" #include "obj_ptr.h" @@ -216,7 +217,8 @@ class ArtField FINAL { private: ObjPtr<mirror::Class> ProxyFindSystemClass(const char* descriptor) REQUIRES_SHARED(Locks::mutator_lock_); - ObjPtr<mirror::Class> ResolveGetType(uint32_t type_idx) REQUIRES_SHARED(Locks::mutator_lock_); + ObjPtr<mirror::Class> ResolveGetType(dex::TypeIndex type_idx) + REQUIRES_SHARED(Locks::mutator_lock_); ObjPtr<mirror::String> ResolveGetStringName(Thread* self, const DexFile& dex_file, uint32_t string_idx, diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h index a652178130..2dfdc16ac0 100644 --- a/runtime/art_method-inl.h +++ b/runtime/art_method-inl.h @@ -183,17 +183,17 @@ inline GcRoot<mirror::Class>* ArtMethod::GetDexCacheResolvedTypes(PointerSize po } template <bool kWithCheck> -inline mirror::Class* ArtMethod::GetDexCacheResolvedType(uint32_t type_index, +inline mirror::Class* ArtMethod::GetDexCacheResolvedType(dex::TypeIndex type_index, PointerSize pointer_size) { if (kWithCheck) { mirror::DexCache* dex_cache = GetInterfaceMethodIfProxy(pointer_size)->GetDeclaringClass()->GetDexCache(); - if (UNLIKELY(type_index >= dex_cache->NumResolvedTypes())) { - ThrowArrayIndexOutOfBoundsException(type_index, dex_cache->NumResolvedTypes()); + if (UNLIKELY(type_index.index_ >= dex_cache->NumResolvedTypes())) { + ThrowArrayIndexOutOfBoundsException(type_index.index_, dex_cache->NumResolvedTypes()); return nullptr; } } - mirror::Class* klass = GetDexCacheResolvedTypes(pointer_size)[type_index].Read(); + mirror::Class* klass = GetDexCacheResolvedTypes(pointer_size)[type_index.index_].Read(); return (klass != nullptr && !klass->IsErroneous()) ? klass : nullptr; } @@ -210,7 +210,7 @@ inline bool ArtMethod::HasSameDexCacheResolvedTypes(ArtMethod* other, PointerSiz return GetDexCacheResolvedTypes(pointer_size) == other->GetDexCacheResolvedTypes(pointer_size); } -inline mirror::Class* ArtMethod::GetClassFromTypeIndex(uint16_t type_idx, +inline mirror::Class* ArtMethod::GetClassFromTypeIndex(dex::TypeIndex type_idx, bool resolve, PointerSize pointer_size) { mirror::Class* type = GetDexCacheResolvedType(type_idx, pointer_size); @@ -336,7 +336,7 @@ inline const DexFile::CodeItem* ArtMethod::GetCodeItem() { return GetDeclaringClass()->GetDexFile().GetCodeItem(GetCodeItemOffset()); } -inline bool ArtMethod::IsResolvedTypeIdx(uint16_t type_idx, PointerSize pointer_size) { +inline bool ArtMethod::IsResolvedTypeIdx(dex::TypeIndex type_idx, PointerSize pointer_size) { DCHECK(!IsProxyMethod()); return GetDexCacheResolvedType(type_idx, pointer_size) != nullptr; } @@ -383,11 +383,10 @@ inline const char* ArtMethod::GetReturnTypeDescriptor() { const DexFile* dex_file = GetDexFile(); const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex()); const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id); - uint16_t return_type_idx = proto_id.return_type_idx_; - return dex_file->GetTypeDescriptor(dex_file->GetTypeId(return_type_idx)); + return dex_file->GetTypeDescriptor(dex_file->GetTypeId(proto_id.return_type_idx_)); } -inline const char* ArtMethod::GetTypeDescriptorFromTypeIdx(uint16_t type_idx) { +inline const char* ArtMethod::GetTypeDescriptorFromTypeIdx(dex::TypeIndex type_idx) { DCHECK(!IsProxyMethod()); const DexFile* dex_file = GetDexFile(); return dex_file->GetTypeDescriptor(dex_file->GetTypeId(type_idx)); @@ -440,7 +439,7 @@ inline mirror::Class* ArtMethod::GetReturnType(bool resolve, PointerSize pointer const DexFile* dex_file = GetDexFile(); const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex()); const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id); - uint16_t return_type_idx = proto_id.return_type_idx_; + dex::TypeIndex return_type_idx = proto_id.return_type_idx_; mirror::Class* type = GetDexCacheResolvedType(return_type_idx, pointer_size); if (type == nullptr && resolve) { type = Runtime::Current()->GetClassLinker()->ResolveType(return_type_idx, this); diff --git a/runtime/art_method.cc b/runtime/art_method.cc index c550a1b6bd..1c8376637c 100644 --- a/runtime/art_method.cc +++ b/runtime/art_method.cc @@ -199,9 +199,9 @@ uint32_t ArtMethod::FindCatchBlock(Handle<mirror::Class> exception_type, // Iterate over the catch handlers associated with dex_pc. PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); for (CatchHandlerIterator it(*code_item, dex_pc); it.HasNext(); it.Next()) { - uint16_t iter_type_idx = it.GetHandlerTypeIndex(); + dex::TypeIndex iter_type_idx = it.GetHandlerTypeIndex(); // Catch all case - if (iter_type_idx == DexFile::kDexNoIndex16) { + if (!iter_type_idx.IsValid()) { found_dex_pc = it.GetHandlerAddress(); break; } diff --git a/runtime/art_method.h b/runtime/art_method.h index b31999f5b4..0e1d7e7303 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h @@ -343,7 +343,7 @@ class ArtMethod FINAL { REQUIRES_SHARED(Locks::mutator_lock_); template <bool kWithCheck = true> - mirror::Class* GetDexCacheResolvedType(uint32_t type_idx, PointerSize pointer_size) + mirror::Class* GetDexCacheResolvedType(dex::TypeIndex type_idx, PointerSize pointer_size) REQUIRES_SHARED(Locks::mutator_lock_); void SetDexCacheResolvedTypes(GcRoot<mirror::Class>* new_dex_cache_types, PointerSize pointer_size) @@ -355,7 +355,9 @@ class ArtMethod FINAL { REQUIRES_SHARED(Locks::mutator_lock_); // Get the Class* from the type index into this method's dex cache. - mirror::Class* GetClassFromTypeIndex(uint16_t type_idx, bool resolve, PointerSize pointer_size) + mirror::Class* GetClassFromTypeIndex(dex::TypeIndex type_idx, + bool resolve, + PointerSize pointer_size) REQUIRES_SHARED(Locks::mutator_lock_); // Returns true if this method has the same name and signature of the other method. @@ -527,7 +529,7 @@ class ArtMethod FINAL { const DexFile::CodeItem* GetCodeItem() REQUIRES_SHARED(Locks::mutator_lock_); - bool IsResolvedTypeIdx(uint16_t type_idx, PointerSize pointer_size) + bool IsResolvedTypeIdx(dex::TypeIndex type_idx, PointerSize pointer_size) REQUIRES_SHARED(Locks::mutator_lock_); int32_t GetLineNumFromDexPC(uint32_t dex_pc) REQUIRES_SHARED(Locks::mutator_lock_); @@ -544,7 +546,7 @@ class ArtMethod FINAL { const char* GetReturnTypeDescriptor() REQUIRES_SHARED(Locks::mutator_lock_); - const char* GetTypeDescriptorFromTypeIdx(uint16_t type_idx) + const char* GetTypeDescriptorFromTypeIdx(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_); // May cause thread suspension due to GetClassFromTypeIdx calling ResolveType this caused a large diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h index 7359243fc2..81adaeb00a 100644 --- a/runtime/class_linker-inl.h +++ b/runtime/class_linker-inl.h @@ -86,7 +86,7 @@ inline mirror::String* ClassLinker::ResolveString(uint32_t string_idx, ArtMethod return string.Ptr(); } -inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, ArtMethod* referrer) { +inline mirror::Class* ClassLinker::ResolveType(dex::TypeIndex type_idx, ArtMethod* referrer) { Thread::PoisonObjectPointersIfDebug(); ObjPtr<mirror::Class> resolved_type = referrer->GetDexCacheResolvedType(type_idx, image_pointer_size_); @@ -103,7 +103,7 @@ inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, ArtMethod* ref return resolved_type.Ptr(); } -inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, ArtField* referrer) { +inline mirror::Class* ClassLinker::ResolveType(dex::TypeIndex type_idx, ArtField* referrer) { Thread::PoisonObjectPointersIfDebug(); ObjPtr<mirror::Class> declaring_class = referrer->GetDeclaringClass(); ObjPtr<mirror::DexCache> dex_cache_ptr = declaring_class->GetDexCache(); diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 4905514221..f552a83192 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -730,10 +730,12 @@ bool ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> b const DexFile& dex_file = java_lang_Object->GetDexFile(); const DexFile::TypeId* void_type_id = dex_file.FindTypeId("V"); CHECK(void_type_id != nullptr); - uint16_t void_type_idx = dex_file.GetIndexForTypeId(*void_type_id); + dex::TypeIndex void_type_idx = dex_file.GetIndexForTypeId(*void_type_id); // Now we resolve void type so the dex cache contains it. We use java.lang.Object class // as referrer so the used dex cache is core's one. - ObjPtr<mirror::Class> resolved_type = ResolveType(dex_file, void_type_idx, java_lang_Object.Get()); + ObjPtr<mirror::Class> resolved_type = ResolveType(dex_file, + void_type_idx, + java_lang_Object.Get()); CHECK_EQ(resolved_type, GetClassRoot(kPrimitiveVoid)); self->AssertNoPendingException(); } @@ -4090,7 +4092,7 @@ void ClassLinker::ResolveMethodExceptionHandlerTypes(ArtMethod* method) { for (; iterator.HasNext(); iterator.Next()) { // Ensure exception types are resolved so that they don't need resolution to be delivered, // unresolved exception types will be ignored by exception delivery - if (iterator.GetHandlerTypeIndex() != DexFile::kDexNoIndex16) { + if (iterator.GetHandlerTypeIndex().IsValid()) { ObjPtr<mirror::Class> exception_type = ResolveType(iterator.GetHandlerTypeIndex(), method); if (exception_type == nullptr) { DCHECK(Thread::Current()->IsExceptionPending()); @@ -4756,7 +4758,7 @@ static void ThrowSignatureCheckResolveReturnTypeException(Handle<mirror::Class> const DexFile* dex_file = m->GetDexFile(); const DexFile::MethodId& method_id = dex_file->GetMethodId(m->GetDexMethodIndex()); const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id); - uint16_t return_type_idx = proto_id.return_type_idx_; + dex::TypeIndex return_type_idx = proto_id.return_type_idx_; std::string return_type = dex_file->PrettyType(return_type_idx); std::string class_loader = mirror::Object::PrettyTypeOf(m->GetDeclaringClass()->GetClassLoader()); ThrowWrappedLinkageError(klass.Get(), @@ -4774,7 +4776,7 @@ static void ThrowSignatureCheckResolveArgException(Handle<mirror::Class> klass, ArtMethod* method, ArtMethod* m, uint32_t index, - uint32_t arg_type_idx) + dex::TypeIndex arg_type_idx) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(Thread::Current()->IsExceptionPending()); DCHECK(!m->IsProxyMethod()); @@ -4864,7 +4866,7 @@ static bool HasSameSignatureWithDifferentClassLoaders(Thread* self, } for (uint32_t i = 0; i < num_types; ++i) { StackHandleScope<1> hs(self); - uint32_t param_type_idx = types1->GetTypeItem(i).type_idx_; + dex::TypeIndex param_type_idx = types1->GetTypeItem(i).type_idx_; Handle<mirror::Class> param_type(hs.NewHandle( method1->GetClassFromTypeIndex(param_type_idx, true /* resolve */, pointer_size))); if (UNLIKELY(param_type.Get() == nullptr)) { @@ -4872,7 +4874,7 @@ static bool HasSameSignatureWithDifferentClassLoaders(Thread* self, method1, i, param_type_idx); return false; } - uint32_t other_param_type_idx = types2->GetTypeItem(i).type_idx_; + dex::TypeIndex other_param_type_idx = types2->GetTypeItem(i).type_idx_; ObjPtr<mirror::Class> other_param_type = method2->GetClassFromTypeIndex(other_param_type_idx, true /* resolve */, pointer_size); if (UNLIKELY(other_param_type == nullptr)) { @@ -5356,8 +5358,8 @@ static bool CheckSuperClassChange(Handle<mirror::Class> klass, bool ClassLinker::LoadSuperAndInterfaces(Handle<mirror::Class> klass, const DexFile& dex_file) { CHECK_EQ(mirror::Class::kStatusIdx, klass->GetStatus()); const DexFile::ClassDef& class_def = dex_file.GetClassDef(klass->GetDexClassDefIndex()); - uint16_t super_class_idx = class_def.superclass_idx_; - if (super_class_idx != DexFile::kDexNoIndex16) { + dex::TypeIndex super_class_idx = class_def.superclass_idx_; + if (super_class_idx.IsValid()) { // Check that a class does not inherit from itself directly. // // TODO: This is a cheap check to detect the straightforward case @@ -5394,7 +5396,7 @@ bool ClassLinker::LoadSuperAndInterfaces(Handle<mirror::Class> klass, const DexF const DexFile::TypeList* interfaces = dex_file.GetInterfacesList(class_def); if (interfaces != nullptr) { for (size_t i = 0; i < interfaces->Size(); i++) { - uint16_t idx = interfaces->GetTypeItem(i).type_idx_; + dex::TypeIndex idx = interfaces->GetTypeItem(i).type_idx_; ObjPtr<mirror::Class> interface = ResolveType(dex_file, idx, klass.Get()); if (interface == nullptr) { DCHECK(Thread::Current()->IsExceptionPending()); @@ -7510,7 +7512,7 @@ mirror::String* ClassLinker::LookupString(const DexFile& dex_file, } ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, ObjPtr<mirror::DexCache> dex_cache, ObjPtr<mirror::ClassLoader> class_loader) { ObjPtr<mirror::Class> type = dex_cache->GetResolvedType(type_idx); @@ -7536,7 +7538,7 @@ ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(const DexFile& dex_file, } mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, ObjPtr<mirror::Class> referrer) { StackHandleScope<2> hs(Thread::Current()); Handle<mirror::DexCache> dex_cache(hs.NewHandle(referrer->GetDexCache())); @@ -7545,7 +7547,7 @@ mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, } mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader) { DCHECK(dex_cache.Get() != nullptr); @@ -7939,7 +7941,7 @@ mirror::MethodType* ClassLinker::ResolveMethodType(const DexFile& dex_file, int32_t i = 0; MutableHandle<mirror::Class> param_class = hs.NewHandle<mirror::Class>(nullptr); for (; it.HasNext(); it.Next()) { - const uint16_t type_idx = it.GetTypeIdx(); + const dex::TypeIndex type_idx = it.GetTypeIdx(); param_class.Assign(ResolveType(dex_file, type_idx, dex_cache, class_loader)); if (param_class.Get() == nullptr) { DCHECK(self->IsExceptionPending()); @@ -8350,10 +8352,10 @@ std::set<DexCacheResolvedClasses> ClassLinker::GetResolvedClasses(bool ignore_bo dex_file->GetBaseLocation(), dex_file->GetLocationChecksum()); size_t num_resolved = 0; - std::unordered_set<uint16_t> class_set; + std::unordered_set<dex::TypeIndex> class_set; CHECK_EQ(num_types, dex_cache->NumResolvedTypes()); for (size_t i = 0; i < num_types; ++i) { - ObjPtr<mirror::Class> klass = dex_cache->GetResolvedType(i); + ObjPtr<mirror::Class> klass = dex_cache->GetResolvedType(dex::TypeIndex(i)); // Filter out null class loader since that is the boot class loader. if (klass == nullptr || (ignore_boot_classes && klass->GetClassLoader() == nullptr)) { continue; @@ -8418,7 +8420,7 @@ std::unordered_set<std::string> ClassLinker::GetClassDescriptorsForProfileKeys( VLOG(profiler) << "Found opened dex file for " << dex_file->GetLocation() << " with " << info.GetClasses().size() << " classes"; DCHECK_EQ(dex_file->GetLocationChecksum(), info.GetLocationChecksum()); - for (uint16_t type_idx : info.GetClasses()) { + for (dex::TypeIndex type_idx : info.GetClasses()) { const DexFile::TypeId& type_id = dex_file->GetTypeId(type_idx); const char* descriptor = dex_file->GetTypeDescriptor(type_id); ret.insert(descriptor); diff --git a/runtime/class_linker.h b/runtime/class_linker.h index 1d29e319d5..95634484fc 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -32,6 +32,7 @@ #include "class_table.h" #include "dex_cache_resolved_classes.h" #include "dex_file.h" +#include "dex_file_types.h" #include "gc_root.h" #include "jni.h" #include "mirror/class.h" @@ -255,7 +256,7 @@ class ClassLinker { // result in the DexCache. The referrer is used to identify the // target DexCache and ClassLoader to use for resolution. mirror::Class* ResolveType(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, ObjPtr<mirror::Class> referrer) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!dex_lock_, !Roles::uninterruptible_); @@ -263,18 +264,18 @@ class ClassLinker { // Resolve a Type with the given index from the DexFile, storing the // result in the DexCache. The referrer is used to identify the // target DexCache and ClassLoader to use for resolution. - mirror::Class* ResolveType(uint16_t type_idx, ArtMethod* referrer) + mirror::Class* ResolveType(dex::TypeIndex type_idx, ArtMethod* referrer) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!dex_lock_, !Roles::uninterruptible_); - mirror::Class* ResolveType(uint16_t type_idx, ArtField* referrer) + mirror::Class* ResolveType(dex::TypeIndex type_idx, ArtField* referrer) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!dex_lock_, !Roles::uninterruptible_); // Look up a resolved type with the given ID from the DexFile. The ClassLoader is used to search // for the type, since it may be referenced from but not contained within the given DexFile. ObjPtr<mirror::Class> LookupResolvedType(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, ObjPtr<mirror::DexCache> dex_cache, ObjPtr<mirror::ClassLoader> class_loader) REQUIRES_SHARED(Locks::mutator_lock_); @@ -284,7 +285,7 @@ class ClassLinker { // type, since it may be referenced from but not contained within // the given DexFile. mirror::Class* ResolveType(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader) REQUIRES_SHARED(Locks::mutator_lock_) diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index 44590ba327..9e17be2518 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -25,6 +25,7 @@ #include "class_linker-inl.h" #include "common_runtime_test.h" #include "dex_file.h" +#include "dex_file_types.h" #include "experimental_flags.h" #include "entrypoints/entrypoint_utils-inl.h" #include "gc/heap.h" @@ -429,7 +430,7 @@ class ClassLinkerTest : public CommonRuntimeTest { } // Verify all the types referenced by this file for (size_t i = 0; i < dex.NumTypeIds(); i++) { - const DexFile::TypeId& type_id = dex.GetTypeId(i); + const DexFile::TypeId& type_id = dex.GetTypeId(dex::TypeIndex(i)); const char* descriptor = dex.GetTypeDescriptor(type_id); AssertDexFileClass(class_loader, descriptor); } @@ -891,7 +892,7 @@ TEST_F(ClassLinkerTest, LookupResolvedType) { hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass")))); AssertNonExistentClass("LMyClass;"); ObjPtr<mirror::Class> klass = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader); - uint32_t type_idx = klass->GetClassDef()->class_idx_; + dex::TypeIndex type_idx = klass->GetClassDef()->class_idx_; ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache(); const DexFile& dex_file = klass->GetDexFile(); EXPECT_OBJ_PTR_EQ(dex_cache->GetResolvedType(type_idx), klass); @@ -1154,7 +1155,7 @@ TEST_F(ClassLinkerTest, ResolveVerifyAndClinit) { ArtMethod* getS0 = klass->FindDirectMethod("getS0", "()Ljava/lang/Object;", kRuntimePointerSize); const DexFile::TypeId* type_id = dex_file->FindTypeId("LStaticsFromCode;"); ASSERT_TRUE(type_id != nullptr); - uint32_t type_idx = dex_file->GetIndexForTypeId(*type_id); + dex::TypeIndex type_idx = dex_file->GetIndexForTypeId(*type_id); mirror::Class* uninit = ResolveVerifyAndClinit(type_idx, clinit, soa.Self(), true, false); EXPECT_TRUE(uninit != nullptr); EXPECT_FALSE(uninit->IsInitialized()); diff --git a/runtime/dex_cache_resolved_classes.h b/runtime/dex_cache_resolved_classes.h index 0febbedf03..f53ca4acb6 100644 --- a/runtime/dex_cache_resolved_classes.h +++ b/runtime/dex_cache_resolved_classes.h @@ -21,6 +21,8 @@ #include <unordered_set> #include <vector> +#include "dex_file_types.h" + namespace art { // Data structure for passing around which classes belonging to a dex cache / dex file are resolved. @@ -59,7 +61,7 @@ class DexCacheResolvedClasses { return location_checksum_; } - const std::unordered_set<uint16_t>& GetClasses() const { + const std::unordered_set<dex::TypeIndex>& GetClasses() const { return classes_; } @@ -68,7 +70,7 @@ class DexCacheResolvedClasses { const std::string base_location_; const uint32_t location_checksum_; // Array of resolved class def indexes. - mutable std::unordered_set<uint16_t> classes_; + mutable std::unordered_set<dex::TypeIndex> classes_; }; inline bool operator<(const DexCacheResolvedClasses& a, const DexCacheResolvedClasses& b) { diff --git a/runtime/dex_file-inl.h b/runtime/dex_file-inl.h index 621b2c5f21..77a63c11ed 100644 --- a/runtime/dex_file-inl.h +++ b/runtime/dex_file-inl.h @@ -58,12 +58,12 @@ inline const char* DexFile::StringDataByIdx(uint32_t idx) const { return StringDataAndUtf16LengthByIdx(idx, &unicode_length); } -inline const char* DexFile::StringByTypeIdx(uint32_t idx, uint32_t* unicode_length) const { +inline const char* DexFile::StringByTypeIdx(dex::TypeIndex idx, uint32_t* unicode_length) const { const TypeId& type_id = GetTypeId(idx); return StringDataAndUtf16LengthByIdx(type_id.descriptor_idx_, unicode_length); } -inline const char* DexFile::StringByTypeIdx(uint32_t idx) const { +inline const char* DexFile::StringByTypeIdx(dex::TypeIndex idx) const { const TypeId& type_id = GetTypeId(idx); return StringDataByIdx(type_id.descriptor_idx_); } diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc index 2ef7509b68..cc544fd51c 100644 --- a/runtime/dex_file.cc +++ b/runtime/dex_file.cc @@ -26,6 +26,7 @@ #include <memory> #include <sstream> +#include <type_traits> #include "base/enums.h" #include "base/file_magic.h" @@ -44,6 +45,9 @@ namespace art { +static_assert(sizeof(dex::TypeIndex) == sizeof(uint16_t), "TypeIndex size is wrong"); +static_assert(std::is_trivially_copyable<dex::TypeIndex>::value, "TypeIndex not trivial"); + static constexpr OatDexFile* kNoOatDexFile = nullptr; const char* DexFile::kClassesDex = "classes.dex"; @@ -550,7 +554,7 @@ uint32_t DexFile::Header::GetVersion() const { return atoi(version); } -const DexFile::ClassDef* DexFile::FindClassDef(uint16_t type_idx) const { +const DexFile::ClassDef* DexFile::FindClassDef(dex::TypeIndex type_idx) const { size_t num_class_defs = NumClassDefs(); // Fast path for rare no class defs case. if (num_class_defs == 0) { @@ -597,9 +601,9 @@ const DexFile::FieldId* DexFile::FindFieldId(const DexFile::TypeId& declaring_kl const DexFile::StringId& name, const DexFile::TypeId& type) const { // Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx - const uint16_t class_idx = GetIndexForTypeId(declaring_klass); + const dex::TypeIndex class_idx = GetIndexForTypeId(declaring_klass); const uint32_t name_idx = GetIndexForStringId(name); - const uint16_t type_idx = GetIndexForTypeId(type); + const dex::TypeIndex type_idx = GetIndexForTypeId(type); int32_t lo = 0; int32_t hi = NumFieldIds() - 1; while (hi >= lo) { @@ -632,7 +636,7 @@ const DexFile::MethodId* DexFile::FindMethodId(const DexFile::TypeId& declaring_ const DexFile::StringId& name, const DexFile::ProtoId& signature) const { // Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx - const uint16_t class_idx = GetIndexForTypeId(declaring_klass); + const dex::TypeIndex class_idx = GetIndexForTypeId(declaring_klass); const uint32_t name_idx = GetIndexForStringId(name); const uint16_t proto_idx = GetIndexForProtoId(signature); int32_t lo = 0; @@ -687,7 +691,7 @@ const DexFile::TypeId* DexFile::FindTypeId(const char* string) const { int32_t hi = NumTypeIds() - 1; while (hi >= lo) { int32_t mid = (hi + lo) / 2; - const TypeId& type_id = GetTypeId(mid); + const TypeId& type_id = GetTypeId(dex::TypeIndex(mid)); const DexFile::StringId& str_id = GetStringId(type_id.descriptor_idx_); const char* str = GetStringData(str_id); int compare = CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(string, str); @@ -726,7 +730,7 @@ const DexFile::TypeId* DexFile::FindTypeId(uint32_t string_idx) const { int32_t hi = NumTypeIds() - 1; while (hi >= lo) { int32_t mid = (hi + lo) / 2; - const TypeId& type_id = GetTypeId(mid); + const TypeId& type_id = GetTypeId(dex::TypeIndex(mid)); if (string_idx > type_id.descriptor_idx_) { lo = mid + 1; } else if (string_idx < type_id.descriptor_idx_) { @@ -738,20 +742,20 @@ const DexFile::TypeId* DexFile::FindTypeId(uint32_t string_idx) const { return nullptr; } -const DexFile::ProtoId* DexFile::FindProtoId(uint16_t return_type_idx, - const uint16_t* signature_type_idxs, +const DexFile::ProtoId* DexFile::FindProtoId(dex::TypeIndex return_type_idx, + const dex::TypeIndex* signature_type_idxs, uint32_t signature_length) const { int32_t lo = 0; int32_t hi = NumProtoIds() - 1; while (hi >= lo) { int32_t mid = (hi + lo) / 2; const DexFile::ProtoId& proto = GetProtoId(mid); - int compare = return_type_idx - proto.return_type_idx_; + int compare = return_type_idx.index_ - proto.return_type_idx_.index_; if (compare == 0) { DexFileParameterIterator it(*this, proto); size_t i = 0; while (it.HasNext() && i < signature_length && compare == 0) { - compare = signature_type_idxs[i] - it.GetTypeIdx(); + compare = signature_type_idxs[i].index_ - it.GetTypeIdx().index_; it.Next(); i++; } @@ -775,8 +779,9 @@ const DexFile::ProtoId* DexFile::FindProtoId(uint16_t return_type_idx, } // Given a signature place the type ids into the given vector -bool DexFile::CreateTypeList(const StringPiece& signature, uint16_t* return_type_idx, - std::vector<uint16_t>* param_type_idxs) const { +bool DexFile::CreateTypeList(const StringPiece& signature, + dex::TypeIndex* return_type_idx, + std::vector<dex::TypeIndex>* param_type_idxs) const { if (signature[0] != '(') { return false; } @@ -813,7 +818,7 @@ bool DexFile::CreateTypeList(const StringPiece& signature, uint16_t* return_type if (type_id == nullptr) { return false; } - uint16_t type_idx = GetIndexForTypeId(*type_id); + dex::TypeIndex type_idx = GetIndexForTypeId(*type_id); if (!process_return) { param_type_idxs->push_back(type_idx); } else { @@ -825,8 +830,8 @@ bool DexFile::CreateTypeList(const StringPiece& signature, uint16_t* return_type } const Signature DexFile::CreateSignature(const StringPiece& signature) const { - uint16_t return_type_idx; - std::vector<uint16_t> param_type_indices; + dex::TypeIndex return_type_idx; + std::vector<dex::TypeIndex> param_type_indices; bool success = CreateTypeList(signature, &return_type_idx, ¶m_type_indices); if (!success) { return Signature::NoSignature(); @@ -971,7 +976,8 @@ bool DexFile::DecodeDebugLocalInfo(const CodeItem* code_item, bool is_static, ui } local_in_reg[reg].name_ = StringDataByIdx(name_idx); - local_in_reg[reg].descriptor_ = StringByTypeIdx(descriptor_idx); + local_in_reg[reg].descriptor_ = + StringByTypeIdx(dex::TypeIndex(dchecked_integral_cast<uint16_t>(descriptor_idx)));; local_in_reg[reg].signature_ = StringDataByIdx(signature_idx); local_in_reg[reg].start_address_ = address; local_in_reg[reg].reg_ = reg; @@ -1225,9 +1231,9 @@ std::string DexFile::PrettyField(uint32_t field_idx, bool with_type) const { return result; } -std::string DexFile::PrettyType(uint32_t type_idx) const { - if (type_idx >= NumTypeIds()) { - return StringPrintf("<<invalid-type-idx-%d>>", type_idx); +std::string DexFile::PrettyType(dex::TypeIndex type_idx) const { + if (type_idx.index_ >= NumTypeIds()) { + return StringPrintf("<<invalid-type-idx-%d>>", type_idx.index_); } const DexFile::TypeId& type_id = GetTypeId(type_idx); return PrettyDescriptor(GetTypeDescriptor(type_id)); @@ -1457,14 +1463,14 @@ void CatchHandlerIterator::Init(const uint8_t* handler_data) { void CatchHandlerIterator::Next() { if (remaining_count_ > 0) { - handler_.type_idx_ = DecodeUnsignedLeb128(¤t_data_); + handler_.type_idx_ = dex::TypeIndex(DecodeUnsignedLeb128(¤t_data_)); handler_.address_ = DecodeUnsignedLeb128(¤t_data_); remaining_count_--; return; } if (catch_all_) { - handler_.type_idx_ = DexFile::kDexNoIndex16; + handler_.type_idx_ = dex::TypeIndex(DexFile::kDexNoIndex16); handler_.address_ = DecodeUnsignedLeb128(¤t_data_); catch_all_ = false; return; @@ -1474,4 +1480,13 @@ void CatchHandlerIterator::Next() { remaining_count_ = -1; } +namespace dex { + +std::ostream& operator<<(std::ostream& os, const TypeIndex& index) { + os << "TypeIndex[" << index.index_ << "]"; + return os; +} + +} // namespace dex + } // namespace art diff --git a/runtime/dex_file.h b/runtime/dex_file.h index da9fa505f2..0a2b48bea9 100644 --- a/runtime/dex_file.h +++ b/runtime/dex_file.h @@ -23,6 +23,7 @@ #include "base/logging.h" #include "base/value_object.h" +#include "dex_file_types.h" #include "globals.h" #include "invoke_type.h" #include "jni.h" @@ -159,17 +160,28 @@ class DexFile { // Raw field_id_item. struct FieldId { - uint16_t class_idx_; // index into type_ids_ array for defining class - uint16_t type_idx_; // index into type_ids_ array for field type + dex::TypeIndex class_idx_; // index into type_ids_ array for defining class + dex::TypeIndex type_idx_; // index into type_ids_ array for field type uint32_t name_idx_; // index into string_ids_ array for field name private: DISALLOW_COPY_AND_ASSIGN(FieldId); }; + // Raw proto_id_item. + struct ProtoId { + uint32_t shorty_idx_; // index into string_ids array for shorty descriptor + dex::TypeIndex return_type_idx_; // index into type_ids array for return type + uint16_t pad_; // padding = 0 + uint32_t parameters_off_; // file offset to type_list for parameter types + + private: + DISALLOW_COPY_AND_ASSIGN(ProtoId); + }; + // Raw method_id_item. struct MethodId { - uint16_t class_idx_; // index into type_ids_ array for defining class + dex::TypeIndex class_idx_; // index into type_ids_ array for defining class uint16_t proto_idx_; // index into proto_ids_ array for method prototype uint32_t name_idx_; // index into string_ids_ array for method name @@ -177,23 +189,12 @@ class DexFile { DISALLOW_COPY_AND_ASSIGN(MethodId); }; - // Raw proto_id_item. - struct ProtoId { - uint32_t shorty_idx_; // index into string_ids array for shorty descriptor - uint16_t return_type_idx_; // index into type_ids array for return type - uint16_t pad_; // padding = 0 - uint32_t parameters_off_; // file offset to type_list for parameter types - - private: - DISALLOW_COPY_AND_ASSIGN(ProtoId); - }; - // Raw class_def_item. struct ClassDef { - uint16_t class_idx_; // index into type_ids_ array for this class + dex::TypeIndex class_idx_; // index into type_ids_ array for this class uint16_t pad1_; // padding = 0 uint32_t access_flags_; - uint16_t superclass_idx_; // index into type_ids_ array for superclass + dex::TypeIndex superclass_idx_; // index into type_ids_ array for superclass uint16_t pad2_; // padding = 0 uint32_t interfaces_off_; // file offset to TypeList uint32_t source_file_idx_; // index into string_ids_ for source file name @@ -225,7 +226,7 @@ class DexFile { // Raw type_item. struct TypeItem { - uint16_t type_idx_; // index into type_ids section + dex::TypeIndex type_idx_; // index into type_ids section private: DISALLOW_COPY_AND_ASSIGN(TypeItem); @@ -540,23 +541,23 @@ class DexFile { } // Returns the TypeId at the specified index. - const TypeId& GetTypeId(uint32_t idx) const { - DCHECK_LT(idx, NumTypeIds()) << GetLocation(); - return type_ids_[idx]; + const TypeId& GetTypeId(dex::TypeIndex idx) const { + DCHECK_LT(idx.index_, NumTypeIds()) << GetLocation(); + return type_ids_[idx.index_]; } - uint16_t GetIndexForTypeId(const TypeId& type_id) const { + dex::TypeIndex GetIndexForTypeId(const TypeId& type_id) const { CHECK_GE(&type_id, type_ids_) << GetLocation(); CHECK_LT(&type_id, type_ids_ + header_->type_ids_size_) << GetLocation(); size_t result = &type_id - type_ids_; DCHECK_LT(result, 65536U) << GetLocation(); - return static_cast<uint16_t>(result); + return dex::TypeIndex(static_cast<uint16_t>(result)); } // Get the descriptor string associated with a given type index. - const char* StringByTypeIdx(uint32_t idx, uint32_t* unicode_length) const; + const char* StringByTypeIdx(dex::TypeIndex idx, uint32_t* unicode_length) const; - const char* StringByTypeIdx(uint32_t idx) const; + const char* StringByTypeIdx(dex::TypeIndex idx) const; // Returns the type descriptor string of a type id. const char* GetTypeDescriptor(const TypeId& type_id) const; @@ -671,7 +672,7 @@ class DexFile { const char* GetClassDescriptor(const ClassDef& class_def) const; // Looks up a class definition by its type index. - const ClassDef* FindClassDef(uint16_t type_idx) const; + const ClassDef* FindClassDef(dex::TypeIndex type_idx) const; const TypeList* GetInterfacesList(const ClassDef& class_def) const { if (class_def.interfaces_off_ == 0) { @@ -711,7 +712,7 @@ class DexFile { } // Returns the ProtoId at the specified index. - const ProtoId& GetProtoId(uint32_t idx) const { + const ProtoId& GetProtoId(uint16_t idx) const { DCHECK_LT(idx, NumProtoIds()) << GetLocation(); return proto_ids_[idx]; } @@ -723,16 +724,18 @@ class DexFile { } // Looks up a proto id for a given return type and signature type list - const ProtoId* FindProtoId(uint16_t return_type_idx, - const uint16_t* signature_type_idxs, uint32_t signature_length) const; - const ProtoId* FindProtoId(uint16_t return_type_idx, - const std::vector<uint16_t>& signature_type_idxs) const { + const ProtoId* FindProtoId(dex::TypeIndex return_type_idx, + const dex::TypeIndex* signature_type_idxs, + uint32_t signature_length) const; + const ProtoId* FindProtoId(dex::TypeIndex return_type_idx, + const std::vector<dex::TypeIndex>& signature_type_idxs) const { return FindProtoId(return_type_idx, &signature_type_idxs[0], signature_type_idxs.size()); } // Given a signature place the type ids into the given vector, returns true on success - bool CreateTypeList(const StringPiece& signature, uint16_t* return_type_idx, - std::vector<uint16_t>* param_type_idxs) const; + bool CreateTypeList(const StringPiece& signature, + dex::TypeIndex* return_type_idx, + std::vector<dex::TypeIndex>* param_type_idxs) const; // Create a Signature from the given string signature or return Signature::NoSignature if not // possible. @@ -1021,7 +1024,7 @@ class DexFile { // Returns a human-readable form of the field at an index. std::string PrettyField(uint32_t field_idx, bool with_type = true) const; // Returns a human-readable form of the type at an index. - std::string PrettyType(uint32_t type_idx) const; + std::string PrettyType(dex::TypeIndex type_idx) const; private: static std::unique_ptr<const DexFile> OpenFile(int fd, @@ -1165,11 +1168,11 @@ class DexFileParameterIterator { bool HasNext() const { return pos_ < size_; } size_t Size() const { return size_; } void Next() { ++pos_; } - uint16_t GetTypeIdx() { + dex::TypeIndex GetTypeIdx() { return type_list_->GetTypeItem(pos_).type_idx_; } const char* GetDescriptor() { - return dex_file_.StringByTypeIdx(GetTypeIdx()); + return dex_file_.StringByTypeIdx(dex::TypeIndex(GetTypeIdx())); } private: const DexFile& dex_file_; @@ -1455,7 +1458,7 @@ class CatchHandlerIterator { Init(handler_data); } - uint16_t GetHandlerTypeIndex() const { + dex::TypeIndex GetHandlerTypeIndex() const { return handler_.type_idx_; } uint32_t GetHandlerAddress() const { @@ -1476,7 +1479,7 @@ class CatchHandlerIterator { void Init(const uint8_t* handler_data); struct CatchHandlerItem { - uint16_t type_idx_; // type index of the caught exception type + dex::TypeIndex type_idx_; // type index of the caught exception type uint32_t address_; // handler address } handler_; const uint8_t* current_data_; // the current handler in dex file. diff --git a/runtime/dex_file_annotations.cc b/runtime/dex_file_annotations.cc index 835f456c9b..3fe2c409ca 100644 --- a/runtime/dex_file_annotations.cc +++ b/runtime/dex_file_annotations.cc @@ -90,7 +90,7 @@ const DexFile::AnnotationItem* SearchAnnotationSet(const DexFile& dex_file, const uint8_t* annotation = annotation_item->annotation_; uint32_t type_index = DecodeUnsignedLeb128(&annotation); - if (strcmp(descriptor, dex_file.StringByTypeIdx(type_index)) == 0) { + if (strcmp(descriptor, dex_file.StringByTypeIdx(dex::TypeIndex(type_index))) == 0) { result = annotation_item; break; } @@ -246,7 +246,7 @@ mirror::Object* ProcessEncodedAnnotation(Handle<mirror::Class> klass, const uint StackHandleScope<2> hs(self); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); Handle<mirror::Class> annotation_class(hs.NewHandle( - class_linker->ResolveType(klass->GetDexFile(), type_index, klass.Get()))); + class_linker->ResolveType(klass->GetDexFile(), dex::TypeIndex(type_index), klass.Get()))); if (annotation_class.Get() == nullptr) { LOG(INFO) << "Unable to resolve " << klass->PrettyClass() << " annotation class " << type_index; DCHECK(Thread::Current()->IsExceptionPending()); @@ -370,13 +370,14 @@ bool ProcessAnnotationValue(Handle<mirror::Class> klass, if (result_style == DexFile::kAllRaw) { annotation_value->value_.SetI(index); } else { + dex::TypeIndex type_index(index); element_object = Runtime::Current()->GetClassLinker()->ResolveType( - klass->GetDexFile(), index, klass.Get()); + klass->GetDexFile(), type_index, klass.Get()); set_object = true; if (element_object == nullptr) { CHECK(self->IsExceptionPending()); if (result_style == DexFile::kAllObjects) { - const char* msg = dex_file.StringByTypeIdx(index); + const char* msg = dex_file.StringByTypeIdx(type_index); self->ThrowNewWrappedException("Ljava/lang/TypeNotPresentException;", msg); element_object = self->GetException(); self->ClearException(); @@ -665,7 +666,7 @@ const DexFile::AnnotationItem* GetAnnotationItemFromAnnotationSet( const uint8_t* annotation = annotation_item->annotation_; uint32_t type_index = DecodeUnsignedLeb128(&annotation); mirror::Class* resolved_class = Runtime::Current()->GetClassLinker()->ResolveType( - klass->GetDexFile(), type_index, klass.Get()); + klass->GetDexFile(), dex::TypeIndex(type_index), klass.Get()); if (resolved_class == nullptr) { std::string temp; LOG(WARNING) << StringPrintf("Unable to resolve %s annotation class %d", @@ -1345,7 +1346,9 @@ void RuntimeEncodedStaticFieldValueIterator::ReadValueToField(ArtField* field) c break; } case kType: { - mirror::Class* resolved = linker_->ResolveType(dex_file_, jval_.i, *dex_cache_, + mirror::Class* resolved = linker_->ResolveType(dex_file_, + dex::TypeIndex(jval_.i), + *dex_cache_, *class_loader_); field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved); break; diff --git a/runtime/dex_file_test.cc b/runtime/dex_file_test.cc index 8e1501ff16..f94d07b252 100644 --- a/runtime/dex_file_test.cc +++ b/runtime/dex_file_test.cc @@ -415,14 +415,14 @@ TEST_F(DexFileTest, FindStringId) { TEST_F(DexFileTest, FindTypeId) { for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) { - const char* type_str = java_lang_dex_file_->StringByTypeIdx(i); + const char* type_str = java_lang_dex_file_->StringByTypeIdx(dex::TypeIndex(i)); const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str); ASSERT_TRUE(type_str_id != nullptr); uint32_t type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id); const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx); ASSERT_EQ(type_id, java_lang_dex_file_->FindTypeId(type_str)); ASSERT_TRUE(type_id != nullptr); - EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id), i); + EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id).index_, i); } } @@ -430,7 +430,7 @@ TEST_F(DexFileTest, FindProtoId) { for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) { const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i); const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find); - std::vector<uint16_t> to_find_types; + std::vector<dex::TypeIndex> to_find_types; if (to_find_tl != nullptr) { for (size_t j = 0; j < to_find_tl->Size(); j++) { to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_); diff --git a/runtime/dex_file_types.h b/runtime/dex_file_types.h new file mode 100644 index 0000000000..c6d95a1d19 --- /dev/null +++ b/runtime/dex_file_types.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2016 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_RUNTIME_DEX_FILE_TYPES_H_ +#define ART_RUNTIME_DEX_FILE_TYPES_H_ + +#include <limits> +#include <ostream> + +namespace art { +namespace dex { + +class TypeIndex { + public: + uint16_t index_; + + TypeIndex() : index_(std::numeric_limits<decltype(index_)>::max()) {} + explicit TypeIndex(uint16_t idx) : index_(idx) {} + + bool IsValid() const { + return index_ != std::numeric_limits<decltype(index_)>::max(); + } + static TypeIndex Invalid() { + return TypeIndex(std::numeric_limits<decltype(index_)>::max()); + } + + bool operator==(const TypeIndex& other) const { + return index_ == other.index_; + } + bool operator!=(const TypeIndex& other) const { + return index_ != other.index_; + } + bool operator<(const TypeIndex& other) const { + return index_ < other.index_; + } + bool operator<=(const TypeIndex& other) const { + return index_ <= other.index_; + } + bool operator>(const TypeIndex& other) const { + return index_ > other.index_; + } + bool operator>=(const TypeIndex& other) const { + return index_ >= other.index_; + } +}; +std::ostream& operator<<(std::ostream& os, const TypeIndex& index); + +} // namespace dex +} // namespace art + +namespace std { + +template<> struct hash<art::dex::TypeIndex> { + size_t operator()(const art::dex::TypeIndex& index) const { + return hash<uint16_t>()(index.index_); + } +}; + +} // namespace std + +#endif // ART_RUNTIME_DEX_FILE_TYPES_H_ diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc index be25803f59..68e9f73927 100644 --- a/runtime/dex_file_verifier.cc +++ b/runtime/dex_file_verifier.cc @@ -76,8 +76,9 @@ const char* DexFileVerifier::CheckLoadStringByIdx(uint32_t idx, const char* erro return dex_file_->StringDataByIdx(idx); } -const char* DexFileVerifier::CheckLoadStringByTypeIdx(uint32_t type_idx, const char* error_string) { - if (UNLIKELY(!CheckIndex(type_idx, dex_file_->NumTypeIds(), error_string))) { +const char* DexFileVerifier::CheckLoadStringByTypeIdx(dex::TypeIndex type_idx, + const char* error_string) { + if (UNLIKELY(!CheckIndex(type_idx.index_, dex_file_->NumTypeIds(), error_string))) { return nullptr; } const DexFile::TypeId& type_id = dex_file_->GetTypeId(type_idx); @@ -525,7 +526,7 @@ bool DexFileVerifier::CheckAndGetHandlerOffsets(const DexFile::CodeItem* code_it bool DexFileVerifier::CheckClassDataItemField(uint32_t idx, uint32_t access_flags, uint32_t class_access_flags, - uint16_t class_type_index, + dex::TypeIndex class_type_index, bool expect_static) { // Check for overflow. if (!CheckIndex(idx, header_->field_ids_size_, "class_data_item field_idx")) { @@ -533,13 +534,13 @@ bool DexFileVerifier::CheckClassDataItemField(uint32_t idx, } // Check that it's the right class. - uint16_t my_class_index = + dex::TypeIndex my_class_index = (reinterpret_cast<const DexFile::FieldId*>(begin_ + header_->field_ids_off_) + idx)-> class_idx_; if (class_type_index != my_class_index) { ErrorStringPrintf("Field's class index unexpected, %" PRIu16 "vs %" PRIu16, - my_class_index, - class_type_index); + my_class_index.index_, + class_type_index.index_); return false; } @@ -563,7 +564,7 @@ bool DexFileVerifier::CheckClassDataItemField(uint32_t idx, bool DexFileVerifier::CheckClassDataItemMethod(uint32_t idx, uint32_t access_flags, uint32_t class_access_flags, - uint16_t class_type_index, + dex::TypeIndex class_type_index, uint32_t code_offset, std::unordered_set<uint32_t>* direct_method_indexes, bool expect_direct) { @@ -574,13 +575,13 @@ bool DexFileVerifier::CheckClassDataItemMethod(uint32_t idx, } // Check that it's the right class. - uint16_t my_class_index = + dex::TypeIndex my_class_index = (reinterpret_cast<const DexFile::MethodId*>(begin_ + header_->method_ids_off_) + idx)-> class_idx_; if (class_type_index != my_class_index) { ErrorStringPrintf("Method's class index unexpected, %" PRIu16 "vs %" PRIu16, - my_class_index, - class_type_index); + my_class_index.index_, + class_type_index.index_); return false; } @@ -789,7 +790,7 @@ bool DexFileVerifier::CheckEncodedAnnotation() { bool DexFileVerifier::FindClassFlags(uint32_t index, bool is_field, - uint16_t* class_type_index, + dex::TypeIndex* class_type_index, uint32_t* class_access_flags) { DCHECK(class_type_index != nullptr); DCHECK(class_access_flags != nullptr); @@ -811,7 +812,7 @@ bool DexFileVerifier::FindClassFlags(uint32_t index, } // Check if that is valid. - if (*class_type_index >= header_->type_ids_size_) { + if (class_type_index->index_ >= header_->type_ids_size_) { return false; } @@ -836,7 +837,7 @@ bool DexFileVerifier::CheckOrderAndGetClassFlags(bool is_field, uint32_t curr_index, uint32_t prev_index, bool* have_class, - uint16_t* class_type_index, + dex::TypeIndex* class_type_index, uint32_t* class_access_flags) { if (curr_index < prev_index) { ErrorStringPrintf("out-of-order %s indexes %" PRIu32 " and %" PRIu32, @@ -862,7 +863,7 @@ bool DexFileVerifier::CheckOrderAndGetClassFlags(bool is_field, template <bool kStatic> bool DexFileVerifier::CheckIntraClassDataItemFields(ClassDataItemIterator* it, bool* have_class, - uint16_t* class_type_index, + dex::TypeIndex* class_type_index, uint32_t* class_access_flags) { DCHECK(it != nullptr); // These calls use the raw access flags to check whether the whole dex field is valid. @@ -897,7 +898,7 @@ bool DexFileVerifier::CheckIntraClassDataItemMethods( ClassDataItemIterator* it, std::unordered_set<uint32_t>* direct_method_indexes, bool* have_class, - uint16_t* class_type_index, + dex::TypeIndex* class_type_index, uint32_t* class_access_flags) { uint32_t prev_index = 0; for (; kDirect ? it->HasNextDirectMethod() : it->HasNextVirtualMethod(); it->Next()) { @@ -935,7 +936,7 @@ bool DexFileVerifier::CheckIntraClassDataItem() { // So we need to explicitly search with the first item we find (either field or method), and then, // as the lookup is expensive, cache the result. bool have_class = false; - uint16_t class_type_index; + dex::TypeIndex class_type_index; uint32_t class_access_flags; // Check fields. @@ -1682,26 +1683,27 @@ bool DexFileVerifier::CheckOffsetToTypeMap(size_t offset, uint16_t type) { return true; } -uint16_t DexFileVerifier::FindFirstClassDataDefiner(const uint8_t* ptr, bool* success) { +dex::TypeIndex DexFileVerifier::FindFirstClassDataDefiner(const uint8_t* ptr, bool* success) { ClassDataItemIterator it(*dex_file_, ptr); *success = true; if (it.HasNextStaticField() || it.HasNextInstanceField()) { LOAD_FIELD(field, it.GetMemberIndex(), "first_class_data_definer field_id", - *success = false; return DexFile::kDexNoIndex16) + *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16)) return field->class_idx_; } if (it.HasNextDirectMethod() || it.HasNextVirtualMethod()) { LOAD_METHOD(method, it.GetMemberIndex(), "first_class_data_definer method_id", - *success = false; return DexFile::kDexNoIndex16) + *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16)) return method->class_idx_; } - return DexFile::kDexNoIndex16; + return dex::TypeIndex(DexFile::kDexNoIndex16); } -uint16_t DexFileVerifier::FindFirstAnnotationsDirectoryDefiner(const uint8_t* ptr, bool* success) { +dex::TypeIndex DexFileVerifier::FindFirstAnnotationsDirectoryDefiner(const uint8_t* ptr, + bool* success) { const DexFile::AnnotationsDirectoryItem* item = reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr); *success = true; @@ -1709,25 +1711,25 @@ uint16_t DexFileVerifier::FindFirstAnnotationsDirectoryDefiner(const uint8_t* pt if (item->fields_size_ != 0) { DexFile::FieldAnnotationsItem* field_items = (DexFile::FieldAnnotationsItem*) (item + 1); LOAD_FIELD(field, field_items[0].field_idx_, "first_annotations_dir_definer field_id", - *success = false; return DexFile::kDexNoIndex16) + *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16)) return field->class_idx_; } if (item->methods_size_ != 0) { DexFile::MethodAnnotationsItem* method_items = (DexFile::MethodAnnotationsItem*) (item + 1); LOAD_METHOD(method, method_items[0].method_idx_, "first_annotations_dir_definer method id", - *success = false; return DexFile::kDexNoIndex16) + *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16)) return method->class_idx_; } if (item->parameters_size_ != 0) { DexFile::ParameterAnnotationsItem* parameter_items = (DexFile::ParameterAnnotationsItem*) (item + 1); LOAD_METHOD(method, parameter_items[0].method_idx_, "first_annotations_dir_definer method id", - *success = false; return DexFile::kDexNoIndex16) + *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16)) return method->class_idx_; } - return DexFile::kDexNoIndex16; + return dex::TypeIndex(DexFile::kDexNoIndex16); } bool DexFileVerifier::CheckInterStringIdItem() { @@ -1797,7 +1799,8 @@ bool DexFileVerifier::CheckInterProtoIdItem() { DexFileParameterIterator it(*dex_file_, *item); while (it.HasNext() && *shorty != '\0') { - if (!CheckIndex(it.GetTypeIdx(), dex_file_->NumTypeIds(), + if (!CheckIndex(it.GetTypeIdx().index_, + dex_file_->NumTypeIds(), "inter_proto_id_item shorty type_idx")) { return false; } @@ -1824,10 +1827,10 @@ bool DexFileVerifier::CheckInterProtoIdItem() { DexFileParameterIterator prev_it(*dex_file_, *prev); while (curr_it.HasNext() && prev_it.HasNext()) { - uint16_t prev_idx = prev_it.GetTypeIdx(); - uint16_t curr_idx = curr_it.GetTypeIdx(); - DCHECK_NE(prev_idx, DexFile::kDexNoIndex16); - DCHECK_NE(curr_idx, DexFile::kDexNoIndex16); + dex::TypeIndex prev_idx = prev_it.GetTypeIdx(); + dex::TypeIndex curr_idx = curr_it.GetTypeIdx(); + DCHECK_NE(prev_idx, dex::TypeIndex(DexFile::kDexNoIndex16)); + DCHECK_NE(curr_idx, dex::TypeIndex(DexFile::kDexNoIndex16)); if (prev_idx < curr_idx) { break; @@ -1951,7 +1954,7 @@ bool DexFileVerifier::CheckInterClassDefItem() { // Check for duplicate class def. if (defined_classes_.find(item->class_idx_) != defined_classes_.end()) { - ErrorStringPrintf("Redefinition of class with type idx: '%d'", item->class_idx_); + ErrorStringPrintf("Redefinition of class with type idx: '%d'", item->class_idx_.index_); return false; } defined_classes_.insert(item->class_idx_); @@ -1985,12 +1988,13 @@ bool DexFileVerifier::CheckInterClassDefItem() { return false; } - if (item->superclass_idx_ != DexFile::kDexNoIndex16) { + if (item->superclass_idx_.IsValid()) { if (header_->GetVersion() >= DexFile::kClassDefinitionOrderEnforcedVersion) { // Check that a class does not inherit from itself directly (by having // the same type idx as its super class). if (UNLIKELY(item->superclass_idx_ == item->class_idx_)) { - ErrorStringPrintf("Class with same type idx as its superclass: '%d'", item->class_idx_); + ErrorStringPrintf("Class with same type idx as its superclass: '%d'", + item->class_idx_.index_); return false; } @@ -2004,8 +2008,8 @@ bool DexFileVerifier::CheckInterClassDefItem() { ErrorStringPrintf("Invalid class definition ordering:" " class with type idx: '%d' defined before" " superclass with type idx: '%d'", - item->class_idx_, - item->superclass_idx_); + item->class_idx_.index_, + item->superclass_idx_.index_); return false; } } @@ -2029,7 +2033,7 @@ bool DexFileVerifier::CheckInterClassDefItem() { // same type idx as one of its immediate implemented interfaces). if (UNLIKELY(interfaces->GetTypeItem(i).type_idx_ == item->class_idx_)) { ErrorStringPrintf("Class with same type idx as implemented interface: '%d'", - item->class_idx_); + item->class_idx_.index_); return false; } @@ -2044,8 +2048,8 @@ bool DexFileVerifier::CheckInterClassDefItem() { ErrorStringPrintf("Invalid class definition ordering:" " class with type idx: '%d' defined before" " implemented interface with type idx: '%d'", - item->class_idx_, - interfaces->GetTypeItem(i).type_idx_); + item->class_idx_.index_, + interfaces->GetTypeItem(i).type_idx_.index_); return false; } } @@ -2065,9 +2069,9 @@ bool DexFileVerifier::CheckInterClassDefItem() { * practice the number of interfaces implemented by any given class is low. */ for (uint32_t i = 1; i < size; i++) { - uint32_t idx1 = interfaces->GetTypeItem(i).type_idx_; + dex::TypeIndex idx1 = interfaces->GetTypeItem(i).type_idx_; for (uint32_t j =0; j < i; j++) { - uint32_t idx2 = interfaces->GetTypeItem(j).type_idx_; + dex::TypeIndex idx2 = interfaces->GetTypeItem(j).type_idx_; if (UNLIKELY(idx1 == idx2)) { ErrorStringPrintf("Duplicate interface: '%s'", dex_file_->StringByTypeIdx(idx1)); return false; @@ -2080,11 +2084,12 @@ bool DexFileVerifier::CheckInterClassDefItem() { if (item->class_data_off_ != 0) { const uint8_t* data = begin_ + item->class_data_off_; bool success; - uint16_t data_definer = FindFirstClassDataDefiner(data, &success); + dex::TypeIndex data_definer = FindFirstClassDataDefiner(data, &success); if (!success) { return false; } - if (UNLIKELY((data_definer != item->class_idx_) && (data_definer != DexFile::kDexNoIndex16))) { + if (UNLIKELY((data_definer != item->class_idx_) && + (data_definer != dex::TypeIndex(DexFile::kDexNoIndex16)))) { ErrorStringPrintf("Invalid class_data_item"); return false; } @@ -2099,12 +2104,12 @@ bool DexFileVerifier::CheckInterClassDefItem() { } const uint8_t* data = begin_ + item->annotations_off_; bool success; - uint16_t annotations_definer = FindFirstAnnotationsDirectoryDefiner(data, &success); + dex::TypeIndex annotations_definer = FindFirstAnnotationsDirectoryDefiner(data, &success); if (!success) { return false; } if (UNLIKELY((annotations_definer != item->class_idx_) && - (annotations_definer != DexFile::kDexNoIndex16))) { + (annotations_definer != dex::TypeIndex(DexFile::kDexNoIndex16)))) { ErrorStringPrintf("Invalid annotations_directory_item"); return false; } @@ -2165,7 +2170,7 @@ bool DexFileVerifier::CheckInterAnnotationSetItem() { bool DexFileVerifier::CheckInterClassDataItem() { ClassDataItemIterator it(*dex_file_, ptr_); bool success; - uint16_t defining_class = FindFirstClassDataDefiner(ptr_, &success); + dex::TypeIndex defining_class = FindFirstClassDataDefiner(ptr_, &success); if (!success) { return false; } @@ -2197,7 +2202,7 @@ bool DexFileVerifier::CheckInterAnnotationsDirectoryItem() { const DexFile::AnnotationsDirectoryItem* item = reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr_); bool success; - uint16_t defining_class = FindFirstAnnotationsDirectoryDefiner(ptr_, &success); + dex::TypeIndex defining_class = FindFirstAnnotationsDirectoryDefiner(ptr_, &success); if (!success) { return false; } @@ -2471,15 +2476,15 @@ static std::string GetStringOrError(const uint8_t* const begin, static std::string GetClassOrError(const uint8_t* const begin, const DexFile::Header* const header, - uint32_t class_idx) { + dex::TypeIndex class_idx) { // The `class_idx` is either `FieldId::class_idx_` or `MethodId::class_idx_` and // it has already been checked in `DexFileVerifier::CheckClassDataItemField()` // or `DexFileVerifier::CheckClassDataItemMethod()`, respectively, to match // a valid defining class. - CHECK_LT(class_idx, header->type_ids_size_); + CHECK_LT(class_idx.index_, header->type_ids_size_); const DexFile::TypeId* type_id = - reinterpret_cast<const DexFile::TypeId*>(begin + header->type_ids_off_) + class_idx; + reinterpret_cast<const DexFile::TypeId*>(begin + header->type_ids_off_) + class_idx.index_; // Assume that the data is OK at this point. Type id offsets have been checked at this point. diff --git a/runtime/dex_file_verifier.h b/runtime/dex_file_verifier.h index 133e4326bc..19a89de2f5 100644 --- a/runtime/dex_file_verifier.h +++ b/runtime/dex_file_verifier.h @@ -20,6 +20,7 @@ #include <unordered_set> #include "dex_file.h" +#include "dex_file_types.h" #include "safe_map.h" namespace art { @@ -76,12 +77,12 @@ class DexFileVerifier { bool CheckClassDataItemField(uint32_t idx, uint32_t access_flags, uint32_t class_access_flags, - uint16_t class_type_index, + dex::TypeIndex class_type_index, bool expect_static); bool CheckClassDataItemMethod(uint32_t idx, uint32_t access_flags, uint32_t class_access_flags, - uint16_t class_type_index, + dex::TypeIndex class_type_index, uint32_t code_offset, std::unordered_set<uint32_t>* direct_method_indexes, bool expect_direct); @@ -90,7 +91,7 @@ class DexFileVerifier { uint32_t curr_index, uint32_t prev_index, bool* have_class, - uint16_t* class_type_index, + dex::TypeIndex* class_type_index, uint32_t* class_access_flags); bool CheckPadding(size_t offset, uint32_t aligned_offset); @@ -104,7 +105,7 @@ class DexFileVerifier { template <bool kStatic> bool CheckIntraClassDataItemFields(ClassDataItemIterator* it, bool* have_class, - uint16_t* class_type_index, + dex::TypeIndex* class_type_index, uint32_t* class_access_flags); // Check all methods of the given type from the given iterator. Load the class data from the first // method, if necessary (and return it), or use the given values. @@ -112,7 +113,7 @@ class DexFileVerifier { bool CheckIntraClassDataItemMethods(ClassDataItemIterator* it, std::unordered_set<uint32_t>* direct_method_indexes, bool* have_class, - uint16_t* class_type_index, + dex::TypeIndex* class_type_index, uint32_t* class_access_flags); bool CheckIntraCodeItem(); @@ -130,8 +131,8 @@ class DexFileVerifier { // Note: as sometimes kDexNoIndex16, being 0xFFFF, is a valid return value, we need an // additional out parameter to signal any errors loading an index. - uint16_t FindFirstClassDataDefiner(const uint8_t* ptr, bool* success); - uint16_t FindFirstAnnotationsDirectoryDefiner(const uint8_t* ptr, bool* success); + dex::TypeIndex FindFirstClassDataDefiner(const uint8_t* ptr, bool* success); + dex::TypeIndex FindFirstAnnotationsDirectoryDefiner(const uint8_t* ptr, bool* success); bool CheckInterStringIdItem(); bool CheckInterTypeIdItem(); @@ -150,7 +151,7 @@ class DexFileVerifier { // Load a string by (type) index. Checks whether the index is in bounds, printing the error if // not. If there is an error, null is returned. const char* CheckLoadStringByIdx(uint32_t idx, const char* error_fmt); - const char* CheckLoadStringByTypeIdx(uint32_t type_idx, const char* error_fmt); + const char* CheckLoadStringByTypeIdx(dex::TypeIndex type_idx, const char* error_fmt); // Load a field/method Id by index. Checks whether the index is in bounds, printing the error if // not. If there is an error, null is returned. @@ -168,7 +169,7 @@ class DexFileVerifier { // linear search. The output values should thus be cached by the caller. bool FindClassFlags(uint32_t index, bool is_field, - uint16_t* class_type_index, + dex::TypeIndex* class_type_index, uint32_t* class_access_flags); // Check validity of the given access flags, interpreted for a field in the context of a class diff --git a/runtime/dex_file_verifier_test.cc b/runtime/dex_file_verifier_test.cc index 3801c228c0..0e0929f21f 100644 --- a/runtime/dex_file_verifier_test.cc +++ b/runtime/dex_file_verifier_test.cc @@ -26,6 +26,7 @@ #include "base/macros.h" #include "common_runtime_test.h" #include "dex_file-inl.h" +#include "dex_file_types.h" #include "leb128.h" #include "scoped_thread_state_change-inl.h" #include "thread-inl.h" @@ -155,7 +156,7 @@ TEST_F(DexFileVerifierTest, MethodId) { "method_id_class_idx", [](DexFile* dex_file) { DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0)); - method_id->class_idx_ = 0xFF; + method_id->class_idx_ = dex::TypeIndex(0xFF); }, "could not find declaring class for direct method index 0"); diff --git a/runtime/dex_instruction.cc b/runtime/dex_instruction.cc index c766b54c0a..751bd51dab 100644 --- a/runtime/dex_instruction.cc +++ b/runtime/dex_instruction.cc @@ -208,9 +208,9 @@ std::string Instruction::DumpString(const DexFile* file) const { case CONST_CLASS: case NEW_INSTANCE: if (file != nullptr) { - uint32_t type_idx = VRegB_21c(); - os << opcode << " v" << static_cast<int>(VRegA_21c()) << ", " << file->PrettyType(type_idx) - << " // type@" << type_idx; + dex::TypeIndex type_idx(VRegB_21c()); + os << opcode << " v" << static_cast<int>(VRegA_21c()) << ", " + << file->PrettyType(type_idx) << " // type@" << type_idx; break; } FALLTHROUGH_INTENDED; @@ -302,17 +302,19 @@ std::string Instruction::DumpString(const DexFile* file) const { FALLTHROUGH_INTENDED; case INSTANCE_OF: if (file != nullptr) { - uint32_t type_idx = VRegC_22c(); - os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", " - << file->PrettyType(type_idx) << " // type@" << type_idx; + dex::TypeIndex type_idx(VRegC_22c()); + os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" + << static_cast<int>(VRegB_22c()) << ", " << file->PrettyType(type_idx) + << " // type@" << type_idx.index_; break; } FALLTHROUGH_INTENDED; case NEW_ARRAY: if (file != nullptr) { - uint32_t type_idx = VRegC_22c(); - os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", " - << file->PrettyType(type_idx) << " // type@" << type_idx; + dex::TypeIndex type_idx(VRegC_22c()); + os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" + << static_cast<int>(VRegB_22c()) << ", " << file->PrettyType(type_idx) + << " // type@" << type_idx.index_; break; } FALLTHROUGH_INTENDED; diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index ed60f598d1..ac52f4e287 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -129,7 +129,7 @@ inline ArtMethod* GetCalleeSaveMethodCaller(Thread* self, Runtime::CalleeSaveTyp template <const bool kAccessCheck> ALWAYS_INLINE -inline mirror::Class* CheckObjectAlloc(uint32_t type_idx, +inline mirror::Class* CheckObjectAlloc(dex::TypeIndex type_idx, ArtMethod* method, Thread* self, bool* slow_path) { @@ -219,7 +219,7 @@ inline mirror::Class* CheckClassInitializedForObjectAlloc(mirror::Class* klass, // check. template <bool kAccessCheck, bool kInstrumented> ALWAYS_INLINE -inline mirror::Object* AllocObjectFromCode(uint32_t type_idx, +inline mirror::Object* AllocObjectFromCode(dex::TypeIndex type_idx, ArtMethod* method, Thread* self, gc::AllocatorType allocator_type) { @@ -275,7 +275,7 @@ inline mirror::Object* AllocObjectFromCodeInitialized(mirror::Class* klass, template <bool kAccessCheck> ALWAYS_INLINE -inline mirror::Class* CheckArrayAlloc(uint32_t type_idx, +inline mirror::Class* CheckArrayAlloc(dex::TypeIndex type_idx, int32_t component_count, ArtMethod* method, bool* slow_path) { @@ -313,7 +313,7 @@ inline mirror::Class* CheckArrayAlloc(uint32_t type_idx, // check. template <bool kAccessCheck, bool kInstrumented> ALWAYS_INLINE -inline mirror::Array* AllocArrayFromCode(uint32_t type_idx, +inline mirror::Array* AllocArrayFromCode(dex::TypeIndex type_idx, int32_t component_count, ArtMethod* method, Thread* self, @@ -562,7 +562,7 @@ inline ArtMethod* FindMethodFromCode(uint32_t method_idx, StackHandleScope<2> hs2(self); HandleWrapperObjPtr<mirror::Object> h_this(hs2.NewHandleWrapper(this_object)); Handle<mirror::Class> h_referring_class(hs2.NewHandle(referrer->GetDeclaringClass())); - const uint16_t method_type_idx = + const dex::TypeIndex method_type_idx = h_referring_class->GetDexFile().GetMethodId(method_idx).class_idx_; mirror::Class* method_reference_class = class_linker->ResolveType(method_type_idx, referrer); if (UNLIKELY(method_reference_class == nullptr)) { @@ -758,7 +758,8 @@ inline ArtMethod* FindMethodFast(uint32_t method_idx, return resolved_method; } else if (type == kSuper) { // TODO This lookup is rather slow. - uint16_t method_type_idx = referring_class->GetDexFile().GetMethodId(method_idx).class_idx_; + dex::TypeIndex method_type_idx = + referring_class->GetDexFile().GetMethodId(method_idx).class_idx_; mirror::Class* method_reference_class = referring_class->GetDexCache()->GetResolvedType(method_type_idx); if (method_reference_class == nullptr) { @@ -788,8 +789,11 @@ inline ArtMethod* FindMethodFast(uint32_t method_idx, } } -inline mirror::Class* ResolveVerifyAndClinit(uint32_t type_idx, ArtMethod* referrer, Thread* self, - bool can_run_clinit, bool verify_access) { +inline mirror::Class* ResolveVerifyAndClinit(dex::TypeIndex type_idx, + ArtMethod* referrer, + Thread* self, + bool can_run_clinit, + bool verify_access) { ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); mirror::Class* klass = class_linker->ResolveType(type_idx, referrer); if (UNLIKELY(klass == nullptr)) { diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc index 1ccb4b004c..5390165ecd 100644 --- a/runtime/entrypoints/entrypoint_utils.cc +++ b/runtime/entrypoints/entrypoint_utils.cc @@ -38,7 +38,7 @@ namespace art { -static inline mirror::Class* CheckFilledNewArrayAlloc(uint32_t type_idx, +static inline mirror::Class* CheckFilledNewArrayAlloc(dex::TypeIndex type_idx, int32_t component_count, ArtMethod* referrer, Thread* self, @@ -82,10 +82,12 @@ static inline mirror::Class* CheckFilledNewArrayAlloc(uint32_t type_idx, } // Helper function to allocate array for FILLED_NEW_ARRAY. -mirror::Array* CheckAndAllocArrayFromCode(uint32_t type_idx, int32_t component_count, - ArtMethod* referrer, Thread* self, +mirror::Array* CheckAndAllocArrayFromCode(dex::TypeIndex type_idx, + int32_t component_count, + ArtMethod* referrer, + Thread* self, bool access_check, - gc::AllocatorType /* allocator_type */) { + gc::AllocatorType allocator_type ATTRIBUTE_UNUSED) { mirror::Class* klass = CheckFilledNewArrayAlloc(type_idx, component_count, referrer, self, access_check); if (UNLIKELY(klass == nullptr)) { @@ -101,12 +103,13 @@ mirror::Array* CheckAndAllocArrayFromCode(uint32_t type_idx, int32_t component_c } // Helper function to allocate array for FILLED_NEW_ARRAY. -mirror::Array* CheckAndAllocArrayFromCodeInstrumented(uint32_t type_idx, - int32_t component_count, - ArtMethod* referrer, - Thread* self, - bool access_check, - gc::AllocatorType /* allocator_type */) { +mirror::Array* CheckAndAllocArrayFromCodeInstrumented( + dex::TypeIndex type_idx, + int32_t component_count, + ArtMethod* referrer, + Thread* self, + bool access_check, + gc::AllocatorType allocator_type ATTRIBUTE_UNUSED) { mirror::Class* klass = CheckFilledNewArrayAlloc(type_idx, component_count, referrer, self, access_check); if (UNLIKELY(klass == nullptr)) { diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h index bcddfb0508..d87dc674bc 100644 --- a/runtime/entrypoints/entrypoint_utils.h +++ b/runtime/entrypoints/entrypoint_utils.h @@ -23,6 +23,7 @@ #include "base/macros.h" #include "base/mutex.h" #include "dex_instruction.h" +#include "dex_file_types.h" #include "gc/allocator_type.h" #include "handle.h" #include "invoke_type.h" @@ -45,7 +46,7 @@ class ScopedObjectAccessAlreadyRunnable; class Thread; template <const bool kAccessCheck> -ALWAYS_INLINE inline mirror::Class* CheckObjectAlloc(uint32_t type_idx, +ALWAYS_INLINE inline mirror::Class* CheckObjectAlloc(dex::TypeIndex type_idx, ArtMethod* method, Thread* self, bool* slow_path) @@ -63,7 +64,7 @@ ALWAYS_INLINE inline mirror::Class* CheckClassInitializedForObjectAlloc(mirror:: // When verification/compiler hasn't been able to verify access, optionally perform an access // check. template <bool kAccessCheck, bool kInstrumented> -ALWAYS_INLINE inline mirror::Object* AllocObjectFromCode(uint32_t type_idx, +ALWAYS_INLINE inline mirror::Object* AllocObjectFromCode(dex::TypeIndex type_idx, ArtMethod* method, Thread* self, gc::AllocatorType allocator_type) @@ -89,7 +90,7 @@ ALWAYS_INLINE inline mirror::Object* AllocObjectFromCodeInitialized( template <bool kAccessCheck> -ALWAYS_INLINE inline mirror::Class* CheckArrayAlloc(uint32_t type_idx, +ALWAYS_INLINE inline mirror::Class* CheckArrayAlloc(dex::TypeIndex type_idx, int32_t component_count, ArtMethod* method, bool* slow_path) @@ -101,7 +102,7 @@ ALWAYS_INLINE inline mirror::Class* CheckArrayAlloc(uint32_t type_idx, // When verification/compiler hasn't been able to verify access, optionally perform an access // check. template <bool kAccessCheck, bool kInstrumented> -ALWAYS_INLINE inline mirror::Array* AllocArrayFromCode(uint32_t type_idx, +ALWAYS_INLINE inline mirror::Array* AllocArrayFromCode(dex::TypeIndex type_idx, int32_t component_count, ArtMethod* method, Thread* self, @@ -118,19 +119,21 @@ ALWAYS_INLINE inline mirror::Array* AllocArrayFromCodeResolved(mirror::Class* kl REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); -extern mirror::Array* CheckAndAllocArrayFromCode(uint32_t type_idx, int32_t component_count, - ArtMethod* method, Thread* self, - bool access_check, - gc::AllocatorType allocator_type) +mirror::Array* CheckAndAllocArrayFromCode(dex::TypeIndex type_idx, + int32_t component_count, + ArtMethod* method, + Thread* self, + bool access_check, + gc::AllocatorType allocator_type) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); -extern mirror::Array* CheckAndAllocArrayFromCodeInstrumented(uint32_t type_idx, - int32_t component_count, - ArtMethod* method, - Thread* self, - bool access_check, - gc::AllocatorType allocator_type) +mirror::Array* CheckAndAllocArrayFromCodeInstrumented(dex::TypeIndex type_idx, + int32_t component_count, + ArtMethod* method, + Thread* self, + bool access_check, + gc::AllocatorType allocator_type) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); @@ -177,7 +180,7 @@ inline ArtMethod* FindMethodFast(uint32_t method_idx, InvokeType type) REQUIRES_SHARED(Locks::mutator_lock_); -inline mirror::Class* ResolveVerifyAndClinit(uint32_t type_idx, +inline mirror::Class* ResolveVerifyAndClinit(dex::TypeIndex type_idx, ArtMethod* referrer, Thread* self, bool can_run_clinit, diff --git a/runtime/entrypoints/quick/quick_alloc_entrypoints.cc b/runtime/entrypoints/quick/quick_alloc_entrypoints.cc index 515fcbf6e6..397655a895 100644 --- a/runtime/entrypoints/quick/quick_alloc_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_alloc_entrypoints.cc @@ -19,6 +19,7 @@ #include "art_method-inl.h" #include "base/enums.h" #include "callee_save_frame.h" +#include "dex_file_types.h" #include "entrypoints/entrypoint_utils-inl.h" #include "mirror/class-inl.h" #include "mirror/object_array-inl.h" @@ -34,7 +35,8 @@ extern "C" mirror::Object* artAllocObjectFromCode ##suffix##suffix2( \ REQUIRES_SHARED(Locks::mutator_lock_) { \ ScopedQuickEntrypointChecks sqec(self); \ if (kUseTlabFastPath && !(instrumented_bool) && (allocator_type) == gc::kAllocatorTypeTLAB) { \ - mirror::Class* klass = method->GetDexCacheResolvedType<false>(type_idx, kRuntimePointerSize); \ + mirror::Class* klass = method->GetDexCacheResolvedType<false>(dex::TypeIndex(type_idx), \ + kRuntimePointerSize); \ if (LIKELY(klass != nullptr && klass->IsInitialized() && !klass->IsFinalizable())) { \ size_t byte_count = klass->GetObjectSize(); \ byte_count = RoundUp(byte_count, gc::space::BumpPointerSpace::kAlignment); \ @@ -51,7 +53,10 @@ extern "C" mirror::Object* artAllocObjectFromCode ##suffix##suffix2( \ } \ } \ } \ - return AllocObjectFromCode<false, instrumented_bool>(type_idx, method, self, allocator_type); \ + return AllocObjectFromCode<false, instrumented_bool>(dex::TypeIndex(type_idx), \ + method, \ + self, \ + allocator_type); \ } \ extern "C" mirror::Object* artAllocObjectFromCodeResolved##suffix##suffix2( \ mirror::Class* klass, ArtMethod* method ATTRIBUTE_UNUSED, Thread* self) \ @@ -101,13 +106,19 @@ extern "C" mirror::Object* artAllocObjectFromCodeWithAccessCheck##suffix##suffix uint32_t type_idx, ArtMethod* method, Thread* self) \ REQUIRES_SHARED(Locks::mutator_lock_) { \ ScopedQuickEntrypointChecks sqec(self); \ - return AllocObjectFromCode<true, instrumented_bool>(type_idx, method, self, allocator_type); \ + return AllocObjectFromCode<true, instrumented_bool>(dex::TypeIndex(type_idx), \ + method, \ + self, \ + allocator_type); \ } \ extern "C" mirror::Array* artAllocArrayFromCode##suffix##suffix2( \ uint32_t type_idx, int32_t component_count, ArtMethod* method, Thread* self) \ REQUIRES_SHARED(Locks::mutator_lock_) { \ ScopedQuickEntrypointChecks sqec(self); \ - return AllocArrayFromCode<false, instrumented_bool>(type_idx, component_count, method, self, \ + return AllocArrayFromCode<false, instrumented_bool>(dex::TypeIndex(type_idx), \ + component_count, \ + method, \ + self, \ allocator_type); \ } \ extern "C" mirror::Array* artAllocArrayFromCodeResolved##suffix##suffix2( \ @@ -121,7 +132,10 @@ extern "C" mirror::Array* artAllocArrayFromCodeWithAccessCheck##suffix##suffix2( uint32_t type_idx, int32_t component_count, ArtMethod* method, Thread* self) \ REQUIRES_SHARED(Locks::mutator_lock_) { \ ScopedQuickEntrypointChecks sqec(self); \ - return AllocArrayFromCode<true, instrumented_bool>(type_idx, component_count, method, self, \ + return AllocArrayFromCode<true, instrumented_bool>(dex::TypeIndex(type_idx), \ + component_count, \ + method, \ + self, \ allocator_type); \ } \ extern "C" mirror::Array* artCheckAndAllocArrayFromCode##suffix##suffix2( \ @@ -129,9 +143,19 @@ extern "C" mirror::Array* artCheckAndAllocArrayFromCode##suffix##suffix2( \ REQUIRES_SHARED(Locks::mutator_lock_) { \ ScopedQuickEntrypointChecks sqec(self); \ if (!(instrumented_bool)) { \ - return CheckAndAllocArrayFromCode(type_idx, component_count, method, self, false, allocator_type); \ + return CheckAndAllocArrayFromCode(dex::TypeIndex(type_idx), \ + component_count, \ + method, \ + self, \ + false, \ + allocator_type); \ } else { \ - return CheckAndAllocArrayFromCodeInstrumented(type_idx, component_count, method, self, false, allocator_type); \ + return CheckAndAllocArrayFromCodeInstrumented(dex::TypeIndex(type_idx), \ + component_count, \ + method, \ + self, \ + false, \ + allocator_type); \ } \ } \ extern "C" mirror::Array* artCheckAndAllocArrayFromCodeWithAccessCheck##suffix##suffix2( \ @@ -139,9 +163,19 @@ extern "C" mirror::Array* artCheckAndAllocArrayFromCodeWithAccessCheck##suffix## REQUIRES_SHARED(Locks::mutator_lock_) { \ ScopedQuickEntrypointChecks sqec(self); \ if (!(instrumented_bool)) { \ - return CheckAndAllocArrayFromCode(type_idx, component_count, method, self, true, allocator_type); \ + return CheckAndAllocArrayFromCode(dex::TypeIndex(type_idx), \ + component_count, \ + method, \ + self, \ + true, \ + allocator_type); \ } else { \ - return CheckAndAllocArrayFromCodeInstrumented(type_idx, component_count, method, self, true, allocator_type); \ + return CheckAndAllocArrayFromCodeInstrumented(dex::TypeIndex(type_idx), \ + component_count, \ + method, \ + self, \ + true, \ + allocator_type); \ } \ } \ extern "C" mirror::String* artAllocStringFromBytesFromCode##suffix##suffix2( \ diff --git a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc index d4384182b2..b1259e1b8d 100644 --- a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc @@ -20,6 +20,7 @@ #include "class_linker-inl.h" #include "class_table-inl.h" #include "dex_file-inl.h" +#include "dex_file_types.h" #include "gc/heap.h" #include "mirror/class-inl.h" #include "mirror/class_loader.h" @@ -37,7 +38,7 @@ extern "C" mirror::Class* artInitializeStaticStorageFromCode(uint32_t type_idx, // given by inheritance. ScopedQuickEntrypointChecks sqec(self); auto* caller = GetCalleeSaveMethodCaller(self, Runtime::kSaveRefsOnly); - return ResolveVerifyAndClinit(type_idx, caller, self, true, false); + return ResolveVerifyAndClinit(dex::TypeIndex(type_idx), caller, self, true, false); } extern "C" mirror::Class* artInitializeTypeFromCode(uint32_t type_idx, Thread* self) @@ -45,7 +46,7 @@ extern "C" mirror::Class* artInitializeTypeFromCode(uint32_t type_idx, Thread* s // Called when method->dex_cache_resolved_types_[] misses. ScopedQuickEntrypointChecks sqec(self); auto* caller = GetCalleeSaveMethodCaller(self, Runtime::kSaveRefsOnly); - return ResolveVerifyAndClinit(type_idx, caller, self, false, false); + return ResolveVerifyAndClinit(dex::TypeIndex(type_idx), caller, self, false, false); } extern "C" mirror::Class* artInitializeTypeAndVerifyAccessFromCode(uint32_t type_idx, Thread* self) @@ -54,7 +55,7 @@ extern "C" mirror::Class* artInitializeTypeAndVerifyAccessFromCode(uint32_t type // unpopulated. ScopedQuickEntrypointChecks sqec(self); auto* caller = GetCalleeSaveMethodCaller(self, Runtime::kSaveRefsOnly); - return ResolveVerifyAndClinit(type_idx, caller, self, false, true); + return ResolveVerifyAndClinit(dex::TypeIndex(type_idx), caller, self, false, true); } extern "C" mirror::String* artResolveStringFromCode(int32_t string_idx, Thread* self) diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc index a32c800491..1b3d339f36 100644 --- a/runtime/interpreter/interpreter.cc +++ b/runtime/interpreter/interpreter.cc @@ -543,7 +543,7 @@ void EnterInterpreterFromDeoptimize(Thread* self, ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); // This is a suspend point. But it's ok since value has been set into shadow_frame. ObjPtr<mirror::Class> klass = class_linker->ResolveType( - instr->VRegB_21c(), shadow_frame->GetMethod()); + dex::TypeIndex(instr->VRegB_21c()), shadow_frame->GetMethod()); DCHECK(klass->IsStringClass()); } } else { diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index 8c63a9e979..05f74d67d4 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -1460,7 +1460,7 @@ static inline bool DoCallCommon(ArtMethod* called_method, ObjPtr<mirror::Object> o = shadow_frame.GetVRegReference(src_reg); if (do_assignability_check && o != nullptr) { PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); - const uint32_t type_idx = params->GetTypeItem(shorty_pos).type_idx_; + const dex::TypeIndex type_idx = params->GetTypeItem(shorty_pos).type_idx_; ObjPtr<mirror::Class> arg_type = method->GetDexCacheResolvedType(type_idx, pointer_size); if (arg_type == nullptr) { @@ -1568,7 +1568,7 @@ bool DoFilledNewArray(const Instruction* inst, return false; } uint16_t type_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c(); - ObjPtr<mirror::Class> array_class = ResolveVerifyAndClinit(type_idx, + ObjPtr<mirror::Class> array_class = ResolveVerifyAndClinit(dex::TypeIndex(type_idx), shadow_frame.GetMethod(), self, false, diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc index 435ac62a9d..989b7da4cf 100644 --- a/runtime/interpreter/interpreter_switch_impl.cc +++ b/runtime/interpreter/interpreter_switch_impl.cc @@ -395,7 +395,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::CONST_CLASS: { PREAMBLE(); - ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(inst->VRegB_21c(), + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()), shadow_frame.GetMethod(), self, false, @@ -434,7 +434,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::CHECK_CAST: { PREAMBLE(); - ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(inst->VRegB_21c(), + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()), shadow_frame.GetMethod(), self, false, @@ -454,7 +454,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::INSTANCE_OF: { PREAMBLE(); - ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(inst->VRegC_22c(), + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegC_22c()), shadow_frame.GetMethod(), self, false, @@ -484,7 +484,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, case Instruction::NEW_INSTANCE: { PREAMBLE(); ObjPtr<mirror::Object> obj = nullptr; - ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(inst->VRegB_21c(), + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()), shadow_frame.GetMethod(), self, false, @@ -495,8 +495,10 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, obj = mirror::String::AllocEmptyString<true>(self, allocator_type); } else { obj = AllocObjectFromCode<do_access_check, true>( - inst->VRegB_21c(), shadow_frame.GetMethod(), self, - Runtime::Current()->GetHeap()->GetCurrentAllocator()); + dex::TypeIndex(inst->VRegB_21c()), + shadow_frame.GetMethod(), + self, + Runtime::Current()->GetHeap()->GetCurrentAllocator()); } } if (UNLIKELY(obj == nullptr)) { @@ -520,7 +522,10 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, PREAMBLE(); int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data)); ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check, true>( - inst->VRegC_22c(), length, shadow_frame.GetMethod(), self, + dex::TypeIndex(inst->VRegC_22c()), + length, + shadow_frame.GetMethod(), + self, Runtime::Current()->GetHeap()->GetCurrentAllocator()); if (UNLIKELY(obj == nullptr)) { HANDLE_PENDING_EXCEPTION(); diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc index 2bd47bbfcf..fbfed402ee 100644 --- a/runtime/interpreter/mterp/mterp.cc +++ b/runtime/interpreter/mterp/mterp.cc @@ -304,7 +304,11 @@ extern "C" size_t MterpConstClass(uint32_t index, ShadowFrame* shadow_frame, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - mirror::Class* c = ResolveVerifyAndClinit(index, shadow_frame->GetMethod(), self, false, false); + mirror::Class* c = ResolveVerifyAndClinit(dex::TypeIndex(index), + shadow_frame->GetMethod(), + self, + false, + false); if (UNLIKELY(c == nullptr)) { return true; } @@ -317,7 +321,11 @@ extern "C" size_t MterpCheckCast(uint32_t index, art::ArtMethod* method, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(index, method, self, false, false); + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(index), + method, + self, + false, + false); if (UNLIKELY(c == nullptr)) { return true; } @@ -335,7 +343,11 @@ extern "C" size_t MterpInstanceOf(uint32_t index, art::ArtMethod* method, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(index, method, self, false, false); + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(index), + method, + self, + false, + false); if (UNLIKELY(c == nullptr)) { return false; // Caller will check for pending exception. Return value unimportant. } @@ -353,7 +365,7 @@ extern "C" size_t MterpNewInstance(ShadowFrame* shadow_frame, Thread* self, uint REQUIRES_SHARED(Locks::mutator_lock_) { const Instruction* inst = Instruction::At(shadow_frame->GetDexPCPtr()); mirror::Object* obj = nullptr; - mirror::Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), + mirror::Class* c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()), shadow_frame->GetMethod(), self, false, @@ -363,9 +375,10 @@ extern "C" size_t MterpNewInstance(ShadowFrame* shadow_frame, Thread* self, uint gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator(); obj = mirror::String::AllocEmptyString<true>(self, allocator_type); } else { - obj = AllocObjectFromCode<false, true>( - inst->VRegB_21c(), shadow_frame->GetMethod(), self, - Runtime::Current()->GetHeap()->GetCurrentAllocator()); + obj = AllocObjectFromCode<false, true>(dex::TypeIndex(inst->VRegB_21c()), + shadow_frame->GetMethod(), + self, + Runtime::Current()->GetHeap()->GetCurrentAllocator()); } } if (UNLIKELY(obj == nullptr)) { @@ -446,7 +459,7 @@ extern "C" size_t MterpNewArray(ShadowFrame* shadow_frame, const Instruction* inst = Instruction::At(dex_pc_ptr); int32_t length = shadow_frame->GetVReg(inst->VRegB_22c(inst_data)); mirror::Object* obj = AllocArrayFromCode<false, true>( - inst->VRegC_22c(), length, shadow_frame->GetMethod(), self, + dex::TypeIndex(inst->VRegC_22c()), length, shadow_frame->GetMethod(), self, Runtime::Current()->GetHeap()->GetCurrentAllocator()); if (UNLIKELY(obj == nullptr)) { return false; diff --git a/runtime/jit/offline_profiling_info.cc b/runtime/jit/offline_profiling_info.cc index b9f5981393..6f2a8c673f 100644 --- a/runtime/jit/offline_profiling_info.cc +++ b/runtime/jit/offline_profiling_info.cc @@ -235,7 +235,7 @@ bool ProfileCompilationInfo::Save(int fd) { AddUintToBuffer(&buffer, method_it); } for (auto class_id : dex_data.class_set) { - AddUintToBuffer(&buffer, class_id); + AddUintToBuffer(&buffer, class_id.index_); } DCHECK_EQ(required_capacity, buffer.size()) << "Failed to add the expected number of bytes in the buffer"; @@ -282,7 +282,7 @@ bool ProfileCompilationInfo::AddMethodIndex(const std::string& dex_location, bool ProfileCompilationInfo::AddClassIndex(const std::string& dex_location, uint32_t checksum, - uint16_t type_idx) { + dex::TypeIndex type_idx) { DexFileData* const data = GetOrAddDexFileData(dex_location, checksum); if (data == nullptr) { return false; @@ -305,7 +305,7 @@ bool ProfileCompilationInfo::ProcessLine(SafeBuffer& line_buffer, for (uint16_t i = 0; i < class_set_size; i++) { uint16_t type_idx = line_buffer.ReadUintAndAdvance<uint16_t>(); - if (!AddClassIndex(dex_location, checksum, type_idx)) { + if (!AddClassIndex(dex_location, checksum, dex::TypeIndex(type_idx))) { return false; } } @@ -569,13 +569,13 @@ bool ProfileCompilationInfo::ContainsMethod(const MethodReference& method_ref) c return false; } -bool ProfileCompilationInfo::ContainsClass(const DexFile& dex_file, uint16_t type_idx) const { +bool ProfileCompilationInfo::ContainsClass(const DexFile& dex_file, dex::TypeIndex type_idx) const { auto info_it = info_.find(GetProfileDexFileKey(dex_file.GetLocation())); if (info_it != info_.end()) { if (!ChecksumMatch(dex_file, info_it->second.checksum)) { return false; } - const std::set<uint16_t>& classes = info_it->second.class_set; + const std::set<dex::TypeIndex>& classes = info_it->second.class_set; return classes.find(type_idx) != classes.end(); } return false; @@ -706,7 +706,7 @@ bool ProfileCompilationInfo::GenerateTestProfile(int fd, if (c < (number_of_classes / kFavorSplit)) { type_idx %= kFavorFirstN; } - info.AddClassIndex(profile_key, 0, type_idx); + info.AddClassIndex(profile_key, 0, dex::TypeIndex(type_idx)); } } return info.Save(fd); diff --git a/runtime/jit/offline_profiling_info.h b/runtime/jit/offline_profiling_info.h index f8ed573b8b..413648829a 100644 --- a/runtime/jit/offline_profiling_info.h +++ b/runtime/jit/offline_profiling_info.h @@ -23,6 +23,7 @@ #include "atomic.h" #include "dex_cache_resolved_classes.h" #include "dex_file.h" +#include "dex_file_types.h" #include "method_reference.h" #include "safe_map.h" @@ -66,7 +67,7 @@ class ProfileCompilationInfo { bool ContainsMethod(const MethodReference& method_ref) const; // Returns true if the class's type is present in the profiling info. - bool ContainsClass(const DexFile& dex_file, uint16_t type_idx) const; + bool ContainsClass(const DexFile& dex_file, dex::TypeIndex type_idx) const; // Dumps all the loaded profile info into a string and returns it. // If dex_files is not null then the method indices will be resolved to their @@ -104,7 +105,7 @@ class ProfileCompilationInfo { explicit DexFileData(uint32_t location_checksum) : checksum(location_checksum) {} uint32_t checksum; std::set<uint16_t> method_set; - std::set<uint16_t> class_set; + std::set<dex::TypeIndex> class_set; bool operator==(const DexFileData& other) const { return checksum == other.checksum && method_set == other.method_set; @@ -115,7 +116,7 @@ class ProfileCompilationInfo { DexFileData* GetOrAddDexFileData(const std::string& dex_location, uint32_t checksum); bool AddMethodIndex(const std::string& dex_location, uint32_t checksum, uint16_t method_idx); - bool AddClassIndex(const std::string& dex_location, uint32_t checksum, uint16_t type_idx); + bool AddClassIndex(const std::string& dex_location, uint32_t checksum, dex::TypeIndex type_idx); bool AddResolvedClasses(const DexCacheResolvedClasses& classes); // Parsing functionality. diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h index 9a6d60e0ad..aa5da2e83b 100644 --- a/runtime/mirror/class-inl.h +++ b/runtime/mirror/class-inl.h @@ -372,7 +372,7 @@ inline bool Class::ResolvedFieldAccessTest(ObjPtr<Class> access_to, // to access the field if the FieldId specifies an accessible subclass of the declaring // class rather than the declaring class itself. ObjPtr<DexCache> referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache; - uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_; + dex::TypeIndex class_idx = referrer_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_; // The referenced class has already been resolved with the field, but may not be in the dex // cache. Use LookupResolveType here to search the class table if it is not in the dex cache. // should be no thread suspension due to the class being resolved. @@ -410,7 +410,7 @@ inline bool Class::ResolvedMethodAccessTest(ObjPtr<Class> access_to, // to access the method if the MethodId specifies an accessible subclass of the declaring // class rather than the declaring class itself. ObjPtr<DexCache> referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache; - uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_; + dex::TypeIndex class_idx = referrer_dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_; // The referenced class has already been resolved with the method, but may not be in the dex // cache. ObjPtr<Class> dex_access_to = Runtime::Current()->GetClassLinker()->LookupResolvedType( @@ -894,7 +894,8 @@ inline void Class::InitializeClassVisitor::operator()(ObjPtr<Object> obj, klass->SetClassSize(class_size_); klass->SetPrimitiveType(Primitive::kPrimNot); // Default to not being primitive. klass->SetDexClassDefIndex(DexFile::kDexNoIndex16); // Default to no valid class def index. - klass->SetDexTypeIndex(DexFile::kDexNoIndex16); // Default to no valid type index. + klass->SetDexTypeIndex(dex::TypeIndex(DexFile::kDexNoIndex16)); // Default to no valid type + // index. // Default to force slow path until initialized. klass->SetObjectSizeAllocFastPath(std::numeric_limits<uint32_t>::max()); } diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index db46027bc8..0cfe29bed9 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -923,7 +923,7 @@ const DexFile::ClassDef* Class::GetClassDef() { return &GetDexFile().GetClassDef(class_def_idx); } -uint16_t Class::GetDirectInterfaceTypeIdx(uint32_t idx) { +dex::TypeIndex Class::GetDirectInterfaceTypeIdx(uint32_t idx) { DCHECK(!IsPrimitive()); DCHECK(!IsArrayClass()); return GetInterfaceTypeList()->GetTypeItem(idx).type_idx_; @@ -947,10 +947,11 @@ ObjPtr<Class> Class::GetDirectInterface(Thread* self, DCHECK(interfaces != nullptr); return interfaces->Get(idx); } else { - uint16_t type_idx = klass->GetDirectInterfaceTypeIdx(idx); + dex::TypeIndex type_idx = klass->GetDirectInterfaceTypeIdx(idx); ObjPtr<Class> interface = klass->GetDexCache()->GetResolvedType(type_idx); if (interface == nullptr) { - interface = Runtime::Current()->GetClassLinker()->ResolveType(klass->GetDexFile(), type_idx, + interface = Runtime::Current()->GetClassLinker()->ResolveType(klass->GetDexFile(), + type_idx, klass.Get()); CHECK(interface != nullptr || self->IsExceptionPending()); } @@ -1130,10 +1131,12 @@ uint32_t Class::Depth() { return depth; } -uint32_t Class::FindTypeIndexInOtherDexFile(const DexFile& dex_file) { +dex::TypeIndex Class::FindTypeIndexInOtherDexFile(const DexFile& dex_file) { std::string temp; const DexFile::TypeId* type_id = dex_file.FindTypeId(GetDescriptor(&temp)); - return (type_id == nullptr) ? DexFile::kDexNoIndex : dex_file.GetIndexForTypeId(*type_id); + return (type_id == nullptr) + ? dex::TypeIndex(DexFile::kDexNoIndex) + : dex_file.GetIndexForTypeId(*type_id); } template <PointerSize kPointerSize, bool kTransactionActive> diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h index 711914dc61..792f626eff 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -20,6 +20,7 @@ #include "base/enums.h" #include "base/iteration_range.h" #include "dex_file.h" +#include "dex_file_types.h" #include "class_flags.h" #include "gc_root.h" #include "gc/allocator_type.h" @@ -1148,16 +1149,17 @@ class MANAGED Class FINAL : public Object { SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, dex_class_def_idx_), class_def_idx); } - uint16_t GetDexTypeIndex() REQUIRES_SHARED(Locks::mutator_lock_) { - return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_type_idx_)); + dex::TypeIndex GetDexTypeIndex() REQUIRES_SHARED(Locks::mutator_lock_) { + return dex::TypeIndex( + static_cast<uint16_t>(GetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_type_idx_)))); } - void SetDexTypeIndex(uint16_t type_idx) REQUIRES_SHARED(Locks::mutator_lock_) { + void SetDexTypeIndex(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_) { // Not called within a transaction. - SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, dex_type_idx_), type_idx); + SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, dex_type_idx_), type_idx.index_); } - uint32_t FindTypeIndexInOtherDexFile(const DexFile& dex_file) + dex::TypeIndex FindTypeIndexInOtherDexFile(const DexFile& dex_file) REQUIRES_SHARED(Locks::mutator_lock_); static Class* GetJavaLangClass() REQUIRES_SHARED(Locks::mutator_lock_) { @@ -1198,7 +1200,7 @@ class MANAGED Class FINAL : public Object { ALWAYS_INLINE uint32_t NumDirectInterfaces() REQUIRES_SHARED(Locks::mutator_lock_); - uint16_t GetDirectInterfaceTypeIdx(uint32_t idx) REQUIRES_SHARED(Locks::mutator_lock_); + dex::TypeIndex GetDirectInterfaceTypeIdx(uint32_t idx) REQUIRES_SHARED(Locks::mutator_lock_); static ObjPtr<Class> GetDirectInterface(Thread* self, Handle<Class> klass, diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h index c7a123b580..d903f71604 100644 --- a/runtime/mirror/dex_cache-inl.h +++ b/runtime/mirror/dex_cache-inl.h @@ -69,15 +69,15 @@ inline void DexCache::ClearString(uint32_t string_idx) { } } -inline Class* DexCache::GetResolvedType(uint32_t type_idx) { - DCHECK_LT(type_idx, NumResolvedTypes()); - return GetResolvedTypes()[type_idx].Read(); +inline Class* DexCache::GetResolvedType(dex::TypeIndex type_idx) { + DCHECK_LT(type_idx.index_, NumResolvedTypes()); + return GetResolvedTypes()[type_idx.index_].Read(); } -inline void DexCache::SetResolvedType(uint32_t type_idx, ObjPtr<Class> resolved) { - DCHECK_LT(type_idx, NumResolvedTypes()); // NOTE: Unchecked, i.e. not throwing AIOOB. +inline void DexCache::SetResolvedType(dex::TypeIndex type_idx, ObjPtr<Class> resolved) { + DCHECK_LT(type_idx.index_, NumResolvedTypes()); // NOTE: Unchecked, i.e. not throwing AIOOB. // TODO default transaction support. - GetResolvedTypes()[type_idx] = GcRoot<Class>(resolved); + GetResolvedTypes()[type_idx.index_] = GcRoot<Class>(resolved); // TODO: Fine-grained marking, so that we don't need to go through all arrays in full. Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(this); } diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h index 1ae694d789..7d82d3ad29 100644 --- a/runtime/mirror/dex_cache.h +++ b/runtime/mirror/dex_cache.h @@ -21,6 +21,7 @@ #include "art_field.h" #include "art_method.h" #include "class.h" +#include "dex_file_types.h" #include "object.h" #include "object_array.h" @@ -223,9 +224,9 @@ class MANAGED DexCache FINAL : public Object { // the string isn't kept live. void ClearString(uint32_t string_idx) REQUIRES_SHARED(Locks::mutator_lock_); - Class* GetResolvedType(uint32_t type_idx) REQUIRES_SHARED(Locks::mutator_lock_); + Class* GetResolvedType(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_); - void SetResolvedType(uint32_t type_idx, ObjPtr<Class> resolved) + void SetResolvedType(dex::TypeIndex type_idx, ObjPtr<Class> resolved) REQUIRES_SHARED(Locks::mutator_lock_); ALWAYS_INLINE ArtMethod* GetResolvedMethod(uint32_t method_idx, PointerSize ptr_size) diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc index 5bf254d961..4b47f7f614 100644 --- a/runtime/mirror/object_test.cc +++ b/runtime/mirror/object_test.cc @@ -313,7 +313,7 @@ TEST_F(ObjectTest, CheckAndAllocArrayFromCode) { ArtMethod* sort = java_util_Arrays->FindDirectMethod("sort", "([I)V", kRuntimePointerSize); const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId("[I"); ASSERT_TRUE(type_id != nullptr); - uint32_t type_idx = java_lang_dex_file_->GetIndexForTypeId(*type_id); + dex::TypeIndex type_idx = java_lang_dex_file_->GetIndexForTypeId(*type_id); Object* array = CheckAndAllocArrayFromCodeInstrumented( type_idx, 3, sort, Thread::Current(), false, Runtime::Current()->GetHeap()->GetCurrentAllocator()); diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc index 866dc7f73f..48feb11924 100644 --- a/runtime/native/dalvik_system_VMRuntime.cc +++ b/runtime/native/dalvik_system_VMRuntime.cc @@ -34,6 +34,7 @@ extern "C" void android_set_application_target_sdk_version(uint32_t version); #include "common_throws.h" #include "debugger.h" #include "dex_file-inl.h" +#include "dex_file_types.h" #include "gc/accounting/card_table-inl.h" #include "gc/allocator/dlmalloc.h" #include "gc/heap.h" @@ -305,7 +306,7 @@ static void PreloadDexCachesResolveString( // Based on ClassLinker::ResolveType. static void PreloadDexCachesResolveType(Thread* self, ObjPtr<mirror::DexCache> dex_cache, - uint32_t type_idx) + dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_) { ObjPtr<mirror::Class> klass = dex_cache->GetResolvedType(type_idx); if (klass != nullptr) { @@ -455,7 +456,7 @@ static void PreloadDexCachesStatsFilled(DexCacheStats* filled) } } for (size_t j = 0; j < dex_cache->NumResolvedTypes(); j++) { - ObjPtr<mirror::Class> klass = dex_cache->GetResolvedType(j); + ObjPtr<mirror::Class> klass = dex_cache->GetResolvedType(dex::TypeIndex(j)); if (klass != nullptr) { filled->num_types++; } @@ -519,7 +520,7 @@ static void VMRuntime_preloadDexCaches(JNIEnv* env, jobject) { if (kPreloadDexCachesTypes) { for (size_t j = 0; j < dex_cache->NumResolvedTypes(); j++) { - PreloadDexCachesResolveType(soa.Self(), dex_cache.Get(), j); + PreloadDexCachesResolveType(soa.Self(), dex_cache.Get(), dex::TypeIndex(j)); } } diff --git a/runtime/native/java_lang_DexCache.cc b/runtime/native/java_lang_DexCache.cc index 71379a51a5..f6de593017 100644 --- a/runtime/native/java_lang_DexCache.cc +++ b/runtime/native/java_lang_DexCache.cc @@ -17,6 +17,7 @@ #include "java_lang_DexCache.h" #include "dex_file.h" +#include "dex_file_types.h" #include "jni_internal.h" #include "mirror/class-inl.h" #include "mirror/dex_cache-inl.h" @@ -53,7 +54,7 @@ static jobject DexCache_getResolvedType(JNIEnv* env, jobject javaDexCache, jint ScopedFastNativeObjectAccess soa(env); ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache); CHECK_LT(static_cast<size_t>(type_index), dex_cache->NumResolvedTypes()); - return soa.AddLocalReference<jobject>(dex_cache->GetResolvedType(type_index)); + return soa.AddLocalReference<jobject>(dex_cache->GetResolvedType(dex::TypeIndex(type_index))); } static jobject DexCache_getResolvedString(JNIEnv* env, jobject javaDexCache, jint string_index) { @@ -68,7 +69,7 @@ static void DexCache_setResolvedType(JNIEnv* env, jobject javaDexCache, jint typ ScopedFastNativeObjectAccess soa(env); ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache); CHECK_LT(static_cast<size_t>(type_index), dex_cache->NumResolvedTypes()); - dex_cache->SetResolvedType(type_index, soa.Decode<mirror::Class>(type)); + dex_cache->SetResolvedType(dex::TypeIndex(type_index), soa.Decode<mirror::Class>(type)); } static void DexCache_setResolvedString(JNIEnv* env, jobject javaDexCache, jint string_index, diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc index c14b6169fb..b120a69642 100644 --- a/runtime/oat_file.cc +++ b/runtime/oat_file.cc @@ -38,6 +38,7 @@ #include "base/stl_util.h" #include "base/systrace.h" #include "base/unix_file/fd_file.h" +#include "dex_file_types.h" #include "elf_file.h" #include "elf_utils.h" #include "gc_root.h" @@ -1342,7 +1343,7 @@ const DexFile::ClassDef* OatFile::OatDexFile::FindClassDef(const DexFile& dex_fi } const DexFile::TypeId* type_id = dex_file.FindTypeId(descriptor); if (type_id != nullptr) { - uint16_t type_idx = dex_file.GetIndexForTypeId(*type_id); + dex::TypeIndex type_idx = dex_file.GetIndexForTypeId(*type_id); return dex_file.FindClassDef(type_idx); } return nullptr; diff --git a/runtime/openjdkjvmti/transform.cc b/runtime/openjdkjvmti/transform.cc index fa2983c19c..7bb5205f05 100644 --- a/runtime/openjdkjvmti/transform.cc +++ b/runtime/openjdkjvmti/transform.cc @@ -33,6 +33,7 @@ #include "class_linker.h" #include "dex_file.h" +#include "dex_file_types.h" #include "gc_root-inl.h" #include "globals.h" #include "jni_env_ext-inl.h" @@ -108,10 +109,10 @@ static void InvalidateExistingMethods(art::Thread* self, // Find the code_item for the method then find the dex_method_index and dex_code_item_offset to // set. const art::DexFile::StringId* new_name_id = dex_file->FindStringId(method.GetName()); - uint16_t method_return_idx = + art::dex::TypeIndex method_return_idx = dex_file->GetIndexForTypeId(*dex_file->FindTypeId(method.GetReturnTypeDescriptor())); const auto* old_type_list = method.GetParameterTypeList(); - std::vector<uint16_t> new_type_list; + std::vector<art::dex::TypeIndex> new_type_list; for (uint32_t i = 0; old_type_list != nullptr && i < old_type_list->Size(); i++) { new_type_list.push_back( dex_file->GetIndexForTypeId( diff --git a/runtime/reflection.cc b/runtime/reflection.cc index 3128380f76..8446b525ad 100644 --- a/runtime/reflection.cc +++ b/runtime/reflection.cc @@ -363,7 +363,7 @@ static void CheckMethodArguments(JavaVMExt* vm, ArtMethod* m, uint32_t* args) Thread* const self = Thread::Current(); PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); for (uint32_t i = 0; i < num_params; i++) { - uint16_t type_idx = params->GetTypeItem(i).type_idx_; + dex::TypeIndex type_idx = params->GetTypeItem(i).type_idx_; ObjPtr<mirror::Class> param_type(m->GetClassFromTypeIndex(type_idx, true /* resolve*/, pointer_size)); diff --git a/runtime/utils/dex_cache_arrays_layout-inl.h b/runtime/utils/dex_cache_arrays_layout-inl.h index c7875b56ec..bd1b044dae 100644 --- a/runtime/utils/dex_cache_arrays_layout-inl.h +++ b/runtime/utils/dex_cache_arrays_layout-inl.h @@ -65,8 +65,8 @@ static constexpr PointerSize GcRootAsPointerSize() { return PointerSize::k32; } -inline size_t DexCacheArraysLayout::TypeOffset(uint32_t type_idx) const { - return types_offset_ + ElementOffset(GcRootAsPointerSize<mirror::Class>(), type_idx); +inline size_t DexCacheArraysLayout::TypeOffset(dex::TypeIndex type_idx) const { + return types_offset_ + ElementOffset(GcRootAsPointerSize<mirror::Class>(), type_idx.index_); } inline size_t DexCacheArraysLayout::TypesSize(size_t num_elements) const { diff --git a/runtime/utils/dex_cache_arrays_layout.h b/runtime/utils/dex_cache_arrays_layout.h index ae3bfab38c..7d4b23a8dd 100644 --- a/runtime/utils/dex_cache_arrays_layout.h +++ b/runtime/utils/dex_cache_arrays_layout.h @@ -18,6 +18,7 @@ #define ART_RUNTIME_UTILS_DEX_CACHE_ARRAYS_LAYOUT_H_ #include "dex_file.h" +#include "dex_file_types.h" namespace art { @@ -59,7 +60,7 @@ class DexCacheArraysLayout { return types_offset_; } - size_t TypeOffset(uint32_t type_idx) const; + size_t TypeOffset(dex::TypeIndex type_idx) const; size_t TypesSize(size_t num_elements) const; diff --git a/runtime/verifier/method_verifier-inl.h b/runtime/verifier/method_verifier-inl.h index def61db81a..363bd8f54f 100644 --- a/runtime/verifier/method_verifier-inl.h +++ b/runtime/verifier/method_verifier-inl.h @@ -74,7 +74,7 @@ inline bool MethodVerifier::HasFailures() const { return !failure_messages_.empty(); } -inline const RegType& MethodVerifier::ResolveCheckedClass(uint32_t class_idx) { +inline const RegType& MethodVerifier::ResolveCheckedClass(dex::TypeIndex class_idx) { DCHECK(!HasFailures()); const RegType& result = ResolveClassAndCheckAccess(class_idx); DCHECK(!HasFailures()); diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index ed24611801..7137db8773 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -1072,7 +1072,7 @@ bool MethodVerifier::ScanTryCatchBlocks() { GetInstructionFlags(dex_pc).SetBranchTarget(); // Ensure exception types are resolved so that they don't need resolution to be delivered, // unresolved exception types will be ignored by exception delivery - if (iterator.GetHandlerTypeIndex() != DexFile::kDexNoIndex16) { + if (iterator.GetHandlerTypeIndex().IsValid()) { mirror::Class* exception_type = linker->ResolveType(*dex_file_, iterator.GetHandlerTypeIndex(), dex_cache_, class_loader_); @@ -1155,13 +1155,13 @@ bool MethodVerifier::VerifyInstruction(const Instruction* inst, uint32_t code_of result = result && CheckMethodIndex(inst->VRegB()); break; case Instruction::kVerifyRegBNewInstance: - result = result && CheckNewInstance(inst->VRegB()); + result = result && CheckNewInstance(dex::TypeIndex(inst->VRegB())); break; case Instruction::kVerifyRegBString: result = result && CheckStringIndex(inst->VRegB()); break; case Instruction::kVerifyRegBType: - result = result && CheckTypeIndex(inst->VRegB()); + result = result && CheckTypeIndex(dex::TypeIndex(inst->VRegB())); break; case Instruction::kVerifyRegBWide: result = result && CheckWideRegisterIndex(inst->VRegB()); @@ -1175,10 +1175,10 @@ bool MethodVerifier::VerifyInstruction(const Instruction* inst, uint32_t code_of result = result && CheckFieldIndex(inst->VRegC()); break; case Instruction::kVerifyRegCNewArray: - result = result && CheckNewArray(inst->VRegC()); + result = result && CheckNewArray(dex::TypeIndex(inst->VRegC())); break; case Instruction::kVerifyRegCType: - result = result && CheckTypeIndex(inst->VRegC()); + result = result && CheckTypeIndex(dex::TypeIndex(inst->VRegC())); break; case Instruction::kVerifyRegCWide: result = result && CheckWideRegisterIndex(inst->VRegC()); @@ -1270,9 +1270,9 @@ inline bool MethodVerifier::CheckMethodIndex(uint32_t idx) { return true; } -inline bool MethodVerifier::CheckNewInstance(uint32_t idx) { - if (idx >= dex_file_->GetHeader().type_ids_size_) { - Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx << " (max " +inline bool MethodVerifier::CheckNewInstance(dex::TypeIndex idx) { + if (idx.index_ >= dex_file_->GetHeader().type_ids_size_) { + Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max " << dex_file_->GetHeader().type_ids_size_ << ")"; return false; } @@ -1298,18 +1298,18 @@ inline bool MethodVerifier::CheckStringIndex(uint32_t idx) { return true; } -inline bool MethodVerifier::CheckTypeIndex(uint32_t idx) { - if (idx >= dex_file_->GetHeader().type_ids_size_) { - Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx << " (max " +inline bool MethodVerifier::CheckTypeIndex(dex::TypeIndex idx) { + if (idx.index_ >= dex_file_->GetHeader().type_ids_size_) { + Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max " << dex_file_->GetHeader().type_ids_size_ << ")"; return false; } return true; } -bool MethodVerifier::CheckNewArray(uint32_t idx) { - if (idx >= dex_file_->GetHeader().type_ids_size_) { - Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx << " (max " +bool MethodVerifier::CheckNewArray(dex::TypeIndex idx) { + if (idx.index_ >= dex_file_->GetHeader().type_ids_size_) { + Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max " << dex_file_->GetHeader().type_ids_size_ << ")"; return false; } @@ -1945,7 +1945,7 @@ bool MethodVerifier::CodeFlowVerifyMethod() { // Returns the index of the first final instance field of the given class, or kDexNoIndex if there // is no such field. -static uint32_t GetFirstFinalInstanceFieldIndex(const DexFile& dex_file, uint16_t type_idx) { +static uint32_t GetFirstFinalInstanceFieldIndex(const DexFile& dex_file, dex::TypeIndex type_idx) { const DexFile::ClassDef* class_def = dex_file.FindClassDef(type_idx); DCHECK(class_def != nullptr); const uint8_t* class_data = dex_file.GetClassData(*class_def); @@ -2293,7 +2293,7 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { case Instruction::CONST_CLASS: { // Get type from instruction if unresolved then we need an access check // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved - const RegType& res_type = ResolveClassAndCheckAccess(inst->VRegB_21c()); + const RegType& res_type = ResolveClassAndCheckAccess(dex::TypeIndex(inst->VRegB_21c())); // Register holds class, ie its type is class, on error it will hold Conflict. work_line_->SetRegisterType<LockOp::kClear>( this, inst->VRegA_21c(), res_type.IsConflict() ? res_type @@ -2363,7 +2363,7 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { * dec_insn.vA when branching to a handler. */ const bool is_checkcast = (inst->Opcode() == Instruction::CHECK_CAST); - const uint32_t type_idx = (is_checkcast) ? inst->VRegB_21c() : inst->VRegC_22c(); + const dex::TypeIndex type_idx((is_checkcast) ? inst->VRegB_21c() : inst->VRegC_22c()); const RegType& res_type = ResolveClassAndCheckAccess(type_idx); if (res_type.IsConflict()) { // If this is a primitive type, fail HARD. @@ -2433,7 +2433,7 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { break; } case Instruction::NEW_INSTANCE: { - const RegType& res_type = ResolveClassAndCheckAccess(inst->VRegB_21c()); + const RegType& res_type = ResolveClassAndCheckAccess(dex::TypeIndex(inst->VRegB_21c())); if (res_type.IsConflict()) { DCHECK_NE(failures_.size(), 0U); break; // bad class @@ -2645,7 +2645,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { // ensure that subsequent merges don't lose type information - such as becoming an // interface from a class that would lose information relevant to field checks. const RegType& orig_type = work_line_->GetRegisterType(this, instance_of_inst->VRegB_22c()); - const RegType& cast_type = ResolveClassAndCheckAccess(instance_of_inst->VRegC_22c()); + const RegType& cast_type = ResolveClassAndCheckAccess( + dex::TypeIndex(instance_of_inst->VRegC_22c())); if (!orig_type.Equals(cast_type) && !cast_type.IsUnresolvedTypes() && !orig_type.IsUnresolvedTypes() && @@ -2883,7 +2884,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { if (return_type == nullptr) { uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); - uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; + dex::TypeIndex return_type_idx = + dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; const char* descriptor = dex_file_->StringByTypeIdx(return_type_idx); return_type = ®_types_.FromDescriptor(GetClassLoader(), descriptor, false); } @@ -2906,7 +2908,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); is_constructor = strcmp("<init>", dex_file_->StringDataByIdx(method_id.name_idx_)) == 0; - uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; + dex::TypeIndex return_type_idx = + dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; return_type_descriptor = dex_file_->StringByTypeIdx(return_type_idx); } else { is_constructor = called_method->IsConstructor(); @@ -2982,7 +2985,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { if (called_method == nullptr) { uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); - uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; + dex::TypeIndex return_type_idx = + dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; descriptor = dex_file_->StringByTypeIdx(return_type_idx); } else { descriptor = called_method->GetReturnTypeDescriptor(); @@ -3036,7 +3040,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { if (abs_method == nullptr) { uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); - uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; + dex::TypeIndex return_type_idx = + dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; descriptor = dex_file_->StringByTypeIdx(return_type_idx); } else { descriptor = abs_method->GetReturnTypeDescriptor(); @@ -3500,8 +3505,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { ClassLinker* linker = Runtime::Current()->GetClassLinker(); for (; iterator.HasNext(); iterator.Next()) { - uint16_t handler_type_idx = iterator.GetHandlerTypeIndex(); - if (handler_type_idx == DexFile::kDexNoIndex16) { + dex::TypeIndex handler_type_idx = iterator.GetHandlerTypeIndex(); + if (!handler_type_idx.IsValid()) { has_catch_all_handler = true; } else { // It is also a catch-all if it is java.lang.Throwable. @@ -3628,7 +3633,7 @@ inline bool MethodVerifier::IsInstantiableOrPrimitive(mirror::Class* klass) { return klass->IsInstantiable() || klass->IsPrimitive(); } -const RegType& MethodVerifier::ResolveClassAndCheckAccess(uint32_t class_idx) { +const RegType& MethodVerifier::ResolveClassAndCheckAccess(dex::TypeIndex class_idx) { mirror::Class* klass = dex_cache_->GetResolvedType(class_idx); const RegType* result = nullptr; if (klass != nullptr) { @@ -3684,7 +3689,7 @@ const RegType& MethodVerifier::GetCaughtExceptionType() { CatchHandlerIterator iterator(handlers_ptr); for (; iterator.HasNext(); iterator.Next()) { if (iterator.GetHandlerAddress() == (uint32_t) work_insn_idx_) { - if (iterator.GetHandlerTypeIndex() == DexFile::kDexNoIndex16) { + if (!iterator.GetHandlerTypeIndex().IsValid()) { common_super = ®_types_.JavaLangThrowable(false); } else { const RegType& exception = ResolveClassAndCheckAccess(iterator.GetHandlerTypeIndex()); @@ -3941,7 +3946,7 @@ ArtMethod* MethodVerifier::VerifyInvocationArgsFromIterator( klass->CannotBeAssignedFromOtherTypes()); } else { const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); - const uint16_t class_idx = dex_file_->GetMethodId(method_idx).class_idx_; + const dex::TypeIndex class_idx = dex_file_->GetMethodId(method_idx).class_idx_; res_method_class = ®_types_.FromDescriptor( GetClassLoader(), dex_file_->StringByTypeIdx(class_idx), @@ -4078,7 +4083,7 @@ ArtMethod* MethodVerifier::VerifyInvocationArgs( // If we're using invoke-super(method), make sure that the executing method's class' superclass // has a vtable entry for the target method. Or the target is on a interface. if (method_type == METHOD_SUPER) { - uint16_t class_idx = dex_file_->GetMethodId(method_idx).class_idx_; + dex::TypeIndex class_idx = dex_file_->GetMethodId(method_idx).class_idx_; const RegType& reference_type = reg_types_.FromDescriptor( GetClassLoader(), dex_file_->StringByTypeIdx(class_idx), @@ -4287,16 +4292,16 @@ ArtMethod* MethodVerifier::VerifyInvokeVirtualQuickArgs(const Instruction* inst, } void MethodVerifier::VerifyNewArray(const Instruction* inst, bool is_filled, bool is_range) { - uint32_t type_idx; + dex::TypeIndex type_idx; if (!is_filled) { DCHECK_EQ(inst->Opcode(), Instruction::NEW_ARRAY); - type_idx = inst->VRegC_22c(); + type_idx = dex::TypeIndex(inst->VRegC_22c()); } else if (!is_range) { DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY); - type_idx = inst->VRegB_35c(); + type_idx = dex::TypeIndex(inst->VRegB_35c()); } else { DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY_RANGE); - type_idx = inst->VRegB_3rc(); + type_idx = dex::TypeIndex(inst->VRegB_3rc()); } const RegType& res_type = ResolveClassAndCheckAccess(type_idx); if (res_type.IsConflict()) { // bad class @@ -5011,7 +5016,7 @@ const RegType& MethodVerifier::GetMethodReturnType() { if (return_type_ == nullptr) { const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_); const DexFile::ProtoId& proto_id = dex_file_->GetMethodPrototype(method_id); - uint16_t return_type_idx = proto_id.return_type_idx_; + dex::TypeIndex return_type_idx = proto_id.return_type_idx_; const char* descriptor = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(return_type_idx)); return_type_ = ®_types_.FromDescriptor(GetClassLoader(), descriptor, false); } diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h index c6ce583ab4..f3faecd9a7 100644 --- a/runtime/verifier/method_verifier.h +++ b/runtime/verifier/method_verifier.h @@ -27,6 +27,7 @@ #include "base/stl_util.h" #include "base/value_object.h" #include "dex_file.h" +#include "dex_file_types.h" #include "handle.h" #include "instruction_flags.h" #include "method_reference.h" @@ -261,7 +262,7 @@ class MethodVerifier { return have_any_pending_runtime_throw_failure_; } - const RegType& ResolveCheckedClass(uint32_t class_idx) + const RegType& ResolveCheckedClass(dex::TypeIndex class_idx) REQUIRES_SHARED(Locks::mutator_lock_); // Returns the method of a quick invoke or null if it cannot be found. ArtMethod* GetQuickInvokedMethod(const Instruction* inst, RegisterLine* reg_line, @@ -471,18 +472,18 @@ class MethodVerifier { // Perform static checks on a "new-instance" instruction. Specifically, make sure the class // reference isn't for an array class. - bool CheckNewInstance(uint32_t idx); + bool CheckNewInstance(dex::TypeIndex idx); /* Ensure that the string index is in the valid range. */ bool CheckStringIndex(uint32_t idx); // Perform static checks on an instruction that takes a class constant. Ensure that the class // index is in the valid range. - bool CheckTypeIndex(uint32_t idx); + bool CheckTypeIndex(dex::TypeIndex idx); // Perform static checks on a "new-array" instruction. Specifically, make sure they aren't // creating an array of arrays that causes the number of dimensions to exceed 255. - bool CheckNewArray(uint32_t idx); + bool CheckNewArray(dex::TypeIndex idx); // Verify an array data table. "cur_offset" is the offset of the fill-array-data instruction. bool CheckArrayData(uint32_t cur_offset); @@ -625,7 +626,7 @@ class MethodVerifier { // Resolves a class based on an index and performs access checks to ensure the referrer can // access the resolved class. - const RegType& ResolveClassAndCheckAccess(uint32_t class_idx) + const RegType& ResolveClassAndCheckAccess(dex::TypeIndex class_idx) REQUIRES_SHARED(Locks::mutator_lock_); /* diff --git a/runtime/verifier/verifier_deps.cc b/runtime/verifier/verifier_deps.cc index c395612d72..8a0f4cfa31 100644 --- a/runtime/verifier/verifier_deps.cc +++ b/runtime/verifier/verifier_deps.cc @@ -137,7 +137,7 @@ bool VerifierDeps::IsInClassPath(ObjPtr<mirror::Class> klass) const { } void VerifierDeps::AddClassResolution(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, mirror::Class* klass) { DexFileDeps* dex_deps = GetDexFileDeps(dex_file); if (dex_deps == nullptr) { @@ -286,7 +286,7 @@ static inline VerifierDeps* GetVerifierDepsSingleton() { } void VerifierDeps::MaybeRecordVerificationStatus(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, MethodVerifier::FailureKind failure_kind) { if (failure_kind == MethodVerifier::kNoFailure) { // We only record classes that did not fully verify at compile time. @@ -302,7 +302,7 @@ void VerifierDeps::MaybeRecordVerificationStatus(const DexFile& dex_file, } void VerifierDeps::MaybeRecordClassResolution(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, mirror::Class* klass) { VerifierDeps* singleton = GetVerifierDepsSingleton(); if (singleton != nullptr) { @@ -340,36 +340,62 @@ void VerifierDeps::MaybeRecordAssignability(const DexFile& dex_file, } } +namespace { + static inline uint32_t DecodeUint32WithOverflowCheck(const uint8_t** in, const uint8_t* end) { CHECK_LT(*in, end); return DecodeUnsignedLeb128(in); } +template<typename T> inline uint32_t Encode(T in); + +template<> inline uint32_t Encode<uint16_t>(uint16_t in) { + return in; +} +template<> inline uint32_t Encode<uint32_t>(uint32_t in) { + return in; +} +template<> inline uint32_t Encode<dex::TypeIndex>(dex::TypeIndex in) { + return in.index_; +} + +template<typename T> inline T Decode(uint32_t in); + +template<> inline uint16_t Decode<uint16_t>(uint32_t in) { + return dchecked_integral_cast<uint16_t>(in); +} +template<> inline uint32_t Decode<uint32_t>(uint32_t in) { + return in; +} +template<> inline dex::TypeIndex Decode<dex::TypeIndex>(uint32_t in) { + return dex::TypeIndex(in); +} + template<typename T1, typename T2> static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2>& t) { - EncodeUnsignedLeb128(out, std::get<0>(t)); - EncodeUnsignedLeb128(out, std::get<1>(t)); + EncodeUnsignedLeb128(out, Encode(std::get<0>(t))); + EncodeUnsignedLeb128(out, Encode(std::get<1>(t))); } template<typename T1, typename T2> static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2>* t) { - T1 v1 = static_cast<T1>(DecodeUint32WithOverflowCheck(in, end)); - T2 v2 = static_cast<T2>(DecodeUint32WithOverflowCheck(in, end)); + T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end)); + T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end)); *t = std::make_tuple(v1, v2); } template<typename T1, typename T2, typename T3> static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2, T3>& t) { - EncodeUnsignedLeb128(out, std::get<0>(t)); - EncodeUnsignedLeb128(out, std::get<1>(t)); - EncodeUnsignedLeb128(out, std::get<2>(t)); + EncodeUnsignedLeb128(out, Encode(std::get<0>(t))); + EncodeUnsignedLeb128(out, Encode(std::get<1>(t))); + EncodeUnsignedLeb128(out, Encode(std::get<2>(t))); } template<typename T1, typename T2, typename T3> static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2, T3>* t) { - T1 v1 = static_cast<T1>(DecodeUint32WithOverflowCheck(in, end)); - T2 v2 = static_cast<T2>(DecodeUint32WithOverflowCheck(in, end)); - T3 v3 = static_cast<T2>(DecodeUint32WithOverflowCheck(in, end)); + T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end)); + T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end)); + T3 v3 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end)); *t = std::make_tuple(v1, v2, v3); } @@ -381,11 +407,12 @@ static inline void EncodeSet(std::vector<uint8_t>* out, const std::set<T>& set) } } +template <typename T> static inline void EncodeUint16Vector(std::vector<uint8_t>* out, - const std::vector<uint16_t>& vector) { + const std::vector<T>& vector) { EncodeUnsignedLeb128(out, vector.size()); - for (uint16_t entry : vector) { - EncodeUnsignedLeb128(out, entry); + for (const T& entry : vector) { + EncodeUnsignedLeb128(out, Encode(entry)); } } @@ -400,14 +427,16 @@ static inline void DecodeSet(const uint8_t** in, const uint8_t* end, std::set<T> } } +template<typename T> static inline void DecodeUint16Vector(const uint8_t** in, const uint8_t* end, - std::vector<uint16_t>* vector) { + std::vector<T>* vector) { DCHECK(vector->empty()); size_t num_entries = DecodeUint32WithOverflowCheck(in, end); vector->reserve(num_entries); for (size_t i = 0; i < num_entries; ++i) { - vector->push_back(dchecked_integral_cast<uint16_t>(DecodeUint32WithOverflowCheck(in, end))); + vector->push_back( + Decode<T>(dchecked_integral_cast<uint16_t>(DecodeUint32WithOverflowCheck(in, end)))); } } @@ -436,6 +465,8 @@ static inline void DecodeStringVector(const uint8_t** in, } } +} // namespace + void VerifierDeps::Encode(const std::vector<const DexFile*>& dex_files, std::vector<uint8_t>* buffer) const { MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_); @@ -599,7 +630,7 @@ void VerifierDeps::Dump(VariableIndentationOutputStream* vios) const { } } - for (uint16_t type_index : dep.second->unverified_classes_) { + for (dex::TypeIndex type_index : dep.second->unverified_classes_) { vios->Stream() << dex_file.StringByTypeIdx(type_index) << " is expected to be verified at runtime\n"; diff --git a/runtime/verifier/verifier_deps.h b/runtime/verifier/verifier_deps.h index 7b419d4260..23e22d956d 100644 --- a/runtime/verifier/verifier_deps.h +++ b/runtime/verifier/verifier_deps.h @@ -57,14 +57,14 @@ class VerifierDeps { // Record the verification status of the class at `type_idx`. static void MaybeRecordVerificationStatus(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, MethodVerifier::FailureKind failure_kind) REQUIRES(!Locks::verifier_deps_lock_); // Record the outcome `klass` of resolving type `type_idx` from `dex_file`. // If `klass` is null, the class is assumed unresolved. static void MaybeRecordClassResolution(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, mirror::Class* klass) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::verifier_deps_lock_); @@ -116,7 +116,7 @@ class VerifierDeps { // NO_THREAD_SAFETY_ANALSYS, as this is queried when the VerifierDeps are // fully created. - const std::vector<uint16_t>& GetUnverifiedClasses(const DexFile& dex_file) const + const std::vector<dex::TypeIndex>& GetUnverifiedClasses(const DexFile& dex_file) const NO_THREAD_SAFETY_ANALYSIS { return GetDexFileDeps(dex_file)->unverified_classes_; } @@ -124,15 +124,15 @@ class VerifierDeps { private: static constexpr uint16_t kUnresolvedMarker = static_cast<uint16_t>(-1); - using ClassResolutionBase = std::tuple<uint32_t, uint16_t>; + using ClassResolutionBase = std::tuple<dex::TypeIndex, uint16_t>; struct ClassResolution : public ClassResolutionBase { ClassResolution() = default; ClassResolution(const ClassResolution&) = default; - ClassResolution(uint32_t type_idx, uint16_t access_flags) + ClassResolution(dex::TypeIndex type_idx, uint16_t access_flags) : ClassResolutionBase(type_idx, access_flags) {} bool IsResolved() const { return GetAccessFlags() != kUnresolvedMarker; } - uint32_t GetDexTypeIndex() const { return std::get<0>(*this); } + dex::TypeIndex GetDexTypeIndex() const { return std::get<0>(*this); } uint16_t GetAccessFlags() const { return std::get<1>(*this); } }; @@ -193,7 +193,7 @@ class VerifierDeps { std::set<MethodResolution> interface_methods_; // List of classes that were not fully verified in that dex file. - std::vector<uint16_t> unverified_classes_; + std::vector<dex::TypeIndex> unverified_classes_; bool Equals(const DexFileDeps& rhs) const; }; @@ -238,7 +238,7 @@ class VerifierDeps { REQUIRES(Locks::verifier_deps_lock_); void AddClassResolution(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, mirror::Class* klass) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::verifier_deps_lock_); |