Skip to content

Commit 647466d

Browse files
committed
[sil-opened-archetype-tracker] Fix a memory leak
Placeholder global_addr instructions were never destroyed. Now they are inserted in the entry basic block and later removed from there by the end of SIL deserialization.
1 parent 0008354 commit 647466d

File tree

2 files changed

+29
-10
lines changed

2 files changed

+29
-10
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,10 @@ class SILBuilder {
423423
return insert(new (F.getModule())
424424
GlobalAddrInst(getSILDebugLocation(Loc), g));
425425
}
426-
426+
GlobalAddrInst *createGlobalAddr(SILLocation Loc, SILType Ty) {
427+
return insert(new (F.getModule())
428+
GlobalAddrInst(getSILDebugLocation(Loc), Ty));
429+
}
427430
IntegerLiteralInst *createIntegerLiteral(IntegerLiteralExpr *E);
428431

429432
IntegerLiteralInst *createIntegerLiteral(SILLocation Loc, SILType Ty,

lib/SIL/SILOpenedArchetypesTracker.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,23 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "swift/SIL/SILBuilder.h"
1314
#include "swift/SIL/SILOpenedArchetypesTracker.h"
1415

1516
using namespace swift;
1617

1718
void SILOpenedArchetypesTracker::addOpenedArchetypeDef(CanArchetypeType archetype,
1819
SILValue Def) {
1920
auto OldDef = getOpenedArchetypeDef(archetype);
20-
if (OldDef && isa<GlobalAddrInst>(OldDef)) {
21-
// It is a forward definition created during deserialization.
22-
// Replace it with the real definition now.
23-
OldDef->replaceAllUsesWith(Def);
24-
OldDef = SILValue();
21+
if (OldDef) {
22+
if (auto *OldI = dyn_cast<GlobalAddrInst>(OldDef)) {
23+
// It is a forward definition created during deserialization.
24+
// Replace it with the real definition now.
25+
OldDef->replaceAllUsesWith(Def);
26+
// Remove the placeholder instruction.
27+
OldI->eraseFromParent();
28+
OldDef = SILValue();
29+
}
2530
}
2631
assert(!OldDef &&
2732
"There can be only one definition of an opened archetype");
@@ -56,11 +61,22 @@ bool SILOpenedArchetypesTracker::registerUsedOpenedArchetypes(CanType Ty) {
5661
if (getOpenedArchetypeDef(archetypeTy))
5762
return;
5863

59-
auto &SILMod = this->getFunction().getModule();
64+
auto *CurF = const_cast<SILFunction *>(&this->getFunction());
65+
auto &SILMod = CurF->getModule();
6066
// Create a placeholder representing a forward definition.
61-
auto Placeholder = new (SILMod)
62-
GlobalAddrInst(SILDebugLocation(),
63-
SILMod.Types.getLoweredType(archetypeTy));
67+
// Add the placeholder at the beginning of the entry block.
68+
SILValue Placeholder;
69+
if (!CurF->getEntryBlock()->empty()) {
70+
SILBuilder B(CurF->getEntryBlock()->begin());
71+
Placeholder =
72+
B.createGlobalAddr(ArtificialUnreachableLocation(),
73+
SILMod.Types.getLoweredType(archetypeTy));
74+
} else {
75+
SILBuilder B(CurF->getEntryBlock());
76+
Placeholder =
77+
B.createGlobalAddr(ArtificialUnreachableLocation(),
78+
SILMod.Types.getLoweredType(archetypeTy));
79+
}
6480
// Make it available to SILBuilder, so that instructions using this
6581
// archetype can be constructed.
6682
addOpenedArchetypeDef(archetypeTy, Placeholder);

0 commit comments

Comments
 (0)