diff --git a/llvm/include/llvm/Support/YAMLTraits.h b/llvm/include/llvm/Support/YAMLTraits.h --- a/llvm/include/llvm/Support/YAMLTraits.h +++ b/llvm/include/llvm/Support/YAMLTraits.h @@ -1464,11 +1464,8 @@ bool canElideEmptySequence() override; class HNode { - virtual void anchor(); - public: - HNode(Node *n) : _node(n) { } - virtual ~HNode() = default; + HNode(Node *n) : _node(n) {} static bool classof(const HNode *) { return true; } @@ -1476,8 +1473,6 @@ }; class EmptyHNode : public HNode { - void anchor() override; - public: EmptyHNode(Node *n) : HNode(n) { } @@ -1487,8 +1482,6 @@ }; class ScalarHNode : public HNode { - void anchor() override; - public: ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { } @@ -1506,8 +1499,6 @@ }; class MapHNode : public HNode { - void anchor() override; - public: MapHNode(Node *n) : HNode(n) { } @@ -1517,16 +1508,13 @@ static bool classof(const MapHNode *) { return true; } - using NameToNodeAndLoc = - StringMap, SMRange>>; + using NameToNodeAndLoc = StringMap>; NameToNodeAndLoc Mapping; SmallVector ValidKeys; }; class SequenceHNode : public HNode { - void anchor() override; - public: SequenceHNode(Node *n) : HNode(n) { } @@ -1536,10 +1524,10 @@ static bool classof(const SequenceHNode *) { return true; } - std::vector> Entries; + std::vector Entries; }; - std::unique_ptr createHNodes(Node *node); + Input::HNode *createHNodes(Node *node); void setError(HNode *hnode, const Twine &message); void setError(Node *node, const Twine &message); void setError(const SMRange &Range, const Twine &message); @@ -1548,6 +1536,9 @@ void reportWarning(Node *hnode, const Twine &message); void reportWarning(const SMRange &Range, const Twine &message); + /// Release memory used by HNodes. + void releaseHNodeBuffers(); + public: // These are only used by operator>>. They could be private // if those templated things could be made friends. @@ -1562,9 +1553,13 @@ private: SourceMgr SrcMgr; // must be before Strm std::unique_ptr Strm; - std::unique_ptr TopNode; + HNode *TopNode = nullptr; std::error_code EC; BumpPtrAllocator StringAllocator; + SpecificBumpPtrAllocator EmptyHNodeAllocator; + SpecificBumpPtrAllocator ScalarHNodeAllocator; + SpecificBumpPtrAllocator MapHNodeAllocator; + SpecificBumpPtrAllocator SequenceHNodeAllocator; document_iterator DocIterator; llvm::BitVector BitValuesUsed; HNode *CurrentNode = nullptr; diff --git a/llvm/lib/Support/YAMLTraits.cpp b/llvm/lib/Support/YAMLTraits.cpp --- a/llvm/lib/Support/YAMLTraits.cpp +++ b/llvm/lib/Support/YAMLTraits.cpp @@ -75,13 +75,6 @@ std::error_code Input::error() { return EC; } -// Pin the vtables to this file. -void Input::HNode::anchor() {} -void Input::EmptyHNode::anchor() {} -void Input::ScalarHNode::anchor() {} -void Input::MapHNode::anchor() {} -void Input::SequenceHNode::anchor() {} - bool Input::outputting() const { return false; } @@ -99,8 +92,9 @@ ++DocIterator; return setCurrentDocument(); } + releaseHNodeBuffers(); TopNode = createHNodes(N); - CurrentNode = TopNode.get(); + CurrentNode = TopNode; return true; } return false; @@ -174,7 +168,7 @@ return false; } MN->ValidKeys.push_back(Key); - HNode *Value = MN->Mapping[Key].first.get(); + HNode *Value = MN->Mapping[Key].first; if (!Value) { if (Required) setError(CurrentNode, Twine("missing required key '") + Key + "'"); @@ -237,7 +231,7 @@ return false; if (SequenceHNode *SQ = dyn_cast(CurrentNode)) { SaveInfo = CurrentNode; - CurrentNode = SQ->Entries[Index].get(); + CurrentNode = SQ->Entries[Index]; return true; } return false; @@ -254,7 +248,7 @@ return false; if (SequenceHNode *SQ = dyn_cast(CurrentNode)) { SaveInfo = CurrentNode; - CurrentNode = SQ->Entries[index].get(); + CurrentNode = SQ->Entries[index]; return true; } return false; @@ -313,7 +307,7 @@ if (SequenceHNode *SQ = dyn_cast(CurrentNode)) { unsigned Index = 0; for (auto &N : SQ->Entries) { - if (ScalarHNode *SN = dyn_cast(N.get())) { + if (ScalarHNode *SN = dyn_cast(N)) { if (SN->value().equals(Str)) { BitValuesUsed[Index] = true; return true; @@ -336,7 +330,7 @@ assert(BitValuesUsed.size() == SQ->Entries.size()); for (unsigned i = 0; i < SQ->Entries.size(); ++i) { if (!BitValuesUsed[i]) { - setError(SQ->Entries[i].get(), "unknown bit value"); + setError(SQ->Entries[i], "unknown bit value"); return; } } @@ -395,7 +389,14 @@ Strm->printError(range, message, SourceMgr::DK_Warning); } -std::unique_ptr Input::createHNodes(Node *N) { +void Input::releaseHNodeBuffers() { + EmptyHNodeAllocator.DestroyAll(); + ScalarHNodeAllocator.DestroyAll(); + SequenceHNodeAllocator.DestroyAll(); + MapHNodeAllocator.DestroyAll(); +} + +Input::HNode *Input::createHNodes(Node *N) { SmallString<128> StringStorage; switch (N->getType()) { case Node::NK_Scalar: { @@ -405,27 +406,27 @@ // Copy string to permanent storage KeyStr = StringStorage.str().copy(StringAllocator); } - return std::make_unique(N, KeyStr); + return new (ScalarHNodeAllocator.Allocate()) ScalarHNode(N, KeyStr); } case Node::NK_BlockScalar: { BlockScalarNode *BSN = dyn_cast(N); StringRef ValueCopy = BSN->getValue().copy(StringAllocator); - return std::make_unique(N, ValueCopy); + return new (ScalarHNodeAllocator.Allocate()) ScalarHNode(N, ValueCopy); } case Node::NK_Sequence: { SequenceNode *SQ = dyn_cast(N); - auto SQHNode = std::make_unique(N); + auto SQHNode = new (SequenceHNodeAllocator.Allocate()) SequenceHNode(N); for (Node &SN : *SQ) { auto Entry = createHNodes(&SN); if (EC) break; - SQHNode->Entries.push_back(std::move(Entry)); + SQHNode->Entries.push_back(Entry); } - return std::move(SQHNode); + return SQHNode; } case Node::NK_Mapping: { MappingNode *Map = dyn_cast(N); - auto mapHNode = std::make_unique(N); + auto mapHNode = new (MapHNodeAllocator.Allocate()) MapHNode(N); for (KeyValueNode &KVN : *Map) { Node *KeyNode = KVN.getKey(); ScalarNode *Key = dyn_cast_or_null(KeyNode); @@ -457,7 +458,7 @@ return std::move(mapHNode); } case Node::NK_Null: - return std::make_unique(N); + return new (EmptyHNodeAllocator.Allocate()) EmptyHNode(N); default: setError(N, "unknown node kind"); return nullptr;