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>