Rewrite ClassLinker::LinkFields().
Rewrite field offset assignment to avoid heap allocations in
most cases. We do one allocation if there are many fields.
Rewrite gap filling to prefer small gaps over big ones. This
creates more natural field ordering. For example,
class A { byte unalign; }
class B extends A {
long l;
byte a, b, c, d, e, f;
}
would have previously had offsets
12, 10, 14, 9, 11, 13, 15
for fields a, b, c, d, e, f, respectively. Now these are
9, 10, 11, 12, 13, 14, 15
in line with their lexicographical order.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: boots.
Bug: 175869411
Change-Id: I558635ac59c959dd85e8a3b015c26a6d90033853
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index c677601..c561c4d 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -485,12 +485,15 @@
// Classes have a different size due to padding field. Strings are variable length.
if (!klass->IsClassClass() && !klass->IsStringClass() && !is_static) {
- // Currently only required for AccessibleObject since of the padding fields. The class linker
- // says AccessibleObject is 9 bytes but sizeof(AccessibleObject) is 12 bytes due to padding.
- // The RoundUp is to get around this case.
+ // The RoundUp is required for some mirror classes that have a gap at the end,
+ // such as AccessibleObject, ByteArrayViewVarHandle and ByteBufferViewVarHandle.
+ // For example, the AccessibleObject has size 9 according to the class linker.
+ // However, the C++ sizeof(AccessibleObject) is 12 bytes due to alignment, even
+ // though members in C++ subclasses are actually starting at offset 9.
+ //
+ // TODO: We could define a subclass with a `uint8_t` member and check its offset instead.
static constexpr size_t kPackAlignment = 4;
- size_t expected_size = RoundUp(is_static ? klass->GetClassSize() : klass->GetObjectSize(),
- kPackAlignment);
+ size_t expected_size = RoundUp(klass->GetObjectSize(), kPackAlignment);
if (sizeof(T) != expected_size) {
LOG(ERROR) << "Class size mismatch:"
<< " class=" << class_descriptor