Skip to content

Commit f7fb5a1

Browse files
authored
Merge pull request swiftlang#36874 from DougGregor/dynamic-data-race-actor-isolation
[Concurrency] Introduce runtime detection of data races.
2 parents 4793126 + b5e818b commit f7fb5a1

30 files changed

+550
-54
lines changed

docs/SIL.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3319,6 +3319,24 @@ lowered by the SIL pipeline, so that IR generation only operands of type
33193319

33203320
The operand is a guaranteed operand, i.e. not consumed.
33213321

3322+
extract_executor
3323+
```````````````
3324+
3325+
::
3326+
3327+
sil-instruction ::= 'extract_executor' sil-operand
3328+
3329+
%1 = extract_executor %0 : $T
3330+
// $T must be Builtin.Executor or conform to the Actor protocol
3331+
// %1 will be of type Builtin.Executor
3332+
3333+
Extracts the executor from the executor or actor operand. SIL generation
3334+
emits this instruction to produce executor values when needed (e.g.,
3335+
to provide to a runtime function). It will be lowered away by the SIL
3336+
pipeline.
3337+
3338+
The operand is a guaranteed operand, i.e. not consumed.
3339+
33223340
dealloc_stack
33233341
`````````````
33243342
::

include/swift/Runtime/Concurrency.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,13 @@ AsyncTask *swift_task_getCurrent(void);
577577
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
578578
ExecutorRef swift_task_getCurrentExecutor(void);
579579

580+
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
581+
bool swift_task_isCurrentExecutor(ExecutorRef executor);
582+
583+
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
584+
void swift_task_reportUnexpectedExecutor(
585+
const unsigned char *file, uintptr_t fileLength, bool fileIsASCII,
586+
uintptr_t line, ExecutorRef executor);
580587
}
581588

582589
#pragma clang diagnostic pop

include/swift/SIL/SILBuilder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2168,6 +2168,13 @@ class SILBuilder {
21682168
Actor, hasOwnership()));
21692169
}
21702170

2171+
ExtractExecutorInst *createExtractExecutor(SILLocation Loc, SILValue Actor) {
2172+
auto resultType = SILType::getPrimitiveObjectType(getASTContext().TheExecutorType);
2173+
return insert(new (getModule()) ExtractExecutorInst(getSILDebugLocation(Loc),
2174+
Actor, hasOwnership(),
2175+
resultType));
2176+
}
2177+
21712178
//===--------------------------------------------------------------------===//
21722179
// Terminator SILInstruction Creation Methods
21732180
//===--------------------------------------------------------------------===//

include/swift/SIL/SILCloner.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3056,6 +3056,15 @@ ::visitHopToExecutorInst(HopToExecutorInst *Inst) {
30563056
getOpValue(Inst->getTargetExecutor())));
30573057
}
30583058

3059+
template <typename ImplClass>
3060+
void SILCloner<ImplClass>
3061+
::visitExtractExecutorInst(ExtractExecutorInst *Inst) {
3062+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
3063+
recordClonedInstruction(Inst,
3064+
getBuilder().createExtractExecutor(
3065+
getOpLocation(Inst->getLoc()),
3066+
getOpValue(Inst->getExpectedExecutor())));
3067+
}
30593068

30603069
} // end namespace swift
30613070

include/swift/SIL/SILInstruction.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3468,6 +3468,21 @@ class HopToExecutorInst
34683468
SILValue getTargetExecutor() const { return getOperand(); }
34693469
};
34703470

3471+
/// Extract the ex that the code is executing on the operand executor already.
3472+
class ExtractExecutorInst
3473+
: public UnaryInstructionBase<SILInstructionKind::ExtractExecutorInst,
3474+
SingleValueInstruction>
3475+
{
3476+
friend SILBuilder;
3477+
3478+
ExtractExecutorInst(SILDebugLocation debugLoc, SILValue executor,
3479+
bool hasOwnership, SILType Ty)
3480+
: UnaryInstructionBase(debugLoc, executor, Ty) { }
3481+
3482+
public:
3483+
SILValue getExpectedExecutor() const { return getOperand(); }
3484+
};
3485+
34713486
/// Instantiates a key path object.
34723487
class KeyPathInst final
34733488
: public InstructionBase<SILInstructionKind::KeyPathInst,

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,8 @@ NON_VALUE_INST(FixLifetimeInst, fix_lifetime,
831831

832832
NON_VALUE_INST(HopToExecutorInst, hop_to_executor,
833833
SILInstruction, MayHaveSideEffects, DoesNotRelease)
834+
SINGLE_VALUE_INST(ExtractExecutorInst, extract_executor,
835+
SILInstruction, MayRead, DoesNotRelease)
834836

835837
NON_VALUE_INST(DestroyValueInst, destroy_value,
836838
SILInstruction, MayHaveSideEffects, MayRelease)

lib/IRGen/IRGenSIL.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,6 +1329,9 @@ class IRGenSILFunction :
13291329
void visitAwaitAsyncContinuationInst(AwaitAsyncContinuationInst *i);
13301330

13311331
void visitHopToExecutorInst(HopToExecutorInst *i);
1332+
void visitExtractExecutorInst(ExtractExecutorInst *i) {
1333+
llvm_unreachable("extract_executor should never be seen in Lowered SIL");
1334+
}
13321335

13331336
void visitKeyPathInst(KeyPathInst *I);
13341337

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ OPERAND_OWNERSHIP(InteriorPointer, RefTailAddr)
254254
OPERAND_OWNERSHIP(InteriorPointer, OpenExistentialBox)
255255
// FIXME: HopToExecutorInst should be an instantaneous use.
256256
OPERAND_OWNERSHIP(InteriorPointer, HopToExecutor)
257+
OPERAND_OWNERSHIP(InteriorPointer, ExtractExecutor)
257258

258259
// Instructions that propagate a value value within a borrow scope.
259260
OPERAND_OWNERSHIP(ForwardingBorrow, TupleExtract)

lib/SIL/IR/SILPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,6 +2145,10 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
21452145
*this << getIDAndType(HTEI->getTargetExecutor());
21462146
}
21472147

2148+
void visitExtractExecutorInst(ExtractExecutorInst *AEI) {
2149+
*this << getIDAndType(AEI->getExpectedExecutor());
2150+
}
2151+
21482152
void visitSwitchValueInst(SwitchValueInst *SII) {
21492153
*this << getIDAndType(SII->getOperand());
21502154
for (unsigned i = 0, e = SII->getNumCases(); i < e; ++i) {

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ CONSTANT_OWNERSHIP_INST(Unowned, ValueToBridgeObject)
151151
CONSTANT_OWNERSHIP_INST(None, GetAsyncContinuation)
152152
CONSTANT_OWNERSHIP_INST(None, GetAsyncContinuationAddr)
153153
CONSTANT_OWNERSHIP_INST(None, ThinToThickFunction)
154+
CONSTANT_OWNERSHIP_INST(None, ExtractExecutor)
155+
154156
#undef CONSTANT_OWNERSHIP_INST
155157

156158
#define CONSTANT_OR_NONE_OWNERSHIP_INST(OWNERSHIP, INST) \

0 commit comments

Comments
 (0)