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

Reply via email to