Skip to content

Commit

Permalink
Merge pull request swiftlang#79781 from nate-chandler/general-coro/20…
Browse files Browse the repository at this point in the history
…250227/1

[CoroutineAccessors] Dispatch and PtrAuth.
  • Loading branch information
nate-chandler authored Mar 8, 2025
2 parents b6b4a7b + 6581fec commit c0ba520
Show file tree
Hide file tree
Showing 45 changed files with 742 additions and 173 deletions.
2 changes: 1 addition & 1 deletion docs/ABI/Mangling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,10 @@ types where the metadata itself has unknown layout.)
global ::= global 'TF' // distributed method accessor
global ::= global 'TI' // implementation of a dynamic_replaceable function
global ::= global 'Tu' // async function pointer of a function
global ::= global 'Tv' // coro function pointer of a function
global ::= global 'TX' // function pointer of a dynamic_replaceable function
global ::= global 'Twb' // back deployment thunk
global ::= global 'TwB' // back deployment fallback function
global ::= global 'Twc' // coro function pointer of a function
global ::= entity entity 'TV' // vtable override thunk, derived followed by base
global ::= type label-list? 'D' // type mangling for the debugger with label list for function types.
global ::= type 'TC' // continuation prototype (not actually used for real symbols)
Expand Down
6 changes: 3 additions & 3 deletions include/swift/ABI/Metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -5094,9 +5094,9 @@ struct DynamicReplacementKey {
uint16_t getExtraDiscriminator() const {
return flags & 0x0000FFFF;
}
bool isAsync() const {
return ((flags >> 16 ) & 0x1);
}
bool isAsync() const { return ((flags >> 16) & 0x1); }
bool isCalleeAllocatedCoroutine() const { return ((flags >> 16) & 0x2); }
bool isData() const { return isAsync() || isCalleeAllocatedCoroutine(); }
};

