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_table.cc b/runtime/class_table.cc
index 3ed1c95..4656b74 100644
--- a/runtime/class_table.cc
+++ b/runtime/class_table.cc
@@ -115,7 +115,7 @@
   return false;
 }
 
-std::size_t ClassTable::ClassDescriptorHashEquals::operator()(const GcRoot<mirror::Class>& root)
+uint32_t ClassTable::ClassDescriptorHashEquals::operator()(const GcRoot<mirror::Class>& root)
     const {
   std::string temp;
   return ComputeModifiedUtf8Hash(root.Read()->GetDescriptor(&temp));
@@ -133,7 +133,7 @@
   return a.Read()->DescriptorEquals(descriptor);
 }
 
-std::size_t ClassTable::ClassDescriptorHashEquals::operator()(const char* descriptor) const {
+uint32_t ClassTable::ClassDescriptorHashEquals::operator()(const char* descriptor) const {
   return ComputeModifiedUtf8Hash(descriptor);
 }
 
@@ -148,4 +148,25 @@
   return true;
 }
 
+size_t ClassTable::WriteToMemory(uint8_t* ptr) const {
+  size_t ret = 0;
+  for (const ClassSet& set : classes_) {
+    uint8_t* address = (ptr != nullptr) ? ptr + ret : nullptr;
+    ret += set.WriteToMemory(address);
+    // Sanity check 2.
+    if (kIsDebugBuild && ptr != nullptr) {
+      size_t read_count;
+      ClassSet class_set(ptr, /*make copy*/false, &read_count);
+      class_set.Verify();
+    }
+  }
+  return ret;
+}
+
+size_t ClassTable::ReadFromMemory(uint8_t* ptr) {
+  size_t read_count = 0;
+  classes_.insert(classes_.begin(), ClassSet(ptr, /*make copy*/false, &read_count));
+  return read_count;
+}
+
 }  // namespace art