ART: Add dex::TypeIndex
Add abstraction for uint16_t type index.
Test: m test-art-host
Change-Id: I47708741c7c579cbbe59ab723c1e31c5fe71f83a
diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc
index bbf9a8b..6665897 100644
--- a/runtime/arch/stub_test.cc
+++ b/runtime/arch/stub_test.cc
@@ -1063,7 +1063,7 @@
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 @@
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 b46b058..25b8ed2 100644
--- a/runtime/art_field.cc
+++ b/runtime/art_field.cc
@@ -48,7 +48,7 @@
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 7c2f490..cacb324 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 @@
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 a652178..2dfdc16 100644
--- a/runtime/art_method-inl.h
+++ b/runtime/art_method-inl.h
@@ -183,17 +183,17 @@
}
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 @@
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 @@
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 @@
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 @@
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 c550a1b..1c83766 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -199,9 +199,9 @@
// 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 b31999f..0e1d7e7 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -343,7 +343,7 @@
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 @@
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 @@
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 @@
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 7359243..81adaeb 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -86,7 +86,7 @@
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 @@
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 4905514..f552a83 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -730,10 +730,12 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
}
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 @@
}
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,
- 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 @@
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 @@
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 @@
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 1d29e31..9563448 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 @@
// 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 @@
// 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 @@
// 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 44590ba..9e17be2 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 @@
}
// 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 @@
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 @@
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 0febbed..f53ca4a 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 @@
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 @@
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 621b2c5..77a63c1 100644
--- a/runtime/dex_file-inl.h
+++ b/runtime/dex_file-inl.h
@@ -58,12 +58,12 @@
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 2ef7509..cc544fd 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 @@
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::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::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 @@
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 @@
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 @@
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 @@
}
// 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 @@
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 @@
}
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 @@
}
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 @@
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::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 @@
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 da9fa50..0a2b48b 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 @@
// 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 @@
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 @@
// 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 @@
}
// 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 @@
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 @@
}
// 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 @@
}
// 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 @@
// 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 @@
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 @@
Init(handler_data);
}
- uint16_t GetHandlerTypeIndex() const {
+ dex::TypeIndex GetHandlerTypeIndex() const {
return handler_.type_idx_;
}
uint32_t GetHandlerAddress() const {
@@ -1476,7 +1479,7 @@
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 835f456..3fe2c40 100644
--- a/runtime/dex_file_annotations.cc
+++ b/runtime/dex_file_annotations.cc
@@ -90,7 +90,7 @@
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 @@
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 @@
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 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 @@
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 8e1501f..f94d07b 100644
--- a/runtime/dex_file_test.cc
+++ b/runtime/dex_file_test.cc
@@ -415,14 +415,14 @@
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 @@
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 0000000..c6d95a1
--- /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 be25803..68e9f73 100644
--- a/runtime/dex_file_verifier.cc
+++ b/runtime/dex_file_verifier.cc
@@ -76,8 +76,9 @@
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::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 @@
}
// 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::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 @@
}
// 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::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 @@
}
// 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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
// 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 @@
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 @@
* 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 @@
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 @@
}
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::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 @@
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 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 133e432..19a89de 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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
// 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 @@
// 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 3801c22..0e0929f 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 @@
"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 c766b54..751bd51 100644
--- a/runtime/dex_instruction.cc
+++ b/runtime/dex_instruction.cc
@@ -208,9 +208,9 @@
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 @@
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 ed60f59..ac52f4e 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -129,7 +129,7 @@
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 @@
// 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 @@
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 @@
// 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 @@
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 @@
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 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 1ccb4b0..5390165 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 @@
}
// 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 @@
}
// 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 bcddfb0..d87dc67 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 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 @@
// 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 @@
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 @@
// 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 @@
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 @@
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 515fcbf..397655a 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 @@
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 @@
} \
} \
} \
- 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 @@
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 @@
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 @@
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 @@
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 d438418..b1259e1 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 @@
// 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 @@
// 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 @@
// 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 a32c800..1b3d339 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -543,7 +543,7 @@
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 8c63a9e..05f74d6 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -1460,7 +1460,7 @@
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 @@
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 435ac62..989b7da 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -395,7 +395,7 @@
}
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 @@
}
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 @@
}
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 @@
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 @@
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 @@
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 2bd47bb..fbfed40 100644
--- a/runtime/interpreter/mterp/mterp.cc
+++ b/runtime/interpreter/mterp/mterp.cc
@@ -304,7 +304,11 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 b9f5981..6f2a8c6 100644
--- a/runtime/jit/offline_profiling_info.cc
+++ b/runtime/jit/offline_profiling_info.cc
@@ -235,7 +235,7 @@
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::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 @@
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 @@
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 @@
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 f8ed573..4136488 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 @@
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 @@
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 @@
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 9a6d60e..aa5da2e 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -372,7 +372,7 @@
// 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 @@
// 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 @@
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 db46027..0cfe29b 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -923,7 +923,7 @@
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 @@
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 @@
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 711914d..792f626 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 @@
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 @@
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 c7a123b..d903f71 100644
--- a/runtime/mirror/dex_cache-inl.h
+++ b/runtime/mirror/dex_cache-inl.h
@@ -69,15 +69,15 @@
}
}
-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 1ae694d..7d82d3a 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 @@
// 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 5bf254d..4b47f7f 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -313,7 +313,7 @@
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 866dc7f..48feb11 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -34,6 +34,7 @@
#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 @@
// 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 @@
}
}
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 @@
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 71379a5..f6de593 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 @@
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 @@
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 c14b616..b120a69 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::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 fa2983c..7bb5205 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 @@
// 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 3128380..8446b52 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -363,7 +363,7 @@
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 c7875b5..bd1b044 100644
--- a/runtime/utils/dex_cache_arrays_layout-inl.h
+++ b/runtime/utils/dex_cache_arrays_layout-inl.h
@@ -65,8 +65,8 @@
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 ae3bfab..7d4b23a 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 @@
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 def61db..363bd8f 100644
--- a/runtime/verifier/method_verifier-inl.h
+++ b/runtime/verifier/method_verifier-inl.h
@@ -74,7 +74,7 @@
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 ed24611..7137db8 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -1072,7 +1072,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
* 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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
}
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 @@
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 c6ce583..f3faecd 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 @@
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 @@
// 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 @@
// 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 c395612..8a0f4cf 100644
--- a/runtime/verifier/verifier_deps.cc
+++ b/runtime/verifier/verifier_deps.cc
@@ -137,7 +137,7 @@
}
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 @@
}
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::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 @@
}
}
+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 @@
}
}
+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 @@
}
}
+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 @@
}
}
+} // 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 @@
}
}
- 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 7b419d4..23e22d9 100644
--- a/runtime/verifier/verifier_deps.h
+++ b/runtime/verifier/verifier_deps.h
@@ -57,14 +57,14 @@
// 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 @@
// 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 @@
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 @@
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 @@
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_);