Use sets of members in CFXA_Node node shuffling code. This is not essential for the first versions of cppgc, since we are not GCing while the stack is still active. -- avoid some indirection while at it. Change-Id: I1bacdb3b21d6cd9a5bbc5b3f19666d8b22594a3c Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/73851 Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp index 212d7b0..c675844 100644 --- a/xfa/fxfa/parser/cxfa_node.cpp +++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -546,12 +546,19 @@ return true; } -std::vector<CXFA_Node*> NodesSortedByDocumentIdx( - const std::set<CXFA_Node*>& rgNodeSet) { - if (rgNodeSet.empty()) - return std::vector<CXFA_Node*>(); +// Stack allocated. Using containers of members would be correct here +// if advanced GC worked with STL. +using NodeSet = std::set<cppgc::Member<CXFA_Node>>; +using NodeSetPair = std::pair<NodeSet, NodeSet>; +using NodeSetPairMap = std::map<uint32_t, NodeSetPair>; +using NodeSetPairMapMap = std::map<CXFA_Node*, NodeSetPairMap>; +using NodeVector = std::vector<cppgc::Member<CXFA_Node>>; - std::vector<CXFA_Node*> rgNodeArray; +NodeVector NodesSortedByDocumentIdx(const NodeSet& rgNodeSet) { + if (rgNodeSet.empty()) + return NodeVector(); + + NodeVector rgNodeArray; CXFA_Node* pCommonParent = (*rgNodeSet.begin())->GetParent(); for (CXFA_Node* pNode = pCommonParent->GetFirstChild(); pNode; pNode = pNode->GetNextSibling()) { @@ -561,40 +568,26 @@ return rgNodeArray; } -using CXFA_NodeSetPair = std::pair<std::set<CXFA_Node*>, std::set<CXFA_Node*>>; -using CXFA_NodeSetPairMap = - std::map<uint32_t, std::unique_ptr<CXFA_NodeSetPair>>; -using CXFA_NodeSetPairMapMap = - std::map<CXFA_Node*, std::unique_ptr<CXFA_NodeSetPairMap>>; - -CXFA_NodeSetPair* NodeSetPairForNode(CXFA_Node* pNode, - CXFA_NodeSetPairMapMap* pMap) { +NodeSetPair* NodeSetPairForNode(CXFA_Node* pNode, NodeSetPairMapMap* pMap) { CXFA_Node* pParentNode = pNode->GetParent(); uint32_t dwNameHash = pNode->GetNameHash(); if (!pParentNode || !dwNameHash) return nullptr; - if (!(*pMap)[pParentNode]) - (*pMap)[pParentNode] = std::make_unique<CXFA_NodeSetPairMap>(); - - CXFA_NodeSetPairMap* pNodeSetPairMap = (*pMap)[pParentNode].get(); - if (!(*pNodeSetPairMap)[dwNameHash]) - (*pNodeSetPairMap)[dwNameHash] = std::make_unique<CXFA_NodeSetPair>(); - - return (*pNodeSetPairMap)[dwNameHash].get(); + return &((*pMap)[pParentNode][dwNameHash]); } -void ReorderDataNodes(const std::set<CXFA_Node*>& sSet1, - const std::set<CXFA_Node*>& sSet2, +void ReorderDataNodes(const NodeSet& sSet1, + const NodeSet& sSet2, bool bInsertBefore) { - CXFA_NodeSetPairMapMap rgMap; + NodeSetPairMapMap rgMap; for (CXFA_Node* pNode : sSet1) { - CXFA_NodeSetPair* pNodeSetPair = NodeSetPairForNode(pNode, &rgMap); + NodeSetPair* pNodeSetPair = NodeSetPairForNode(pNode, &rgMap); if (pNodeSetPair) pNodeSetPair->first.insert(pNode); } for (CXFA_Node* pNode : sSet2) { - CXFA_NodeSetPair* pNodeSetPair = NodeSetPairForNode(pNode, &rgMap); + NodeSetPair* pNodeSetPair = NodeSetPairForNode(pNode, &rgMap); if (pNodeSetPair) { if (pdfium::Contains(pNodeSetPair->first, pNode)) pNodeSetPair->first.erase(pNode); @@ -602,19 +595,13 @@ pNodeSetPair->second.insert(pNode); } } - for (const auto& iter1 : rgMap) { - CXFA_NodeSetPairMap* pNodeSetPairMap = iter1.second.get(); - if (!pNodeSetPairMap) - continue; - - for (const auto& iter2 : *pNodeSetPairMap) { - CXFA_NodeSetPair* pNodeSetPair = iter2.second.get(); - if (!pNodeSetPair) - continue; + for (auto& iter1 : rgMap) { + NodeSetPairMap* pNodeSetPairMap = &iter1.second; + for (auto& iter2 : *pNodeSetPairMap) { + NodeSetPair* pNodeSetPair = &iter2.second; if (!pNodeSetPair->first.empty() && !pNodeSetPair->second.empty()) { - std::vector<CXFA_Node*> rgNodeArray1 = - NodesSortedByDocumentIdx(pNodeSetPair->first); - std::vector<CXFA_Node*> rgNodeArray2 = + NodeVector rgNodeArray1 = NodesSortedByDocumentIdx(pNodeSetPair->first); + NodeVector rgNodeArray2 = NodesSortedByDocumentIdx(pNodeSetPair->second); CXFA_Node* pParentNode = nullptr; CXFA_Node* pBeforeNode = nullptr; @@ -626,7 +613,7 @@ pParentNode = pLastNode->GetParent(); pBeforeNode = pLastNode->GetNextSibling(); } - for (auto* pCurNode : rgNodeArray1) { + for (auto& pCurNode : rgNodeArray1) { pParentNode->RemoveChildAndNotify(pCurNode, true); pParentNode->InsertChildAndNotify(pCurNode, pBeforeNode); } @@ -1926,29 +1913,25 @@ iCount > 0 ? item->GetNextSibling() : GetNextSibling(); GetParent()->InsertChildAndNotify(pNewInstance, pNextSibling); if (bMoveDataBindingNodes) { - std::set<CXFA_Node*> sNew; - std::set<CXFA_Node*> sAfter; + NodeSet sNew; CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode> sIteratorNew(pNewInstance); for (CXFA_Node* pNode = sIteratorNew.GetCurrent(); pNode; pNode = sIteratorNew.MoveToNext()) { CXFA_Node* pDataNode = pNode->GetBindData(); - if (!pDataNode) - continue; - - sNew.insert(pDataNode); + if (pDataNode) + sNew.insert(pDataNode); } + NodeSet sAfter; CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode> sIteratorAfter(pNextSibling); for (CXFA_Node* pNode = sIteratorAfter.GetCurrent(); pNode; pNode = sIteratorAfter.MoveToNext()) { CXFA_Node* pDataNode = pNode->GetBindData(); - if (!pDataNode) - continue; - - sAfter.insert(pDataNode); + if (pDataNode) + sAfter.insert(pDataNode); } ReorderDataNodes(sNew, sAfter, false); } @@ -1961,29 +1944,25 @@ GetParent()->InsertChildAndNotify(pNewInstance, pBeforeInstance); if (bMoveDataBindingNodes) { - std::set<CXFA_Node*> sNew; - std::set<CXFA_Node*> sBefore; + NodeSet sNew; CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode> sIteratorNew(pNewInstance); for (CXFA_Node* pNode = sIteratorNew.GetCurrent(); pNode; pNode = sIteratorNew.MoveToNext()) { CXFA_Node* pDataNode = pNode->GetBindData(); - if (!pDataNode) - continue; - - sNew.insert(pDataNode); + if (pDataNode) + sNew.insert(pDataNode); } + NodeSet sBefore; CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode> sIteratorBefore(pBeforeInstance); for (CXFA_Node* pNode = sIteratorBefore.GetCurrent(); pNode; pNode = sIteratorBefore.MoveToNext()) { CXFA_Node* pDataNode = pNode->GetBindData(); - if (!pDataNode) - continue; - - sBefore.insert(pDataNode); + if (pDataNode) + sBefore.insert(pDataNode); } ReorderDataNodes(sNew, sBefore, true); }