Skip to content

[Distributed] Undo new record and mangling scheme for dist.p.witnesses #71801

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,4 @@ HANDLE_SWIFT_SECTION(protocs, "__swift5_protos", "swift5_protocols",
".sw5prt$B")
HANDLE_SWIFT_SECTION(acfuncs, "__swift5_acfuncs", "swift5_accessible_functions",
".sw5acfn$B")
HANDLE_SWIFT_SECTION(dacfuncs, "__swift5_acpfuns", "swift5_accessible_protocol_requirement_functions",
".sw5acpfn$B")
HANDLE_SWIFT_SECTION(mpenum, "__swift5_mpenum", "swift5_mpenum", ".sw5mpen$B")
5 changes: 0 additions & 5 deletions include/swift/Runtime/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,10 +307,6 @@ extern uintptr_t __COMPATIBILITY_LIBRARIES_CANNOT_CHECK_THE_IS_SWIFT_BIT_DIRECTL
#define __ptrauth_swift_accessible_function_record \
__ptrauth(ptrauth_key_process_independent_data, 1, \
SpecialPointerAuthDiscriminators::AccessibleFunctionRecord)
#define __ptrauth_swift_accessible_protocol_requirement_function_record \
__ptrauth(ptrauth_key_process_independent_data, 1, \
SpecialPointerAuthDiscriminators:: \
AccessibleProtocolRequirementFunctionRecord)
#define __ptrauth_swift_objc_superclass \
__ptrauth(ptrauth_key_process_independent_data, 1, \
swift::SpecialPointerAuthDiscriminators::ObjCSuperclass)
Expand Down Expand Up @@ -359,7 +355,6 @@ extern uintptr_t __COMPATIBILITY_LIBRARIES_CANNOT_CHECK_THE_IS_SWIFT_BIT_DIRECTL
#define __ptrauth_swift_escalation_notification_function
#define __ptrauth_swift_dispatch_invoke_function
#define __ptrauth_swift_accessible_function_record
#define __ptrauth_swift_accessible_protocol_requirement_function_record
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we're removing the entire new section kind; this is safe since no release is using this yet.

#define __ptrauth_swift_objc_superclass
#define __ptrauth_swift_runtime_function_entry
#define __ptrauth_swift_runtime_function_entry_with_key(__key)
Expand Down
1 change: 1 addition & 0 deletions lib/AST/DistributedDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ bool swift::checkDistributedSerializationRequirementIsExactlyCodable(
std::count(protocols.begin(), protocols.end(), decodable) == 1;
}

