Skip to content

Commit e9c7f3c

Browse files
authored
[Distributed] Target identifiers for protocol calls (#70928)
1 parent 9eb9a2e commit e9c7f3c

File tree

58 files changed

+1304
-250
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1304
-250
lines changed

include/swift/ABI/Metadata.h

+18-1
Original file line numberDiff line numberDiff line change
@@ -4970,7 +4970,7 @@ class DynamicReplacementScope
49704970
/// and then called through a fully-abstracted entry point whose arguments
49714971
/// can be constructed in code.
49724972
template <typename Runtime>
4973-
struct TargetAccessibleFunctionRecord final {
4973+
struct TargetAccessibleFunctionRecord {
49744974
public:
49754975
/// The name of the function, which is a unique string assigned to the
49764976
/// function so it can be looked up later.
@@ -4992,7 +4992,24 @@ struct TargetAccessibleFunctionRecord final {
49924992
AccessibleFunctionFlags Flags;
49934993
};
49944994

4995+
/// More advanced than AccessibleFunctionRecord and contains Actor name
4996+
template <typename Runtime>
4997+
struct TargetAccessibleProtocolRequirementFunctionRecord
4998+
: public TargetAccessibleFunctionRecord<Runtime> {
4999+
public:
5000+
/// The concrete Actor type for this accessor.
5001+
RelativeDirectPointer<const char, /*nullable*/ false> ConcreteActorName;
5002+
5003+
/// The concrete witness method mangled name.
5004+
/// The record name for such record is the mangled name of the protocol
5005+
/// method. This is the mangled name of the concrete witness method.
5006+
RelativeDirectPointer<const char, /*nullable*/ false>
5007+
ConcreteWitnessMethodName;
5008+
};
5009+
49955010
using AccessibleFunctionRecord = TargetAccessibleFunctionRecord<InProcess>;
5011+
using AccessibleProtocolRequirementFunctionRecord =
5012+
TargetAccessibleProtocolRequirementFunctionRecord<InProcess>;
49965013

49975014
enum class PackLifetime : uint8_t {
49985015
OnStack = 0,

include/swift/ABI/MetadataValues.h

+2
Original file line numberDiff line numberDiff line change
@@ -1574,6 +1574,8 @@ namespace SpecialPointerAuthDiscriminators {
15741574

15751575
/// Functions accessible at runtime (i.e. distributed method accessors).
15761576
const uint16_t AccessibleFunctionRecord = 0x438c; // = 17292
1577+
const uint16_t AccessibleProtocolRequirementFunctionRecord =
1578+
0xa98e; // = 43406
15771579

15781580
/// C type GetExtraInhabitantTag function descriminator
15791581
const uint16_t GetExtraInhabitantTagFunction = 0x392e; // = 14638

include/swift/AST/ASTMangler.h

+1
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ class ASTMangler : public Mangler {
159159
DistributedThunk,
160160
DistributedAccessor,
161161
AccessibleFunctionRecord,
162+
AccessibleProtocolRequirementFunctionRecord,
162163
BackDeploymentThunk,
163164
BackDeploymentFallback,
164165
HasSymbolQuery,

include/swift/AST/Attr.h

+22
Original file line numberDiff line numberDiff line change
@@ -2603,6 +2603,28 @@ class RawLayoutAttr final : public DeclAttribute {
26032603
}
26042604
};
26052605

2606+
/// The @_distributedThunkTarget(for:) attribute.
2607+
class DistributedThunkTargetAttr final
2608+
: public DeclAttribute {
2609+
2610+
AbstractFunctionDecl *TargetFunction;
2611+
2612+
public:
2613+
DistributedThunkTargetAttr(AbstractFunctionDecl *target)
2614+
: DeclAttribute(DeclAttrKind::DistributedThunkTarget, SourceLoc(),
2615+
SourceRange(),
2616+
/*Implicit=*/false),
2617+
TargetFunction(target) {}
2618+
2619+
AbstractFunctionDecl *getTargetFunction() const {
2620+
return TargetFunction;
2621+
}
2622+
2623+
static bool classof(const DeclAttribute *DA) {
2624+
return DA->getKind() == DeclAttrKind::DistributedThunkTarget;
2625+
}
2626+
};
2627+
26062628
/// Predicate used to filter MatchingAttributeRange.
26072629
template <typename ATTR, bool AllowInvalid> struct ToAttributeKind {
26082630
ToAttributeKind() {}

include/swift/AST/Decl.h

+15-6
Original file line numberDiff line numberDiff line change
@@ -2773,6 +2773,12 @@ class ValueDecl : public Decl {
27732773
Bits.ValueDecl.Synthesized = value;
27742774
}
27752775

2776+
/// Does this have a 'distributed' modifier?
2777+
///
2778+
/// Only member methods and computed properties of a `distributed actor`
2779+
/// can be distributed.
2780+
bool isDistributed() const;
2781+
27762782
bool hasName() const { return bool(Name); }
27772783
bool isOperator() const { return Name.isOperator(); }
27782784

@@ -5869,9 +5875,6 @@ class AbstractStorageDecl : public ValueDecl {
58695875

58705876
bool hasAnyNativeDynamicAccessors() const;
58715877

5872-
/// Does this have a 'distributed' modifier?
5873-
bool isDistributed() const;
5874-
58755878
/// Return a distributed thunk if this computed property is marked as
58765879
/// 'distributed' and and nullptr otherwise.
58775880
FuncDecl *getDistributedThunk() const;
@@ -7379,9 +7382,6 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
73797382
/// Returns if the function is 'rethrows' or 'reasync'.
73807383
bool hasPolymorphicEffect(EffectKind kind) const;
73817384

7382-
/// Returns 'true' if the function is distributed.
7383-
bool isDistributed() const;
7384-
73857385
/// Is this a thunk function used to access a distributed method
73867386
/// or computed property outside of its actor isolation context?
73877387
bool isDistributedThunk() const {
@@ -7528,6 +7528,15 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
75287528
getSILSynthesizeKind() == SILSynthesizeKind::DistributedActorFactory;
75297529
}
75307530

7531+
/// Return a vector of distributed requirements that this distributed method
7532+
/// is implementing.
7533+
///
7534+
/// If the method is witness to multiple requirements this is incorrect and
7535+
/// should be diagnosed during type-checking as it may make remoteCalls
7536+
/// ambiguous.
7537+
llvm::ArrayRef<ValueDecl *>
7538+
getDistributedMethodWitnessedProtocolRequirements() const;
7539+
75317540
/// Determines whether this function is a 'remoteCall' function,
75327541
/// which is used as ad-hoc protocol requirement by the
75337542
/// 'DistributedActorSystem' protocol.

include/swift/AST/DeclAttr.def

+4-1
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,10 @@ SIMPLE_DECL_ATTR(_noExistentials, NoExistentials,
485485
SIMPLE_DECL_ATTR(_noObjCBridging, NoObjCBridging,
486486
OnAbstractFunction | OnSubscript | UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
487487
155)
488-
LAST_DECL_ATTR(NoObjCBridging)
488+
DECL_ATTR(_distributedThunkTarget, DistributedThunkTarget,
489+
OnAbstractFunction | UserInaccessible | ABIStableToAdd | ABIBreakingToRemove | APIStableToAdd | APIStableToRemove,
490+
156)
491+
LAST_DECL_ATTR(DistributedThunkTarget)
489492

490493
#undef DECL_ATTR_ALIAS
491494
#undef CONTEXTUAL_DECL_ATTR_ALIAS

include/swift/AST/TypeCheckRequests.h

+21
Original file line numberDiff line numberDiff line change
@@ -1372,6 +1372,27 @@ class GetDistributedActorArgumentDecodingMethodRequest :
13721372
bool isCached() const { return true; }
13731373
};
13741374

1375+
/// Find out if a distributed method is implementing a distributed protocol
1376+
/// requirement.
1377+
class GetDistributedMethodWitnessedProtocolRequirements :
1378+
public SimpleRequest<GetDistributedMethodWitnessedProtocolRequirements,
1379+
llvm::ArrayRef<ValueDecl *> (AbstractFunctionDecl *),
1380+
RequestFlags::Cached> {
1381+
public:
1382+
using SimpleRequest::SimpleRequest;
1383+
1384+
private:
1385+
friend SimpleRequest;
1386+
1387+
llvm::ArrayRef<ValueDecl *> evaluate(
1388+
Evaluator &evaluator,
1389+
AbstractFunctionDecl *nominal) const;
1390+
1391+
public:
1392+
// Caching
1393+
bool isCached() const { return true; }
1394+
};
1395+
13751396
/// Retrieve the static "shared" property within a global actor that provides
13761397
/// the actor instance representing the global actor.
13771398
///

include/swift/AST/TypeCheckerTypeIDZone.def

+3
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ SWIFT_REQUEST(TypeChecker, GetDistributedActorSystemPropertyRequest,
150150
SWIFT_REQUEST(TypeChecker, GetDistributedRemoteCallTargetInitFunctionRequest,
151151
ConstructorDecl *(NominalTypeDecl *),
152152
Cached, NoLocationInfo)
153+
SWIFT_REQUEST(TypeChecker, GetDistributedMethodWitnessedProtocolRequirements,
154+
ArrayRef<ValueDecl *> (AbstractFunctionDecl *),
155+
Cached, NoLocationInfo)
153156
SWIFT_REQUEST(TypeChecker, GetDistributedRemoteCallArgumentInitFunctionRequest,
154157
ConstructorDecl *(NominalTypeDecl *),
155158
Cached, NoLocationInfo)

include/swift/Demangling/DemangleNodes.def

+3
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,9 @@ NODE(AsyncSuspendResumePartialFunction)
358358
NODE(AccessibleFunctionRecord)
359359
NODE(CompileTimeConst)
360360

361+
// Added in Swift 5.11
362+
NODE(AccessibleProtocolRequirementFunctionRecord)
363+
361364
// Added in Swift 5.7
362365
NODE(BackDeploymentThunk)
363366
NODE(BackDeploymentFallback)

include/swift/IRGen/Linking.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,8 @@ class LinkEntity {
382382
/// A SIL global variable. The pointer is a SILGlobalVariable*.
383383
SILGlobalVariable,
384384

385-
/// An outlined read-only global object. The pointer is a SILGlobalVariable*.
385+
/// An outlined read-only global object. The pointer is a
386+
/// SILGlobalVariable*.
386387
ReadOnlyGlobalObject,
387388

388389
// These next few are protocol-conformance kinds.
@@ -513,13 +514,15 @@ class LinkEntity {
513514

514515
/// The pointer is SILFunction*
515516
DistributedAccessor,
516-
/// An async function pointer for a distributed accessor (method or property).
517+
/// An async function pointer for a distributed accessor (method or
518+
/// property).
517519
/// The pointer is a SILFunction*.
518520
DistributedAccessorAsyncPointer,
519521

520522
/// Accessible function record, which describes a function that can be
521523
/// looked up by name by the runtime.
522524
AccessibleFunctionRecord,
525+
AccessibleProtocolRequirementFunctionRecord,
523526

524527
/// Extended existential type shape.
525528
/// Pointer is the (generalized) existential type.

include/swift/RemoteInspection/RuntimeHeaders/llvm/BinaryFormat/Swift.def

+2
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ HANDLE_SWIFT_SECTION(protocs, "__swift5_protos", "swift5_protocols",
3030
".sw5prt$B")
3131
HANDLE_SWIFT_SECTION(acfuncs, "__swift5_acfuncs", "swift5_accessible_functions",
3232
".sw5acfn$B")
33+
HANDLE_SWIFT_SECTION(dacfuncs, "__swift5_acpfuns", "swift5_accessible_protocol_requirement_functions",
34+
".sw5acpfn$B")
3335
HANDLE_SWIFT_SECTION(mpenum, "__swift5_mpenum", "swift5_mpenum", ".sw5mpen$B")

include/swift/Runtime/AccessibleFunction.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,17 @@
2424
namespace swift {
2525
namespace runtime {
2626

27-
SWIFT_RUNTIME_STDLIB_SPI const AccessibleFunctionRecord *
27+
SWIFT_RUNTIME_STDLIB_SPI
28+
const AccessibleFunctionRecord *swift_findAccessibleFunctionForConcreteType(
29+
bool findConcreteWitness,
30+
// concrete target type, when performing a protocol method call
31+
const char *targetActorTypeNameStart, size_t targetActorTypeNameLength,
32+
// method (concrete method name, or protocol method name)
33+
const char *targetNameStart, size_t targetNameLength);
34+
35+
// DEPRECATED: Prefer 'swift_findAccessibleFunctionForConcreteType'
36+
SWIFT_RUNTIME_STDLIB_SPI
37+
const AccessibleFunctionRecord *
2838
swift_findAccessibleFunction(const char *targetNameStart,
2939
size_t targetNameLength);
3040

include/swift/Runtime/Config.h

+5
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,10 @@ extern uintptr_t __COMPATIBILITY_LIBRARIES_CANNOT_CHECK_THE_IS_SWIFT_BIT_DIRECTL
307307
#define __ptrauth_swift_accessible_function_record \
308308
__ptrauth(ptrauth_key_process_independent_data, 1, \
309309
SpecialPointerAuthDiscriminators::AccessibleFunctionRecord)
310+
#define __ptrauth_swift_accessible_protocol_requirement_function_record \
311+
__ptrauth(ptrauth_key_process_independent_data, 1, \
312+
SpecialPointerAuthDiscriminators:: \
313+
AccessibleProtocolRequirementFunctionRecord)
310314
#define __ptrauth_swift_objc_superclass \
311315
__ptrauth(ptrauth_key_process_independent_data, 1, \
312316
swift::SpecialPointerAuthDiscriminators::ObjCSuperclass)
@@ -355,6 +359,7 @@ extern uintptr_t __COMPATIBILITY_LIBRARIES_CANNOT_CHECK_THE_IS_SWIFT_BIT_DIRECTL
355359
#define __ptrauth_swift_escalation_notification_function
356360
#define __ptrauth_swift_dispatch_invoke_function
357361
#define __ptrauth_swift_accessible_function_record
362+
#define __ptrauth_swift_accessible_protocol_requirement_function_record
358363
#define __ptrauth_swift_objc_superclass
359364
#define __ptrauth_swift_runtime_function_entry
360365
#define __ptrauth_swift_runtime_function_entry_with_key(__key)

lib/AST/ASTMangler.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,8 @@ void ASTMangler::appendSymbolKind(SymbolKind SKind) {
922922
case SymbolKind::DistributedThunk: return appendOperator("TE");
923923
case SymbolKind::DistributedAccessor: return appendOperator("TF");
924924
case SymbolKind::AccessibleFunctionRecord: return appendOperator("HF");
925+
case SymbolKind::AccessibleProtocolRequirementFunctionRecord:
926+
return appendOperator("HpF");
925927
case SymbolKind::BackDeploymentThunk: return appendOperator("Twb");
926928
case SymbolKind::BackDeploymentFallback: return appendOperator("TwB");
927929
case SymbolKind::HasSymbolQuery: return appendOperator("TwS");

lib/AST/Attr.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -1898,6 +1898,8 @@ StringRef DeclAttribute::getAttrName() const {
18981898
return "_section";
18991899
case DeclAttrKind::Documentation:
19001900
return "_documentation";
1901+
case DeclAttrKind::DistributedThunkTarget:
1902+
return "_distributedThunkTarget";
19011903
case DeclAttrKind::Nonisolated:
19021904
if (cast<NonisolatedAttr>(this)->isUnsafe()) {
19031905
return "nonisolated(unsafe)";

lib/AST/Decl.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -11349,7 +11349,8 @@ ActorIsolation::forActorInstanceSelf(ValueDecl *decl) {
1134911349
}
1135011350

1135111351
NominalTypeDecl *ActorIsolation::getActor() const {
11352-
assert(getKind() == ActorInstance);
11352+
assert(getKind() == ActorInstance ||
11353+
getKind() == GlobalActor);
1135311354

1135411355
if (silParsed)
1135511356
return nullptr;

lib/AST/DistributedDecl.cpp

+30-10
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,20 @@ using namespace swift;
6565
/******************************************************************************/
6666

6767
// TODO(distributed): make into a request
68-
Type swift::getConcreteReplacementForProtocolActorSystemType(ValueDecl *member) {
69-
auto &C = member->getASTContext();
70-
auto *DC = member->getDeclContext();
68+
Type swift::getConcreteReplacementForProtocolActorSystemType(
69+
ValueDecl *anyValue) {
70+
auto &C = anyValue->getASTContext();
71+
72+
// FIXME(distributed): clean this up, we want a method that gets us AS type
73+
// given any value, but is this the best way?
74+
DeclContext *DC;
75+
if (auto nominal = dyn_cast<NominalTypeDecl>(anyValue)) {
76+
DC = nominal;
77+
} else if (auto extension = dyn_cast<ExtensionDecl>(anyValue)) {
78+
DC = extension->getExtendedNominal();
79+
} else {
80+
DC = anyValue->getDeclContext();
81+
}
7182
auto DA = C.getDistributedActorDecl();
7283

7384
// === When declared inside an actor, we can get the type directly
@@ -78,7 +89,7 @@ Type swift::getConcreteReplacementForProtocolActorSystemType(ValueDecl *member)
7889
/// === Maybe the value is declared in a protocol?
7990
if (auto protocol = DC->getSelfProtocolDecl()) {
8091
GenericSignature signature;
81-
if (auto *genericContext = member->getAsGenericContext()) {
92+
if (auto *genericContext = anyValue->getAsGenericContext()) {
8293
signature = genericContext->getGenericSignature();
8394
} else {
8495
signature = DC->getGenericSignatureOfContext();
@@ -312,7 +323,6 @@ Type ASTContext::getAssociatedTypeOfDistributedSystemOfActor(
312323
/******** Functions on DistributedActorSystem and friends *********************/
313324
/******************************************************************************/
314325

315-
316326
FuncDecl*
317327
ASTContext::getDistributedActorArgumentDecodingMethod(NominalTypeDecl *actor) {
318328
if (!actor->isDistributedActor())
@@ -380,6 +390,20 @@ bool swift::checkDistributedSerializationRequirementIsExactlyCodable(
380390
std::count(protocols.begin(), protocols.end(), decodable) == 1;
381391
}
382392

393+
llvm::ArrayRef<ValueDecl *>
394+
AbstractFunctionDecl::getDistributedMethodWitnessedProtocolRequirements() const {
395+
auto mutableThis = const_cast<AbstractFunctionDecl *>(this);
396+
397+
// Only a 'distributed' decl can witness 'distributed' protocol
398+
if (!isDistributed()) {
399+
return llvm::ArrayRef<ValueDecl *>();
400+
}
401+
402+
return evaluateOrDefault(
403+
getASTContext().evaluator,
404+
GetDistributedMethodWitnessedProtocolRequirements(mutableThis), {});
405+
}
406+
383407
/******************************************************************************/
384408
/********************* Ad-hoc protocol requirement checks *********************/
385409
/******************************************************************************/
@@ -1257,11 +1281,7 @@ AbstractFunctionDecl::isDistributedTargetInvocationResultHandlerOnReturn() const
12571281
/********************** Distributed Functions *********************************/
12581282
/******************************************************************************/
12591283

1260-
bool AbstractFunctionDecl::isDistributed() const {
1261-
return getAttrs().hasAttribute<DistributedActorAttr>();
1262-
}
1263-
1264-
bool AbstractStorageDecl::isDistributed() const {
1284+
bool ValueDecl::isDistributed() const {
12651285
return getAttrs().hasAttribute<DistributedActorAttr>();
12661286
}
12671287

lib/ASTGen/Sources/ASTGen/DeclAttrs.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,8 @@ extension ASTGenVisitor {
253253
.usableFromInline,
254254
.used,
255255
.warnUnqualifiedAccess,
256-
.weakLinked:
256+
.weakLinked,
257+
.distributedThunkTarget:
257258

258259
return self.generateSimpleDeclAttr(attribute: node, kind: attrKind)
259260

lib/Demangling/NodePrinter.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ class NodePrinter {
630630
case Node::Kind::AsyncAwaitResumePartialFunction:
631631
case Node::Kind::AsyncSuspendResumePartialFunction:
632632
case Node::Kind::AccessibleFunctionRecord:
633+
case Node::Kind::AccessibleProtocolRequirementFunctionRecord:
633634
case Node::Kind::BackDeploymentThunk:
634635
case Node::Kind::BackDeploymentFallback:
635636
case Node::Kind::ExtendedExistentialTypeShape:
@@ -2294,6 +2295,11 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
22942295
Printer << "accessible function runtime record for ";
22952296
}
22962297
return nullptr;
2298+
case Node::Kind::AccessibleProtocolRequirementFunctionRecord:
2299+
if (!Options.ShortenThunk) {
2300+
Printer << "accessible distributed function runtime record for ";
2301+
}
2302+
return nullptr;
22972303
case Node::Kind::DynamicallyReplaceableFunctionKey:
22982304
if (!Options.ShortenThunk) {
22992305
Printer << "dynamically replaceable key for ";

0 commit comments

Comments
 (0)