Skip to content

Commit 84c7b77

Browse files
committed
Make opaque type descriptors dynamically replaceable
This is to support dynamic function replacement of functions with opaque result type. This approach requires that all state is thrown away (that could contain the old returned type for an opaque type) between replacements. rdar://48887938
1 parent 904ba9b commit 84c7b77

21 files changed

+601
-31
lines changed

include/swift/Demangling/DemangleNodes.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,10 @@ NODE(AccessorFunctionReference)
266266
NODE(OpaqueType)
267267
NODE(OpaqueTypeDescriptorSymbolicReference)
268268
NODE(OpaqueTypeDescriptor)
269+
NODE(OpaqueTypeDescriptorAccessor)
270+
NODE(OpaqueTypeDescriptorAccessorImpl)
271+
NODE(OpaqueTypeDescriptorAccessorKey)
272+
NODE(OpaqueTypeDescriptorAccessorVar)
269273
NODE(OpaqueReturnType)
270274
CONTEXT_NODE(OpaqueReturnTypeOf)
271275

include/swift/IRGen/Linking.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ class LinkEntity {
199199
/// The descriptor for an opaque type.
200200
/// The pointer is an OpaqueTypeDecl*.
201201
OpaqueTypeDescriptor,
202+
OpaqueTypeDescriptorAccessor,
203+
OpaqueTypeDescriptorAccessorImpl,
204+
OpaqueTypeDescriptorAccessorKey,
205+
OpaqueTypeDescriptorAccessorVar,
202206

203207
/// The metadata pattern for a generic nominal type.
204208
/// The pointer is a NominalTypeDecl*.
@@ -706,6 +710,30 @@ class LinkEntity {
706710
return entity;
707711
}
708712

713+
static LinkEntity forOpaqueTypeDescriptorAccessor(OpaqueTypeDecl *decl) {
714+
LinkEntity entity;
715+
entity.setForDecl(Kind::OpaqueTypeDescriptorAccessor, decl);
716+
return entity;
717+
}
718+
719+
static LinkEntity forOpaqueTypeDescriptorAccessorImpl(OpaqueTypeDecl *decl) {
720+
LinkEntity entity;
721+
entity.setForDecl(Kind::OpaqueTypeDescriptorAccessorImpl, decl);
722+
return entity;
723+
}
724+
725+
static LinkEntity forOpaqueTypeDescriptorAccessorKey(OpaqueTypeDecl *decl) {
726+
LinkEntity entity;
727+
entity.setForDecl(Kind::OpaqueTypeDescriptorAccessorKey, decl);
728+
return entity;
729+
}
730+
731+
static LinkEntity forOpaqueTypeDescriptorAccessorVar(OpaqueTypeDecl *decl) {
732+
LinkEntity entity;
733+
entity.setForDecl(Kind::OpaqueTypeDescriptorAccessorVar, decl);
734+
return entity;
735+
}
736+
709737
static LinkEntity forPropertyDescriptor(AbstractStorageDecl *decl) {
710738
assert(decl->exportsPropertyDescriptor());
711739
LinkEntity entity;

lib/Demangling/Demangler.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1805,6 +1805,18 @@ NodePointer Demangler::demangleMetatype() {
18051805
return createWithPoppedType(Node::Kind::GenericTypeMetadataPattern);
18061806
case 'a':
18071807
return createWithPoppedType(Node::Kind::TypeMetadataAccessFunction);
1808+
case 'g':
1809+
return createWithChild(Node::Kind::OpaqueTypeDescriptorAccessor,
1810+
popNode());
1811+
case 'h':
1812+
return createWithChild(Node::Kind::OpaqueTypeDescriptorAccessorImpl,
1813+
popNode());
1814+
case 'j':
1815+
return createWithChild(Node::Kind::OpaqueTypeDescriptorAccessorKey,
1816+
popNode());
1817+
case 'k':
1818+
return createWithChild(Node::Kind::OpaqueTypeDescriptorAccessorVar,
1819+
popNode());
18081820
case 'I':
18091821
return createWithPoppedType(Node::Kind::TypeMetadataInstantiationCache);
18101822
case 'i':

lib/Demangling/NodePrinter.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,10 @@ class NodePrinter {
415415
case Node::Kind::ObjCMetadataUpdateFunction:
416416
case Node::Kind::ObjCResilientClassStub:
417417
case Node::Kind::OpaqueTypeDescriptor:
418+
case Node::Kind::OpaqueTypeDescriptorAccessor:
419+
case Node::Kind::OpaqueTypeDescriptorAccessorImpl:
420+
case Node::Kind::OpaqueTypeDescriptorAccessorKey:
421+
case Node::Kind::OpaqueTypeDescriptorAccessorVar:
418422
case Node::Kind::Owned:
419423
case Node::Kind::OwningAddressor:
420424
case Node::Kind::OwningMutableAddressor:
@@ -1733,6 +1737,22 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
17331737
Printer << "opaque type descriptor for ";
17341738
print(Node->getChild(0));
17351739
return nullptr;
1740+
case Node::Kind::OpaqueTypeDescriptorAccessor:
1741+
Printer << "opaque type descriptor accessor for ";
1742+
print(Node->getChild(0));
1743+
return nullptr;
1744+
case Node::Kind::OpaqueTypeDescriptorAccessorImpl:
1745+
Printer << "opaque type descriptor accessor impl for ";
1746+
print(Node->getChild(0));
1747+
return nullptr;
1748+
case Node::Kind::OpaqueTypeDescriptorAccessorKey:
1749+
Printer << "opaque type descriptor accessor key for ";
1750+
print(Node->getChild(0));
1751+
return nullptr;
1752+
case Node::Kind::OpaqueTypeDescriptorAccessorVar:
1753+
Printer << "opaque type descriptor accessor var for ";
1754+
print(Node->getChild(0));
1755+
return nullptr;
17361756
case Node::Kind::CoroutineContinuationPrototype:
17371757
Printer << "coroutine continuation prototype for ";
17381758
print(Node->getChild(0));

lib/Demangling/OldRemangler.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,6 +2038,18 @@ void Remangler::mangleOpaqueType(Node *node) {
20382038
void Remangler::mangleOpaqueTypeDescriptor(Node *node) {
20392039
unreachable("unsupported");
20402040
}
2041+
void Remangler::mangleOpaqueTypeDescriptorAccessor(Node *node) {
2042+
unreachable("unsupported");
2043+
}
2044+
void Remangler::mangleOpaqueTypeDescriptorAccessorImpl(Node *node) {
2045+
unreachable("unsupported");
2046+
}
2047+
void Remangler::mangleOpaqueTypeDescriptorAccessorKey(Node *node) {
2048+
unreachable("unsupported");
2049+
}
2050+
void Remangler::mangleOpaqueTypeDescriptorAccessorVar(Node *node) {
2051+
unreachable("unsupported");
2052+
}
20412053
void Remangler::mangleAccessorFunctionReference(Node *node) {
20422054
unreachable("can't remangle");
20432055
}

lib/Demangling/Remangler.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,6 +1599,26 @@ void Remangler::mangleOpaqueTypeDescriptor(Node *node) {
15991599
Buffer << "MQ";
16001600
}
16011601

1602+
void Remangler::mangleOpaqueTypeDescriptorAccessor(Node *node) {
1603+
mangleSingleChildNode(node);
1604+
Buffer << "Mg";
1605+
}
1606+
1607+
void Remangler::mangleOpaqueTypeDescriptorAccessorImpl(Node *node) {
1608+
mangleSingleChildNode(node);
1609+
Buffer << "Mh";
1610+
}
1611+
1612+
void Remangler::mangleOpaqueTypeDescriptorAccessorKey(Node *node) {
1613+
mangleSingleChildNode(node);
1614+
Buffer << "Mj";
1615+
}
1616+
1617+
void Remangler::mangleOpaqueTypeDescriptorAccessorVar(Node *node) {
1618+
mangleSingleChildNode(node);
1619+
Buffer << "Mk";
1620+
}
1621+
16021622
void Remangler::manglePropertyDescriptor(Node *node) {
16031623
mangleSingleChildNode(node);
16041624
Buffer << "MV";

lib/IRGen/GenArchetype.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/AST/ASTContext.h"
2020
#include "swift/AST/Decl.h"
2121
#include "swift/AST/GenericEnvironment.h"
22+
#include "swift/AST/IRGenOptions.h"
2223
#include "swift/AST/Types.h"
2324
#include "swift/IRGen/Linking.h"
2425
#include "swift/SIL/SILValue.h"
@@ -389,7 +390,6 @@ llvm::Value *irgen::emitDynamicTypeOfOpaqueArchetype(IRGenFunction &IGF,
389390
Address addr,
390391
SILType type) {
391392
auto archetype = type.castTo<ArchetypeType>();
392-
393393
// Acquire the archetype's static metadata.
394394
llvm::Value *metadata =
395395
emitArchetypeTypeMetadataRef(IGF, archetype, MetadataState::Complete)
@@ -450,14 +450,31 @@ withOpaqueTypeGenericArgs(IRGenFunction &IGF,
450450
}
451451
}
452452

453+
static llvm::Value *
454+
getAddressOfOpaqueTypeDescriptor(IRGenFunction &IGF,
455+
OpaqueTypeDecl *opaqueDecl) {
456+
auto &IGM = IGF.IGM;
457+
458+
// Support dynamically replacing the return type as part of dynamic function
459+
// replacement.
460+
if (!IGM.getOptions().shouldOptimize()) {
461+
auto descriptorAccessor = IGM.getAddrOfOpaqueTypeDescriptorAccessFunction(
462+
opaqueDecl, NotForDefinition, false);
463+
auto desc = IGF.Builder.CreateCall(descriptorAccessor, {});
464+
desc->setDoesNotThrow();
465+
desc->setCallingConv(IGM.SwiftCC);
466+
return desc;
467+
}
468+
return IGM.getAddrOfOpaqueTypeDescriptor(opaqueDecl, ConstantInit());
469+
}
470+
453471
MetadataResponse irgen::emitOpaqueTypeMetadataRef(IRGenFunction &IGF,
454472
CanOpaqueTypeArchetypeType archetype,
455473
DynamicMetadataRequest request) {
456474
auto accessorFn = IGF.IGM.getGetOpaqueTypeMetadataFn();
457475
auto opaqueDecl = archetype->getDecl();
458-
auto descriptor = IGF.IGM
459-
.getAddrOfOpaqueTypeDescriptor(opaqueDecl, ConstantInit());
460476

477+
auto *descriptor = getAddressOfOpaqueTypeDescriptor(IGF, opaqueDecl);
461478
auto indexValue = llvm::ConstantInt::get(IGF.IGM.SizeTy, 0);
462479

463480
llvm::CallInst *result = nullptr;
@@ -482,8 +499,9 @@ llvm::Value *irgen::emitOpaqueTypeWitnessTableRef(IRGenFunction &IGF,
482499
ProtocolDecl *protocol) {
483500
auto accessorFn = IGF.IGM.getGetOpaqueTypeConformanceFn();
484501
auto opaqueDecl = archetype->getDecl();
485-
auto descriptor = IGF.IGM
486-
.getAddrOfOpaqueTypeDescriptor(opaqueDecl, ConstantInit());
502+
503+
504+
llvm::Value *descriptor = getAddressOfOpaqueTypeDescriptor(IGF, opaqueDecl);
487505

488506
auto foundProtocol = std::find(archetype->getConformsTo().begin(),
489507
archetype->getConformsTo().end(),

0 commit comments

Comments
 (0)