// TODO(distributed): probably can be removed?
llvm::ArrayRef<ValueDecl *>
AbstractFunctionDecl::getDistributedMethodWitnessedProtocolRequirements() const {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not 100% sure yet so I kept it around for now

auto mutableThis = const_cast<AbstractFunctionDecl *>(this);
Expand Down
32 changes: 1 addition & 31 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4417,14 +4417,6 @@ void IRGenModule::addAccessibleFunction(SILFunction *func) {
AccessibleFunctions.push_back(func);
}

void IRGenModule::addAccessibleFunctionDistributedAliased(
std::string mangledRecordName,
std::optional<std::string> mangledActorTypeName,
SILFunction *func) {
AccessibleProtocolFunctions.push_back(AccessibleProtocolFunctionsData(
func, mangledRecordName, mangledActorTypeName));
}

/// Emit the protocol conformance list and return it (if asContiguousArray is
/// true, otherwise the records are emitted as individual globals and
/// nullptr is returned).
Expand Down Expand Up @@ -4748,11 +4740,10 @@ void IRGenModule::emitAccessibleFunction(
}

void IRGenModule::emitAccessibleFunctions() {
if (AccessibleFunctions.empty() && AccessibleProtocolFunctions.empty())
if (AccessibleFunctions.empty())
return;

StringRef fnsSectionName;
StringRef protocolFnsSectionName;
switch (TargetInfo.OutputObjectFormat) {
case llvm::Triple::DXContainer:
case llvm::Triple::GOFF:
Expand All @@ -4762,17 +4753,14 @@ void IRGenModule::emitAccessibleFunctions() {
"the selected object format.");
case llvm::Triple::MachO:
fnsSectionName = "__TEXT, __swift5_acfuncs, regular";
protocolFnsSectionName = "__TEXT, __swift5_acpfuns, regular";
break;
case llvm::Triple::ELF:
case llvm::Triple::Wasm:
fnsSectionName = "swift5_accessible_functions";
protocolFnsSectionName = "swift5_accessible_protocol_requirement_functions";
break;
case llvm::Triple::XCOFF:
case llvm::Triple::COFF:
fnsSectionName = ".sw5acfn$B";
protocolFnsSectionName = ".sw5acpfn$B";
break;
}

Expand All @@ -4786,24 +4774,6 @@ void IRGenModule::emitAccessibleFunctions() {
fnsSectionName, mangledRecordName,
/*mangledActorName=*/{}, mangledFunctionName, func);
}

for (auto accessibleInfo : AccessibleProtocolFunctions) {
auto func = accessibleInfo.function;

std::string mangledRecordName =
accessibleInfo.mangledRecordName
? (*accessibleInfo.mangledRecordName)
: LinkEntity::forAccessibleFunctionRecord(func).mangleAsString();
std::string mangledFunctionName =
LinkEntity::forSILFunction(func).mangleAsString();
std::string mangledActorName = accessibleInfo.concreteMangledTypeName
? *accessibleInfo.concreteMangledTypeName
: "<none>";

emitAccessibleFunction(
protocolFnsSectionName, mangledRecordName,
mangledActorName, mangledFunctionName, func);
}
}

