[vm] Use LoadWordFromPool in AssertAssignable on ARMs instead of raw ldr
Pool offsets might be not encodable as immediates. However
InstructionPattern::DecodeLoadWordFromPool can decode anything that
LoadWordFromPool can emit.
Fixes https://github.com/flutter/flutter/issues/18332
Change-Id: I8873f523bb65844e7256c0c3030edea4cc591830
Reviewed-on: https://dart-review.googlesource.com/59640
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index ab6f811..10b2c61 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -767,6 +767,13 @@
void LoadIsolate(Register rd);
+ // Load word from pool from the given offset using encoding that
+ // InstructionPattern::DecodeLoadWordFromPool can decode.
+ void LoadWordFromPoolOffset(Register rd,
+ int32_t offset,
+ Register pp,
+ Condition cond);
+
void LoadObject(Register rd, const Object& object, Condition cond = AL);
void LoadUniqueObject(Register rd, const Object& object, Condition cond = AL);
void LoadFunctionFromCalleePool(Register dst,
@@ -1110,11 +1117,6 @@
void BindARMv6(Label* label);
void BindARMv7(Label* label);
- void LoadWordFromPoolOffset(Register rd,
- int32_t offset,
- Register pp,
- Condition cond);
-
void BranchLink(const ExternalLabel* label);
class CodeComment : public ZoneAllocated {
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index b0d94c2..368e4a3 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -1493,6 +1493,10 @@
void LoadImmediate(Register reg, int64_t imm);
void LoadDImmediate(VRegister reg, double immd);
+ // Load word from pool from the given offset using encoding that
+ // InstructionPattern::DecodeLoadWordFromPool can decode.
+ void LoadWordFromPoolOffset(Register dst, uint32_t offset, Register pp = PP);
+
void PushObject(const Object& object) {
LoadObject(TMP, object);
Push(TMP);
@@ -1618,7 +1622,6 @@
bool constant_pool_allowed_;
- void LoadWordFromPoolOffset(Register dst, uint32_t offset, Register pp = PP);
void LoadWordFromPoolOffsetFixed(Register dst, uint32_t offset);
void LoadObjectHelper(Register dst, const Object& obj, bool is_unique);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index 6d150d3..6233ee3 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -743,7 +743,8 @@
__ LoadField(R9,
FieldAddress(kDstTypeReg,
AbstractType::type_test_stub_entry_point_offset()));
- __ ldr(kSubtypeTestCacheReg, Address(PP, sub_type_cache_offset));
+ __ LoadWordFromPoolOffset(kSubtypeTestCacheReg, sub_type_cache_offset, PP,
+ AL);
__ blx(R9);
EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
__ Bind(&done);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index cef314e..5a11f70 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -712,7 +712,7 @@
const intptr_t sub_type_cache_index = __ object_pool_wrapper().AddObject(
Object::null_object(), Patchability::kPatchable);
const intptr_t sub_type_cache_offset =
- ObjectPool::element_offset(sub_type_cache_index);
+ ObjectPool::element_offset(sub_type_cache_index) - kHeapObjectTag;
const intptr_t dst_name_index =
__ object_pool_wrapper().AddObject(dst_name, Patchability::kPatchable);
ASSERT((sub_type_cache_index + 1) == dst_name_index);
@@ -721,7 +721,7 @@
__ LoadField(R9,
FieldAddress(kDstTypeReg,
AbstractType::type_test_stub_entry_point_offset()));
- __ ldr(kSubtypeTestCacheReg, Address(PP, sub_type_cache_offset));
+ __ LoadWordFromPoolOffset(kSubtypeTestCacheReg, sub_type_cache_offset);
__ blr(R9);
EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
__ Bind(&done);
diff --git a/runtime/vm/instructions_arm.h b/runtime/vm/instructions_arm.h
index 0738d64..e11c947 100644
--- a/runtime/vm/instructions_arm.h
+++ b/runtime/vm/instructions_arm.h
@@ -42,6 +42,10 @@
// address of the first instruction in the sequence. Returns the register
// being loaded and the index in the pool being read from in the output
// parameters 'reg' and 'index' respectively.
+ // IMPORANT: When generating code loading values from pool on ARM use
+ // LoadWordFromPool macro instruction instead of emitting direct load.
+ // The macro instruction takes care of pool offsets that can't be
+ // encoded as immediates.
static uword DecodeLoadWordFromPool(uword end,
Register* reg,
intptr_t* index);
diff --git a/runtime/vm/instructions_arm64.h b/runtime/vm/instructions_arm64.h
index 10c74f5..1355cfe 100644
--- a/runtime/vm/instructions_arm64.h
+++ b/runtime/vm/instructions_arm64.h
@@ -42,6 +42,10 @@
// address of the first instruction in the sequence. Returns the register
// being loaded and the index in the pool being read from in the output
// parameters 'reg' and 'index' respectively.
+ // IMPORANT: When generating code loading values from pool on ARM64 use
+ // LoadWordFromPool macro instruction instead of emitting direct load.
+ // The macro instruction takes care of pool offsets that can't be
+ // encoded as immediates.
static uword DecodeLoadWordFromPool(uword end,
Register* reg,
intptr_t* index);