Skip to content

Commit 9965df7

Browse files
authored
Merge pull request #40270 from xedin/thunks-for-dist-methods
[Distributed] Implement distributed method accessors
2 parents c4e8844 + d6d9b55 commit 9965df7

File tree

70 files changed

+2186
-91
lines changed

Some content is hidden

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

70 files changed

+2186
-91
lines changed

docs/ABI/Mangling.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ Globals
143143
global ::= opaque-type 'Ho' // opaque type descriptor runtime record
144144
#endif
145145
global ::= protocol-conformance 'Hc' // protocol conformance runtime record
146+
global ::= global 'HF' // accessible function runtime record
146147

147148
global ::= nominal-type 'Mo' // class metadata immediate member base offset
148149

@@ -218,6 +219,7 @@ types where the metadata itself has unknown layout.)
218219
global ::= global 'TD' // dynamic dispatch thunk
219220
global ::= global 'Td' // direct method reference thunk
220221
global ::= global 'TE' // distributed actor thunk
222+
global ::= global 'TF' // distributed method accessor
221223
global ::= global 'TI' // implementation of a dynamic_replaceable function
222224
global ::= global 'Tu' // async function pointer of a function
223225
global ::= global 'TX' // function pointer of a dynamic_replaceable function

include/swift/ABI/Metadata.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5036,6 +5036,30 @@ class DynamicReplacementScope
50365036
uint32_t getFlags() { return flags; }
50375037
};
50385038

5039+
/// An "accessible" function that can be looked up based on a string key,
5040+
/// and then called through a fully-abstracted entry point whose arguments
5041+
/// can be constructed in code.
5042+
template <typename Runtime>
5043+
struct TargetAccessibleFunctionRecord final {
5044+
public:
5045+
/// The name of the function, which is a unique string assigned to the
5046+
/// function so it can be looked up later.
5047+
RelativeDirectPointer<const char, /*nullable*/ false> Name;
5048+
5049+
/// The Swift function type, encoded as a mangled name.
5050+
RelativeDirectPointer<const char, /*nullable*/ false> FunctionType;
5051+
5052+
/// The fully-abstracted function to call.
5053+
///
5054+
/// Could be a sync or async function pointer depending on flags.
5055+
RelativeDirectPointer<void *, /*nullable*/ false> Function;
5056+
5057+
/// Flags providing more information about the function.
5058+
AccessibleFunctionFlags Flags;
5059+
};
5060+
5061+
using AccessibleFunctionRecord = TargetAccessibleFunctionRecord<InProcess>;
5062+
50395063
} // end namespace swift
50405064

50415065
#pragma clang diagnostic pop

include/swift/ABI/MetadataValues.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2312,6 +2312,21 @@ enum class ContinuationStatus : size_t {
23122312
Resumed = 2
23132313
};
23142314

2315+
/// Flags that go in a TargetAccessibleFunction structure.
2316+
class AccessibleFunctionFlags : public FlagSet<uint32_t> {
2317+
public:
2318+
enum {
2319+
/// Whether this is a "distributed" actor function.
2320+
Distributed = 0,
2321+
};
2322+
2323+
explicit AccessibleFunctionFlags(uint32_t bits) : FlagSet(bits) {}
2324+
constexpr AccessibleFunctionFlags() {}
2325+
2326+
/// Whether the this is a "distributed" actor function.
2327+
FLAGSET_DEFINE_FLAG_ACCESSORS(Distributed, isDistributed, setDistributed)
2328+
};
2329+
23152330
} // end namespace swift
23162331

23172332
#endif // SWIFT_ABI_METADATAVALUES_H

include/swift/AST/ASTMangler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ class ASTMangler : public Mangler {
104104
SwiftAsObjCThunk,
105105
ObjCAsSwiftThunk,
106106
DistributedThunk,
107+
DistributedMethodAccessor,
108+
AccessibleFunctionRecord
107109
};
108110

109111
ASTMangler(bool DWARFMangling = false)

include/swift/Demangling/DemangleNodes.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ CONTEXT_NODE(Destructor)
7171
CONTEXT_NODE(DidSet)
7272
NODE(Directness)
7373
NODE(DistributedThunk)
74+
NODE(DistributedMethodAccessor)
7475
NODE(DynamicAttribute)
7576
NODE(DirectMethodReferenceAttribute)
7677
NODE(DynamicSelf)
@@ -325,5 +326,8 @@ NODE(IndexSubset)
325326
NODE(AsyncAwaitResumePartialFunction)
326327
NODE(AsyncSuspendResumePartialFunction)
327328

329+
// Added in Swift 5.6
330+
NODE(AccessibleFunctionRecord)
331+
328332
#undef CONTEXT_NODE
329333
#undef NODE

