Skip to content

Avoid malloc allocations in the runtime #23131

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 6 commits into from
Mar 7, 2019
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
8 changes: 8 additions & 0 deletions include/swift/Basic/Mangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ class Mangler {
}
};

void addSubstWordsInIdent(const WordReplacement &repl) {
SubstWordsInIdent.push_back(repl);
}

void addWord(const SubstitutionWord &word) {
Words.push_back(word);
}

/// Returns the buffer as a StringRef, needed by mangleIdentifier().
StringRef getBufferStr() const {
return StringRef(Storage.data(), Storage.size());
Expand Down
18 changes: 9 additions & 9 deletions include/swift/Demangling/Demangle.h
Original file line number Diff line number Diff line change
Expand Up @@ -490,23 +490,23 @@ void mangleIdentifier(const char *data, size_t length,
bool usePunycode = true);

/// Remangle a demangled parse tree.
///
/// If \p BorrowFrom is specified, the initial bump pointer memory is
/// borrowed from the free memory of BorrowFrom.
std::string mangleNode(NodePointer root,
NodeFactory *BorrowFrom = nullptr);
std::string mangleNode(NodePointer root);

using SymbolicResolver =
llvm::function_ref<Demangle::NodePointer (SymbolicReferenceKind,
const void *)>;

/// Remangle a demangled parse tree, using a callback to resolve
/// symbolic references.
std::string mangleNode(NodePointer root, SymbolicResolver resolver);

/// Remangle a demangled parse tree, using a callback to resolve
/// symbolic references.
///
/// If \p BorrowFrom is specified, the initial bump pointer memory is
/// borrowed from the free memory of BorrowFrom.
std::string mangleNode(NodePointer root, SymbolicResolver resolver,
NodeFactory *BorrowFrom = nullptr);
/// The returned string is owned by \p Factory. This means \p Factory must stay
/// alive as long as the returned string is used.
llvm::StringRef mangleNode(NodePointer root, SymbolicResolver resolver,
NodeFactory &Factory);

/// Remangle in the old mangling scheme.
///
Expand Down
14 changes: 13 additions & 1 deletion include/swift/Demangling/Demangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,11 @@ template<typename T> class Vector {
Capacity = 0;
Elems = 0;
}


void clear() {
NumElems = 0;
}

iterator begin() { return Elems; }
iterator end() { return Elems + NumElems; }

Expand All @@ -299,6 +303,11 @@ template<typename T> class Vector {

T &back() { return (*this)[NumElems - 1]; }

void resetSize(size_t toPos) {
assert(toPos <= NumElems);
NumElems = toPos;
}

void push_back(const T &NewElem, NodeFactory &Factory) {
if (NumElems >= Capacity)
Factory.Reallocate(Elems, Capacity, /*Growth*/ 1);
Expand Down Expand Up @@ -327,6 +336,9 @@ class CharVector : public Vector<char> {
// Append an integer as readable number.
void append(int Number, NodeFactory &Factory);

// Append an unsigned 64 bit integer as readable number.
void append(unsigned long long Number, NodeFactory &Factory);

StringRef str() const {
return StringRef(Elems, NumElems);
}
Expand Down
6 changes: 3 additions & 3 deletions include/swift/Demangling/ManglingUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,13 @@ void mangleIdentifier(Mangler &M, StringRef ident) {
if (WordIdx >= 0) {
// We found a word substitution!
assert(WordIdx < 26);
M.SubstWordsInIdent.push_back({wordStartPos, WordIdx});
M.addSubstWordsInIdent({wordStartPos, WordIdx});
} else if (wordLen >= 2 && M.Words.size() < M.MaxNumWords) {
// It's a new word: remember it.
// Note: at this time the word's start position is relative to the
// begin of the identifier. We must update it afterwards so that it is
// relative to the begin of the whole mangled Buffer.
M.Words.push_back({wordStartPos, wordLen});
M.addWord({wordStartPos, wordLen});
}
wordStartPos = NotInsideWord;
}
Expand All @@ -181,7 +181,7 @@ void mangleIdentifier(Mangler &M, StringRef ident) {

size_t Pos = 0;
// Add a dummy-word at the end of the list.
M.SubstWordsInIdent.push_back({ident.size(), -1});
M.addSubstWordsInIdent({ident.size(), -1});

// Mangle a sequence of word substitutions and sub-strings.
for (size_t Idx = 0, End = M.SubstWordsInIdent.size(); Idx < End; ++Idx) {
Expand Down
18 changes: 9 additions & 9 deletions include/swift/Demangling/TypeDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ class TypeDecoder {
if (Node->getNumChildren() < 2)
return BuiltType();

std::vector<BuiltType> args;
SmallVector<BuiltType, 8> args;

const auto &genericArgs = Node->getChild(1);
assert(genericArgs->getKind() == NodeKind::TypeList);
Expand Down Expand Up @@ -427,7 +427,7 @@ class TypeDecoder {
return BuiltType();

// Find the protocol list.
std::vector<BuiltProtocolDecl> Protocols;
SmallVector<BuiltProtocolDecl, 8> Protocols;
auto TypeList = Node->getChild(0);
if (TypeList->getKind() == NodeKind::ProtocolList &&
TypeList->getNumChildren() >= 1) {
Expand Down Expand Up @@ -514,7 +514,7 @@ class TypeDecoder {
return BuiltType();

bool hasParamFlags = false;
std::vector<FunctionParam<BuiltType>> parameters;
SmallVector<FunctionParam<BuiltType>, 8> parameters;
if (!decodeMangledFunctionInputType(Node->getChild(isThrow ? 1 : 0),
parameters, hasParamFlags))
return BuiltType();
Expand All @@ -531,9 +531,9 @@ class TypeDecoder {
}
case NodeKind::ImplFunctionType: {
auto calleeConvention = ImplParameterConvention::Direct_Unowned;
std::vector<ImplFunctionParam<BuiltType>> parameters;
std::vector<ImplFunctionResult<BuiltType>> results;
std::vector<ImplFunctionResult<BuiltType>> errorResults;
SmallVector<ImplFunctionParam<BuiltType>, 8> parameters;
SmallVector<ImplFunctionResult<BuiltType>, 8> results;
SmallVector<ImplFunctionResult<BuiltType>, 8> errorResults;
ImplFunctionTypeFlags flags;

for (unsigned i = 0; i < Node->getNumChildren(); i++) {
Expand Down Expand Up @@ -611,7 +611,7 @@ class TypeDecoder {
return decodeMangledType(Node->getChild(0));

case NodeKind::Tuple: {
std::vector<BuiltType> elements;
SmallVector<BuiltType, 8> elements;
std::string labels;
bool variadic = false;
for (auto &element : *Node) {
Expand Down Expand Up @@ -785,7 +785,7 @@ class TypeDecoder {
private:
template <typename T>
bool decodeImplFunctionPart(Demangle::NodePointer node,
std::vector<T> &results) {
SmallVectorImpl<T> &results) {
if (node->getNumChildren() != 2)
return true;

Expand Down Expand Up @@ -871,7 +871,7 @@ class TypeDecoder {

bool decodeMangledFunctionInputType(
Demangle::NodePointer node,
std::vector<FunctionParam<BuiltType>> &params,
SmallVectorImpl<FunctionParam<BuiltType>> &params,
bool &hasParamFlags) {
// Look through a couple of sugar nodes.
if (node->getKind() == NodeKind::Type ||
Expand Down
12 changes: 6 additions & 6 deletions include/swift/Reflection/TypeRefBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,12 @@ class TypeRefBuilder {

Optional<std::string>
createTypeDecl(Node *node, bool &typeAlias) {
return Demangle::mangleNode(node, &Dem);
return Demangle::mangleNode(node);
}

BuiltProtocolDecl
createProtocolDecl(Node *node) {
return std::make_pair(Demangle::mangleNode(node, &Dem), false);
return std::make_pair(Demangle::mangleNode(node), false);
}

BuiltProtocolDecl
Expand Down Expand Up @@ -274,21 +274,21 @@ class TypeRefBuilder {

const BoundGenericTypeRef *
createBoundGenericType(const Optional<std::string> &mangledName,
const std::vector<const TypeRef *> &args,
ArrayRef<const TypeRef *> args,
const TypeRef *parent) {
return BoundGenericTypeRef::create(*this, *mangledName, args, parent);
}

const TupleTypeRef *
createTupleType(const std::vector<const TypeRef *> &elements,
createTupleType(ArrayRef<const TypeRef *> elements,
std::string &&labels, bool isVariadic) {
// FIXME: Add uniqueness checks in TupleTypeRef::Profile and
// unittests/Reflection/TypeRef.cpp if using labels for identity.
return TupleTypeRef::create(*this, elements, isVariadic);
}

const FunctionTypeRef *createFunctionType(
const std::vector<remote::FunctionParam<const TypeRef *>> &params,
ArrayRef<remote::FunctionParam<const TypeRef *>> params,
const TypeRef *result, FunctionTypeFlags flags) {
return FunctionTypeRef::create(*this, params, result, flags);
}
Expand Down Expand Up @@ -406,7 +406,7 @@ class TypeRefBuilder {

const ObjCClassTypeRef *
createBoundGenericObjCClassType(const std::string &name,
std::vector<const TypeRef *> &args) {
ArrayRef<const TypeRef *> args) {
// Remote reflection just ignores generic arguments for Objective-C
// lightweight generic types, since they don't affect layout.
return createObjCClassType(name);
Expand Down
11 changes: 10 additions & 1 deletion lib/Demangling/Demangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,14 +465,23 @@ void CharVector::append(StringRef Rhs, NodeFactory &Factory) {
}

void CharVector::append(int Number, NodeFactory &Factory) {
const int MaxIntPrintSize = 8;
const int MaxIntPrintSize = 11;
if (NumElems + MaxIntPrintSize > Capacity)
Factory.Reallocate(Elems, Capacity, /*Growth*/ MaxIntPrintSize);
int Length = snprintf(Elems + NumElems, MaxIntPrintSize, "%d", Number);
assert(Length > 0 && Length < MaxIntPrintSize);
NumElems += Length;
}

void CharVector::append(unsigned long long Number, NodeFactory &Factory) {
const int MaxPrintSize = 21;
if (NumElems + MaxPrintSize > Capacity)
Factory.Reallocate(Elems, Capacity, /*Growth*/ MaxPrintSize);
int Length = snprintf(Elems + NumElems, MaxPrintSize, "%llu", Number);
assert(Length > 0 && Length < MaxPrintSize);
NumElems += Length;
}

//////////////////////////////////
// Demangler member functions //
//////////////////////////////////
Expand Down
Loading