Skip to content

Commit c4e135e

Browse files
authored
[ORC] Fix transfer to unknown ResourceTrackers (#114063)
When transferring resources, the destination tracker key may not be in the internal map, invalidating iterators and value references. The added test creates such situation and would fail before with "Finalized allocation was not deallocated." For good measure, fix the same pattern in RTDyldObjectLinkingLayer which is harder to test because it "only" results in memory managers being deleted in the wrong order.
1 parent 217700b commit c4e135e

File tree

3 files changed

+38
-10
lines changed

3 files changed

+38
-10
lines changed

llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -701,16 +701,15 @@ Error ObjectLinkingLayer::handleRemoveResources(JITDylib &JD, ResourceKey K) {
701701
void ObjectLinkingLayer::handleTransferResources(JITDylib &JD,
702702
ResourceKey DstKey,
703703
ResourceKey SrcKey) {
704-
auto I = Allocs.find(SrcKey);
705-
if (I != Allocs.end()) {
706-
auto &SrcAllocs = I->second;
704+
if (Allocs.contains(SrcKey)) {
705+
// DstKey may not be in the DenseMap yet, so the following line may resize
706+
// the container and invalidate iterators and value references.
707707
auto &DstAllocs = Allocs[DstKey];
708+
auto &SrcAllocs = Allocs[SrcKey];
708709
DstAllocs.reserve(DstAllocs.size() + SrcAllocs.size());
709710
for (auto &Alloc : SrcAllocs)
710711
DstAllocs.push_back(std::move(Alloc));
711712

712-
// Erase SrcKey entry using value rather than iterator I: I may have been
713-
// invalidated when we looked up DstKey.
714713
Allocs.erase(SrcKey);
715714
}
716715

llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -430,16 +430,15 @@ Error RTDyldObjectLinkingLayer::handleRemoveResources(JITDylib &JD,
430430
void RTDyldObjectLinkingLayer::handleTransferResources(JITDylib &JD,
431431
ResourceKey DstKey,
432432
ResourceKey SrcKey) {
433-
auto I = MemMgrs.find(SrcKey);
434-
if (I != MemMgrs.end()) {
435-
auto &SrcMemMgrs = I->second;
433+
if (MemMgrs.contains(SrcKey)) {
434+
// DstKey may not be in the DenseMap yet, so the following line may resize
435+
// the container and invalidate iterators and value references.
436436
auto &DstMemMgrs = MemMgrs[DstKey];
437+
auto &SrcMemMgrs = MemMgrs[SrcKey];
437438
DstMemMgrs.reserve(DstMemMgrs.size() + SrcMemMgrs.size());
438439
for (auto &MemMgr : SrcMemMgrs)
439440
DstMemMgrs.push_back(std::move(MemMgr));
440441

441-
// Erase SrcKey entry using value rather than iterator I: I may have been
442-
// invalidated when we looked up DstKey.
443442
MemMgrs.erase(SrcKey);
444443
}
445444
}

llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,36 @@ TEST_F(ObjectLinkingLayerTest, AddLinkGraph) {
6565
EXPECT_THAT_EXPECTED(ES.lookup(&JD, "_X"), Succeeded());
6666
}
6767

68+
TEST_F(ObjectLinkingLayerTest, ResourceTracker) {
69+
// This test transfers allocations to previously unknown ResourceTrackers,
70+
// while increasing the number of trackers in the ObjectLinkingLayer, which
71+
// may invalidate some iterators internally.
72+
std::vector<ResourceTrackerSP> Trackers;
73+
for (unsigned I = 0; I < 64; I++) {
74+
auto G = std::make_unique<LinkGraph>("foo", Triple("x86_64-apple-darwin"),
75+
8, llvm::endianness::little,
76+
x86_64::getEdgeKindName);
77+
78+
auto &Sec1 = G->createSection("__data", MemProt::Read | MemProt::Write);
79+
auto &B1 = G->createContentBlock(Sec1, BlockContent,
80+
orc::ExecutorAddr(0x1000), 8, 0);
81+
llvm::SmallString<0> SymbolName;
82+
SymbolName += "_X";
83+
SymbolName += std::to_string(I);
84+
G->addDefinedSymbol(B1, 4, SymbolName, 4, Linkage::Strong, Scope::Default,
85+
false, false);
86+
87+
auto RT1 = JD.createResourceTracker();
88+
EXPECT_THAT_ERROR(ObjLinkingLayer.add(RT1, std::move(G)), Succeeded());
89+
EXPECT_THAT_EXPECTED(ES.lookup(&JD, SymbolName), Succeeded());
90+
91+
auto RT2 = JD.createResourceTracker();
92+
RT1->transferTo(*RT2);
93+
94+
Trackers.push_back(RT2);
95+
}
96+
}
97+
6898
TEST_F(ObjectLinkingLayerTest, ClaimLateDefinedWeakSymbols) {
6999
// Check that claiming weak symbols works as expected.
70100
//

0 commit comments

Comments
 (0)