[ReleaseDevirtualizer] fix non-detriministic crash.

rdar://problem/23868367
This commit is contained in:
Erik Eckstein
2015-12-14 09:57:05 -08:00
parent 212cb4a65c
commit 0880ddd6c7

View File

@@ -87,10 +87,12 @@ void ReleaseDevirtualizer::run() {
if (LastRelease) {
if (auto *DRI = dyn_cast<DeallocRefInst>(&I)) {
Changed |= devirtualizeReleaseOfObject(LastRelease, DRI);
LastRelease = nullptr;
continue;
}
if (auto *AI = dyn_cast<ApplyInst>(&I)) {
Changed |= devirtualizeReleaseOfBuffer(LastRelease, AI);
LastRelease = nullptr;
continue;
}
}
@@ -112,6 +114,8 @@ bool ReleaseDevirtualizer::
devirtualizeReleaseOfObject(SILInstruction *ReleaseInst,
DeallocRefInst *DeallocInst) {
DEBUG(llvm::dbgs() << " try to devirtualize " << *ReleaseInst);
// We only do the optimization for stack promoted object, because for these
// we know that they don't have associated objects, which are _not_ released
// by the deinit method.
@@ -138,6 +142,8 @@ bool ReleaseDevirtualizer::
devirtualizeReleaseOfBuffer(SILInstruction *ReleaseInst,
ApplyInst *DeallocCall) {
DEBUG(llvm::dbgs() << " try to devirtualize " << *ReleaseInst);
// Is this a deallocation of a buffer?
SILFunction *DeallocFn = DeallocCall->getCalleeFunction();
if (!DeallocFn || DeallocFn->getName() != "swift_bufferDeallocateFromStack")
@@ -180,6 +186,8 @@ devirtualizeReleaseOfBuffer(SILInstruction *ReleaseInst,
bool ReleaseDevirtualizer::createDeinitCall(SILType AllocType,
SILInstruction *ReleaseInst,
SILValue object) {
DEBUG(llvm::dbgs() << " create deinit call\n");
ClassDecl *Cl = AllocType.getClassOrBoundGenericClass();
assert(Cl && "no class type allocated with alloc_ref");