Skip to content

Commit 32d1627

Browse files
committed
Merge pull request #1696 from eeckstein/fix_release_devirtualizer
Fix release devirtualizer
2 parents 3ad269d + bf87de3 commit 32d1627

File tree

28 files changed

+409
-40
lines changed

28 files changed

+409
-40
lines changed

docs/Runtime.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ Returns a random number. Only used by allocation profiling tools.
160160
000000000002b290 T _swift_isUniquelyReferencedOrPinned_nonNull_native
161161
000000000002af00 T _swift_isUniquelyReferenced_native
162162
000000000002aea0 T _swift_isUniquelyReferenced_nonNull_native
163+
00000000000????? T _swift_setDeallocating
163164
000000000001d280 T _swift_isDeallocating
164165
```
165166

docs/SIL.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2300,6 +2300,21 @@ zero, the object is destroyed and ``@weak`` references are cleared. When both
23002300
its strong and unowned reference counts reach zero, the object's memory is
23012301
deallocated.
23022302

2303+
set_deallocating
2304+
````````````````
2305+
::
2306+
2307+
set_deallocating %0 : $T
2308+
// $T must be a reference type.
2309+
2310+
Explicitly sets the state of the object referenced by ``%0`` to deallocated.
2311+
This is the same operation what's done by a strong_release immediately before
2312+
it calls the deallocator of the object.
2313+
2314+
It is expected that the strong reference count of the object is one.
2315+
Furthermore, no other thread may increment the strong reference count during
2316+
execution of this instruction.
2317+
23032318
strong_retain_unowned
23042319
`````````````````````
23052320
::

include/swift/Runtime/HeapObject.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,12 @@ SWIFT_RUNTIME_EXPORT
292292
extern "C" void (*SWIFT_CC(RegisterPreservingCC)
293293
_swift_release_n)(HeapObject *object, uint32_t n);
294294

295+
/// Sets the RC_DEALLOCATING_FLAG flag. This is done non-atomically.
296+
/// The strong reference count of \p object must be 1 and no other thread may
297+
/// retain the object during executing this function.
298+
SWIFT_RUNTIME_EXPORT
299+
extern "C" void swift_setDeallocating(HeapObject *object);
300+
295301
// Refcounting observation hooks for memory tools. Don't use these.
296302
SWIFT_RUNTIME_EXPORT
297303
extern "C" size_t swift_retainCount(HeapObject *object);

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,13 @@ FUNCTION_WITH_GLOBAL_SYMBOL_AND_IMPL(NativeStrongReleaseN, swift_release_n,
167167
ARGS(RefCountedPtrTy, Int32Ty),
168168
ATTRS(NoUnwind))
169169

170+
// void swift_setDeallocating(void *ptr);
171+
FUNCTION(NativeSetDeallocating, swift_setDeallocating,
172+
DefaultCC,
173+
RETURNS(VoidTy),
174+
ARGS(RefCountedPtrTy),
175+
ATTRS(NoUnwind))
176+
170177
// void swift_unknownRetain_n(void *ptr, int32_t n);
171178
FUNCTION(UnknownRetainN, swift_unknownRetain_n,
172179
DefaultCC,

include/swift/SIL/SILBuilder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,12 @@ class SILBuilder {
674674
getSILDebugLocation(Loc), operand));
675675
}
676676

677+
SetDeallocatingInst *createSetDeallocating(SILLocation Loc,
678+
SILValue operand) {
679+
return insert(new (F.getModule()) SetDeallocatingInst(
680+
getSILDebugLocation(Loc), operand));
681+
}
682+
677683
StructInst *createStruct(SILLocation Loc, SILType Ty,
678684
ArrayRef<SILValue> Elements) {
679685
return insert(

include/swift/SIL/SILCloner.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,15 @@ SILCloner<ImplClass>::visitAutoreleaseValueInst(AutoreleaseValueInst *Inst) {
10501050
getOpValue(Inst->getOperand())));
10511051
}
10521052

1053+
template<typename ImplClass>
1054+
void
1055+
SILCloner<ImplClass>::visitSetDeallocatingInst(SetDeallocatingInst *Inst) {
1056+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1057+
doPostProcess(Inst,
1058+
getBuilder().createSetDeallocating(getOpLocation(Inst->getLoc()),
1059+
getOpValue(Inst->getOperand())));
1060+
}
1061+
10531062
template<typename ImplClass>
10541063
void
10551064
SILCloner<ImplClass>::visitStructInst(StructInst *Inst) {

include/swift/SIL/SILInstruction.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2322,6 +2322,20 @@ class AutoreleaseValueInst
23222322
: UnaryInstructionBase(DebugLoc, operand) {}
23232323
};
23242324

2325+
/// SetDeallocatingInst - Sets the operand in deallocating state.
2326+
///
2327+
/// This is the same operation what's done by a strong_release immediately
2328+
/// before it calls the deallocator of the object.
2329+
class SetDeallocatingInst
2330+
: public UnaryInstructionBase<ValueKind::SetDeallocatingInst,
2331+
RefCountingInst,
2332+
/*HasValue*/ false> {
2333+
friend class SILBuilder;
2334+
2335+
SetDeallocatingInst(SILDebugLocation DebugLoc, SILValue operand)
2336+
: UnaryInstructionBase(DebugLoc, operand) {}
2337+
};
2338+
23252339
/// StrongPinInst - Ensure that the operand is retained and pinned, if
23262340
/// not by this operation then by some enclosing pin.
23272341
///

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ ABSTRACT_VALUE(SILInstruction, ValueBase)
123123
MayRelease)
124124
INST(RetainValueInst, RefCountingInst, MayHaveSideEffects, DoesNotRelease)
125125
INST(ReleaseValueInst, RefCountingInst, MayHaveSideEffects, MayRelease)
126+
INST(SetDeallocatingInst, RefCountingInst, MayHaveSideEffects,
127+
DoesNotRelease)
126128
INST(AutoreleaseValueInst, RefCountingInst, MayHaveSideEffects,
127129
DoesNotRelease)
128130
VALUE_RANGE(RefCountingInst, StrongRetainInst, AutoreleaseValueInst)

include/swift/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
5454
/// describe what change you made. The content of this comment isn't important;
5555
/// it just ensures a conflict if two people change the module format.
5656
/// describe what change you made.
57-
const uint16_t VERSION_MINOR = 240; // Last change: @_cdecl
57+
const uint16_t VERSION_MINOR = 241; // Last change: set_deallocating instruction
5858

5959
using DeclID = PointerEmbeddedInt<unsigned, 31>;
6060
using DeclIDField = BCFixed<31>;

lib/IRGen/GenHeap.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,11 @@ void IRGenFunction::emitNativeStrongRelease(llvm::Value *value) {
11121112
emitUnaryRefCountCall(*this, IGM.getNativeStrongReleaseFn(), value);
11131113
}
11141114

1115+
void IRGenFunction::emitNativeSetDeallocating(llvm::Value *value) {
1116+
if (doesNotRequireRefCounting(value)) return;
1117+
emitUnaryRefCountCall(*this, IGM.getNativeSetDeallocatingFn(), value);
1118+
}
1119+
11151120
void IRGenFunction::emitNativeUnownedInit(llvm::Value *value,
11161121
Address dest) {
11171122
dest = Builder.CreateStructGEP(dest, 0, Size(0));

0 commit comments

Comments
 (0)