AArch64: oat patches should be 32-bit ints.
This makes the arm64 backend consistent with the behaviour of the code
in oat_writer.cc and in the patchoat tool.
It also reduces the size of boot.oat by 1.6% (aosp_arm64-eng build).
Change-Id: Ia0b96737159c08955cd7b776ee396ff578cd58f6
diff --git a/compiler/dex/quick/arm64/int_arm64.cc b/compiler/dex/quick/arm64/int_arm64.cc
index 88123e1..97f3994 100644
--- a/compiler/dex/quick/arm64/int_arm64.cc
+++ b/compiler/dex/quick/arm64/int_arm64.cc
@@ -925,7 +925,7 @@
LIR* Arm64Mir2Lir::OpPcRelLoad(RegStorage reg, LIR* target) {
ScopedMemRefType mem_ref_type(this, ResourceMask::kLiteral);
- return RawLIR(current_dalvik_offset_, WIDE(kA64Ldr2rp), reg.GetReg(), 0, 0, 0, 0, target);
+ return RawLIR(current_dalvik_offset_, kA64Ldr2rp, As32BitReg(reg).GetReg(), 0, 0, 0, 0, target);
}
LIR* Arm64Mir2Lir::OpVldm(RegStorage r_base, int count) {
diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc
index f305017..e18116e 100644
--- a/compiler/dex/quick/codegen_util.cc
+++ b/compiler/dex/quick/codegen_util.cc
@@ -447,15 +447,16 @@
buf.push_back((data >> 24) & 0xff);
}
-// Push 8 bytes on 64-bit target systems; 4 on 32-bit target systems.
-static void PushPointer(std::vector<uint8_t>&buf, const void* pointer, bool target64) {
- uint64_t data = reinterpret_cast<uintptr_t>(pointer);
- if (target64) {
- Push32(buf, data & 0xFFFFFFFF);
- Push32(buf, (data >> 32) & 0xFFFFFFFF);
- } else {
- Push32(buf, static_cast<uint32_t>(data));
- }
+/**
+ * @brief Push a compressed reference which needs patching at link/patchoat-time.
+ * @details This needs to be kept consistent with the code which actually does the patching in
+ * oat_writer.cc and in the patchoat tool.
+ */
+static void PushUnpatchedReference(std::vector<uint8_t>&buf) {
+ // Note that we can safely initialize the patches to zero. The code deduplication mechanism takes
+ // the patches into account when determining whether two pieces of codes are functionally
+ // equivalent.
+ Push32(buf, UINT32_C(0));
}
static void AlignBuffer(std::vector<uint8_t>&buf, size_t offset) {
@@ -481,9 +482,7 @@
reinterpret_cast<const DexFile*>(UnwrapPointer(data_lir->operands[1]));
patches_.push_back(LinkerPatch::CodePatch(code_buffer_.size(),
target_dex_file, target_method_idx));
- const DexFile::MethodId& target_method_id = target_dex_file->GetMethodId(target_method_idx);
- // unique value based on target to ensure code deduplication works
- PushPointer(code_buffer_, &target_method_id, cu_->target64);
+ PushUnpatchedReference(code_buffer_);
data_lir = NEXT_LIR(data_lir);
}
data_lir = method_literal_list_;
@@ -493,9 +492,7 @@
reinterpret_cast<const DexFile*>(UnwrapPointer(data_lir->operands[1]));
patches_.push_back(LinkerPatch::MethodPatch(code_buffer_.size(),
target_dex_file, target_method_idx));
- const DexFile::MethodId& target_method_id = target_dex_file->GetMethodId(target_method_idx);
- // unique value based on target to ensure code deduplication works
- PushPointer(code_buffer_, &target_method_id, cu_->target64);
+ PushUnpatchedReference(code_buffer_);
data_lir = NEXT_LIR(data_lir);
}
// Push class literals.
@@ -506,9 +503,7 @@
reinterpret_cast<const DexFile*>(UnwrapPointer(data_lir->operands[1]));
patches_.push_back(LinkerPatch::TypePatch(code_buffer_.size(),
class_dex_file, target_type_idx));
- const DexFile::TypeId& target_method_id = class_dex_file->GetTypeId(target_type_idx);
- // unique value based on target to ensure code deduplication works
- PushPointer(code_buffer_, &target_method_id, cu_->target64);
+ PushUnpatchedReference(code_buffer_);
data_lir = NEXT_LIR(data_lir);
}
}
@@ -772,7 +767,9 @@
/* Determine the offset of each literal field */
int Mir2Lir::AssignLiteralOffset(CodeOffset offset) {
offset = AssignLiteralOffsetCommon(literal_list_, offset);
- unsigned int ptr_size = GetInstructionSetPointerSize(cu_->instruction_set);
+ constexpr unsigned int ptr_size = sizeof(uint32_t);
+ COMPILE_ASSERT(ptr_size >= sizeof(mirror::HeapReference<mirror::Object>),
+ ptr_size_cannot_hold_a_heap_reference);
offset = AssignLiteralPointerOffsetCommon(code_literal_list_, offset, ptr_size);
offset = AssignLiteralPointerOffsetCommon(method_literal_list_, offset, ptr_size);
offset = AssignLiteralPointerOffsetCommon(class_literal_list_, offset, ptr_size);