Merge "Speed up relative_patcher_arm64_test."
diff --git a/dex2oat/linker/arm/relative_patcher_thumb2_test.cc b/dex2oat/linker/arm/relative_patcher_thumb2_test.cc
index 3d7277a..b93e091 100644
--- a/dex2oat/linker/arm/relative_patcher_thumb2_test.cc
+++ b/dex2oat/linker/arm/relative_patcher_thumb2_test.cc
@@ -827,26 +827,38 @@
}
}
-#define TEST_BAKER_FIELD_WIDE(offset, ref_reg) \
- TEST_F(Thumb2RelativePatcherTest, \
- BakerOffsetWide##offset##_##ref_reg) { \
- TestBakerFieldWide(offset, ref_reg); \
+TEST_F(Thumb2RelativePatcherTest, BakerOffsetWide) {
+ struct TestCase {
+ uint32_t offset;
+ uint32_t ref_reg;
+ };
+ static const TestCase test_cases[] = {
+ { 0u, 0u },
+ { 8u, 3u },
+ { 28u, 7u },
+ { 0xffcu, 11u },
+ };
+ for (const TestCase& test_case : test_cases) {
+ Reset();
+ TestBakerFieldWide(test_case.offset, test_case.ref_reg);
}
+}
-TEST_BAKER_FIELD_WIDE(/* offset */ 0, /* ref_reg */ 0)
-TEST_BAKER_FIELD_WIDE(/* offset */ 8, /* ref_reg */ 3)
-TEST_BAKER_FIELD_WIDE(/* offset */ 28, /* ref_reg */ 7)
-TEST_BAKER_FIELD_WIDE(/* offset */ 0xffc, /* ref_reg */ 11)
-
-#define TEST_BAKER_FIELD_NARROW(offset, ref_reg) \
- TEST_F(Thumb2RelativePatcherTest, \
- BakerOffsetNarrow##offset##_##ref_reg) { \
- TestBakerFieldNarrow(offset, ref_reg); \
+TEST_F(Thumb2RelativePatcherTest, BakerOffsetNarrow) {
+ struct TestCase {
+ uint32_t offset;
+ uint32_t ref_reg;
+ };
+ static const TestCase test_cases[] = {
+ { 0, 0u },
+ { 8, 3u },
+ { 28, 7u },
+ };
+ for (const TestCase& test_case : test_cases) {
+ Reset();
+ TestBakerFieldNarrow(test_case.offset, test_case.ref_reg);
}
-
-TEST_BAKER_FIELD_NARROW(/* offset */ 0, /* ref_reg */ 0)
-TEST_BAKER_FIELD_NARROW(/* offset */ 8, /* ref_reg */ 3)
-TEST_BAKER_FIELD_NARROW(/* offset */ 28, /* ref_reg */ 7)
+}
TEST_F(Thumb2RelativePatcherTest, BakerOffsetThunkInTheMiddle) {
// One thunk in the middle with maximum distance branches to it from both sides.
diff --git a/dex2oat/linker/arm64/relative_patcher_arm64_test.cc b/dex2oat/linker/arm64/relative_patcher_arm64_test.cc
index 9e3bb97..0fc4610 100644
--- a/dex2oat/linker/arm64/relative_patcher_arm64_test.cc
+++ b/dex2oat/linker/arm64/relative_patcher_arm64_test.cc
@@ -783,174 +783,242 @@
EXPECT_TRUE(CheckThunk(thunk_offset));
}
-TEST_F(Arm64RelativePatcherTestDefault, StringBssEntry1) {
- TestNopsAdrpLdr(0u, 0x12345678u, 0x1234u);
-}
-
-TEST_F(Arm64RelativePatcherTestDefault, StringBssEntry2) {
- TestNopsAdrpLdr(0u, -0x12345678u, 0x4444u);
-}
-
-TEST_F(Arm64RelativePatcherTestDefault, StringBssEntry3) {
- TestNopsAdrpLdr(0u, 0x12345000u, 0x3ffcu);
-}
-
-TEST_F(Arm64RelativePatcherTestDefault, StringBssEntry4) {
- TestNopsAdrpLdr(0u, 0x12345000u, 0x4000u);
-}
-
-TEST_F(Arm64RelativePatcherTestDefault, StringReference1) {
- TestNopsAdrpAdd(0u, 0x12345678u);
-}
-
-TEST_F(Arm64RelativePatcherTestDefault, StringReference2) {
- TestNopsAdrpAdd(0u, -0x12345678u);
-}
-
-TEST_F(Arm64RelativePatcherTestDefault, StringReference3) {
- TestNopsAdrpAdd(0u, 0x12345000u);
-}
-
-TEST_F(Arm64RelativePatcherTestDefault, StringReference4) {
- TestNopsAdrpAdd(0u, 0x12345ffcu);
-}
-
-#define TEST_FOR_OFFSETS(test, disp1, disp2) \
- test(0xff4u, disp1) test(0xff8u, disp1) test(0xffcu, disp1) test(0x1000u, disp1) \
- test(0xff4u, disp2) test(0xff8u, disp2) test(0xffcu, disp2) test(0x1000u, disp2)
-
-#define DEFAULT_LDUR_LDR_TEST(adrp_offset, disp) \
- TEST_F(Arm64RelativePatcherTestDefault, StringBssEntry ## adrp_offset ## Ldur ## disp) { \
- bool has_thunk = ((adrp_offset) == 0xff8u || (adrp_offset) == 0xffcu); \
- TestAdrpLdurLdr(adrp_offset, has_thunk, 0x12345678u, disp); \
+TEST_F(Arm64RelativePatcherTestDefault, StringBssEntry) {
+ struct TestCase {
+ uint32_t bss_begin;
+ uint32_t string_entry_offset;
+ };
+ static const TestCase test_cases[] = {
+ { 0x12345678u, 0x1234u },
+ { -0x12345678u, 0x4444u },
+ { 0x12345000u, 0x3ffcu },
+ { 0x12345000u, 0x4000u }
+ };
+ for (const TestCase& test_case : test_cases) {
+ Reset();
+ TestNopsAdrpLdr(/*num_nops=*/ 0u, test_case.bss_begin, test_case.string_entry_offset);
}
+}
-TEST_FOR_OFFSETS(DEFAULT_LDUR_LDR_TEST, 0x1234, 0x1238)
-
-#define DENVER64_LDUR_LDR_TEST(adrp_offset, disp) \
- TEST_F(Arm64RelativePatcherTestDenver64, StringBssEntry ## adrp_offset ## Ldur ## disp) { \
- TestAdrpLdurLdr(adrp_offset, false, 0x12345678u, disp); \
+TEST_F(Arm64RelativePatcherTestDefault, StringReference) {
+ for (uint32_t string_offset : { 0x12345678u, -0x12345678u, 0x12345000u, 0x12345ffcu}) {
+ Reset();
+ TestNopsAdrpAdd(/*num_nops=*/ 0u, string_offset);
}
+}
-TEST_FOR_OFFSETS(DENVER64_LDUR_LDR_TEST, 0x1234, 0x1238)
+template <typename Test>
+void TestForAdrpOffsets(Test test, std::initializer_list<uint32_t> args) {
+ for (uint32_t adrp_offset : { 0xff4u, 0xff8u, 0xffcu, 0x1000u }) {
+ for (uint32_t arg : args) {
+ test(adrp_offset, arg);
+ }
+ }
+}
+
+TEST_F(Arm64RelativePatcherTestDefault, StringBssEntryLdur) {
+ TestForAdrpOffsets(
+ [&](uint32_t adrp_offset, uint32_t string_entry_offset) {
+ Reset();
+ bool has_thunk = ((adrp_offset) == 0xff8u || (adrp_offset) == 0xffcu);
+ TestAdrpLdurLdr(adrp_offset, has_thunk, /*bss_begin=*/ 0x12345678u, string_entry_offset);
+ },
+ { 0x1234u, 0x1238u });
+}
+
+TEST_F(Arm64RelativePatcherTestDenver64, StringBssEntryLdur) {
+ TestForAdrpOffsets(
+ [&](uint32_t adrp_offset, uint32_t string_entry_offset) {
+ Reset();
+ TestAdrpLdurLdr(adrp_offset,
+ /*has_thunk=*/ false,
+ /*bss_begin=*/ 0x12345678u,
+ string_entry_offset);
+ },
+ { 0x1234u, 0x1238u });
+}
// LDR <Wt>, <label> is always aligned. We should never have to use a fixup.
-#define LDRW_PCREL_LDR_TEST(adrp_offset, disp) \
- TEST_F(Arm64RelativePatcherTestDefault, StringBssEntry ## adrp_offset ## WPcRel ## disp) { \
- TestAdrpLdrPcRelLdr(kLdrWPcRelInsn, disp, adrp_offset, false, 0x12345678u, 0x1234u); \
- }
-
-TEST_FOR_OFFSETS(LDRW_PCREL_LDR_TEST, 0x1234, 0x1238)
+TEST_F(Arm64RelativePatcherTestDefault, StringBssEntryWPcRel) {
+ TestForAdrpOffsets(
+ [&](uint32_t adrp_offset, uint32_t pcrel_disp) {
+ Reset();
+ TestAdrpLdrPcRelLdr(kLdrWPcRelInsn,
+ pcrel_disp,
+ adrp_offset,
+ /*has_thunk=*/ false,
+ /*bss_begin=*/ 0x12345678u,
+ /*string_entry_offset=*/ 0x1234u);
+ },
+ { 0x1234u, 0x1238u });
+}
// LDR <Xt>, <label> is aligned when offset + displacement is a multiple of 8.
-#define LDRX_PCREL_LDR_TEST(adrp_offset, disp) \
- TEST_F(Arm64RelativePatcherTestDefault, StringBssEntry ## adrp_offset ## XPcRel ## disp) { \
- bool unaligned = !IsAligned<8u>((adrp_offset) + 4u + static_cast<uint32_t>(disp)); \
- bool has_thunk = ((adrp_offset) == 0xff8u || (adrp_offset) == 0xffcu) && unaligned; \
- TestAdrpLdrPcRelLdr(kLdrXPcRelInsn, disp, adrp_offset, has_thunk, 0x12345678u, 0x1234u); \
- }
-
-TEST_FOR_OFFSETS(LDRX_PCREL_LDR_TEST, 0x1234, 0x1238)
+TEST_F(Arm64RelativePatcherTestDefault, StringBssEntryXPcRel) {
+ TestForAdrpOffsets(
+ [&](uint32_t adrp_offset, uint32_t pcrel_disp) {
+ Reset();
+ bool unaligned = !IsAligned<8u>((adrp_offset) + 4u + static_cast<uint32_t>(pcrel_disp));
+ bool has_thunk = ((adrp_offset) == 0xff8u || (adrp_offset) == 0xffcu) && unaligned;
+ TestAdrpLdrPcRelLdr(kLdrXPcRelInsn,
+ pcrel_disp,
+ adrp_offset,
+ has_thunk,
+ /*bss_begin=*/ 0x12345678u,
+ /*string_entry_offset=*/ 0x1234u);
+ },
+ { 0x1234u, 0x1238u });
+}
// LDR <Wt>, [SP, #<pimm>] and LDR <Xt>, [SP, #<pimm>] are always aligned. No fixup needed.
-#define LDRW_SPREL_LDR_TEST(adrp_offset, disp) \
- TEST_F(Arm64RelativePatcherTestDefault, StringBssEntry ## adrp_offset ## WSpRel ## disp) { \
- TestAdrpLdrSpRelLdr(kLdrWSpRelInsn, (disp) >> 2, adrp_offset, false, 0x12345678u, 0x1234u); \
- }
+TEST_F(Arm64RelativePatcherTestDefault, StringBssEntryWSpRel) {
+ TestForAdrpOffsets(
+ [&](uint32_t adrp_offset, uint32_t disp) {
+ Reset();
+ TestAdrpLdrSpRelLdr(kLdrWSpRelInsn,
+ /*sprel_disp_in_load_units=*/ disp >> 2,
+ adrp_offset,
+ /*has_thunk=*/ false,
+ /*bss_begin=*/ 0x12345678u,
+ /*string_entry_offset=*/ 0x1234u);
+ },
+ { 0u, 4u });
+}
-TEST_FOR_OFFSETS(LDRW_SPREL_LDR_TEST, 0, 4)
+TEST_F(Arm64RelativePatcherTestDefault, StringBssEntryXSpRel) {
+ TestForAdrpOffsets(
+ [&](uint32_t adrp_offset, uint32_t disp) {
+ Reset();
+ TestAdrpLdrSpRelLdr(kLdrXSpRelInsn,
+ /*sprel_disp_in_load_units=*/ (disp) >> 3,
+ adrp_offset,
+ /*has_thunk=*/ false,
+ /*bss_begin=*/ 0x12345678u,
+ /*string_entry_offset=*/ 0x1234u);
+ },
+ { 0u, 8u });
+}
-#define LDRX_SPREL_LDR_TEST(adrp_offset, disp) \
- TEST_F(Arm64RelativePatcherTestDefault, StringBssEntry ## adrp_offset ## XSpRel ## disp) { \
- TestAdrpLdrSpRelLdr(kLdrXSpRelInsn, (disp) >> 3, adrp_offset, false, 0x12345678u, 0x1234u); \
- }
+TEST_F(Arm64RelativePatcherTestDefault, StringReferenceLdur) {
+ TestForAdrpOffsets(
+ [&](uint32_t adrp_offset, uint32_t string_offset) {
+ Reset();
+ bool has_thunk = ((adrp_offset) == 0xff8u || (adrp_offset) == 0xffcu);
+ TestAdrpLdurAdd(adrp_offset, has_thunk, string_offset);
+ },
+ { 0x12345678u, 0xffffc840u });
+}
-TEST_FOR_OFFSETS(LDRX_SPREL_LDR_TEST, 0, 8)
+TEST_F(Arm64RelativePatcherTestDenver64, StringReferenceLdur) {
+ TestForAdrpOffsets(
+ [&](uint32_t adrp_offset, uint32_t string_offset) {
+ Reset();
+ TestAdrpLdurAdd(adrp_offset, /*has_thunk=*/ false, string_offset);
+ },
+ { 0x12345678u, 0xffffc840U });
+}
-#define DEFAULT_LDUR_ADD_TEST(adrp_offset, disp) \
- TEST_F(Arm64RelativePatcherTestDefault, StringReference ## adrp_offset ## Ldur ## disp) { \
- bool has_thunk = ((adrp_offset) == 0xff8u || (adrp_offset) == 0xffcu); \
- TestAdrpLdurAdd(adrp_offset, has_thunk, disp); \
- }
+TEST_F(Arm64RelativePatcherTestDefault, StringReferenceSubX3X2) {
+ TestForAdrpOffsets(
+ [&](uint32_t adrp_offset, uint32_t string_offset) {
+ Reset();
+ /* SUB unrelated to "ADRP x0, addr". */ \
+ uint32_t sub = kSubXInsn | (100 << 10) | (2u << 5) | 3u; /* SUB x3, x2, #100 */
+ TestAdrpInsn2Add(sub, adrp_offset, /*has_thunk=*/ false, string_offset);
+ },
+ { 0x12345678u, 0xffffc840u });
+}
-TEST_FOR_OFFSETS(DEFAULT_LDUR_ADD_TEST, 0x12345678, 0xffffc840)
+TEST_F(Arm64RelativePatcherTestDefault, StringReferenceSubsX3X0) {
+ TestForAdrpOffsets(
+ [&](uint32_t adrp_offset, uint32_t string_offset) {
+ Reset();
+ /* SUBS that uses the result of "ADRP x0, addr". */ \
+ uint32_t subs = kSubsXInsn | (100 << 10) | (0u << 5) | 3u; /* SUBS x3, x0, #100 */
+ TestAdrpInsn2Add(subs, adrp_offset, /*has_thunk=*/ false, string_offset);
+ },
+ { 0x12345678u, 0xffffc840u });
+}
-#define DENVER64_LDUR_ADD_TEST(adrp_offset, disp) \
- TEST_F(Arm64RelativePatcherTestDenver64, StringReference ## adrp_offset ## Ldur ## disp) { \
- TestAdrpLdurAdd(adrp_offset, false, disp); \
- }
+TEST_F(Arm64RelativePatcherTestDefault, StringReferenceAddX0X0) {
+ TestForAdrpOffsets(
+ [&](uint32_t adrp_offset, uint32_t string_offset) {
+ Reset();
+ /* ADD that uses the result register of "ADRP x0, addr" as both source and destination. */
+ uint32_t add = kSubXInsn | (100 << 10) | (0u << 5) | 0u; /* ADD x0, x0, #100 */
+ TestAdrpInsn2Add(add, adrp_offset, /*has_thunk=*/ false, string_offset);
+ },
+ { 0x12345678u, 0xffffc840 });
+}
-TEST_FOR_OFFSETS(DENVER64_LDUR_ADD_TEST, 0x12345678, 0xffffc840)
-
-#define DEFAULT_SUBX3X2_ADD_TEST(adrp_offset, disp) \
- TEST_F(Arm64RelativePatcherTestDefault, StringReference ## adrp_offset ## SubX3X2 ## disp) { \
- /* SUB unrelated to "ADRP x0, addr". */ \
- uint32_t sub = kSubXInsn | (100 << 10) | (2u << 5) | 3u; /* SUB x3, x2, #100 */ \
- TestAdrpInsn2Add(sub, adrp_offset, false, disp); \
- }
-
-TEST_FOR_OFFSETS(DEFAULT_SUBX3X2_ADD_TEST, 0x12345678, 0xffffc840)
-
-#define DEFAULT_SUBSX3X0_ADD_TEST(adrp_offset, disp) \
- TEST_F(Arm64RelativePatcherTestDefault, StringReference ## adrp_offset ## SubsX3X0 ## disp) { \
- /* SUBS that uses the result of "ADRP x0, addr". */ \
- uint32_t subs = kSubsXInsn | (100 << 10) | (0u << 5) | 3u; /* SUBS x3, x0, #100 */ \
- TestAdrpInsn2Add(subs, adrp_offset, false, disp); \
- }
-
-TEST_FOR_OFFSETS(DEFAULT_SUBSX3X0_ADD_TEST, 0x12345678, 0xffffc840)
-
-#define DEFAULT_ADDX0X0_ADD_TEST(adrp_offset, disp) \
- TEST_F(Arm64RelativePatcherTestDefault, StringReference ## adrp_offset ## AddX0X0 ## disp) { \
- /* ADD that uses the result register of "ADRP x0, addr" as both source and destination. */ \
- uint32_t add = kSubXInsn | (100 << 10) | (0u << 5) | 0u; /* ADD x0, x0, #100 */ \
- TestAdrpInsn2Add(add, adrp_offset, false, disp); \
- }
-
-TEST_FOR_OFFSETS(DEFAULT_ADDX0X0_ADD_TEST, 0x12345678, 0xffffc840)
-
-#define DEFAULT_ADDSX0X2_ADD_TEST(adrp_offset, disp) \
- TEST_F(Arm64RelativePatcherTestDefault, StringReference ## adrp_offset ## AddsX0X2 ## disp) { \
- /* ADDS that does not use the result of "ADRP x0, addr" but overwrites that register. */ \
- uint32_t adds = kAddsXInsn | (100 << 10) | (2u << 5) | 0u; /* ADDS x0, x2, #100 */ \
- bool has_thunk = ((adrp_offset) == 0xff8u || (adrp_offset) == 0xffcu); \
- TestAdrpInsn2Add(adds, adrp_offset, has_thunk, disp); \
- }
-
-TEST_FOR_OFFSETS(DEFAULT_ADDSX0X2_ADD_TEST, 0x12345678, 0xffffc840)
+TEST_F(Arm64RelativePatcherTestDefault, StringReferenceAddsX0X2) {
+ TestForAdrpOffsets(
+ [&](uint32_t adrp_offset, uint32_t string_offset) {
+ Reset();
+ /* ADDS that does not use the result of "ADRP x0, addr" but overwrites that register. */
+ uint32_t adds = kAddsXInsn | (100 << 10) | (2u << 5) | 0u; /* ADDS x0, x2, #100 */
+ bool has_thunk = ((adrp_offset) == 0xff8u || (adrp_offset) == 0xffcu);
+ TestAdrpInsn2Add(adds, adrp_offset, has_thunk, string_offset);
+ },
+ { 0x12345678u, 0xffffc840u });
+}
// LDR <Wt>, <label> is always aligned. We should never have to use a fixup.
-#define LDRW_PCREL_ADD_TEST(adrp_offset, disp) \
- TEST_F(Arm64RelativePatcherTestDefault, StringReference ## adrp_offset ## WPcRel ## disp) { \
- TestAdrpLdrPcRelAdd(kLdrWPcRelInsn, disp, adrp_offset, false, 0x12345678u); \
- }
-
-TEST_FOR_OFFSETS(LDRW_PCREL_ADD_TEST, 0x1234, 0x1238)
+TEST_F(Arm64RelativePatcherTestDefault, StringReferenceWPcRel) {
+ TestForAdrpOffsets(
+ [&](uint32_t adrp_offset, uint32_t pcrel_disp) {
+ Reset();
+ TestAdrpLdrPcRelAdd(kLdrWPcRelInsn,
+ pcrel_disp,
+ adrp_offset,
+ /*has_thunk=*/ false,
+ /*string_offset=*/ 0x12345678u);
+ },
+ { 0x1234u, 0x1238u });
+}
// LDR <Xt>, <label> is aligned when offset + displacement is a multiple of 8.
-#define LDRX_PCREL_ADD_TEST(adrp_offset, disp) \
- TEST_F(Arm64RelativePatcherTestDefault, StringReference ## adrp_offset ## XPcRel ## disp) { \
- bool unaligned = !IsAligned<8u>((adrp_offset) + 4u + static_cast<uint32_t>(disp)); \
- bool has_thunk = ((adrp_offset) == 0xff8u || (adrp_offset) == 0xffcu) && unaligned; \
- TestAdrpLdrPcRelAdd(kLdrXPcRelInsn, disp, adrp_offset, has_thunk, 0x12345678u); \
- }
-
-TEST_FOR_OFFSETS(LDRX_PCREL_ADD_TEST, 0x1234, 0x1238)
+TEST_F(Arm64RelativePatcherTestDefault, StringReferenceXPcRel) {
+ TestForAdrpOffsets(
+ [&](uint32_t adrp_offset, uint32_t pcrel_disp) {
+ Reset();
+ bool unaligned = !IsAligned<8u>((adrp_offset) + 4u + static_cast<uint32_t>(pcrel_disp));
+ bool has_thunk = ((adrp_offset) == 0xff8u || (adrp_offset) == 0xffcu) && unaligned;
+ TestAdrpLdrPcRelAdd(kLdrXPcRelInsn,
+ pcrel_disp,
+ adrp_offset,
+ has_thunk,
+ /*string_offset=*/ 0x12345678u);
+ },
+ { 0x1234u, 0x1238u });
+}
// LDR <Wt>, [SP, #<pimm>] and LDR <Xt>, [SP, #<pimm>] are always aligned. No fixup needed.
-#define LDRW_SPREL_ADD_TEST(adrp_offset, disp) \
- TEST_F(Arm64RelativePatcherTestDefault, StringReference ## adrp_offset ## WSpRel ## disp) { \
- TestAdrpLdrSpRelAdd(kLdrWSpRelInsn, (disp) >> 2, adrp_offset, false, 0x12345678u); \
- }
+TEST_F(Arm64RelativePatcherTestDefault, StringReferenceWSpRel) {
+ TestForAdrpOffsets(
+ [&](uint32_t adrp_offset, uint32_t disp) {
+ Reset();
+ TestAdrpLdrSpRelAdd(kLdrWSpRelInsn,
+ /*sprel_disp_in_load_units=*/ (disp) >> 2,
+ adrp_offset,
+ /*has_thunk=*/ false,
+ /*string_offset=*/ 0x12345678u);
+ },
+ { 0u, 4u });
+}
-TEST_FOR_OFFSETS(LDRW_SPREL_ADD_TEST, 0, 4)
-
-#define LDRX_SPREL_ADD_TEST(adrp_offset, disp) \
- TEST_F(Arm64RelativePatcherTestDefault, StringReference ## adrp_offset ## XSpRel ## disp) { \
- TestAdrpLdrSpRelAdd(kLdrXSpRelInsn, (disp) >> 3, adrp_offset, false, 0x12345678u); \
- }
-
-TEST_FOR_OFFSETS(LDRX_SPREL_ADD_TEST, 0, 8)
+TEST_F(Arm64RelativePatcherTestDefault, StringReferenceXSpRel) {
+ TestForAdrpOffsets(
+ [&](uint32_t adrp_offset, uint32_t disp) {
+ Reset();
+ TestAdrpLdrSpRelAdd(kLdrXSpRelInsn,
+ /*sprel_disp_in_load_units=*/ (disp) >> 3,
+ adrp_offset,
+ /*has_thunk=*/ false,
+ /*string_offset=*/ 0x12345678u);
+ },
+ { 0u, 8u });
+}
void Arm64RelativePatcherTest::TestBakerField(uint32_t offset, uint32_t ref_reg) {
uint32_t valid_regs[] = {
@@ -1039,15 +1107,22 @@
}
}
-#define TEST_BAKER_FIELD(offset, ref_reg) \
- TEST_F(Arm64RelativePatcherTestDefault, \
- BakerOffset##offset##_##ref_reg) { \
- TestBakerField(offset, ref_reg); \
+TEST_F(Arm64RelativePatcherTestDefault, BakerOffset) {
+ struct TestCase {
+ uint32_t offset;
+ uint32_t ref_reg;
+ };
+ static const TestCase test_cases[] = {
+ { 0u, 0u },
+ { 8u, 15u},
+ { 0x3ffcu, 29u },
+ };
+ for (const TestCase& test_case : test_cases) {
+ Reset();
+ TestBakerField(test_case.offset, test_case.ref_reg);
}
+}
-TEST_BAKER_FIELD(/* offset */ 0, /* ref_reg */ 0)
-TEST_BAKER_FIELD(/* offset */ 8, /* ref_reg */ 15)
-TEST_BAKER_FIELD(/* offset */ 0x3ffc, /* ref_reg */ 29)
TEST_F(Arm64RelativePatcherTestDefault, BakerOffsetThunkInTheMiddle) {
// One thunk in the middle with maximum distance branches to it from both sides.
diff --git a/dex2oat/linker/relative_patcher_test.h b/dex2oat/linker/relative_patcher_test.h
index 9725570..56ff0ef 100644
--- a/dex2oat/linker/relative_patcher_test.h
+++ b/dex2oat/linker/relative_patcher_test.h
@@ -50,7 +50,7 @@
compiled_methods_(),
patched_code_(),
output_(),
- out_("test output stream", &output_) {
+ out_(nullptr) {
// Override CommonCompilerTest's defaults.
instruction_set_ = instruction_set;
number_of_threads_ = 1u;
@@ -61,10 +61,7 @@
OverrideInstructionSetFeatures(instruction_set_, variant_);
CommonCompilerTest::SetUp();
- patcher_ = RelativePatcher::Create(compiler_options_->GetInstructionSet(),
- compiler_options_->GetInstructionSetFeatures(),
- &thunk_provider_,
- &method_offset_map_);
+ Reset();
}
void TearDown() override {
@@ -73,6 +70,24 @@
CommonCompilerTest::TearDown();
}
+ // Reset the helper to start another test. Creating and tearing down the Runtime is expensive,
+ // so we merge related tests together.
+ void Reset() {
+ thunk_provider_.Reset();
+ method_offset_map_.map.clear();
+ patcher_ = RelativePatcher::Create(compiler_options_->GetInstructionSet(),
+ compiler_options_->GetInstructionSetFeatures(),
+ &thunk_provider_,
+ &method_offset_map_);
+ bss_begin_ = 0u;
+ string_index_to_offset_map_.clear();
+ compiled_method_refs_.clear();
+ compiled_methods_.clear();
+ patched_code_.clear();
+ output_.clear();
+ out_.reset(new VectorOutputStream("test output stream", &output_));
+ }
+
MethodReference MethodRef(uint32_t method_idx) {
CHECK_NE(method_idx, 0u);
return MethodReference(nullptr, method_idx);
@@ -127,7 +142,7 @@
DCHECK(output_.empty());
uint8_t dummy_trampoline[kTrampolineSize];
memset(dummy_trampoline, 0, sizeof(dummy_trampoline));
- out_.WriteFully(dummy_trampoline, kTrampolineSize);
+ out_->WriteFully(dummy_trampoline, kTrampolineSize);
offset = kTrampolineSize;
static const uint8_t kPadding[] = {
0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u
@@ -135,14 +150,14 @@
uint8_t dummy_header[sizeof(OatQuickMethodHeader)];
memset(dummy_header, 0, sizeof(dummy_header));
for (auto& compiled_method : compiled_methods_) {
- offset = patcher_->WriteThunks(&out_, offset);
+ offset = patcher_->WriteThunks(out_.get(), offset);
uint32_t alignment_size = CodeAlignmentSize(offset);
CHECK_LE(alignment_size, sizeof(kPadding));
- out_.WriteFully(kPadding, alignment_size);
+ out_->WriteFully(kPadding, alignment_size);
offset += alignment_size;
- out_.WriteFully(dummy_header, sizeof(OatQuickMethodHeader));
+ out_->WriteFully(dummy_header, sizeof(OatQuickMethodHeader));
offset += sizeof(OatQuickMethodHeader);
ArrayRef<const uint8_t> code = compiled_method->GetQuickCode();
if (!compiled_method->GetPatches().empty()) {
@@ -179,10 +194,10 @@
}
}
}
- out_.WriteFully(&code[0], code.size());
+ out_->WriteFully(&code[0], code.size());
offset += code.size();
}
- offset = patcher_->WriteThunks(&out_, offset);
+ offset = patcher_->WriteThunks(out_.get(), offset);
CHECK_EQ(offset, output_size);
CHECK_EQ(output_.size(), output_size);
}
@@ -270,6 +285,10 @@
*debug_name = value.GetDebugName();
}
+ void Reset() {
+ thunk_map_.clear();
+ }
+
private:
class ThunkKey {
public:
@@ -342,7 +361,7 @@
std::vector<std::unique_ptr<CompiledMethod>> compiled_methods_;
std::vector<uint8_t> patched_code_;
std::vector<uint8_t> output_;
- VectorOutputStream out_;
+ std::unique_ptr<VectorOutputStream> out_;
};
} // namespace linker