idl/source/objects/object.cxx | 5 +- idl/source/objects/types.cxx | 4 - include/sfx2/msg.hxx | 25 ++++++----- sfx2/source/appl/appuno.cxx | 86 ++++++++++++++++++++-------------------- sfx2/source/control/objface.cxx | 39 +----------------- 5 files changed, 66 insertions(+), 93 deletions(-)
New commits: commit d4c0e39d93f3038a18cba975c25bb42aa125166c Author: Noel Grandin <noelgran...@gmail.com> AuthorDate: Wed May 1 13:33:41 2024 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Thu May 2 14:37:56 2024 +0200 make the slot data constinit because it takes a surprising amount of time to initialise it at runtime during startup (*) have to convert the std::function in SfxType to a function pointer, because the std::function constructor is not constinit compatible. (*) the SfxType0..SfxTypeN types need some reinterpret_cast to work around the lack of zero-sized trailing arrays in c++ (*) Sadly MSVC does not support taking the address of symbols in constinit structures, so we cannot make the SfxSlot array constinit. Change-Id: I300ee770cc115d30bc25c819f2ad34b29633876c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166963 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/idl/source/objects/object.cxx b/idl/source/objects/object.cxx index 0b2fadec2d77..9138ab075a2d 100644 --- a/idl/source/objects/object.cxx +++ b/idl/source/objects/object.cxx @@ -269,7 +269,7 @@ void SvMetaClass::WriteSfx( SvIdlDataBase & rBase, SvStream & rOutStm ) return; } // write parameter array - rOutStm.WriteOString("static SfxFormalArgument a").WriteOString(GetName()).WriteOString("Args_Impl[] =") << endl; + rOutStm.WriteOString("static const SfxFormalArgument a").WriteOString(GetName()).WriteOString("Args_Impl[] =") << endl; rOutStm.WriteChar('{') << endl; std::vector<sal_uInt32> aSuperList; @@ -304,7 +304,8 @@ void SvMetaClass::WriteSfx( SvIdlDataBase & rBase, SvStream & rOutStm ) rOutStm << endl; // write slotmap - rOutStm.WriteOString("static SfxSlot a").WriteOString(GetName()).WriteOString("Slots_Impl[] =") << endl; + rOutStm.WriteOString("static SfxSlot a").WriteOString(GetName()) + .WriteOString("Slots_Impl[").WriteOString(OString::number(nSlotCount == 0 ? 1 : nSlotCount)).WriteOString("] =") << endl; rOutStm.WriteChar( '{' ) << endl; // write all attributes diff --git a/idl/source/objects/types.cxx b/idl/source/objects/types.cxx index b98d90c93d85..08fa843d6f96 100644 --- a/idl/source/objects/types.cxx +++ b/idl/source/objects/types.cxx @@ -242,7 +242,7 @@ void SvMetaType::WriteSfxItem( rOutStm.WriteOString( "extern " ); if (bExport) rOutStm.WriteOString( "SFX2_DLLPUBLIC " ); - rOutStm.WriteOString( aTypeName ) + rOutStm.WriteOString( "constinit const " ).WriteOString( aTypeName ) .WriteOString( aVarName ).WriteChar( ';' ) << endl; if (bReturn) return; @@ -252,7 +252,7 @@ void SvMetaType::WriteSfxItem( rOutStm.WriteOString( "#if !defined(_WIN32) && (defined(DISABLE_DYNLOADING) && (defined(ANDROID) || defined(IOS) || defined(EMSCRIPTEN) || defined(LINUX)))" ) << endl; rOutStm.WriteOString( "__attribute__((__weak__))" ) << endl; rOutStm.WriteOString( "#endif" ) << endl; - rOutStm.WriteOString( aTypeName ).WriteOString( aVarName ) + rOutStm.WriteOString( "constinit const " ).WriteOString( aTypeName ).WriteOString( aVarName ) .WriteOString( " = " ) << endl; rOutStm.WriteChar( '{' ) << endl; diff --git a/include/sfx2/msg.hxx b/include/sfx2/msg.hxx index 8023f0846f60..88d9f68cf6ca 100644 --- a/include/sfx2/msg.hxx +++ b/include/sfx2/msg.hxx @@ -98,30 +98,33 @@ template<class T> SfxPoolItem* createSfxPoolItem() { return T::CreateDefault(); } + struct SfxType { - std::function<SfxPoolItem* ()> createSfxPoolItemFunc; + SfxPoolItem* (*createSfxPoolItemFunc)(); const std::type_info* pType; sal_uInt16 nAttribs; - SfxTypeAttrib aAttrib[1]; // variable length const std::type_info* Type() const{return pType;} std::unique_ptr<SfxPoolItem> CreateItem() const { return std::unique_ptr<SfxPoolItem>(createSfxPoolItemFunc()); } + inline const SfxTypeAttrib& getAttrib(sal_uInt16 idx) const; }; -struct SfxType0 +struct SfxTypeImpl : public SfxType +{ + SfxTypeAttrib aAttrib[1]; // variable length +}; + +// Some casting to work around the lack of zero-sized trailing arrays in c++ +inline const SfxTypeAttrib& SfxType::getAttrib(sal_uInt16 idx) const +{ return reinterpret_cast<const SfxTypeImpl*>(this)->aAttrib[idx]; } + +struct SfxType0 : public SfxType { - std::function<SfxPoolItem* ()> createSfxPoolItemFunc; - const std::type_info* pType; - sal_uInt16 nAttribs; - const std::type_info* Type() const { return pType;} }; -#define SFX_DECL_TYPE(n) struct SfxType##n \ +#define SFX_DECL_TYPE(n) struct SfxType##n : public SfxType \ { \ - std::function<SfxPoolItem* ()> createSfxPoolItemFunc; \ - const std::type_info* pType; \ - sal_uInt16 nAttribs; \ SfxTypeAttrib aAttrib[n]; \ } diff --git a/sfx2/source/appl/appuno.cxx b/sfx2/source/appl/appuno.cxx index 7aa37e031143..948b8d7abb4d 100644 --- a/sfx2/source/appl/appuno.cxx +++ b/sfx2/source/appl/appuno.cxx @@ -60,37 +60,37 @@ using namespace ::com::sun::star::io; // needs to be converted to a better data structure SfxFormalArgument const aFormalArgs[] = { - { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "SuggestedSaveAsName", SID_DEFAULTFILENAME }, - { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "SuggestedSaveAsDir", SID_DEFAULTFILEPATH }, - { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "VersionAuthor", SID_DOCINFO_AUTHOR }, - { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "VersionComment", SID_DOCINFO_COMMENTS }, - { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "DontTerminateEdit", FN_PARAM_1 }, - { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "VersionMajor", SID_DOCINFO_MAJOR }, - { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "FilterOptions", SID_FILE_FILTEROPTIONS }, - { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "FilterName", SID_FILTER_NAME }, - { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "Margin1", SID_RULER_MARGIN1 }, - { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "Margin2", SID_RULER_MARGIN2 }, -// { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "FileName", SID_FILE_NAME }, - { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "URL", SID_FILE_NAME }, - { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "OpenFlags", SID_OPTIONS }, - { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "Overwrite", SID_OVERWRITE }, - { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "Password", SID_PASSWORD }, - { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "PasswordInteraction", SID_PASSWORDINTERACTION }, - { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "Referer", SID_REFERER }, - { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "SaveTo", SID_SAVETO }, - { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "TemplateName", SID_TEMPLATE_NAME }, - { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "TemplateRegion", SID_TEMPLATE_REGIONNAME }, -// { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "Region", SID_TEMPLATE_REGIONNAME }, -// { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "Name", SID_TEMPLATE_NAME }, - { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "Unpacked", SID_UNPACK }, - { reinterpret_cast<SfxType*>(&aSfxInt16Item_Impl), "Version", SID_VERSION }, - { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "SaveACopy", SID_SAVEACOPYITEM }, - { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "NoFileSync", SID_NO_FILE_SYNC }, - { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "NoThumbnail", SID_NO_THUMBNAIL }, - { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "NoEmbDataSet", SID_NO_EMBEDDED_DS }, - { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "IsRedactMode", SID_IS_REDACT_MODE }, - { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "RedactionStyle", SID_REDACTION_STYLE }, - { reinterpret_cast<SfxType*>(&aSfxStringItem_Impl), "AdditionsTag", FN_PARAM_ADDITIONS_TAG }, + { static_cast<const SfxType*>(&aSfxStringItem_Impl), "SuggestedSaveAsName", SID_DEFAULTFILENAME }, + { static_cast<const SfxType*>(&aSfxStringItem_Impl), "SuggestedSaveAsDir", SID_DEFAULTFILEPATH }, + { static_cast<const SfxType*>(&aSfxStringItem_Impl), "VersionAuthor", SID_DOCINFO_AUTHOR }, + { static_cast<const SfxType*>(&aSfxStringItem_Impl), "VersionComment", SID_DOCINFO_COMMENTS }, + { static_cast<const SfxType*>(&aSfxBoolItem_Impl), "DontTerminateEdit", FN_PARAM_1 }, + { static_cast<const SfxType*>(&aSfxBoolItem_Impl), "VersionMajor", SID_DOCINFO_MAJOR }, + { static_cast<const SfxType*>(&aSfxStringItem_Impl), "FilterOptions", SID_FILE_FILTEROPTIONS }, + { static_cast<const SfxType*>(&aSfxStringItem_Impl), "FilterName", SID_FILTER_NAME }, + { static_cast<const SfxType*>(&aSfxStringItem_Impl), "Margin1", SID_RULER_MARGIN1 }, + { static_cast<const SfxType*>(&aSfxStringItem_Impl), "Margin2", SID_RULER_MARGIN2 }, +// { static_cast<const SfxType*>(&aSfxStringItem_Impl), "FileName", SID_FILE_NAME }, + { static_cast<const SfxType*>(&aSfxStringItem_Impl), "URL", SID_FILE_NAME }, + { static_cast<const SfxType*>(&aSfxStringItem_Impl), "OpenFlags", SID_OPTIONS }, + { static_cast<const SfxType*>(&aSfxBoolItem_Impl), "Overwrite", SID_OVERWRITE }, + { static_cast<const SfxType*>(&aSfxStringItem_Impl), "Password", SID_PASSWORD }, + { static_cast<const SfxType*>(&aSfxBoolItem_Impl), "PasswordInteraction", SID_PASSWORDINTERACTION }, + { static_cast<const SfxType*>(&aSfxStringItem_Impl), "Referer", SID_REFERER }, + { static_cast<const SfxType*>(&aSfxBoolItem_Impl), "SaveTo", SID_SAVETO }, + { static_cast<const SfxType*>(&aSfxStringItem_Impl), "TemplateName", SID_TEMPLATE_NAME }, + { static_cast<const SfxType*>(&aSfxStringItem_Impl), "TemplateRegion", SID_TEMPLATE_REGIONNAME }, +// { static_cast<const SfxType*>(&aSfxStringItem_Impl), "Region", SID_TEMPLATE_REGIONNAME }, +// { static_cast<const SfxType*>(&aSfxStringItem_Impl), "Name", SID_TEMPLATE_NAME }, + { static_cast<const SfxType*>(&aSfxBoolItem_Impl), "Unpacked", SID_UNPACK }, + { static_cast<const SfxType*>(&aSfxInt16Item_Impl), "Version", SID_VERSION }, + { static_cast<const SfxType*>(&aSfxBoolItem_Impl), "SaveACopy", SID_SAVEACOPYITEM }, + { static_cast<const SfxType*>(&aSfxBoolItem_Impl), "NoFileSync", SID_NO_FILE_SYNC }, + { static_cast<const SfxType*>(&aSfxBoolItem_Impl), "NoThumbnail", SID_NO_THUMBNAIL }, + { static_cast<const SfxType*>(&aSfxBoolItem_Impl), "NoEmbDataSet", SID_NO_EMBEDDED_DS }, + { static_cast<const SfxType*>(&aSfxBoolItem_Impl), "IsRedactMode", SID_IS_REDACT_MODE }, + { static_cast<const SfxType*>(&aSfxStringItem_Impl), "RedactionStyle", SID_REDACTION_STYLE }, + { static_cast<const SfxType*>(&aSfxStringItem_Impl), "AdditionsTag", FN_PARAM_ADDITIONS_TAG }, }; sal_uInt16 const nMediaArgsCount = SAL_N_ELEMENTS(aFormalArgs); @@ -242,9 +242,9 @@ void TransformParameters( sal_uInt16 nSlotId, const uno::Sequence<beans::Propert for ( nSub=0; nSub<nSubCount; nSub++ ) { // search sub item by name - if ( rPropValue.Name == (pSlot->aUnoName + "." + pType->aAttrib[nSub].aName) ) + if ( rPropValue.Name == (pSlot->aUnoName + "." + pType->getAttrib(nSub).aName) ) { - sal_uInt8 nSubId = static_cast<sal_uInt8>(static_cast<sal_Int8>(pType->aAttrib[nSub].nAID)); + sal_uInt8 nSubId = static_cast<sal_uInt8>(static_cast<sal_Int8>(pType->getAttrib(nSub).nAID)); if ( bConvertTwips ) nSubId |= CONVERT_TWIPS; if ( pItem->PutValue( rPropValue.Value, nSubId ) ) @@ -344,14 +344,14 @@ void TransformParameters( sal_uInt16 nSlotId, const uno::Sequence<beans::Propert for ( sal_uInt16 nSub=0; nSub<nSubCount; nSub++ ) { // search sub item by name - if ( rProp.Name == (rArg.aName + "." + pType->aAttrib[nSub].aName) ) + if ( rProp.Name == (rArg.aName + "." + pType->getAttrib(nSub).aName) ) { // at least one member found ... bRet = true; #ifdef DBG_UTIL ++nFoundArgs; #endif - sal_uInt8 nSubId = static_cast<sal_uInt8>(static_cast<sal_Int8>(pType->aAttrib[nSub].nAID)); + sal_uInt8 nSubId = static_cast<sal_uInt8>(static_cast<sal_Int8>(pType->getAttrib(nSub).nAID)); if ( bConvertTwips ) nSubId |= CONVERT_TWIPS; if (!pItem->PutValue( rProp.Value, nSubId ) ) @@ -1311,17 +1311,17 @@ void TransformItems( sal_uInt16 nSlotId, const SfxItemSet& rSet, uno::Sequence<b // complex type, add a property value for every member of the struct for ( sal_uInt16 n=1; n<=nSubCount; ++n ) { - sal_uInt8 nSubId = static_cast<sal_uInt8>(static_cast<sal_Int8>(pType->aAttrib[n-1].nAID)); + sal_uInt8 nSubId = static_cast<sal_uInt8>(static_cast<sal_Int8>(pType->getAttrib(n-1).nAID)); if ( bConvertTwips ) nSubId |= CONVERT_TWIPS; - DBG_ASSERT(( pType->aAttrib[n-1].nAID ) <= 127, "Member ID out of range" ); + DBG_ASSERT(( pType->getAttrib(n-1).nAID ) <= 127, "Member ID out of range" ); pValue[nActProp].Name = pSlot->aUnoName + "." + - pType->aAttrib[n-1].aName; + pType->getAttrib(n-1).aName; if ( !pItem->QueryValue( pValue[nActProp++].Value, nSubId ) ) { - SAL_WARN( "sfx", "Sub item " << pType->aAttrib[n-1].nAID + SAL_WARN( "sfx", "Sub item " << pType->getAttrib(n-1).nAID << " not convertible in slot: " << nSlotId ); } } @@ -1356,18 +1356,18 @@ void TransformItems( sal_uInt16 nSlotId, const SfxItemSet& rSet, uno::Sequence<b // complex type, add a property value for every member of the struct for ( sal_uInt16 n = 1; n <= nSubCount; ++n ) { - sal_uInt8 nSubId = static_cast<sal_uInt8>(static_cast<sal_Int8>(rArg.pType->aAttrib[n-1].nAID)); + sal_uInt8 nSubId = static_cast<sal_uInt8>(static_cast<sal_Int8>(rArg.pType->getAttrib(n-1).nAID)); if ( bConvertTwips ) nSubId |= CONVERT_TWIPS; - DBG_ASSERT((rArg.pType->aAttrib[n-1].nAID) <= 127, "Member ID out of range" ); + DBG_ASSERT((rArg.pType->getAttrib(n-1).nAID) <= 127, "Member ID out of range" ); pValue[nActProp].Name = rArg.aName + "." + - rArg.pType->aAttrib[n-1].aName ; + rArg.pType->getAttrib(n-1).aName ; if ( !pItem->QueryValue( pValue[nActProp++].Value, nSubId ) ) { SAL_WARN( "sfx", "Sub item " - << rArg.pType->aAttrib[n-1].nAID + << rArg.pType->getAttrib(n-1).nAID << " not convertible in slot: " << rArg.nSlotId ); } diff --git a/sfx2/source/control/objface.cxx b/sfx2/source/control/objface.cxx index ed4393fa45d3..96afa430ac4e 100644 --- a/sfx2/source/control/objface.cxx +++ b/sfx2/source/control/objface.cxx @@ -30,12 +30,6 @@ extern "C" { -static int -SfxCompareSlots_qsort( const void* pSmaller, const void* pBigger ) -{ - return static_cast<int>(static_cast<SfxSlot const *>(pSmaller)->GetSlotId()) - - static_cast<int>(static_cast<SfxSlot const *>(pBigger)->GetSlotId()); -} static int SfxCompareSlots_bsearch( const void* pSmaller, const void* pBigger ) @@ -113,39 +107,14 @@ void SfxInterface::SetSlotMap( SfxSlot& rSlotMap, sal_uInt16 nSlotCount ) pSlots = &rSlotMap; nCount = nSlotCount; SfxSlot* pIter = pSlots; - if ( 1 == nCount && !pIter->pNextSlot ) - pIter->pNextSlot = pIter; if ( !pIter->pNextSlot ) { - // sort the SfxSlots by id - qsort( pSlots, nCount, sizeof(SfxSlot), SfxCompareSlots_qsort ); - - // link masters and slaves - sal_uInt16 nIter = 1; - for ( pIter = pSlots; nIter <= nCount; ++pIter, ++nIter ) - { - - assert( nIter == nCount || - pIter->GetSlotId() != (pIter+1)->GetSlotId() ); - - if ( nullptr == pIter->GetNextSlot() ) + assert(std::is_sorted(pSlots, pSlots + nCount, + [](const SfxSlot& rLHS, const SfxSlot& rRHS) { - // Slots referring in circle to the next with the same - // Status method. - SfxSlot *pLastSlot = pIter; - for ( sal_uInt16 n = nIter; n < Count(); ++n ) - { - SfxSlot *pCurSlot = pSlots+n; - if ( pCurSlot->GetStateFnc() == pIter->GetStateFnc() ) - { - pLastSlot->pNextSlot = pCurSlot; - pLastSlot = pCurSlot; - } - } - pLastSlot->pNextSlot = pIter; - } - } + return rLHS.GetSlotId() < rRHS.GetSlotId(); + })); } #ifdef DBG_UTIL else