Skip to content

Commit 521c996

Browse files
committed
[JITLink] Move Symbol to new block before updating size.
Symbol::setSize asserts that the new size does not overflow the containing block, so we need to point the Symbol at the correct Block before updating its size (otherwise we may get a spurious overflow assertion).
1 parent 3155199 commit 521c996

File tree

2 files changed

+38
-29
lines changed

2 files changed

+38
-29
lines changed

llvm/lib/ExecutionEngine/JITLink/JITLink.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,9 @@ std::vector<Block *> LinkGraph::splitBlockImpl(std::vector<Block *> Blocks,
204204

205205
auto TransferSymbol = [](Symbol &Sym, Block &B) {
206206
Sym.setOffset(Sym.getAddress() - B.getAddress());
207+
Sym.setBlock(B);
207208
if (Sym.getSize() > B.getSize())
208209
Sym.setSize(B.getSize() - Sym.getOffset());
209-
Sym.setBlock(B);
210210
};
211211

212212
// Transfer symbols to all blocks except the last one.

llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -622,9 +622,12 @@ TEST(LinkGraphTest, SplitBlock) {
622622
false, false);
623623
auto &S4 = G.addDefinedSymbol(B1, 12, "S4", 4, Linkage::Strong,
624624
Scope::Default, false, false);
625-
// Add a symbol that extends beyond the split.
625+
// Add some symbols that extend beyond splits, one in the first block and one
626+
// in a subsequent block.
626627
auto &S5 = G.addDefinedSymbol(B1, 0, "S5", 16, Linkage::Strong,
627628
Scope::Default, false, false);
629+
auto &S6 = G.addDefinedSymbol(B1, 6, "S6", 10, Linkage::Strong,
630+
Scope::Default, false, false);
628631

629632
// Add an extra block, EB, and target symbols, and use these to add edges
630633
// from B1 to EB.
@@ -646,54 +649,56 @@ TEST(LinkGraphTest, SplitBlock) {
646649
B1.addEdge(Edge::FirstRelocation, 12, ES4, 0);
647650

648651
// Split B1.
649-
auto Blocks = G.splitBlock(B1, ArrayRef<int>({8}));
652+
auto Blocks = G.splitBlock(B1, ArrayRef<int>({4, 12}));
650653

651-
EXPECT_EQ(Blocks.size(), 2U);
654+
EXPECT_EQ(Blocks.size(), 3U);
652655
EXPECT_EQ(Blocks[0], &B1);
653656
auto &B2 = *Blocks[1];
657+
auto &B3 = *Blocks[2];
654658

655659
// Check that the block addresses and content matches what we would expect.
656660
EXPECT_EQ(B1.getAddress(), B1Addr);
657-
EXPECT_EQ(B1.getContent(), BlockContent.slice(0, 8));
658-
EXPECT_EQ(B1.edges_size(), 2U);
661+
EXPECT_EQ(B1.getContent(), BlockContent.slice(0, 4));
662+
EXPECT_EQ(B1.edges_size(), 1U);
659663

660-
EXPECT_EQ(B2.getAddress(), B1Addr + 8);
661-
EXPECT_EQ(B2.getContent(), BlockContent.slice(8));
664+
EXPECT_EQ(B2.getAddress(), B1Addr + 4);
665+
EXPECT_EQ(B2.getContent(), BlockContent.slice(4, 8));
662666
EXPECT_EQ(B2.edges_size(), 2U);
663667

668+
EXPECT_EQ(B3.getAddress(), B1Addr + 12);
669+
EXPECT_EQ(B3.getContent(), BlockContent.slice(12));
670+
EXPECT_EQ(B3.edges_size(), 1U);
671+
664672
// Check that symbols in B2 were transferred as expected:
665-
// We expect S1 and S2 to have been transferred to B1, and S3 and S4 to have
666-
// remained attached to B2. Symbols S3 and S4 should have had their offsets
667-
// slid to account for the change in address of B1.
673+
// We expect S1 and S5 to have been transferred to B1; S2, S3 and S6 to
674+
// B2; and S4 to B3. Symbols should have had their offsets slid to account
675+
// for the change of containing block.
668676
EXPECT_EQ(&S1.getBlock(), &B1);
669677
EXPECT_EQ(S1.getOffset(), 0U);
670678

671-
EXPECT_EQ(&S2.getBlock(), &B1);
672-
EXPECT_EQ(S2.getOffset(), 4U);
679+
EXPECT_EQ(&S2.getBlock(), &B2);
680+
EXPECT_EQ(S2.getOffset(), 0U);
673681

674682
EXPECT_EQ(&S3.getBlock(), &B2);
675-
EXPECT_EQ(S3.getOffset(), 0U);
683+
EXPECT_EQ(S3.getOffset(), 4U);
676684

677-
EXPECT_EQ(&S4.getBlock(), &B2);
678-
EXPECT_EQ(S4.getOffset(), 4U);
685+
EXPECT_EQ(&S4.getBlock(), &B3);
686+
EXPECT_EQ(S4.getOffset(), 0U);
679687

680688
EXPECT_EQ(&S5.getBlock(), &B1);
681689
EXPECT_EQ(S5.getOffset(), 0U);
682690

691+
EXPECT_EQ(&S6.getBlock(), &B2);
692+
EXPECT_EQ(S6.getOffset(), 2U);
693+
683694
// Size shrinks to fit.
684-
EXPECT_EQ(S5.getSize(), 8U);
685-
686-
// Check that edges in B2 have been transferred as expected:
687-
// Both blocks should now have two edges each at offsets 0 and 4.
688-
EXPECT_EQ(llvm::size(B1.edges()), 2);
689-
if (size(B1.edges()) == 2) {
690-
auto *E1 = &*B1.edges().begin();
691-
auto *E2 = &*(B1.edges().begin() + 1);
692-
if (E2->getOffset() < E1->getOffset())
693-
std::swap(E1, E2);
694-
EXPECT_EQ(E1->getOffset(), 0U);
695-
EXPECT_EQ(E2->getOffset(), 4U);
696-
}
695+
EXPECT_EQ(S5.getSize(), 4U);
696+
EXPECT_EQ(S6.getSize(), 6U);
697+
698+
// Check that edges in have been transferred as expected:
699+
EXPECT_EQ(llvm::size(B1.edges()), 1);
700+
if (size(B1.edges()) == 2)
701+
EXPECT_EQ(B1.edges().begin()->getOffset(), 0U);
697702

698703
EXPECT_EQ(llvm::size(B2.edges()), 2);
699704
if (size(B2.edges()) == 2) {
@@ -704,6 +709,10 @@ TEST(LinkGraphTest, SplitBlock) {
704709
EXPECT_EQ(E1->getOffset(), 0U);
705710
EXPECT_EQ(E2->getOffset(), 4U);
706711
}
712+
713+
EXPECT_EQ(llvm::size(B3.edges()), 1);
714+
if (size(B3.edges()) == 2)
715+
EXPECT_EQ(B3.edges().begin()->getOffset(), 0U);
707716
}
708717

709718
TEST(LinkGraphTest, GraphAllocationMethods) {

0 commit comments

Comments
 (0)