/// Fetch a global reference to a reference to the given Objective-C class.
Expand Down
5 changes: 0 additions & 5 deletions lib/IRGen/IRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2232,8 +2232,3 @@ bool swift::writeEmptyOutputFilesFor(
}
return false;
}
IRGenModule::AccessibleProtocolFunctionsData::AccessibleProtocolFunctionsData(
SILFunction *function, const std::optional<std::string> &mangledRecordName,
const std::optional<std::string> &concreteMangledTypeName)
: function(function), mangledRecordName(mangledRecordName),
concreteMangledTypeName(concreteMangledTypeName) {}
23 changes: 0 additions & 23 deletions lib/IRGen/IRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -1152,10 +1152,6 @@ class IRGenModule {
void addObjCClassStub(llvm::Constant *addr);
void addProtocolConformance(ConformanceDescription &&conformance);
void addAccessibleFunction(SILFunction *func);
void addAccessibleFunctionDistributedAliased(
std::string mangledRecordName,
std::optional<std::string> mangledActorTypeName,
SILFunction *func);

llvm::Constant *emitSwiftProtocols(bool asContiguousArray);
llvm::Constant *emitProtocolConformances(bool asContiguousArray);
Expand Down Expand Up @@ -1314,25 +1310,6 @@ class IRGenModule {
/// up at runtime.
SmallVector<SILFunction *, 4> AccessibleFunctions;

struct AccessibleProtocolFunctionsData {
SILFunction *function;
/// Mangled name of the requirement function.
std::optional<std::string> mangledRecordName;
std::optional<std::string> concreteMangledTypeName;
AccessibleProtocolFunctionsData(
SILFunction *function,
const std::optional<std::string> &mangledRecordName,
const std::optional<std::string> &concreteMangledTypeName);
};
/// List of all functions which are protocol *requirements* which may be
/// looked up by name at runtime. The record can be used to pair
/// a concrete implementation type with the protocol (record) name,
/// in order to locate the *witness* function name on this specific type.
///
/// The witness function name can then be used to look up the witness at
/// runtime by inspecting `AccessibleFunctions`.
SmallVector<AccessibleProtocolFunctionsData, 4> AccessibleProtocolFunctions;

/// Map of Objective-C protocols and protocol references, bitcast to i8*.
/// The interesting global variables relating to an ObjC protocol.
struct ObjCProtocolPair {
Expand Down
31 changes: 1 addition & 30 deletions lib/IRGen/IRGenSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2476,36 +2476,7 @@ void IRGenSILFunction::emitSILFunction() {
IGM.emitDistributedTargetAccessor(CurSILFn);
IGM.addAccessibleFunction(CurSILFn);

if (auto val = CurSILFn->getLocation().castToASTNode<ValueDecl>()) {
if (auto attr =
val->getAttrs().getAttribute<DistributedThunkTargetAttr>()) {

// the original `distributed func`
auto func = attr->getTargetFunction();

auto distributedRequirements = func->getDistributedMethodWitnessedProtocolRequirements();
if (distributedRequirements.size() == 1) {
auto protocolFunc = distributedRequirements.front();
Mangle::ASTMangler mangler;
// The mangled name of the requirement is the name of the record
auto mangledProtocolFuncName =
mangler.mangleDistributedThunk(cast<FuncDecl>(protocolFunc));

std::optional<std::string> mangledActorTypeName;
if (isa<ClassDecl>(func->getDeclContext()->getAsDecl())) {
// a concrete type, not a "distributed" protocol
mangledActorTypeName = mangler.mangleAnyDecl(
func->getDeclContext()->getSelfNominalTypeDecl(),
/*prefix=*/true);
}

IGM.addAccessibleFunctionDistributedAliased(
/*mangledRecordName=*/mangledProtocolFuncName,
/*mangledActorTypeName=*/mangledActorTypeName,
CurSILFn);
}
}
}
// TODO(distributed): for protocols emit a special accessor
}

// Configure the dominance resolver.
Expand Down
45 changes: 17 additions & 28 deletions lib/Sema/CodeSynthesisDistributedActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,17 @@ static void forwardParameters(AbstractFunctionDecl *afd,
}
}

static llvm::StringRef
mangleDistributedThunkForAccessorRecordName(
ASTContext &C, AbstractFunctionDecl *thunk) {
Mangle::ASTMangler mangler;

// default mangling
auto mangled =
C.AllocateCopy(mangler.mangleDistributedThunk(cast<FuncDecl>(thunk)));
return mangled;
}

static std::pair<BraceStmt *, bool>
deriveBodyDistributed_thunk(AbstractFunctionDecl *thunk, void *context) {
auto implicit = true;
Expand Down Expand Up @@ -519,34 +530,12 @@ deriveBodyDistributed_thunk(AbstractFunctionDecl *thunk, void *context) {

{
// --- Mangle the thunk name
Mangle::ASTMangler mangler;

// FIXME: cleanup
StringLiteralExpr *mangledTargetStringLiteral = nullptr;
auto witnessedDistributedRequirements =
func->getDistributedMethodWitnessedProtocolRequirements();

if (witnessedDistributedRequirements.size() == 1) {
auto protocolFunc = witnessedDistributedRequirements.front();

// we expect to witness exactly one distributed requirement,
// otherwise we should have diagnosed errors about more than 1 already.
std::string mangledString =
mangler.mangleDistributedThunk(cast<FuncDecl>(protocolFunc));
// FIXME: make it THUNK so the mangling is right
// MUST BE LIKE: s4main28GreeterP_ConcreteSystem_StubC5greetSSyYaKFTE

StringRef mangled = C.AllocateCopy(mangledString);
mangledTargetStringLiteral =
new (C) StringLiteralExpr(mangled, SourceRange(), implicit);
} else {
// default mangling
auto mangled =
C.AllocateCopy(mangler.mangleDistributedThunk(cast<FuncDecl>(thunk)));
mangledTargetStringLiteral =
new (C) StringLiteralExpr(mangled, SourceRange(), implicit);
}
assert(mangledTargetStringLiteral && "must be initialized");
auto mangledAccessorRecordName =
mangleDistributedThunkForAccessorRecordName(C, thunk);

StringLiteralExpr *mangledTargetStringLiteral =
new (C) StringLiteralExpr(mangledAccessorRecordName,
SourceRange(), implicit);

// --- let target = RemoteCallTarget(<mangled name>)
targetVar->setInterfaceType(remoteCallTargetTy);
Expand Down
92 changes: 1 addition & 91 deletions stdlib/public/Distributed/DistributedActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,94 +32,6 @@ findDistributedAccessor(const char *targetNameStart, size_t targetNameLength) {
return nullptr;
}

/// Find an accessible function record given a concrete actor type we're
/// attempting to make the call on, and the remote call method identifier.
static const AccessibleFunctionRecord *findDistributedProtocolMethodAccessor(
bool findConcreteWitness, const char *targetActorTypeNameStart,
size_t targetActorTypeNameLength, const char *targetNameStart,
size_t targetNameLength) {
// Find using just the method identifier;
// This will work if the call is a concrete method identifier
if (auto *func = runtime::swift_findAccessibleFunctionForConcreteType(
findConcreteWitness, targetActorTypeNameStart,
targetActorTypeNameLength, targetNameStart, targetNameLength)) {
assert(func->Flags.isDistributed());
return func;
}

return nullptr;
}

/// Given the presence of protocol witness distributed invocation targets,
/// obtain a concrete target name.
///
/// A distributed target can be identified by a protocol method name:
/// ```
/// protocol WorkerProtocol {
/// associatedtype Ret
/// distributed func func test() -> Ret
/// }
/// ```
///
/// So the remote call identifier may be "WorkerProtocol.test", however in order
/// to perform the invocation on a concrete target actor, we need to obtain
/// the concrete function we are about to invoke -- not least because of
/// its generic context details.
///
/// A concrete type on the server may be:
///
/// ```
/// distributed actor WorkerImpl: WorkerProtocol {
/// distributed func func test() -> String { "Hello" }
/// }
/// ```
///
/// Thus this method allows mapping the "protocol method identifier" and
/// concrete actor name, into the target witness name.
///
/// This way the generic context and other concrete information may be obtained
/// in order to perform the call on the concrete `WorkerImpl` type.
SWIFT_CC(swift)
SWIFT_EXPORT_FROM(swiftDistributed)
TypeNamePair swift_distributed_getConcreteAccessibleWitnessName(
DefaultActor *actor, const char *targetNameStart, size_t targetNameLength) {

// TODO(distributed): Avoid mangling twice; we do it here and in `execute_`
auto actorTy = swift_getObjectType(actor);
auto actorTyNamePair = swift_getMangledTypeName(actorTy);
std::string actorTyName = actorTyNamePair.data;

auto accessor = findDistributedProtocolMethodAccessor(
/*findConcreteWitness=*/true, actorTyNamePair.data,
actorTyNamePair.length, targetNameStart, targetNameLength);

if (!accessor) {
return {"", 0};
}

auto concreteNameData = accessor->Name.get();
auto concreteNameLength = strlen(accessor->Name.get());
return {concreteNameData, concreteNameLength};
}

SWIFT_CC(swift)
SWIFT_EXPORT_FROM(swiftDistributed)
void *swift_distributed_getGenericEnvironmentForConcreteActor(
DefaultActor *actor, const char *targetNameStart, size_t targetNameLength) {

// TODO(distributed): Avoid mangling twice; we do it here and in `execute_`
auto actorTy = swift_getObjectType(actor);
auto actorTyNamePair = swift_getMangledTypeName(actorTy);

auto *accessor = findDistributedProtocolMethodAccessor(
/*findConcreteWitness=*/true, actorTyNamePair.data,
actorTyNamePair.length, targetNameStart, targetNameLength);
if (!accessor) {
return nullptr;
}

return accessor->GenericEnvironment.get();
}

SWIFT_CC(swift)
SWIFT_EXPORT_FROM(swiftDistributed)
Expand All @@ -141,9 +53,7 @@ void *swift_distributed_getGenericEnvironment(const char *targetNameStart,
/// numWitnessTables: UInt
/// ) async throws
using TargetExecutorSignature =
AsyncSignature<void(/*on=*/DefaultActor *, // FIXME(distributed): Make this
// accept AnyObject and not
// witness tables
AsyncSignature<void(/*on=*/DefaultActor *,
/*targetName=*/const char *, /*targetNameSize=*/size_t,
/*argumentDecoder=*/HeapObject *,
/*argumentTypes=*/const Metadata *const *,
Expand Down
Loading