diff options
author | 2018-11-16 10:19:17 +0000 | |
---|---|---|
committer | 2018-11-16 10:19:17 +0000 | |
commit | b321ac28f726a7ed41f277382d85702ffdfbe00f (patch) | |
tree | c454b79ad7abfda5323daa2ce4257c8fe3adacf5 | |
parent | 9296e18a6af90d88ff3b557031659216c0cd130e (diff) | |
parent | b74574a5e497dbabbd716c758a9047b2dbdb2fb3 (diff) |
Merge "Speed up relative_patcher_arm64_test."
-rw-r--r-- | dex2oat/linker/arm/relative_patcher_thumb2_test.cc | 46 | ||||
-rw-r--r-- | dex2oat/linker/arm64/relative_patcher_arm64_test.cc | 367 | ||||
-rw-r--r-- | dex2oat/linker/relative_patcher_test.h | 43 |
3 files changed, 281 insertions, 175 deletions
diff --git a/dex2oat/linker/arm/relative_patcher_thumb2_test.cc b/dex2oat/linker/arm/relative_patcher_thumb2_test.cc index 3d7277aab3..b93e091ae6 100644 --- a/dex2oat/linker/arm/relative_patcher_thumb2_test.cc +++ b/dex2oat/linker/arm/relative_patcher_thumb2_test.cc @@ -827,26 +827,38 @@ void Thumb2RelativePatcherTest::TestBakerFieldNarrow(uint32_t offset, uint32_t r } } -#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 9e3bb978fb..0fc4610909 100644 --- a/dex2oat/linker/arm64/relative_patcher_arm64_test.cc +++ b/dex2oat/linker/arm64/relative_patcher_arm64_test.cc @@ -783,174 +783,242 @@ TEST_F(Arm64RelativePatcherTestDefault, CallOtherJustTooFarBefore) { 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, 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_F(Arm64RelativePatcherTestDefault, StringReference1) { - TestNopsAdrpAdd(0u, 0x12345678u); +TEST_F(Arm64RelativePatcherTestDefault, StringReference) { + for (uint32_t string_offset : { 0x12345678u, -0x12345678u, 0x12345000u, 0x12345ffcu}) { + Reset(); + TestNopsAdrpAdd(/*num_nops=*/ 0u, string_offset); + } } -TEST_F(Arm64RelativePatcherTestDefault, StringReference2) { - TestNopsAdrpAdd(0u, -0x12345678u); +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, StringReference3) { - TestNopsAdrpAdd(0u, 0x12345000u); +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(Arm64RelativePatcherTestDefault, StringReference4) { - TestNopsAdrpAdd(0u, 0x12345ffcu); +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 }); } -#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_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_FOR_OFFSETS(DENVER64_LDUR_LDR_TEST, 0x1234, 0x1238) - // 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_FOR_OFFSETS(LDRW_SPREL_LDR_TEST, 0, 4) - -#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_FOR_OFFSETS(LDRX_SPREL_LDR_TEST, 0, 8) - -#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_FOR_OFFSETS(DEFAULT_LDUR_ADD_TEST, 0x12345678, 0xffffc840) - -#define DENVER64_LDUR_ADD_TEST(adrp_offset, disp) \ - TEST_F(Arm64RelativePatcherTestDenver64, StringReference ## adrp_offset ## Ldur ## disp) { \ - TestAdrpLdurAdd(adrp_offset, false, disp); \ - } - -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_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(DEFAULT_SUBX3X2_ADD_TEST, 0x12345678, 0xffffc840) +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 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_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(DEFAULT_SUBSX3X0_ADD_TEST, 0x12345678, 0xffffc840) +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_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_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_ADDX0X0_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 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_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(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_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_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(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 @@ void Arm64RelativePatcherTest::TestBakerField(uint32_t offset, uint32_t ref_reg) } } -#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 9725570570..56ff0ef3ca 100644 --- a/dex2oat/linker/relative_patcher_test.h +++ b/dex2oat/linker/relative_patcher_test.h @@ -50,7 +50,7 @@ class RelativePatcherTest : public CommonCompilerTest { 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 @@ class RelativePatcherTest : public CommonCompilerTest { 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 @@ class RelativePatcherTest : public CommonCompilerTest { 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 @@ class RelativePatcherTest : public CommonCompilerTest { 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 @@ class RelativePatcherTest : public CommonCompilerTest { 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 @@ class RelativePatcherTest : public CommonCompilerTest { } } } - 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 @@ class RelativePatcherTest : public CommonCompilerTest { *debug_name = value.GetDebugName(); } + void Reset() { + thunk_map_.clear(); + } + private: class ThunkKey { public: @@ -342,7 +361,7 @@ class RelativePatcherTest : public CommonCompilerTest { 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 |