diff options
author | Noel Grandin <noelgrandin@gmail.com> | 2021-09-19 11:13:53 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2021-09-20 17:48:08 +0200 |
commit | afd918a81bc2dce4830bc94cbd88b9038f5715ff (patch) | |
tree | 5d6d46d4c149be04b34066f15fff470d19ec9127 /svl | |
parent | 88b72d85ef82a5a6ca019ef9b88f5389db067c83 (diff) |
introduce SfxItemSetFixed and use it in DefaultProperties
DefaultProperties::SetObjectItemSet is very hot when loading
shapes, and a large chunk of that cost is allocating the pool item
array.
So use a template class to allocate the array in-line to the class,
which means it can be allocated on-stack.
Change-Id: Ic53b41f35784726362de38fceb35f8634cddf0a4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122310
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'svl')
-rw-r--r-- | svl/source/items/itemiter.cxx | 4 | ||||
-rw-r--r-- | svl/source/items/itemset.cxx | 97 |
2 files changed, 69 insertions, 32 deletions
diff --git a/svl/source/items/itemiter.cxx b/svl/source/items/itemiter.cxx index fb00339877c7..3e4b927d2af9 100644 --- a/svl/source/items/itemiter.cxx +++ b/svl/source/items/itemiter.cxx @@ -30,7 +30,7 @@ SfxItemIter::SfxItemIter(const SfxItemSet& rItemSet) } else { - SfxPoolItem const** ppFnd = m_rSet.m_pItems.get(); + SfxPoolItem const** ppFnd = m_rSet.m_ppItems; // Find the first Item that is set for (m_nStart = 0; !*(ppFnd + m_nStart); ++m_nStart) @@ -50,7 +50,7 @@ SfxItemIter::~SfxItemIter() {} // Precondition : m_nCurrent < m_nEnd const SfxPoolItem* SfxItemIter::ImplNextItem() { - SfxPoolItem const** ppFnd = m_rSet.m_pItems.get(); + SfxPoolItem const** ppFnd = m_rSet.m_ppItems; do { m_nCurrent++; diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx index 418471183aed..04fab3c9306e 100644 --- a/svl/source/items/itemset.cxx +++ b/svl/source/items/itemset.cxx @@ -52,18 +52,35 @@ SfxItemSet::SfxItemSet(SfxItemPool& rPool) SfxItemSet::SfxItemSet( SfxItemPool& rPool, SfxAllItemSetFlag ) : m_pPool(&rPool) , m_pParent(nullptr) + , m_ppItems(nullptr) , m_nCount(0) + , m_bItemsFixed(false) { } +/** special constructor for SfxItemSetFixed */ +SfxItemSet::SfxItemSet( SfxItemPool& rPool, WhichRangesContainer&& ranges, SfxPoolItem const ** ppItems ) + : m_pPool(&rPool) + , m_pParent(nullptr) + , m_ppItems(ppItems) + , m_pWhichRanges(std::move(ranges)) + , m_nCount(0) + , m_bItemsFixed(true) +{ + assert(ppItems); + assert(m_pWhichRanges.size() > 0); + assert(svl::detail::validRanges2(m_pWhichRanges)); +} + SfxItemSet::SfxItemSet( SfxItemPool & pool, const WhichRangesContainer& wids, std::size_t items): m_pPool(&pool), m_pParent(nullptr), - m_pItems(new SfxPoolItem const *[items]{}), + m_ppItems(new SfxPoolItem const *[items]{}), m_pWhichRanges(wids), - m_nCount(0) + m_nCount(0), + m_bItemsFixed(false) { assert(wids.size() != 0); assert(svl::detail::validRanges2(m_pWhichRanges)); @@ -84,16 +101,20 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rASet ) , m_pParent( rASet.m_pParent ) , m_pWhichRanges( rASet.m_pWhichRanges ) , m_nCount( rASet.m_nCount ) + , m_bItemsFixed(false) { if (rASet.m_pWhichRanges.empty()) + { + m_ppItems = nullptr; return; + } auto nCnt = svl::detail::CountRanges(m_pWhichRanges); - m_pItems.reset(new const SfxPoolItem* [nCnt] {}); + m_ppItems = new const SfxPoolItem* [nCnt] {}; // Copy attributes - SfxPoolItem const** ppDst = m_pItems.get(); - SfxPoolItem const** ppSrc = rASet.m_pItems.get(); + SfxPoolItem const** ppDst = m_ppItems; + SfxPoolItem const** ppSrc = rASet.m_ppItems; for( sal_uInt16 n = nCnt; n; --n, ++ppDst, ++ppSrc ) if ( nullptr == *ppSrc || // Current Default? IsInvalidItem(*ppSrc) || // DontCare? @@ -118,10 +139,21 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rASet ) SfxItemSet::SfxItemSet(SfxItemSet&& rASet) noexcept : m_pPool( rASet.m_pPool ) , m_pParent( rASet.m_pParent ) - , m_pItems( std::move(rASet.m_pItems) ) + , m_ppItems( rASet.m_ppItems ) , m_pWhichRanges( std::move(rASet.m_pWhichRanges) ) , m_nCount( rASet.m_nCount ) + , m_bItemsFixed(false) { + if (rASet.m_bItemsFixed) + { + // have to make a copy + int noItems = svl::detail::CountRanges(m_pWhichRanges); + m_ppItems = new const SfxPoolItem* [noItems]; + std::copy(rASet.m_ppItems, rASet.m_ppItems + noItems, m_ppItems); + } + else + // taking over ownership + rASet.m_ppItems = nullptr; rASet.m_pPool = nullptr; rASet.m_pParent = nullptr; rASet.m_nCount = 0; @@ -135,7 +167,7 @@ SfxItemSet::~SfxItemSet() sal_uInt16 nCount = TotalCount(); if( Count() ) { - SfxPoolItem const** ppFnd = m_pItems.get(); + SfxPoolItem const** ppFnd = m_ppItems; for( sal_uInt16 nCnt = nCount; nCnt; --nCnt, ++ppFnd ) if( *ppFnd && !IsInvalidItem(*ppFnd) ) { @@ -154,7 +186,8 @@ SfxItemSet::~SfxItemSet() } } - m_pItems.reset(); + if (!m_bItemsFixed) + delete[] m_ppItems; m_pWhichRanges.reset(); // for invariant-testing } @@ -167,7 +200,7 @@ sal_uInt16 SfxItemSet::ClearItem( sal_uInt16 nWhich ) return 0; sal_uInt16 nDel = 0; - SfxPoolItem const** ppFnd = m_pItems.get(); + SfxPoolItem const** ppFnd = m_ppItems; if( nWhich ) { @@ -253,7 +286,7 @@ sal_uInt16 SfxItemSet::ClearItem( sal_uInt16 nWhich ) void SfxItemSet::ClearInvalidItems() { - SfxPoolItem const** ppFnd = m_pItems.get(); + SfxPoolItem const** ppFnd = m_ppItems; for (const WhichPair& rPair : m_pWhichRanges) { for( sal_uInt16 nWhich = rPair.first; nWhich <= rPair.second; ++nWhich, ++ppFnd ) @@ -269,7 +302,7 @@ void SfxItemSet::InvalidateAllItems() { assert( !m_nCount && "There are still Items set" ); m_nCount = TotalCount(); - memset(static_cast<void*>(m_pItems.get()), -1, m_nCount * sizeof(SfxPoolItem*)); + memset(static_cast<void*>(m_ppItems), -1, m_nCount * sizeof(SfxPoolItem*)); } SfxItemState SfxItemSet::GetItemState( sal_uInt16 nWhich, @@ -281,7 +314,7 @@ SfxItemState SfxItemSet::GetItemState( sal_uInt16 nWhich, SfxItemState eRet = SfxItemState::UNKNOWN; do { - SfxPoolItem const** ppFnd = pCurrentSet->m_pItems.get(); + SfxPoolItem const** ppFnd = pCurrentSet->m_ppItems; for (const WhichPair& rPair : pCurrentSet->m_pWhichRanges) { if ( rPair.first <= nWhich && nWhich <= rPair.second ) @@ -334,7 +367,7 @@ const SfxPoolItem* SfxItemSet::PutImpl( const SfxPoolItem& rItem, sal_uInt16 nWh return nullptr; //FIXME: Only because of Outliner bug } - SfxPoolItem const** ppFnd = m_pItems.get(); + SfxPoolItem const** ppFnd = m_ppItems; for (const WhichPair& rPair : m_pWhichRanges) { if( rPair.first <= nWhich && nWhich <= rPair.second ) @@ -431,7 +464,7 @@ bool SfxItemSet::Put( const SfxItemSet& rSet, bool bInvalidAsDefault ) bool bRet = false; if( rSet.Count() ) { - SfxPoolItem const** ppFnd = rSet.m_pItems.get(); + SfxPoolItem const** ppFnd = rSet.m_ppItems; for (const WhichPair& rPair : rSet.m_pWhichRanges) { for ( sal_uInt16 nWhich = rPair.first; nWhich <= rPair.second; ++nWhich, ++ppFnd ) @@ -477,7 +510,7 @@ void SfxItemSet::PutExtended ) { // don't "optimize" with "if( rSet.Count()" because of dont-care + defaults - SfxPoolItem const** ppFnd = rSet.m_pItems.get(); + SfxPoolItem const** ppFnd = rSet.m_ppItems; for (const WhichPair& rPair : rSet.m_pWhichRanges) { for ( sal_uInt16 nWhich = rPair.first; nWhich <= rPair.second; ++nWhich, ++ppFnd ) @@ -619,14 +652,18 @@ void SfxItemSet::RecreateRanges_Impl(const WhichRangesContainer& pNewRanges) sal_uInt16 nOldTotalCount = TotalCount(); for ( sal_uInt16 nItem = 0; nItem < nOldTotalCount; ++nItem ) { - const SfxPoolItem *pItem = m_pItems[nItem]; + const SfxPoolItem *pItem = m_ppItems[nItem]; if ( pItem && !IsInvalidItem(pItem) && pItem->Which() ) m_pPool->Remove(*pItem); } } // replace old items-array and ranges - m_pItems.reset( aNewItems ); + if (m_bItemsFixed) + m_bItemsFixed = false; + else + delete[] m_ppItems; + m_ppItems = aNewItems; m_nCount = nNewCount; } @@ -710,7 +747,7 @@ const SfxPoolItem& SfxItemSet::Get( sal_uInt16 nWhich, bool bSrchInParent) const { if( pCurrentSet->Count() ) { - SfxPoolItem const** ppFnd = pCurrentSet->m_pItems.get(); + SfxPoolItem const** ppFnd = pCurrentSet->m_ppItems; for (auto const & pPtr : pCurrentSet->m_pWhichRanges) { if( pPtr.first <= nWhich && nWhich <= pPtr.second ) @@ -784,8 +821,8 @@ void SfxItemSet::Intersect( const SfxItemSet& rSet ) if( m_pWhichRanges == rSet.m_pWhichRanges ) { sal_uInt16 nSize = TotalCount(); - SfxPoolItem const** ppFnd1 = m_pItems.get(); - SfxPoolItem const** ppFnd2 = rSet.m_pItems.get(); + SfxPoolItem const** ppFnd1 = m_ppItems; + SfxPoolItem const** ppFnd2 = rSet.m_ppItems; for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 ) if( *ppFnd1 && !*ppFnd2 ) @@ -833,8 +870,8 @@ void SfxItemSet::Differentiate( const SfxItemSet& rSet ) if( m_pWhichRanges == rSet.m_pWhichRanges ) { sal_uInt16 nSize = TotalCount(); - SfxPoolItem const** ppFnd1 = m_pItems.get(); - SfxPoolItem const** ppFnd2 = rSet.m_pItems.get(); + SfxPoolItem const** ppFnd1 = m_ppItems; + SfxPoolItem const** ppFnd2 = rSet.m_ppItems; for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 ) if( *ppFnd1 && *ppFnd2 ) @@ -1026,8 +1063,8 @@ void SfxItemSet::MergeValues( const SfxItemSet& rSet ) if( m_pWhichRanges == rSet.m_pWhichRanges ) { sal_uInt16 nSize = TotalCount(); - SfxPoolItem const** ppFnd1 = m_pItems.get(); - SfxPoolItem const** ppFnd2 = rSet.m_pItems.get(); + SfxPoolItem const** ppFnd1 = m_ppItems; + SfxPoolItem const** ppFnd2 = rSet.m_ppItems; for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 ) MergeItem_Impl(m_pPool, m_nCount, ppFnd1, *ppFnd2, false/*bIgnoreDefaults*/); @@ -1056,7 +1093,7 @@ void SfxItemSet::MergeValues( const SfxItemSet& rSet ) void SfxItemSet::MergeValue( const SfxPoolItem& rAttr, bool bIgnoreDefaults ) { - SfxPoolItem const** ppFnd = m_pItems.get(); + SfxPoolItem const** ppFnd = m_ppItems; const sal_uInt16 nWhich = rAttr.Which(); for( auto const & pPtr : m_pWhichRanges ) { @@ -1073,7 +1110,7 @@ void SfxItemSet::MergeValue( const SfxPoolItem& rAttr, bool bIgnoreDefaults ) void SfxItemSet::InvalidateItem( sal_uInt16 nWhich ) { - SfxPoolItem const** ppFnd = m_pItems.get(); + SfxPoolItem const** ppFnd = m_ppItems; for( auto const & pPtr : m_pWhichRanges ) { if( pPtr.first <= nWhich && nWhich <= pPtr.second ) @@ -1163,12 +1200,12 @@ bool SfxItemSet::Equals(const SfxItemSet &rCmp, bool bComparePool) const } // Are all pointers the same? - if (0 == memcmp( m_pItems.get(), rCmp.m_pItems.get(), nCount1 * sizeof(m_pItems[0]) )) + if (0 == memcmp( m_ppItems, rCmp.m_ppItems, nCount1 * sizeof(m_ppItems[0]) )) return true; // We need to compare each one separately then - const SfxPoolItem **ppItem1 = m_pItems.get(); - const SfxPoolItem **ppItem2 = rCmp.m_pItems.get(); + const SfxPoolItem **ppItem1 = m_ppItems; + const SfxPoolItem **ppItem2 = rCmp.m_ppItems; for ( sal_uInt16 nPos = 0; nPos < nCount1; ++nPos ) { // If the pointers of the poolable Items are not the same, the Items @@ -1239,7 +1276,7 @@ SfxItemSet SfxItemSet::CloneAsValue(bool bItems, SfxItemPool *pToPool ) const void SfxItemSet::PutDirect(const SfxPoolItem &rItem) { - SfxPoolItem const** ppFnd = m_pItems.get(); + SfxPoolItem const** ppFnd = m_ppItems; const sal_uInt16 nWhich = rItem.Which(); #ifdef DBG_UTIL IsPoolDefaultItem(&rItem) || m_pPool->CheckItemInPool(&rItem); |