summaryrefslogtreecommitdiff
path: root/runtime/class_linker_test.cc
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2021-01-27 15:20:56 +0000
committer Vladimir Marko <vmarko@google.com> 2021-01-28 14:14:16 +0000
commitc7993d55b2912532c1b0917e6b0ca43097bed21d (patch)
tree1145ce1c0ffbbd729d0a6c1b53c608bf7adb3d6a /runtime/class_linker_test.cc
parent22538e4672348c56d4d44d6113bedd6b47d0abd0 (diff)
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
Diffstat (limited to 'runtime/class_linker_test.cc')
-rw-r--r--runtime/class_linker_test.cc13
1 files changed, 8 insertions, 5 deletions
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index c677601c0d..c561c4d591 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -485,12 +485,15 @@ struct CheckOffsets {
// 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