ART: Add dex::TypeIndex

Add abstraction for uint16_t type index.

Test: m test-art-host
Change-Id: I47708741c7c579cbbe59ab723c1e31c5fe71f83a
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h
index 9711516..f056dd3 100644
--- a/compiler/driver/compiler_driver-inl.h
+++ b/compiler/driver/compiler_driver-inl.h
@@ -38,7 +38,7 @@
 
 inline mirror::Class* CompilerDriver::ResolveClass(
     const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
-    Handle<mirror::ClassLoader> class_loader, uint16_t cls_index,
+    Handle<mirror::ClassLoader> class_loader, dex::TypeIndex cls_index,
     const DexCompilationUnit* mUnit) {
   DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile());
   DCHECK_EQ(class_loader.Get(), GetClassLoader(soa, mUnit));
@@ -141,7 +141,7 @@
     mirror::Class* referrer_class,
     ArtMember* resolved_member,
     uint16_t member_idx,
-    uint32_t* storage_index) {
+    dex::TypeIndex* storage_index) {
   DCHECK(resolved_member->IsStatic());
   if (LIKELY(referrer_class != nullptr)) {
     ObjPtr<mirror::Class> members_class = resolved_member->GetDeclaringClass();
@@ -156,7 +156,7 @@
       // TODO: for images we can elide the static storage base null check
       // if we know there's a non-null entry in the image
       const DexFile* dex_file = dex_cache->GetDexFile();
-      uint32_t storage_idx = DexFile::kDexNoIndex;
+      dex::TypeIndex storage_idx(DexFile::kDexNoIndex16);
       if (LIKELY(members_class->GetDexCache() == dex_cache)) {
         // common case where the dex cache of both the referrer and the member are the same,
         // no need to search the dex file
@@ -166,27 +166,27 @@
         // of the class mentioned in the dex file and there is no dex cache entry.
         storage_idx = resolved_member->GetDeclaringClass()->FindTypeIndexInOtherDexFile(*dex_file);
       }
-      if (storage_idx != DexFile::kDexNoIndex) {
+      if (storage_idx.IsValid()) {
         *storage_index = storage_idx;
         return std::make_pair(true, !resolved_member->IsFinal());
       }
     }
   }
   // Conservative defaults.
-  *storage_index = DexFile::kDexNoIndex;
+  *storage_index = dex::TypeIndex(DexFile::kDexNoIndex16);
   return std::make_pair(false, false);
 }
 
 inline std::pair<bool, bool> CompilerDriver::IsFastStaticField(
     mirror::DexCache* dex_cache, mirror::Class* referrer_class,
-    ArtField* resolved_field, uint16_t field_idx, uint32_t* storage_index) {
+    ArtField* resolved_field, uint16_t field_idx, dex::TypeIndex* storage_index) {
   return IsClassOfStaticMemberAvailableToReferrer(
       dex_cache, referrer_class, resolved_field, field_idx, storage_index);
 }
 
 inline bool CompilerDriver::IsClassOfStaticMethodAvailableToReferrer(
     mirror::DexCache* dex_cache, mirror::Class* referrer_class,
-    ArtMethod* resolved_method, uint16_t method_idx, uint32_t* storage_index) {
+    ArtMethod* resolved_method, uint16_t method_idx, dex::TypeIndex* storage_index) {
   std::pair<bool, bool> result = IsClassOfStaticMemberAvailableToReferrer(
       dex_cache, referrer_class, resolved_method, method_idx, storage_index);
   // Only the first member of `result` is meaningful, as there is no
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index aa0d10b..c62e214 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -969,7 +969,7 @@
   }
   DCHECK(profile_compilation_info_ != nullptr);
   const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_idx);
