ART: Compress LengthPrefixedArray on 32-bit targets.
Previously, the LengthPrefixedArray<ArtMethod> on 32-bit
targets contained a 64-bit length field followed by the
ArtMethod elements with size only a multiple of 4, not 8.
Consequently, an odd-length array broke the alignment for
the following array which would have the 64-bit length
placed at an unaligned address.
To fix that, we make the length field 32-bit and explicitly
pass the alignment information to the LengthPrefixedArray.
This also makes the 32-bit boot image a bit smaller.
On Nexus 5, AOSP, ToT, the field section is 11528B smaller
and the method section is 21036B smaller. 64-bit targets
should see the same savings for the field section but no
difference for the methods section.
Change-Id: I3e03e7b94129025c8a1c117c27645a34dec516d2
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 887e204..b15747f 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -92,14 +92,18 @@
CheckPointerSize(pointer_size);
auto* methods = GetDirectMethodsPtrUnchecked();
DCHECK(methods != nullptr);
- return &methods->At(i, ArtMethod::ObjectSize(pointer_size));
+ return &methods->At(i,
+ ArtMethod::ObjectSize(pointer_size),
+ ArtMethod::ObjectAlignment(pointer_size));
}
inline ArtMethod* Class::GetDirectMethod(size_t i, size_t pointer_size) {
CheckPointerSize(pointer_size);
auto* methods = GetDirectMethodsPtr();
DCHECK(methods != nullptr);
- return &methods->At(i, ArtMethod::ObjectSize(pointer_size));
+ return &methods->At(i,
+ ArtMethod::ObjectSize(pointer_size),
+ ArtMethod::ObjectAlignment(pointer_size));
}
template<VerifyObjectFlags kVerifyFlags>
@@ -133,7 +137,9 @@
CheckPointerSize(pointer_size);
LengthPrefixedArray<ArtMethod>* methods = GetVirtualMethodsPtrUnchecked();
DCHECK(methods != nullptr);
- return &methods->At(i, ArtMethod::ObjectSize(pointer_size));
+ return &methods->At(i,
+ ArtMethod::ObjectSize(pointer_size),
+ ArtMethod::ObjectAlignment(pointer_size));
}
inline PointerArray* Class::GetVTable() {
@@ -837,29 +843,31 @@
inline IterationRange<StrideIterator<ArtMethod>> Class::GetDirectMethods(size_t pointer_size) {
CheckPointerSize(pointer_size);
return MakeIterationRangeFromLengthPrefixedArray(GetDirectMethodsPtrUnchecked(),
- ArtMethod::ObjectSize(pointer_size));
+ ArtMethod::ObjectSize(pointer_size),
+ ArtMethod::ObjectAlignment(pointer_size));
}
inline IterationRange<StrideIterator<ArtMethod>> Class::GetVirtualMethods(size_t pointer_size) {
CheckPointerSize(pointer_size);
return MakeIterationRangeFromLengthPrefixedArray(GetVirtualMethodsPtrUnchecked(),
- ArtMethod::ObjectSize(pointer_size));
+ ArtMethod::ObjectSize(pointer_size),
+ ArtMethod::ObjectAlignment(pointer_size));
}
inline IterationRange<StrideIterator<ArtField>> Class::GetIFields() {
- return MakeIterationRangeFromLengthPrefixedArray(GetIFieldsPtr(), sizeof(ArtField));
+ return MakeIterationRangeFromLengthPrefixedArray(GetIFieldsPtr());
}
inline IterationRange<StrideIterator<ArtField>> Class::GetSFields() {
- return MakeIterationRangeFromLengthPrefixedArray(GetSFieldsPtr(), sizeof(ArtField));
+ return MakeIterationRangeFromLengthPrefixedArray(GetSFieldsPtr());
}
inline IterationRange<StrideIterator<ArtField>> Class::GetIFieldsUnchecked() {
- return MakeIterationRangeFromLengthPrefixedArray(GetIFieldsPtrUnchecked(), sizeof(ArtField));
+ return MakeIterationRangeFromLengthPrefixedArray(GetIFieldsPtrUnchecked());
}
inline IterationRange<StrideIterator<ArtField>> Class::GetSFieldsUnchecked() {
- return MakeIterationRangeFromLengthPrefixedArray(GetSFieldsPtrUnchecked(), sizeof(ArtField));
+ return MakeIterationRangeFromLengthPrefixedArray(GetSFieldsPtrUnchecked());
}
inline MemberOffset Class::EmbeddedImTableOffset(size_t pointer_size) {