include/swift/IRGen/Linking.h

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,16 @@ class LinkEntity {
481481
/// name is known.
482482
/// The pointer is a const char* of the name.
483483
KnownAsyncFunctionPointer,
484+
485+
/// The pointer is SILFunction*
486+
DistributedMethodAccessor,
487+
/// An async function pointer for a distributed method accessor.
488+
/// The pointer is a SILFunction*.
489+
DistributedMethodAccessorAsyncPointer,
490+
491+
/// Accessible function record, which describes a function that can be
492+
/// looked up by name by the runtime.
493+
AccessibleFunctionRecord,
484494
};
485495
friend struct llvm::DenseMapInfo<LinkEntity>;
486496

@@ -1236,6 +1246,13 @@ class LinkEntity {
12361246
Kind, unsigned(LinkEntity::Kind::PartialApplyForwarderAsyncFunctionPointer));
12371247
break;
12381248

1249+
case LinkEntity::Kind::DistributedMethodAccessor: {
1250+
entity.Data = LINKENTITY_SET_FIELD(
1251+
Kind,
1252+
unsigned(LinkEntity::Kind::DistributedMethodAccessorAsyncPointer));
1253+
break;
1254+
}
1255+
12391256
default:
12401257
llvm_unreachable("Link entity kind cannot have an async function pointer");
12411258
}
@@ -1263,6 +1280,24 @@ class LinkEntity {
12631280
return entity;
12641281
}
12651282

1283+
static LinkEntity forDistributedMethodAccessor(SILFunction *method) {
1284+
LinkEntity entity;
1285+
entity.Pointer = method;
1286+
entity.SecondaryPointer = nullptr;
1287+
entity.Data =
1288+
LINKENTITY_SET_FIELD(Kind, unsigned(Kind::DistributedMethodAccessor));
1289+
return entity;
1290+
}
1291+
1292+
static LinkEntity forAccessibleFunctionRecord(SILFunction *func) {
1293+
LinkEntity entity;
1294+
entity.Pointer = func;
1295+
entity.SecondaryPointer = nullptr;
1296+
entity.Data =
1297+
LINKENTITY_SET_FIELD(Kind, unsigned(Kind::AccessibleFunctionRecord));
1298+
return entity;
1299+
}
1300+
12661301
LinkEntity getUnderlyingEntityForAsyncFunctionPointer() const {
12671302
LinkEntity entity;
12681303
entity.Pointer = Pointer;
@@ -1294,6 +1329,11 @@ class LinkEntity {
12941329
Kind, unsigned(LinkEntity::Kind::PartialApplyForwarder));
12951330
break;
12961331

1332+
case LinkEntity::Kind::DistributedMethodAccessorAsyncPointer:
1333+
entity.Data = LINKENTITY_SET_FIELD(
1334+
Kind, unsigned(LinkEntity::Kind::DistributedMethodAccessor));
1335+
break;
1336+
12971337
default:
12981338
llvm_unreachable("Link entity is not an async function pointer");
12991339
}
@@ -1341,7 +1381,9 @@ class LinkEntity {
13411381
return getKind() == Kind::AsyncFunctionPointer ||
13421382
getKind() == Kind::DynamicallyReplaceableFunctionVariable ||
13431383
getKind() == Kind::DynamicallyReplaceableFunctionKey ||
1344-
getKind() == Kind::SILFunction;
1384+
getKind() == Kind::SILFunction ||
1385+
getKind() == Kind::DistributedMethodAccessor ||
1386+
getKind() == Kind::AccessibleFunctionRecord;
13451387
}
13461388

13471389
SILFunction *getSILFunction() const {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===---- AcceesibleFunction.h - Runtime accessible functions ---*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// The runtime interface for functions accessible by name.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_RUNTIME_ACCESSIBLE_FUNCTION_H
18+
#define SWIFT_RUNTIME_ACCESSIBLE_FUNCTION_H
19+
20+
#include "swift/ABI/Metadata.h"
21+
22+
#include <cstdint>
23+
24+
namespace swift {
25+
namespace runtime {
26+
27+
SWIFT_RUNTIME_STDLIB_SPI const AccessibleFunctionRecord *
28+
swift_findAccessibleFunction(const char *targetNameStart,
29+
size_t targetNameLength);
30+
31+
} // end namespace runtime
32+
} // end namespace swift
33+
34+
#endif

include/swift/SIL/SILFunction.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ enum IsExactSelfClass_t {
5959
IsNotExactSelfClass,
6060
IsExactSelfClass,
6161
};
62+
enum IsDistributed_t {
63+
IsNotDistributed,
64+
IsDistributed,
65+
};
6266

6367
enum class PerformanceConstraints : uint8_t {
6468
None = 0,
@@ -294,6 +298,9 @@ class SILFunction
294298
/// invoked with a `self` argument of the exact base class type.
295299
unsigned ExactSelfClass : 1;
296300

301+
/// Check whether this is a distributed method.
302+
unsigned IsDistributed : 1;
303+
297304
/// True if this function is inlined at least once. This means that the
298305
/// debug info keeps a pointer to this function.
299306
unsigned Inlined : 1;
@@ -373,14 +380,16 @@ class SILFunction
373380
SubclassScope classSubclassScope, Inline_t inlineStrategy,
374381
EffectsKind E, const SILDebugScope *debugScope,
375382
IsDynamicallyReplaceable_t isDynamic,
376-
IsExactSelfClass_t isExactSelfClass);
383+
IsExactSelfClass_t isExactSelfClass,
384+
IsDistributed_t isDistributed);
377385

