Skip to content

Commit 170d9e9

Browse files
committed
SIL: Let SILGlobalVariables be destroyed.
This fixes a memory leak: instructions of the static initializer block were not be freed. rdar://problem/66931238
1 parent 6f2cfa6 commit 170d9e9

File tree

4 files changed

+31
-14
lines changed

4 files changed

+31
-14
lines changed

include/swift/SIL/SILBasicBlock.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ public llvm::ilist_node<SILBasicBlock>, public SILAllocated<SILBasicBlock> {
7676
/// This method unlinks 'self' from the containing SILFunction and deletes it.
7777
void eraseFromParent();
7878

79+
/// Remove all instructions of a SILGlobalVariable's static initializer block.
80+
void clearStaticInitializerBlock(SILModule &module);
81+
7982
//===--------------------------------------------------------------------===//
8083
// SILInstruction List Inspection and Manipulation
8184
//===--------------------------------------------------------------------===//

include/swift/SIL/SILGlobalVariable.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ public ilist_node_traits<::swift::SILGlobalVariable> {
233233
using SILGlobalVariable = ::swift::SILGlobalVariable;
234234

235235
public:
236-
static void deleteNode(SILGlobalVariable *V) {}
236+
static void deleteNode(SILGlobalVariable *V) { V->~SILGlobalVariable(); }
237237

238238
private:
239239
void createNode(const SILGlobalVariable &);

lib/SIL/IR/SILBasicBlock.cpp

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,30 +43,43 @@ SILBasicBlock::SILBasicBlock(SILFunction *parent, SILBasicBlock *relativeToBB,
4343
}
4444
}
4545
SILBasicBlock::~SILBasicBlock() {
46+
if (!getParent()) {
47+
assert(ArgumentList.empty() &&
48+
"a static initializer block must not have arguments");
49+
assert(InstList.empty() &&
50+
"a static initializer block must be cleared before the destructor");
51+
return;
52+
}
53+
54+
SILModule &M = getModule();
55+
4656
// Invalidate all of the basic block arguments.
4757
for (auto *Arg : ArgumentList) {
48-
getModule().notifyDeleteHandlers(Arg);
58+
M.notifyDeleteHandlers(Arg);
4959
}
5060

5161
dropAllReferences();
5262

53-
SILModule *M = nullptr;
54-
if (getParent())
55-
M = &getParent()->getModule();
56-
5763
for (auto I = begin(), E = end(); I != E;) {
5864
auto Inst = &*I;
5965
++I;
60-
if (M) {
61-
// Notify the delete handlers that the instructions in this block are
62-
// being deleted.
63-
M->notifyDeleteHandlers(Inst);
64-
}
6566
erase(Inst);
6667
}
68+
assert(InstList.empty());
69+
}
70+
71+
void SILBasicBlock::clearStaticInitializerBlock(SILModule &module) {
72+
assert(!getParent() && "not a global variable's static initializer block");
73+
assert(ArgumentList.empty() &&
74+
"a static initializer block must not have arguments");
6775

68-
// iplist's destructor is going to destroy the InstList.
69-
InstList.clearAndLeakNodesUnsafely();
76+
for (auto I = begin(), E = end(); I != E;) {
77+
SILInstruction *Inst = &*I;
78+
++I;
79+
InstList.erase(Inst);
80+
module.deallocateInst(Inst);
81+
}
82+
assert(InstList.empty());
7083
}
7184

7285
int SILBasicBlock::getDebugID() const {

lib/SIL/IR/SILGlobalVariable.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ SILGlobalVariable::SILGlobalVariable(SILModule &Module, SILLinkage Linkage,
5858
}
5959

6060
SILGlobalVariable::~SILGlobalVariable() {
61-
getModule().GlobalVariableMap.erase(Name);
61+
StaticInitializerBlock.dropAllReferences();
62+
StaticInitializerBlock.clearStaticInitializerBlock(Module);
6263
}
6364

6465
/// Get this global variable's fragile attribute.

0 commit comments

Comments
 (0)