Skip to content

Commit df0a8b3

Browse files
committed
DI: Track of initialization state of trivial fields in root class initializers
While we don't need to destroy these fields, we still need to know when the class is _semantically_ fully initialized, since this will determine if we're going to release the class, running the deinitializer, or if we're going to deallocate the memory for the instance directly.
1 parent e624957 commit df0a8b3

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

lib/SILOptimizer/Mandatory/DIMemoryUseCollector.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,11 @@ class DIMemoryObjectInfo {
176176
MemoryInst->isDerivedClassSelfOnly();
177177
}
178178

179+
/// True if this memory object is the 'self' of a root class init method.
180+
bool isRootClassSelf() const {
181+
return isClassInitSelf() && MemoryInst->isRootSelf();
182+
}
183+
179184
/// True if this memory object is the 'self' of a non-root class init method.
180185
bool isNonRootClassSelf() const {
181186
return isClassInitSelf() && !MemoryInst->isRootSelf();

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,13 @@ void LifetimeChecker::handleStoreUse(unsigned UseID) {
10721072
// it for later. Once we've collected all of the conditional init/assigns,
10731073
// we can insert a single control variable for the memory object for the
10741074
// whole function.
1075-
if (!Use.onlyTouchesTrivialElements(TheMemory))
1075+
//
1076+
// For root class initializers, we must keep track of initializations of
1077+
// trivial stored properties also, since we need to know when the object
1078+
// has been fully initialized when deciding if a strong_release should
1079+
// lower to a partial_dealloc_ref.
1080+
if (TheMemory.isRootClassSelf() ||
1081+
!Use.onlyTouchesTrivialElements(TheMemory))
10761082
HasConditionalInitAssign = true;
10771083
return;
10781084
}
@@ -2285,7 +2291,13 @@ SILValue LifetimeChecker::handleConditionalInitAssign() {
22852291
// If this ambiguous store is only of trivial types, then we don't need to
22862292
// do anything special. We don't even need keep the init bit for the
22872293
// element precise.
2288-
if (Use.onlyTouchesTrivialElements(TheMemory))
2294+
//
2295+
// For root class initializers, we must keep track of initializations of
2296+
// trivial stored properties also, since we need to know when the object
2297+
// has been fully initialized when deciding if a strong_release should
2298+
// lower to a partial_dealloc_ref.
2299+
if (!TheMemory.isRootClassSelf() &&
2300+
Use.onlyTouchesTrivialElements(TheMemory))
22892301
continue;
22902302

22912303
B.setInsertionPoint(Use.Inst);

0 commit comments

Comments
 (0)