-  uint16_t type_idx = class_def.class_idx_;
+  dex::TypeIndex type_idx = class_def.class_idx_;
   bool result = profile_compilation_info_->ContainsClass(dex_file, type_idx);
   if (kDebugProfileGuidedCompilation) {
     LOG(INFO) << "[ProfileGuidedCompilation] " << (result ? "Verified" : "Skipped") << " method:"
@@ -981,7 +981,7 @@
 class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor {
  public:
   explicit ResolveCatchBlockExceptionsClassVisitor(
-      std::set<std::pair<uint16_t, const DexFile*>>& exceptions_to_resolve)
+      std::set<std::pair<dex::TypeIndex, const DexFile*>>& exceptions_to_resolve)
      : exceptions_to_resolve_(exceptions_to_resolve) {}
 
   virtual bool operator()(ObjPtr<mirror::Class> c) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -1012,8 +1012,8 @@
         has_catch_all = true;
       }
       for (int32_t j = 0; j < encoded_catch_handler_size; j++) {
-        uint16_t encoded_catch_handler_handlers_type_idx =
-            DecodeUnsignedLeb128(&encoded_catch_handler_list);
+        dex::TypeIndex encoded_catch_handler_handlers_type_idx =
+            dex::TypeIndex(DecodeUnsignedLeb128(&encoded_catch_handler_list));
         // Add to set of types to resolve if not already in the dex cache resolved types
         if (!method_handle->IsResolvedTypeIdx(encoded_catch_handler_handlers_type_idx,
                                               pointer_size)) {
@@ -1030,7 +1030,7 @@
     }
   }
 