378386
static SILFunction *
379387
create(SILModule &M, SILLinkage linkage, StringRef name,
380388
CanSILFunctionType loweredType, GenericEnvironment *genericEnv,
381389
Optional<SILLocation> loc, IsBare_t isBareSILFunction,
382390
IsTransparent_t isTrans, IsSerialized_t isSerialized,
383391
ProfileCounter entryCount, IsDynamicallyReplaceable_t isDynamic,
392+
IsDistributed_t isDistributed,
384393
IsExactSelfClass_t isExactSelfClass,
385394
IsThunk_t isThunk = IsNotThunk,
386395
SubclassScope classSubclassScope = SubclassScope::NotApplicable,
@@ -399,7 +408,8 @@ class SILFunction
399408
Inline_t inlineStrategy, EffectsKind E,
400409
const SILDebugScope *DebugScope,
401410
IsDynamicallyReplaceable_t isDynamic,
402-
IsExactSelfClass_t isExactSelfClass);
411+
IsExactSelfClass_t isExactSelfClass,
412+
IsDistributed_t isDistributed);
403413

404414
/// Set has ownership to the given value. True means that the function has
405415
/// ownership, false means it does not.
@@ -747,6 +757,14 @@ class SILFunction
747757
ExactSelfClass = t;
748758
}
749759

760+
IsDistributed_t isDistributed() const {
761+
return IsDistributed_t(IsDistributed);
762+
}
763+
void
764+
setIsDistributed(IsDistributed_t value = IsDistributed_t::IsDistributed) {
765+
IsDistributed = value;
766+
}
767+
750768
/// Get the DeclContext of this function.
751769
DeclContext *getDeclContext() const { return DeclCtxt; }
752770

include/swift/SIL/SILFunctionBuilder.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,16 @@ class SILFunctionBuilder {
6767
IsSerialized_t isSerialized,
6868
ProfileCounter entryCount,
6969
IsThunk_t isThunk,
70-
IsDynamicallyReplaceable_t isDynamic);
70+
IsDynamicallyReplaceable_t isDynamic,
71+
IsDistributed_t isDistributed);
7172

7273
/// Return the declaration of a function, or create it if it doesn't exist.
7374
SILFunction *getOrCreateFunction(
7475
SILLocation loc, StringRef name, SILLinkage linkage,
7576
CanSILFunctionType type, IsBare_t isBareSILFunction,
7677
IsTransparent_t isTransparent, IsSerialized_t isSerialized,
7778
IsDynamicallyReplaceable_t isDynamic,
79+
IsDistributed_t isDistributed,
7880
ProfileCounter entryCount = ProfileCounter(),
7981
IsThunk_t isThunk = IsNotThunk,
8082
SubclassScope subclassScope = SubclassScope::NotApplicable);
@@ -102,6 +104,7 @@ class SILFunctionBuilder {
102104
Optional<SILLocation> loc, IsBare_t isBareSILFunction,
103105
IsTransparent_t isTrans, IsSerialized_t isSerialized,
104106
IsDynamicallyReplaceable_t isDynamic,
107+
IsDistributed_t isDistributed,
105108
ProfileCounter entryCount = ProfileCounter(),
106109
IsThunk_t isThunk = IsNotThunk,
107110
SubclassScope subclassScope = SubclassScope::NotApplicable,

include/swift/SIL/TypeSubstCloner.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
446446
ParentFunction->getLocation(), MangledName, SILLinkage::Shared,
447447
ParentFunction->getLoweredFunctionType(), ParentFunction->isBare(),
448448
ParentFunction->isTransparent(), ParentFunction->isSerialized(),
449-
IsNotDynamic, 0, ParentFunction->isThunk(),
449+
IsNotDynamic, IsNotDistributed, 0, ParentFunction->isThunk(),
450450
ParentFunction->getClassSubclassScope());
451451
// Increment the ref count for the inlined function, so it doesn't
452452
// get deleted before we can emit abstract debug info for it.

