Fix LinkFieldsComparator.
Define order for primitive types with the same sizes.
Previously, the comparator would consider the fields equal
so the order would depend on std::sort() implementation.
Changing the STL implementation could silently change the
field offsets. (And, unlike std::stable_sort(), the
std::sort() doesn't even need to be deterministic.)
(cherry picked from commit d577748c041aa6df599218f3cb31697ecf032730)
Change-Id: I9b769d023864aa36c52918c7c3dd11c0f6b8f40e
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index b80aa5a..eb3ee0d 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -5143,17 +5143,22 @@
Primitive::Type type1 = field1->GetTypeAsPrimitiveType();
Primitive::Type type2 = field2->GetTypeAsPrimitiveType();
if (type1 != type2) {
- bool is_primitive1 = type1 != Primitive::kPrimNot;
- bool is_primitive2 = type2 != Primitive::kPrimNot;
- bool is64bit1 = is_primitive1 && (type1 == Primitive::kPrimLong ||
- type1 == Primitive::kPrimDouble);
- bool is64bit2 = is_primitive2 && (type2 == Primitive::kPrimLong ||
- type2 == Primitive::kPrimDouble);
- int order1 = !is_primitive1 ? 0 : (is64bit1 ? 1 : 2);
- int order2 = !is_primitive2 ? 0 : (is64bit2 ? 1 : 2);
- if (order1 != order2) {
- return order1 < order2;
+ if (type1 == Primitive::kPrimNot) {
+ // Reference always goes first.
+ return true;
}
+ if (type2 == Primitive::kPrimNot) {
+ // Reference always goes first.
+ return false;
+ }
+ size_t size1 = Primitive::ComponentSize(type1);
+ size_t size2 = Primitive::ComponentSize(type2);
+ if (size1 != size2) {
+ // Larger primitive types go first.
+ return size1 > size2;
+ }
+ // Primitive types differ but sizes match. Arbitrarily order by primitive type.
+ return type1 < type2;
}
// same basic group? then sort by string.
return strcmp(field1->GetName(), field2->GetName()) < 0;
diff --git a/runtime/oat.cc b/runtime/oat.cc
index 9d98f30..a1b99db 100644
--- a/runtime/oat.cc
+++ b/runtime/oat.cc
@@ -23,7 +23,7 @@
namespace art {
const uint8_t OatHeader::kOatMagic[] = { 'o', 'a', 't', '\n' };
-const uint8_t OatHeader::kOatVersion[] = { '0', '4', '1', '\0' };
+const uint8_t OatHeader::kOatVersion[] = { '0', '4', '2', '\0' };
static size_t ComputeOatHeaderSize(const SafeMap<std::string, std::string>* variable_data) {
size_t estimate = 0U;