-  std::set<std::pair<uint16_t, const DexFile*>>& exceptions_to_resolve_;
+  std::set<std::pair<dex::TypeIndex, const DexFile*>>& exceptions_to_resolve_;
 };
 
 class RecordImageClassesVisitor : public ClassVisitor {
@@ -1078,7 +1078,7 @@
   // Resolve exception classes referenced by the loaded classes. The catch logic assumes
   // exceptions are resolved by the verifier when there is a catch block in an interested method.
   // Do this here so that exception classes appear to have been specified image classes.
-  std::set<std::pair<uint16_t, const DexFile*>> unresolved_exception_types;
+  std::set<std::pair<dex::TypeIndex, const DexFile*>> unresolved_exception_types;
   StackHandleScope<1> hs(self);
   Handle<mirror::Class> java_lang_Throwable(
       hs.NewHandle(class_linker->FindSystemClass(self, "Ljava/lang/Throwable;")));
@@ -1086,8 +1086,8 @@
     unresolved_exception_types.clear();
     ResolveCatchBlockExceptionsClassVisitor visitor(unresolved_exception_types);
     class_linker->VisitClasses(&visitor);
-    for (const std::pair<uint16_t, const DexFile*>& exception_type : unresolved_exception_types) {
-      uint16_t exception_type_idx = exception_type.first;
+    for (const auto& exception_type : unresolved_exception_types) {
+      dex::TypeIndex exception_type_idx = exception_type.first;
       const DexFile* dex_file = exception_type.second;
       StackHandleScope<2> hs2(self);
       Handle<mirror::DexCache> dex_cache(hs2.NewHandle(class_linker->RegisterDexFile(*dex_file,
@@ -1338,7 +1338,7 @@
 
 bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx,
                                                 Handle<mirror::DexCache> dex_cache,
-                                                uint32_t type_idx) {
+                                                dex::TypeIndex type_idx) {
   // Get type from dex cache assuming it was populated by the verifier
   mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
   if (resolved_class == nullptr) {
@@ -1367,7 +1367,7 @@
 
 bool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx,
                                                             Handle<mirror::DexCache> dex_cache,
-                                                            uint32_t type_idx,
+                                                            dex::TypeIndex type_idx,
                                                             bool* finalizable) {
   // Get type from dex cache assuming it was populated by the verifier.
   mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
@@ -1861,7 +1861,7 @@
  public:
   explicit ResolveTypeVisitor(const ParallelCompilationManager* manager) : manager_(manager) {
   }
-  virtual void Visit(size_t type_idx) OVERRIDE REQUIRES(!Locks::mutator_lock_) {
+  void Visit(size_t type_idx) OVERRIDE REQUIRES(!Locks::mutator_lock_) {
   // Class derived values are more complicated, they require the linker and loader.
     ScopedObjectAccess soa(Thread::Current());
     ClassLinker* class_linker = manager_->GetClassLinker();
@@ -1872,7 +1872,10 @@
     Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->RegisterDexFile(
         dex_file,
         class_loader.Get())));
-    mirror::Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader);
+    mirror::Class* klass = class_linker->ResolveType(dex_file,
+                                                     dex::TypeIndex(type_idx),
+                                                     dex_cache,
+                                                     class_loader);
 
     if (klass == nullptr) {
       soa.Self()->AssertPendingException();
@@ -1952,9 +1955,9 @@
       for (const DexFile* dex_file : dex_files) {
         // Fetch the list of unverified classes and turn it into a set for faster
         // lookups.
-        const std::vector<uint16_t>& unverified_classes =
+        const std::vector<dex::TypeIndex>& unverified_classes =
             verifier_deps->GetUnverifiedClasses(*dex_file);
-        std::set<uint16_t> set(unverified_classes.begin(), unverified_classes.end());
+        std::set<dex::TypeIndex> set(unverified_classes.begin(), unverified_classes.end());
         for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
           const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
           const char* descriptor = dex_file->GetClassDescriptor(class_def);
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 1bd3546..c7719fb 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -31,6 +31,7 @@
 #include "class_reference.h"
 #include "compiler.h"
 #include "dex_file.h"
+#include "dex_file_types.h"
 #include "driver/compiled_method_storage.h"
 #include "jit/offline_profiling_info.h"
 #include "invoke_type.h"
@@ -188,14 +189,14 @@
   // Are runtime access checks necessary in the compiled code?
   bool CanAccessTypeWithoutChecks(uint32_t referrer_idx,
                                   Handle<mirror::DexCache> dex_cache,
-                                  uint32_t type_idx)
+                                  dex::TypeIndex type_idx)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   // Are runtime access and instantiable checks necessary in the code?
   // out_is_finalizable is set to whether the type is finalizable.
   bool CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx,
                                               Handle<mirror::DexCache> dex_cache,
-                                              uint32_t type_idx,
+                                              dex::TypeIndex type_idx,
                                               bool* out_is_finalizable)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
@@ -207,7 +208,7 @@
 
   mirror::Class* ResolveClass(
       const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
-      Handle<mirror::ClassLoader> class_loader, uint16_t type_index,
+      Handle<mirror::ClassLoader> class_loader, dex::TypeIndex type_index,
       const DexCompilationUnit* mUnit)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
@@ -234,9 +235,11 @@
 
   // Can we fast-path an SGET/SPUT access to a static field? If yes, compute the type index
   // of the declaring class in the referrer's dex file.
-  std::pair<bool, bool> IsFastStaticField(
-      mirror::DexCache* dex_cache, mirror::Class* referrer_class,
-      ArtField* resolved_field, uint16_t field_idx, uint32_t* storage_index)
+  std::pair<bool, bool> IsFastStaticField(mirror::DexCache* dex_cache,
+                                          mirror::Class* referrer_class,
+                                          ArtField* resolved_field,
+                                          uint16_t field_idx,
+                                          dex::TypeIndex* storage_index)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   // Return whether the declaring class of `resolved_method` is
@@ -248,7 +251,7 @@
                                                 mirror::Class* referrer_class,
                                                 ArtMethod* resolved_method,
                                                 uint16_t method_idx,
-                                                uint32_t* storage_index)
+                                                dex::TypeIndex* storage_index)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   // Resolve a method. Returns null on failure, including incompatible class change.
@@ -395,7 +398,7 @@
                                                                  mirror::Class* referrer_class,
                                                                  ArtMember* resolved_member,
                                                                  uint16_t member_idx,
-                                                                 uint32_t* storage_index)
+                                                                 dex::TypeIndex* storage_index)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   // Can `referrer_class` access the resolved `member`?
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index 9679a79..f40c712 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -24,6 +24,7 @@
 #include "class_linker-inl.h"
 #include "common_compiler_test.h"
 #include "dex_file.h"
+#include "dex_file_types.h"
 #include "gc/heap.h"
 #include "mirror/class-inl.h"
 #include "mirror/class_loader.h"
@@ -115,9 +116,9 @@
   }
   EXPECT_EQ(dex.NumTypeIds(), dex_cache->NumResolvedTypes());
   for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) {
-    mirror::Class* type = dex_cache->GetResolvedType(i);
+    mirror::Class* type = dex_cache->GetResolvedType(dex::TypeIndex(i));
     EXPECT_TRUE(type != nullptr) << "type_idx=" << i
-                              << " " << dex.GetTypeDescriptor(dex.GetTypeId(i));
+                              << " " << dex.GetTypeDescriptor(dex.GetTypeId(dex::TypeIndex(i)));
   }
   EXPECT_EQ(dex.NumMethodIds(), dex_cache->NumResolvedMethods());
   auto* cl = Runtime::Current()->GetClassLinker();