Store class tables in the image

Reduces how long it takes to load an application image.

N5 boot.art size
Before: 8007680
After: 8122368

Also reduces boot time by how long AddImageClassesToClassTable
used to take (~20ms).

Changed class hashes to be uint32_t to fix cross compilation. We need
serialized hash tables to be valid with different pointer sizes.

Bug: 22858531

Change-Id: I463fc83f499ff75f509e80c253a55b9116ee5b89
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 2dd2a83..879544f 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1017,6 +1017,15 @@
   mirror::Throwable::SetClass(GetClassRoot(kJavaLangThrowable));
   mirror::StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement));
 
+  const ImageHeader& header = space->GetImageHeader();
+  const ImageSection& section = header.GetImageSection(ImageHeader::kSectionClassTable);
+  if (section.Size() > 0u) {
+    WriterMutexLock mu(self, *Locks::classlinker_classes_lock_);
+    ClassTable* const class_table = InsertClassTableForClassLoader(nullptr);
+    class_table->ReadFromMemory(space->Begin() + section.Offset());
+    dex_cache_boot_image_class_lookup_required_ = false;
+  }
+
   FinishInit(self);
 
   VLOG(startup) << "ClassLinker::InitFromImage exiting";
@@ -2786,9 +2795,11 @@
   Thread* self = Thread::Current();
   WriterMutexLock mu(self, *Locks::classlinker_classes_lock_);
   ScopedAssertNoThreadSuspension ants(self, "Moving image classes to class table");
+
+  ClassTable* const class_table = InsertClassTableForClassLoader(class_loader);
+
   mirror::ObjectArray<mirror::DexCache>* dex_caches = GetImageDexCaches(image_space);
   std::string temp;
-  ClassTable* const class_table = InsertClassTableForClassLoader(class_loader);
   for (int32_t i = 0; i < dex_caches->GetLength(); i++) {
     mirror::DexCache* dex_cache = dex_caches->Get(i);
     GcRoot<mirror::Class>* types = dex_cache->GetResolvedTypes();