lib/AST/ASTMangler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,8 @@ void ASTMangler::appendSymbolKind(SymbolKind SKind) {
849849
case SymbolKind::SwiftAsObjCThunk: return appendOperator("To");
850850
case SymbolKind::ObjCAsSwiftThunk: return appendOperator("TO");
851851
case SymbolKind::DistributedThunk: return appendOperator("TE");
852+
case SymbolKind::DistributedMethodAccessor: return appendOperator("TF");
853+
case SymbolKind::AccessibleFunctionRecord: return appendOperator("HF");
852854
}
853855
}
854856

lib/Demangling/Demangler.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,14 @@ bool swift::Demangle::isFunctionAttr(Node::Kind kind) {
133133
case Node::Kind::OutlinedBridgedMethod:
134134
case Node::Kind::MergedFunction:
135135
case Node::Kind::DistributedThunk:
136+
case Node::Kind::DistributedMethodAccessor:
136137
case Node::Kind::DynamicallyReplaceableFunctionImpl:
137138
case Node::Kind::DynamicallyReplaceableFunctionKey:
138139
case Node::Kind::DynamicallyReplaceableFunctionVar:
139140
case Node::Kind::AsyncFunctionPointer:
140141
case Node::Kind::AsyncAwaitResumePartialFunction:
141142
case Node::Kind::AsyncSuspendResumePartialFunction:
143+
case Node::Kind::AccessibleFunctionRecord:
142144
return true;
143145
default:
144146
return false;
@@ -799,7 +801,7 @@ NodePointer Demangler::demangleOperator() {
799801
return createWithChild(
800802
Node::Kind::ProtocolConformanceRefInProtocolModule, popProtocol());
801803

802-
// Runtime records (type/protocol/conformance)
804+
// Runtime records (type/protocol/conformance/function)
803805
case 'c':
804806
return createWithChild(Node::Kind::ProtocolConformanceDescriptorRecord,
805807
popProtocolConformance());
@@ -809,6 +811,8 @@ NodePointer Demangler::demangleOperator() {
809811
return createWithChild(Node::Kind::OpaqueTypeDescriptorRecord, popNode());
810812
case 'r':
811813
return createWithChild(Node::Kind::ProtocolDescriptorRecord, popProtocol());
814+
case 'F':
815+
return createNode(Node::Kind::AccessibleFunctionRecord);
812816

813817
default:
814818
pushBack();
@@ -2363,6 +2367,7 @@ NodePointer Demangler::demangleThunkOrSpecialization() {
23632367
case 'D': return createNode(Node::Kind::DynamicAttribute);
23642368
case 'd': return createNode(Node::Kind::DirectMethodReferenceAttribute);
23652369
case 'E': return createNode(Node::Kind::DistributedThunk);
2370+
case 'F': return createNode(Node::Kind::DistributedMethodAccessor);
23662371
case 'a': return createNode(Node::Kind::PartialApplyObjCForwarder);
23672372
case 'A': return createNode(Node::Kind::PartialApplyForwarder);
23682373
case 'm': return createNode(Node::Kind::MergedFunction);

lib/Demangling/NodePrinter.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,7 @@ class NodePrinter {
559559
case Node::Kind::ProtocolConformanceRefInProtocolModule:
560560
case Node::Kind::ProtocolConformanceRefInOtherModule:
561561
case Node::Kind::DistributedThunk:
562+
case Node::Kind::DistributedMethodAccessor:
562563
case Node::Kind::DynamicallyReplaceableFunctionKey:
563564
case Node::Kind::DynamicallyReplaceableFunctionImpl:
564565
case Node::Kind::DynamicallyReplaceableFunctionVar:
@@ -585,6 +586,7 @@ class NodePrinter {
585586
case Node::Kind::IndexSubset:
586587
case Node::Kind::AsyncAwaitResumePartialFunction:
587588
case Node::Kind::AsyncSuspendResumePartialFunction:
589+
case Node::Kind::AccessibleFunctionRecord:
588590
return false;
589591
}
590592
printer_unreachable("bad node kind");
@@ -1997,6 +1999,16 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
19971999
Printer << "distributed thunk for ";
19982000
}
19992001
return nullptr;
2002+
case Node::Kind::DistributedMethodAccessor:
2003+
if (!Options.ShortenThunk) {
2004+
Printer << "distributed method accessor for ";
2005+
}
2006+
return nullptr;
2007+
case Node::Kind::AccessibleFunctionRecord:
2008+
if (!Options.ShortenThunk) {
2009+
Printer << "accessible function runtime record for ";
2010+
}
2011+
return nullptr;
20002012
case Node::Kind::DynamicallyReplaceableFunctionKey:
20012013
if (!Options.ShortenThunk) {
20022014
Printer << "dynamically replaceable key for ";

0 commit comments

Comments
 (0)