Skip to content

Commit 80e86fb

Browse files
committed
Runtime: make the demangler use stack allocated memory.
This reduces the amount of mallocs significantly.
1 parent 8404c73 commit 80e86fb

File tree

6 files changed

+40
-31
lines changed

6 files changed

+40
-31
lines changed

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,12 @@ class TypeRefBuilder {
210210

211211
Optional<std::string>
212212
createTypeDecl(Node *node, bool &typeAlias) {
213-
return Demangle::mangleNode(node);
213+
return Demangle::mangleNode(node, &Dem);
214214
}
215215

216216
BuiltProtocolDecl
217217
createProtocolDecl(Node *node) {
218-
return std::make_pair(Demangle::mangleNode(node), false);
218+
return std::make_pair(Demangle::mangleNode(node, &Dem), false);
219219
}
220220

221221
BuiltProtocolDecl

stdlib/public/Reflection/TypeRefBuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ static std::string normalizeReflectionName(Demangler &dem, StringRef reflectionN
5656

5757
// Remangle the reflection name to resolve symbolic references.
5858
if (auto node = dem.demangleType(reflectionName)) {
59-
return mangleNode(node);
59+
return mangleNode(node, &dem);
6060
}
6161

6262
// Fall back to the raw string.

stdlib/public/runtime/Demangle.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ _buildDemanglingForNominalType(const Metadata *type, Demangle::Demangler &Dem) {
284284
// Gather the complete set of generic arguments that must be written to
285285
// form this type.
286286
std::vector<const Metadata *> allGenericArgs;
287-
gatherWrittenGenericArgs(type, description, allGenericArgs);
287+
gatherWrittenGenericArgs(type, description, allGenericArgs, Dem);
288288

289289
// Demangle the generic arguments.
290290
std::vector<NodePointer> demangledGenerics;

stdlib/public/runtime/Metadata.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,7 +2189,7 @@ static inline ClassROData *getROData(ClassMetadata *theClass) {
21892189

21902190
static void initGenericClassObjCName(ClassMetadata *theClass) {
21912191
// Use the remangler to generate a mangled name from the type metadata.
2192-
Demangle::Demangler Dem;
2192+
Demangle::StackAllocatedDemangler<4096> Dem;
21932193
// Resolve symbolic references to a unique mangling that can be encoded in
21942194
// the class name.
21952195
Dem.setSymbolicReferenceResolver(ResolveToDemanglingForContext(Dem));
@@ -2202,7 +2202,7 @@ static void initGenericClassObjCName(ClassMetadata *theClass) {
22022202
auto globalNode = Dem.createNode(Demangle::Node::Kind::Global);
22032203
globalNode->addChild(typeNode, Dem);
22042204

2205-
auto string = Demangle::mangleNodeOld(globalNode);
2205+
auto string = Demangle::mangleNodeOld(globalNode, &Dem);
22062206

22072207
// If the class is in the Swift module, add a $ to the end of the ObjC
22082208
// name. The old and new Swift libraries must be able to coexist in
@@ -5016,7 +5016,7 @@ void swift::verifyMangledNameRoundtrip(const Metadata *metadata) {
50165016

50175017
if (!verificationEnabled) return;
50185018

5019-
Demangle::Demangler Dem;
5019+
Demangle::StackAllocatedDemangler<1024> Dem;
50205020
Dem.setSymbolicReferenceResolver(ResolveToDemanglingForContext(Dem));
50215021

50225022
auto node = _swift_buildDemanglingForMetadata(metadata, Dem);

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,17 @@ using namespace reflection;
5050
#include <dlfcn.h>
5151
#endif
5252

53-
/// Produce a Demangler value suitable for resolving runtime type metadata
54-
/// strings.
55-
static Demangler getDemanglerForRuntimeTypeResolution() {
56-
Demangler dem;
57-
// Resolve symbolic references to type contexts into the absolute address of
58-
// the type context descriptor, so that if we see a symbolic reference in the
59-
// mangled name we can immediately find the associated metadata.
60-
dem.setSymbolicReferenceResolver(ResolveAsSymbolicReference(dem));
61-
return dem;
62-
}
53+
/// A Demangler suitable for resolving runtime type metadata strings.
54+
template <class Base = Demangler>
55+
class DemanglerForRuntimeTypeResolution : public Base {
56+
public:
57+
DemanglerForRuntimeTypeResolution() {
58+
// Resolve symbolic references to type contexts into the absolute address of
59+
// the type context descriptor, so that if we see a symbolic reference in
60+
// the mangled name we can immediately find the associated metadata.
61+
Base::setSymbolicReferenceResolver(ResolveAsSymbolicReference(*this));
62+
}
63+
};
6364

6465
NodePointer
6566
ResolveAsSymbolicReference::operator()(SymbolicReferenceKind kind,
@@ -416,7 +417,7 @@ swift::_contextDescriptorMatchesMangling(const ContextDescriptor *context,
416417

417418
// Check that the context being extended matches as well.
418419
auto extendedContextNode = node->getChild(1);
419-
auto demangler = getDemanglerForRuntimeTypeResolution();
420+
DemanglerForRuntimeTypeResolution<> demangler;
420421

421422
auto extendedDescriptorFromNode =
422423
_findNominalTypeDescriptor(extendedContextNode, demangler);
@@ -593,7 +594,7 @@ _findNominalTypeDescriptor(Demangle::NodePointer node,
593594
(const ContextDescriptor *)symbolicNode->getIndex());
594595

595596
auto mangledName =
596-
Demangle::mangleNode(node, ExpandResolvedSymbolicReferences(Dem));
597+
Demangle::mangleNode(node, ExpandResolvedSymbolicReferences(Dem), &Dem);
597598

598599
// Look for an existing entry.
599600
// Find the bucket for the metadata entry.
@@ -723,7 +724,7 @@ _findProtocolDescriptor(NodePointer node,
723724
(const ContextDescriptor *)symbolicNode->getIndex());
724725

725726
mangledName =
726-
Demangle::mangleNode(node, ExpandResolvedSymbolicReferences(Dem));
727+
Demangle::mangleNode(node, ExpandResolvedSymbolicReferences(Dem), &Dem);
727728

728729
// Look for an existing entry.
729730
// Find the bucket for the metadata entry.
@@ -820,10 +821,13 @@ Optional<unsigned> swift::_depthIndexToFlatIndex(
820821
/// \returns true if the innermost descriptor is generic.
821822
bool swift::_gatherGenericParameterCounts(
822823
const ContextDescriptor *descriptor,
823-
std::vector<unsigned> &genericParamCounts) {
824+
std::vector<unsigned> &genericParamCounts,
825+
Demangler &BorrowFrom) {
824826
// If we have an extension descriptor, extract the extended type and use
825827
// that.
826-
auto demangler = getDemanglerForRuntimeTypeResolution();
828+
DemanglerForRuntimeTypeResolution<> demangler;
829+
demangler.providePreallocatedMemory(BorrowFrom);
830+
827831
if (auto extension = dyn_cast<ExtensionContextDescriptor>(descriptor)) {
828832
if (auto extendedType =
829833
_findExtendedTypeContextDescriptor(extension, demangler))
@@ -835,7 +839,7 @@ bool swift::_gatherGenericParameterCounts(
835839

836840
// Recurse to record the parent context's generic parameters.
837841
if (auto parent = descriptor->Parent.get())
838-
(void)_gatherGenericParameterCounts(parent, genericParamCounts);
842+
(void)_gatherGenericParameterCounts(parent, genericParamCounts, demangler);
839843

840844
// Record a new level of generic parameters if the count exceeds the
841845
// previous count.
@@ -961,7 +965,7 @@ class DecodedMetadataBuilder {
961965
#if SWIFT_OBJC_INTEROP
962966
// Look for a Swift-defined @objc protocol with the Swift 3 mangling that
963967
// is used for Objective-C entities.
964-
std::string objcMangledName = "_Tt" + mangleNodeOld(node) + "_";
968+
std::string objcMangledName = "_Tt" + mangleNodeOld(node, &demangler) + "_";
965969
if (auto protocol = objc_getProtocol(objcMangledName.c_str()))
966970
return ProtocolDescriptorRef::forObjC(protocol);
967971
#endif
@@ -1024,7 +1028,7 @@ class DecodedMetadataBuilder {
10241028
// Figure out the various levels of generic parameters we have in
10251029
// this type.
10261030
std::vector<unsigned> genericParamCounts;
1027-
(void)_gatherGenericParameterCounts(typeDecl, genericParamCounts);
1031+
(void)_gatherGenericParameterCounts(typeDecl, genericParamCounts, demangler);
10281032
unsigned numTotalGenericParams =
10291033
genericParamCounts.empty() ? 0 : genericParamCounts.back();
10301034

@@ -1048,7 +1052,7 @@ class DecodedMetadataBuilder {
10481052
// If we have a parent, gather it's generic arguments "as written".
10491053
if (parent) {
10501054
gatherWrittenGenericArgs(parent, parent->getTypeContextDescriptor(),
1051-
allGenericArgs);
1055+
allGenericArgs, demangler);
10521056
}
10531057

10541058
// Add the generic arguments we were given.
@@ -1294,7 +1298,8 @@ static TypeInfo swift_getTypeByMangledNameImpl(
12941298
StringRef typeName,
12951299
SubstGenericParameterFn substGenericParam,
12961300
SubstDependentWitnessTableFn substWitnessTable) {
1297-
auto demangler = getDemanglerForRuntimeTypeResolution();
1301+
DemanglerForRuntimeTypeResolution<StackAllocatedDemangler<2048>> demangler;
1302+
12981303
NodePointer node;
12991304

13001305
// Check whether this is the convenience syntax "ModuleName.ClassName".
@@ -1620,7 +1625,8 @@ demangleToGenericParamRef(StringRef typeName) {
16201625
void swift::gatherWrittenGenericArgs(
16211626
const Metadata *metadata,
16221627
const TypeContextDescriptor *description,
1623-
std::vector<const Metadata *> &allGenericArgs) {
1628+
std::vector<const Metadata *> &allGenericArgs,
1629+
Demangler &BorrowFrom) {
16241630
auto generics = description->getGenericContext();
16251631
if (!generics)
16261632
return;
@@ -1674,7 +1680,8 @@ void swift::gatherWrittenGenericArgs(
16741680

16751681
// Retrieve the mapping information needed for depth/index -> flat index.
16761682
std::vector<unsigned> genericParamCounts;
1677-
(void)_gatherGenericParameterCounts(description, genericParamCounts);
1683+
(void)_gatherGenericParameterCounts(description, genericParamCounts,
1684+
BorrowFrom);
16781685

16791686
// Walk through the generic requirements to evaluate same-type
16801687
// constraints that are needed to fill in missing generic arguments.

stdlib/public/runtime/Private.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,8 @@ class TypeInfo {
386386
///
387387
/// \returns true if the innermost descriptor is generic.
388388
bool _gatherGenericParameterCounts(const ContextDescriptor *descriptor,
389-
std::vector<unsigned> &genericParamCounts);
389+
std::vector<unsigned> &genericParamCounts,
390+
Demangler &BorrowFrom);
390391

391392
/// Map depth/index to a flat index.
392393
llvm::Optional<unsigned> _depthIndexToFlatIndex(
@@ -451,7 +452,8 @@ class TypeInfo {
451452
/// \endcode
452453
void gatherWrittenGenericArgs(const Metadata *metadata,
453454
const TypeContextDescriptor *description,
454-
std::vector<const Metadata *> &allGenericArgs);
455+
std::vector<const Metadata *> &allGenericArgs,
456+
Demangler &BorrowFrom);
455457

456458
Demangle::NodePointer
457459
_buildDemanglingForContext(const ContextDescriptor *context,

0 commit comments

Comments
 (0)