Handle classes with a huge number of direct methods.

Make sure that fields Class::copied_methods_offset_ and
Class::virtual_method_offset_ are correctly interpreted as unsigned
16-bit integers.

Test: art/test/testrunner/testrunner.py -j4 -t 648-many-direct-methods
Bug: 33650497
Change-Id: I63e97d5b7e08d58252ff4831b63c4035ecc55979
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 6c723ef..5122b37 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -96,7 +96,13 @@
 }
 
 inline uint32_t Class::GetCopiedMethodsStartOffset() {
-  return GetFieldShort(OFFSET_OF_OBJECT_MEMBER(Class, copied_methods_offset_));
+  // Object::GetFieldShort returns an int16_t value, but
+  // Class::copied_methods_offset_ is an uint16_t value; cast the
+  // latter to int16_t before returning it as an uint32_t value, so
+  // that uint16_t values between 2^15 and 2^16-1 are correctly
+  // handled.
+  return static_cast<uint16_t>(
+      GetFieldShort(OFFSET_OF_OBJECT_MEMBER(Class, copied_methods_offset_)));
 }
 
 inline uint32_t Class::GetDirectMethodsStartOffset() {
@@ -104,7 +110,13 @@
 }
 
 inline uint32_t Class::GetVirtualMethodsStartOffset() {
-  return GetFieldShort(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_offset_));
+  // Object::GetFieldShort returns an int16_t value, but
+  // Class::virtual_method_offset_ is an uint16_t value; cast the
+  // latter to int16_t before returning it as an uint32_t value, so
+  // that uint16_t values between 2^15 and 2^16-1 are correctly
+  // handled.
+  return static_cast<uint16_t>(
+      GetFieldShort(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_offset_)));
 }
 
 template<VerifyObjectFlags kVerifyFlags>