/// A record describing a dynamic function replacement.
Expand Down
37 changes: 37 additions & 0 deletions include/swift/ABI/MetadataValues.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,23 @@ class MethodDescriptorFlags {

bool isAsync() const { return Value & IsAsyncMask; }

bool isCalleeAllocatedCoroutine() const {
switch (getKind()) {
case Kind::Method:
case Kind::Init:
case Kind::Getter:
case Kind::Setter:
case Kind::ModifyCoroutine:
case Kind::ReadCoroutine:
return false;
case Kind::Read2Coroutine:
case Kind::Modify2Coroutine:
return true;
}
}

bool isData() const { return isAsync() || isCalleeAllocatedCoroutine(); }

uint16_t getExtraDiscriminator() const {
return (Value >> ExtraDiscriminatorShift);
}
Expand Down Expand Up @@ -649,6 +666,26 @@ class ProtocolRequirementFlags {

bool isAsync() const { return Value & IsAsyncMask; }

bool isCalleeAllocatedCoroutine() const {
switch (getKind()) {
case Kind::BaseProtocol:
case Kind::Method:
case Kind::Init:
case Kind::Getter:
case Kind::Setter:
case Kind::ReadCoroutine:
case Kind::ModifyCoroutine:
case Kind::AssociatedTypeAccessFunction:
case Kind::AssociatedConformanceAccessFunction:
return false;
case Kind::Read2Coroutine:
case Kind::Modify2Coroutine:
return true;
}
}

bool isData() const { return isAsync() || isCalleeAllocatedCoroutine(); }

bool isSignedWithAddress() const {
return getKind() != Kind::BaseProtocol;
}
Expand Down
29 changes: 23 additions & 6 deletions include/swift/AST/IRGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,26 @@ struct PointerAuthOptions : clang::PointerAuthOptions {

/// Type layout string descriminator.
PointerAuthSchema TypeLayoutString;

/// Like SwiftFunctionPointers but for use with CoroFunctionPointer values.
PointerAuthSchema CoroSwiftFunctionPointers;

/// Like SwiftClassMethods but for use with CoroFunctionPointer values.
PointerAuthSchema CoroSwiftClassMethods;

/// Like ProtocolWitnesses but for use with CoroFunctionPointer values.
PointerAuthSchema CoroProtocolWitnesses;

/// Like SwiftClassMethodPointers but for use with CoroFunctionPointer
/// values.
PointerAuthSchema CoroSwiftClassMethodPointers;

/// Like SwiftDynamicReplacements but for use with CoroFunctionPointer
/// values.
PointerAuthSchema CoroSwiftDynamicReplacements;

/// Like PartialApplyCapture but for use with CoroFunctionPointer values.
PointerAuthSchema CoroPartialApplyCapture;
};

enum class JITDebugArtifact : unsigned {
Expand Down Expand Up @@ -502,9 +522,6 @@ class IRGenOptions {
// Whether to emit typed malloc during coroutine frame allocation.
unsigned EmitTypeMallocForCoroFrame : 1;

// Whether to use the yield_once ABI when emitting yield_once_2 coroutines.
unsigned EmitYieldOnce2AsYieldOnce : 1;

// Whether to force emission of a frame for all async functions
// (LLVM's 'frame-pointer=all').
unsigned AsyncFramePointerAll : 1;
Expand Down Expand Up @@ -621,9 +638,9 @@ class IRGenOptions {
ColocateTypeDescriptors(true), UseRelativeProtocolWitnessTables(false),
UseFragileResilientProtocolWitnesses(false), EnableHotColdSplit(false),
EmitAsyncFramePushPopMetadata(true), EmitTypeMallocForCoroFrame(false),
EmitYieldOnce2AsYieldOnce(true), AsyncFramePointerAll(false),
UseProfilingMarkerThunks(false), UseCoroCCX8664(false),
UseCoroCCArm64(false), DebugInfoForProfiling(false), CmdArgs(),
AsyncFramePointerAll(false), UseProfilingMarkerThunks(false),
UseCoroCCX8664(false), UseCoroCCArm64(false),
DebugInfoForProfiling(false), CmdArgs(),
SanitizeCoverage(llvm::SanitizerCoverageOptions()),
TypeInfoFilter(TypeInfoDumpFilter::All),
PlatformCCallingConvention(llvm::CallingConv::C), UseCASBackend(false),
Expand Down
3 changes: 0 additions & 3 deletions include/swift/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -477,9 +477,6 @@ SUPPRESSIBLE_EXPERIMENTAL_FEATURE(CoroutineAccessors, true)
/// modify/read single-yield coroutines always execute code post-yield code
EXPERIMENTAL_FEATURE(CoroutineAccessorsUnwindOnCallerError, false)

/// modify/read coroutines use the callee-allocated ABI
EXPERIMENTAL_FEATURE(CoroutineAccessorsAllocateInCallee, false)

/// When a parameter has unspecified isolation, infer it as main actor isolated.
EXPERIMENTAL_FEATURE(GenerateForceToMainActorThunks, false)

Expand Down
1 change: 1 addition & 0 deletions include/swift/Demangling/DemangleNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ NODE(DependentGenericInverseConformanceRequirement)
NODE(Integer)
NODE(NegativeInteger)
NODE(DependentGenericParamValueMarker)
NODE(CoroFunctionPointer)

#undef CONTEXT_NODE
#undef NODE
14 changes: 14 additions & 0 deletions include/swift/IRGen/Linking.h
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,11 @@ class LinkEntity {
/// The pointer is the llvm::Function* for a partial apply forwarder.
PartialApplyForwarderCoroFunctionPointer,

/// An coro function pointer to a function which is known to exist whose
/// name is known.
/// The pointer is a const char* of the name.
KnownCoroFunctionPointer,

/// An coro function pointer for a distributed accessor (method or
/// property).
/// The pointer is a SILFunction*.
Expand Down Expand Up @@ -1553,6 +1558,15 @@ class LinkEntity {
return entity;
}

static LinkEntity forKnownCoroFunctionPointer(const char *name) {
LinkEntity entity;
entity.Pointer = const_cast<char *>(name);
entity.SecondaryPointer = nullptr;
entity.Data =
LINKENTITY_SET_FIELD(Kind, unsigned(Kind::KnownCoroFunctionPointer));
return entity;
}

LinkEntity getUnderlyingEntityForCoroFunctionPointer() const {
LinkEntity entity;
entity.Pointer = Pointer;
Expand Down
1 change: 1 addition & 0 deletions include/swift/SIL/SILDeclRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,7 @@ struct SILDeclRef {
}

bool hasAsync() const;
bool isCalleeAllocatedCoroutine() const;

/// Return the hash code for the SIL declaration.
friend llvm::hash_code hash_value(swift::SILDeclRef ref) {
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10931,7 +10931,7 @@ bool AccessorDecl::isRequirementWithSynthesizedDefaultImplementation() const {
if (!requiresFeatureCoroutineAccessors(getAccessorKind())) {
return false;
}
if (getStorage()->getOverrideLoc()) {
if (!requiresNewWitnessTableEntry()) {
return false;
}
return getStorage()->requiresCorrespondingUnderscoredCoroutineAccessor(
Expand Down
1 change: 0 additions & 1 deletion lib/AST/FeatureSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,6 @@ UNINTERESTING_FEATURE(SafeInteropWrappers)
UNINTERESTING_FEATURE(AssumeResilientCxxTypes)
UNINTERESTING_FEATURE(ImportNonPublicCxxMembers)
UNINTERESTING_FEATURE(CoroutineAccessorsUnwindOnCallerError)
UNINTERESTING_FEATURE(CoroutineAccessorsAllocateInCallee)

bool swift::usesFeatureIsolatedDeinit(const Decl *decl) {
if (auto cd = dyn_cast<ClassDecl>(decl)) {
Expand Down
3 changes: 3 additions & 0 deletions lib/Demangling/Demangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ bool swift::Demangle::isFunctionAttr(Node::Kind kind) {
case Node::Kind::BackDeploymentThunk:
case Node::Kind::BackDeploymentFallback:
case Node::Kind::HasSymbolQuery:
case Node::Kind::CoroFunctionPointer:
return true;
default:
return false;
Expand Down Expand Up @@ -3134,6 +3135,8 @@ NodePointer Demangler::demangleThunkOrSpecialization() {
switch (nextChar()) {
case 'b': return createNode(Node::Kind::BackDeploymentThunk);
case 'B': return createNode(Node::Kind::BackDeploymentFallback);
case 'c':
return createNode(Node::Kind::CoroFunctionPointer);
case 'S': return createNode(Node::Kind::HasSymbolQuery);
default:
return nullptr;
Expand Down
4 changes: 4 additions & 0 deletions lib/Demangling/NodePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,7 @@ class NodePrinter {
case Node::Kind::ObjectiveCProtocolSymbolicReference:
case Node::Kind::DependentGenericInverseConformanceRequirement:
case Node::Kind::DependentGenericParamValueMarker:
case Node::Kind::CoroFunctionPointer:
return false;
}
printer_unreachable("bad node kind");
Expand Down Expand Up @@ -3478,6 +3479,9 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
Printer << signedValue;
return nullptr;
}
case Node::Kind::CoroFunctionPointer:
Printer << "coro function pointer to ";
return nullptr;
}

printer_unreachable("bad node kind!");
Expand Down
5 changes: 5 additions & 0 deletions lib/Demangling/OldRemangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1198,6 +1198,11 @@ ManglingError Remangler::mangleAsyncFunctionPointer(Node *node,
return ManglingError::Success;
}

ManglingError Remangler::mangleCoroFunctionPointer(Node *node, unsigned depth) {
Buffer << "Twc";
return ManglingError::Success;
}

ManglingError Remangler::mangleDeallocator(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleSimpleEntity(node, 'F', "D", ctx, depth + 1);
Expand Down
6 changes: 6 additions & 0 deletions lib/Demangling/Remangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,11 @@ ManglingError Remangler::mangleAsyncFunctionPointer(Node *node,
return ManglingError::Success;
}

ManglingError Remangler::mangleCoroFunctionPointer(Node *node, unsigned depth) {
Buffer << "Twc";
return ManglingError::Success;
}

ManglingError Remangler::mangleDependentAssociatedTypeRef(Node *node,
unsigned depth) {
RETURN_IF_ERROR(mangleIdentifier(node->getFirstChild(), depth));
Expand Down Expand Up @@ -1836,6 +1841,7 @@ ManglingError Remangler::mangleGlobal(Node *node, unsigned depth) {
case Node::Kind::BackDeploymentThunk:
case Node::Kind::BackDeploymentFallback:
case Node::Kind::HasSymbolQuery:
case Node::Kind::CoroFunctionPointer:
mangleInReverseOrder = true;
break;
default:
Expand Down
9 changes: 3 additions & 6 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3674,12 +3674,9 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
Args.hasFlag(OPT_enable_fragile_resilient_protocol_witnesses,
OPT_disable_fragile_resilient_protocol_witnesses,
Opts.UseFragileResilientProtocolWitnesses);
Opts.UseProfilingMarkerThunks =
Args.hasFlag(OPT_enable_profiling_marker_thunks,
OPT_disable_profiling_marker_thunks,
Opts.UseProfilingMarkerThunks);
Opts.EmitYieldOnce2AsYieldOnce =
!LangOpts.hasFeature(Feature::CoroutineAccessorsAllocateInCallee);
Opts.UseProfilingMarkerThunks = Args.hasFlag(
OPT_enable_profiling_marker_thunks, OPT_disable_profiling_marker_thunks,
Opts.UseProfilingMarkerThunks);
Opts.EnableHotColdSplit =
Args.hasFlag(OPT_enable_split_cold_code,
OPT_disable_split_cold_code,
Expand Down
8 changes: 5 additions & 3 deletions lib/IRGen/Callee.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,11 @@ namespace irgen {
FunctionPointerKind(SpecialKind kind)
: value(unsigned(kind) + SpecialOffset) {}
FunctionPointerKind(CanSILFunctionType fnType)
: FunctionPointerKind(fnType->isAsync()
? BasicKind::AsyncFunctionPointer
: BasicKind::Function) {}
: FunctionPointerKind(fnType->isAsync()
? BasicKind::AsyncFunctionPointer
: fnType->isCalleeAllocatedCoroutine()
? BasicKind::CoroFunctionPointer
: BasicKind::Function) {}

static FunctionPointerKind defaultSync() {
return BasicKind::Function;
Expand Down
Loading

0 comments on commit c0ba520

Please sign in to comment.