Move .art.rel data to a section in .art, part 1.
Refactor the code so that we can collect all relocation
offsets while writing the image.
Test: Manually verify that the aosp_taimen-userdebug boot
image is identical before and after this change;
using WIP follow-up code, check that we record the
same locations as the patchoat-generated .rel files.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 77856493
Change-Id: Id8c78e417e77e859a82a680504253f41e84560d6
diff --git a/runtime/image.cc b/runtime/image.cc
index 7819c0b..7083ee1 100644
--- a/runtime/image.cc
+++ b/runtime/image.cc
@@ -135,11 +135,6 @@
return reinterpret_cast<ArtMethod*>(image_methods_[index]);
}
-void ImageHeader::SetImageMethod(ImageMethod index, ArtMethod* method) {
- CHECK_LT(static_cast<size_t>(index), kImageMethodsCount);
- image_methods_[index] = reinterpret_cast<uint64_t>(method);
-}
-
std::ostream& operator<<(std::ostream& os, const ImageSection& section) {
return os << "size=" << section.Size() << " range=" << section.Offset() << "-" << section.End();
}
diff --git a/runtime/image.h b/runtime/image.h
index c1cde0a..2c6fb54 100644
--- a/runtime/image.h
+++ b/runtime/image.h
@@ -240,7 +240,6 @@
}
ArtMethod* GetImageMethod(ImageMethod index) const;
- void SetImageMethod(ImageMethod index, ArtMethod* method);
const ImageSection& GetImageSection(ImageSections index) const {
DCHECK_LT(static_cast<size_t>(index), kSectionCount);
diff --git a/runtime/intern_table.h b/runtime/intern_table.h
index c9127d6..5ba3e18 100644
--- a/runtime/intern_table.h
+++ b/runtime/intern_table.h
@@ -39,7 +39,7 @@
enum VisitRootFlags : uint8_t;
namespace linker {
-class OatWriter;
+class ImageWriter;
} // namespace linker
namespace mirror {
@@ -227,6 +227,7 @@
// modifying the zygote intern table. The back of table is modified when strings are interned.
std::vector<UnorderedSet> tables_;
+ friend class linker::ImageWriter;
ART_FRIEND_TEST(InternTableTest, CrossHash);
};
@@ -286,6 +287,7 @@
// Weak root state, used for concurrent system weak processing and more.
gc::WeakRootState weak_root_state_ GUARDED_BY(Locks::intern_table_lock_);
+ friend class linker::ImageWriter;
friend class Transaction;
ART_FRIEND_TEST(InternTableTest, CrossHash);
DISALLOW_COPY_AND_ASSIGN(InternTable);
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index fffd7f3..bc72517 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -331,11 +331,11 @@
}
inline ImTable* Class::GetImt(PointerSize pointer_size) {
- return GetFieldPtrWithSize<ImTable*>(MemberOffset(ImtPtrOffset(pointer_size)), pointer_size);
+ return GetFieldPtrWithSize<ImTable*>(ImtPtrOffset(pointer_size), pointer_size);
}
inline void Class::SetImt(ImTable* imt, PointerSize pointer_size) {
- return SetFieldPtrWithSize<false>(MemberOffset(ImtPtrOffset(pointer_size)), imt, pointer_size);
+ return SetFieldPtrWithSize<false>(ImtPtrOffset(pointer_size), imt, pointer_size);
}
inline MemberOffset Class::EmbeddedVTableEntryOffset(uint32_t i, PointerSize pointer_size) {
@@ -1070,20 +1070,26 @@
inline void Class::FixupNativePointers(Class* dest,
PointerSize pointer_size,
const Visitor& visitor) {
+ auto dest_address_fn = [dest](MemberOffset offset) {
+ return reinterpret_cast<void**>(reinterpret_cast<uintptr_t>(dest) + offset.Uint32Value());
+ };
// Update the field arrays.
LengthPrefixedArray<ArtField>* const sfields = GetSFieldsPtr();
- LengthPrefixedArray<ArtField>* const new_sfields = visitor(sfields);
+ void** sfields_dest_address = dest_address_fn(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
+ LengthPrefixedArray<ArtField>* const new_sfields = visitor(sfields, sfields_dest_address);
if (sfields != new_sfields) {
dest->SetSFieldsPtrUnchecked(new_sfields);
}
LengthPrefixedArray<ArtField>* const ifields = GetIFieldsPtr();
- LengthPrefixedArray<ArtField>* const new_ifields = visitor(ifields);
+ void** ifields_dest_address = dest_address_fn(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
+ LengthPrefixedArray<ArtField>* const new_ifields = visitor(ifields, ifields_dest_address);
if (ifields != new_ifields) {
dest->SetIFieldsPtrUnchecked(new_ifields);
}
// Update method array.
LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
- LengthPrefixedArray<ArtMethod>* new_methods = visitor(methods);
+ void** methods_dest_address = dest_address_fn(OFFSET_OF_OBJECT_MEMBER(Class, methods_));
+ LengthPrefixedArray<ArtMethod>* new_methods = visitor(methods, methods_dest_address);
if (methods != new_methods) {
dest->SetMethodsPtrInternal(new_methods);
}
@@ -1091,16 +1097,18 @@
if (!IsTemp() && ShouldHaveEmbeddedVTable<kVerifyNone, kReadBarrierOption>()) {
for (int32_t i = 0, count = GetEmbeddedVTableLength(); i < count; ++i) {
ArtMethod* method = GetEmbeddedVTableEntry(i, pointer_size);
- void** dest_addr = reinterpret_cast<void**>(reinterpret_cast<uintptr_t>(dest) +
- EmbeddedVTableEntryOffset(i, pointer_size).Uint32Value());
- ArtMethod* new_method = visitor(method, dest_addr);
+ void** method_dest_addr = dest_address_fn(EmbeddedVTableEntryOffset(i, pointer_size));
+ ArtMethod* new_method = visitor(method, method_dest_addr);
if (method != new_method) {
dest->SetEmbeddedVTableEntryUnchecked(i, new_method, pointer_size);
}
}
}
if (!IsTemp() && ShouldHaveImt<kVerifyNone, kReadBarrierOption>()) {
- dest->SetImt(visitor(GetImt(pointer_size)), pointer_size);
+ ImTable* imt = GetImt(pointer_size);
+ void** imt_dest_addr = dest_address_fn(ImtPtrOffset(pointer_size));
+ ImTable* new_imt = visitor(imt, imt_dest_addr);
+ dest->SetImt(new_imt, pointer_size);
}
}
diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h
index faec6e6..bbe15ac 100644
--- a/runtime/mirror/dex_cache-inl.h
+++ b/runtime/mirror/dex_cache-inl.h
@@ -257,7 +257,7 @@
} else {
auto* array = reinterpret_cast<std::atomic<ConversionPair32>*>(pair_array);
ConversionPair32 value = array[idx].load(std::memory_order_relaxed);
- return NativeDexCachePair<T>(reinterpret_cast<T*>(value.first), value.second);
+ return NativeDexCachePair<T>(reinterpret_cast32<T*>(value.first), value.second);
}
}
@@ -272,9 +272,8 @@
AtomicStoreRelease16B(&array[idx], v);
} else {
auto* array = reinterpret_cast<std::atomic<ConversionPair32>*>(pair_array);
- ConversionPair32 v(
- dchecked_integral_cast<uint32_t>(reinterpret_cast<uintptr_t>(pair.object)),
- dchecked_integral_cast<uint32_t>(pair.index));
+ ConversionPair32 v(reinterpret_cast32<uint32_t>(pair.object),
+ dchecked_integral_cast<uint32_t>(pair.index));
array[idx].store(v, std::memory_order_release);
}
}
diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index 941248e..ab5fb85 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -27,11 +27,14 @@
namespace art {
+namespace linker {
+class ImageWriter;
+} // namespace linker
+
class ArtField;
class ArtMethod;
struct DexCacheOffsets;
class DexFile;
-class ImageWriter;
union JValue;
class LinearAlloc;
class Thread;
@@ -539,6 +542,7 @@
uint32_t num_strings_; // Number of elements in the strings_ array.
friend struct art::DexCacheOffsets; // for verifying offset information
+ friend class linker::ImageWriter;
friend class Object; // For VisitReferences
DISALLOW_IMPLICIT_CONSTRUCTORS(DexCache);
};
diff --git a/runtime/mirror/executable.h b/runtime/mirror/executable.h
index 23dd787..bf66d79 100644
--- a/runtime/mirror/executable.h
+++ b/runtime/mirror/executable.h
@@ -42,6 +42,10 @@
void SetArtMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
mirror::Class* GetDeclaringClass() REQUIRES_SHARED(Locks::mutator_lock_);
+ static MemberOffset ArtMethodOffset() {
+ return MemberOffset(OFFSETOF_MEMBER(Executable, art_method_));
+ }
+
private:
uint16_t has_real_parameter_data_;
HeapReference<mirror::Class> declaring_class_;
@@ -51,9 +55,6 @@
uint32_t access_flags_;
uint32_t dex_method_index_;
- static MemberOffset ArtMethodOffset() {
- return MemberOffset(OFFSETOF_MEMBER(Executable, art_method_));
- }
static MemberOffset DeclaringClassOffset() {
return MemberOffset(OFFSETOF_MEMBER(Executable, declaring_class_));
}
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index c7cffed..2801928 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -542,7 +542,7 @@
void SetFieldPtr64(MemberOffset field_offset, T new_value)
REQUIRES_SHARED(Locks::mutator_lock_) {
SetFieldPtrWithSize<kTransactionActive, kCheckTransaction, kVerifyFlags>(
- field_offset, new_value, 8u);
+ field_offset, new_value, PointerSize::k64);
}
template<bool kTransactionActive,
@@ -554,10 +554,8 @@
PointerSize pointer_size)
REQUIRES_SHARED(Locks::mutator_lock_) {
if (pointer_size == PointerSize::k32) {
- uintptr_t ptr = reinterpret_cast<uintptr_t>(new_value);
- DCHECK_EQ(static_cast<uint32_t>(ptr), ptr); // Check that we dont lose any non 0 bits.
SetField32<kTransactionActive, kCheckTransaction, kVerifyFlags>(
- field_offset, static_cast<int32_t>(static_cast<uint32_t>(ptr)));
+ field_offset, reinterpret_cast32<int32_t>(new_value));
} else {
SetField64<kTransactionActive, kCheckTransaction, kVerifyFlags>(
field_offset, reinterpret_cast64<int64_t>(new_value));
@@ -658,8 +656,8 @@
ALWAYS_INLINE T GetFieldPtrWithSize(MemberOffset field_offset, PointerSize pointer_size)
REQUIRES_SHARED(Locks::mutator_lock_) {
if (pointer_size == PointerSize::k32) {
- uint64_t address = static_cast<uint32_t>(GetField32<kVerifyFlags, kIsVolatile>(field_offset));
- return reinterpret_cast<T>(static_cast<uintptr_t>(address));
+ int32_t v = GetField32<kVerifyFlags, kIsVolatile>(field_offset);
+ return reinterpret_cast32<T>(v);
} else {
int64_t v = GetField64<kVerifyFlags, kIsVolatile>(field_offset);
return reinterpret_cast64<T>(v);