[Libreoffice-commits] core.git: comphelper/source compilerplugins/clang editeng/source include/basegfx include/comphelper include/editeng include/formula include/xmloff xmloff/source

Noel Grandin (via logerrit) logerrit at kemper.freedesktop.org
Fri May 29 07:40:51 UTC 2020


 comphelper/source/container/enumhelper.cxx  |    4 
 compilerplugins/clang/pahole-all-classes.py |  155 +++++++++++++++-------------
 editeng/source/outliner/paralist.cxx        |    4 
 include/basegfx/DrawCommands.hxx            |    2 
 include/comphelper/PropertyInfoHash.hxx     |   17 +--
 include/comphelper/enumhelper.hxx           |    4 
 include/comphelper/interfacecontainer2.hxx  |    2 
 include/comphelper/propertysetinfo.hxx      |    4 
 include/editeng/outliner.hxx                |   20 +--
 include/formula/FormulaCompiler.hxx         |    2 
 include/xmloff/maptype.hxx                  |   17 ++-
 include/xmloff/xmlictxt.hxx                 |    6 -
 xmloff/source/core/xmlictxt.cxx             |   10 -
 13 files changed, 142 insertions(+), 105 deletions(-)

New commits:
commit 31b0be0f21479323408e128f2e8a1a795e037e74
Author:     Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Thu May 28 13:18:41 2020 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Fri May 29 09:40:12 2020 +0200

    improve pahole script and pack a few classes
    
    (*) fix: I was substracting the padding space instead of adding it
    when calculating how much free space we had to improve.
    
    (*) sort input data, so we process structs located in the same DSO
    together, which reduces GDB's memory usage
    
    (*) handle another error condition, where gdbs output is sufficiently
    mixed up that we miss the end of commands terminator
    
    Change-Id: Ic4bb92b736f38a2b3d90e4a14485152b7f869b43
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95041
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/comphelper/source/container/enumhelper.cxx b/comphelper/source/container/enumhelper.cxx
index 6c05c89d3cd7..edcb03c669cc 100644
--- a/comphelper/source/container/enumhelper.cxx
+++ b/comphelper/source/container/enumhelper.cxx
@@ -27,8 +27,8 @@ namespace comphelper
 
 OEnumerationByName::OEnumerationByName(const css::uno::Reference<css::container::XNameAccess>& _rxAccess)
     :m_aNames(_rxAccess->getElementNames())
-    ,m_nPos(0)
     ,m_xAccess(_rxAccess)
+    ,m_nPos(0)
     ,m_bListening(false)
 {
     impl_startDisposeListening();
@@ -38,8 +38,8 @@ OEnumerationByName::OEnumerationByName(const css::uno::Reference<css::container:
 OEnumerationByName::OEnumerationByName(const css::uno::Reference<css::container::XNameAccess>& _rxAccess,
                                        const css::uno::Sequence< OUString >&           _aNames  )
     :m_aNames(_aNames)
-    ,m_nPos(0)
     ,m_xAccess(_rxAccess)
+    ,m_nPos(0)
     ,m_bListening(false)
 {
     impl_startDisposeListening();
diff --git a/compilerplugins/clang/pahole-all-classes.py b/compilerplugins/clang/pahole-all-classes.py
index b95b92543427..16e851d82c7a 100755
--- a/compilerplugins/clang/pahole-all-classes.py
+++ b/compilerplugins/clang/pahole-all-classes.py
@@ -8,10 +8,8 @@
 # (2) First run the unusedfields loplugin to generate a log file
 # (3) Install the pahole stuff into your gdb, I used this one:
 #     https://github.com/PhilArmstrong/pahole-gdb
-# (4) Edit the loop near the top of the script to only produce results for one of our modules.
-#     Note that this will make GDB soak up about 8G of RAM, which is why I don't do more than one module at a time
-# (5) Run the script
-#     ./compilerplugins/clang/pahole-all-classes.py > ./compilerplugins/clang/pahole.results
+# (4) Run the script
+#     ./compilerplugins/clang/pahole-all-classes.py
 #
 
 import _thread
@@ -27,6 +25,7 @@ a = subprocess.Popen("cat n1", stdout=subprocess.PIPE, shell=True)
 
 classSet = set()
 classSourceLocDict = dict()
+locToClassDict = dict()
 with a.stdout as txt:
     for line in txt:
         tokens = line.decode('utf8').strip().split("\t")
@@ -38,6 +37,7 @@ with a.stdout as txt:
         if className in classSet: continue
         classSet.add(className)
         classSourceLocDict[className] = srcLoc
+        locToClassDict[srcLoc] = className
 a.terminate()
 
 # Some of the pahole commands are going to fail, and I cannot read the error stream and the input stream
@@ -57,83 +57,100 @@ def write_pahole_commands(classes):
 # to split them up, and that creates a mess in the parsing logic.
 def read_generator(gdbOutput):
     while True:
-        line = gdbOutput.readline().decode('utf8').strip()
+        line = gdbOutput.readline();
+        if line == "": return # end of file
+        line = line.decode('utf8').strip()
+        print("gdb: " + line)
         for split in line.split("(gdb)"):
             split = split.strip()
             if len(split) == 0: continue
             if "all-done" in split: return
             yield split
 
-classList = sorted(classSet)
+# build list of classes sorted by source location to increase the chances of
+# processing stuff stored in the same DSO together
+sortedLocs = sorted(locToClassDict.keys())
+classList = list()
+for src in sortedLocs:
+    if "include/" in src:
+        classList.append(locToClassDict[src])
 
-# Process 200 classes at a time, otherwise gdb's memory usage blows up and kills the machine
-#
-while len(classList) > 0:
+with open("compilerplugins/clang/pahole.results", "wt") as f:
+    # Process 400 classes at a time, otherwise gdb's memory usage blows up and kills the machine
+    # This number is chosen to make gdb peak at around 8G.
+    while len(classList) > 0:
 
-    currClassList = classList[1:200];
-    classList = classList[200:]
+        currClassList = classList[0:500];
+        classList = classList[500:]
 
-    gdbProc = subprocess.Popen("gdb", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
+        gdbProc = subprocess.Popen("gdb", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
 
-    stdin = io.TextIOWrapper(gdbProc.stdin, 'utf-8')
+        stdin = io.TextIOWrapper(gdbProc.stdin, 'utf-8')
 
-    # make gdb load all the debugging info
-    stdin.write("set confirm off\n")
-    for filename in sorted(os.listdir('instdir/program')):
-        if filename.endswith(".so"):
-            stdin.write("add-symbol-file instdir/program/" + filename + "\n")
-    stdin.flush()
+        # make gdb load all the debugging info
+        stdin.write("set confirm off\n")
+        # make gdb not wrap output and mess up my parsing
+        stdin.write("set width unlimited\n")
+        for filename in sorted(os.listdir('instdir/program')):
+            if filename.endswith(".so"):
+                stdin.write("add-symbol-file instdir/program/" + filename + "\n")
+        stdin.flush()
 
 
-    _thread.start_new_thread( write_pahole_commands, (currClassList,) )
+        _thread.start_new_thread( write_pahole_commands, (currClassList,) )
 
-    firstLineRegex = re.compile("/\*\s+(\d+)\s+\*/ struct")
-    fieldLineRegex = re.compile("/\*\s+(\d+)\s+(\d+)\s+\*/ ")
-    holeLineRegex = re.compile("/\* XXX (\d+) bit hole, try to pack \*/")
-    # sometimes pahole can't determine the size of a sub-struct, and then it returns bad data
-    bogusLineRegex = re.compile("/\*\s+\d+\s+0\s+\*/")
-    structLines = list()
-    foundHole = False
-    cumulativeHoleBits = 0
-    structSize = 0
-    foundBogusLine = False
-    # pahole doesn't report space at the end of the structure, so work it out myself
-    sizeOfFields = 0
-    for line in read_generator(gdbProc.stdout):
-        structLines.append(line)
-        firstLineMatch = firstLineRegex.match(line)
-        if firstLineMatch:
-            structSize = int(firstLineMatch.group(1))
-        holeLineMatch = holeLineRegex.match(line)
-        if holeLineMatch:
-            foundHole = True
-            cumulativeHoleBits += int(holeLineMatch.group(1))
-        fieldLineMatch = fieldLineRegex.match(line)
-        if fieldLineMatch:
-            fieldSize = int(fieldLineMatch.group(2))
-            sizeOfFields = int(fieldLineMatch.group(1)) + fieldSize
-        if bogusLineRegex.match(line):
-            foundBogusLine = True
-        if line == "}":
-            # Ignore very large structs, packing those is not going to help much, and
-            # re-organising them can make them much less readable.
-            if foundHole and len(structLines) < 12 and structSize < 100 and not foundBogusLine:
-                # Verify that we have enough hole-space that removing it will result in a structure
-                # that still satisfies alignment requirements, otherwise the compiler will just put empty
-                # space at the end of the struct.
-                # TODO improve detection of the required alignment for a structure
-                potentialSpace = (cumulativeHoleBits / 8) + (sizeOfFields - structSize)
-                if potentialSpace >= 8:
-                    for line in structLines:
-                        print(line)
-                    if (sizeOfFields - structSize) > 0:
-                        print("hole at end of struct: " + str(sizeOfFields - structSize))
-            #  reset state
-            structLines.clear()
-            foundHole = False
-            cumulativeHoleBits = 0
-            structSize = 0
-            foundBogusLine = False
-            actualStructSize = 0
+        firstLineRegex = re.compile("/\*\s+(\d+)\s+\*/ struct") # /* 16 */ struct Foo
+        fieldLineRegex = re.compile("/\*\s+(\d+)\s+(\d+)\s+\*/ ") # /* 12 8 */ class rtl::OUString aName
+        holeLineRegex = re.compile("/\* XXX (\d+) bit hole, try to pack \*/")
+        # sometimes pahole can't determine the size of a sub-struct, and then it returns bad data
+        bogusLineRegex = re.compile("/\*\s+\d+\s+0\s+\*/")
+        structLines = list()
+        foundHole = False
+        cumulativeHoleBits = 0
+        alignedStructSize = 0
+        foundBogusLine = False
+        # pahole doesn't report space at the end of the structure, so work it out myself
+        sizeOfStructWithoutPadding = 0
+        for line in read_generator(gdbProc.stdout):
+            structLines.append(line)
+            firstLineMatch = firstLineRegex.match(line)
+            if firstLineMatch:
+                alignedStructSize = int(firstLineMatch.group(1))
+                structLines.clear()
+                structLines.append(line)
+            holeLineMatch = holeLineRegex.match(line)
+            if holeLineMatch:
+                foundHole = True
+                cumulativeHoleBits += int(holeLineMatch.group(1))
+            fieldLineMatch = fieldLineRegex.match(line)
+            if fieldLineMatch:
+                fieldPosInBytes = int(fieldLineMatch.group(1))
+                fieldSizeInBytes = int(fieldLineMatch.group(2))
+                sizeOfStructWithoutPadding = fieldPosInBytes + fieldSizeInBytes
+            if bogusLineRegex.match(line):
+                foundBogusLine = True
+            if line == "}":
+                # Ignore very large structs, packing those is not going to help much, and
+                # re-organising them can make them much less readable.
+                if foundHole and len(structLines) < 16 and alignedStructSize < 100 and not foundBogusLine:
+                    # Verify that, after packing, and compiler alignment, the new structure will be actually smaller.
+                    # Sometimes, we can save space, but the compiler will align the structure such that we don't
+                    # actually save any space.
+                    # TODO improve detection of the required alignment for a structure
+                    holeAtEnd = alignedStructSize - sizeOfStructWithoutPadding
+                    potentialSpace = (cumulativeHoleBits / 8) + holeAtEnd
+                    if potentialSpace >= 8:
+                        for line in structLines:
+                            f.write(line + "\n")
+                        if holeAtEnd > 0:
+                            f.write("hole at end of struct: " + str(holeAtEnd) + "\n")
+                        f.write("\n")
+                #  reset state
+                structLines.clear()
+                foundHole = False
+                cumulativeHoleBits = 0
+                structSize = 0
+                foundBogusLine = False
+                actualStructSize = 0
 
-    gdbProc.terminate()
+        gdbProc.terminate()
diff --git a/editeng/source/outliner/paralist.cxx b/editeng/source/outliner/paralist.cxx
index 4e03e24c2438..1e560b56ca68 100644
--- a/editeng/source/outliner/paralist.cxx
+++ b/editeng/source/outliner/paralist.cxx
@@ -54,8 +54,8 @@ Paragraph::Paragraph( sal_Int16 nDDepth )
 }
 
 Paragraph::Paragraph( const ParagraphData& rData )
-: nFlags( ParaFlag::NONE )
-, aBulSize( -1, -1)
+: aBulSize( -1, -1)
+, nFlags( ParaFlag::NONE )
 , bVisible( true )
 {
     nDepth = rData.nDepth;
diff --git a/include/basegfx/DrawCommands.hxx b/include/basegfx/DrawCommands.hxx
index e9e3b935b8cf..fef43689b4a9 100644
--- a/include/basegfx/DrawCommands.hxx
+++ b/include/basegfx/DrawCommands.hxx
@@ -43,8 +43,8 @@ enum class GradientType
 class GradientStop
 {
 public:
-    float mfOffset;
     basegfx::BColor maColor;
+    float mfOffset;
     float mfOpacity;
 };
 
diff --git a/include/comphelper/PropertyInfoHash.hxx b/include/comphelper/PropertyInfoHash.hxx
index 03c4373001d2..8c584ce5a572 100644
--- a/include/comphelper/PropertyInfoHash.hxx
+++ b/include/comphelper/PropertyInfoHash.hxx
@@ -28,15 +28,20 @@ namespace comphelper
 {
     struct PropertyInfo
     {
-        OUString const maName;
-        sal_Int32 const mnHandle;
-        css::uno::Type const maType;
-        sal_Int16 const mnAttributes;
+        OUString maName;
+        css::uno::Type maType;
+        sal_Int32 mnHandle;
+        sal_Int16 mnAttributes;
+
+        PropertyInfo(OUString const & aName, sal_Int32 nHandle, css::uno::Type const & aType, sal_Int16 nAttributes)
+            : maName(aName), maType(aType), mnHandle(nHandle), mnAttributes(nAttributes) {}
+        PropertyInfo(OUString && aName, sal_Int32 nHandle, css::uno::Type const & aType, sal_Int16 nAttributes)
+            : maName(std::move(aName)), maType(aType), mnHandle(nHandle), mnAttributes(nAttributes) {}
     };
     struct PropertyData
     {
-        sal_uInt8 const mnMapId;
-        PropertyInfo const *mpInfo;
+        sal_uInt8 mnMapId;
+        const PropertyInfo *mpInfo;
         PropertyData ( sal_uInt8 nMapId, PropertyInfo const *pInfo )
         : mnMapId ( nMapId )
         , mpInfo ( pInfo ) {}
diff --git a/include/comphelper/enumhelper.hxx b/include/comphelper/enumhelper.hxx
index 16d95b76e808..5e5e000d78df 100644
--- a/include/comphelper/enumhelper.hxx
+++ b/include/comphelper/enumhelper.hxx
@@ -46,9 +46,9 @@ class COMPHELPER_DLLPUBLIC OEnumerationByName final : private OEnumerationLock
                                                           css::lang::XEventListener    >
 {
     css::uno::Sequence< OUString > const                m_aNames;
+    css::uno::Reference< css::container::XNameAccess >  m_xAccess;
     sal_Int32                                           m_nPos;
-    css::uno::Reference< css::container::XNameAccess >    m_xAccess;
-    bool                                            m_bListening;
+    bool                                                m_bListening;
 
 public:
     OEnumerationByName(const css::uno::Reference< css::container::XNameAccess >& _rxAccess);
diff --git a/include/comphelper/interfacecontainer2.hxx b/include/comphelper/interfacecontainer2.hxx
index c049a6c6726e..626ef830211d 100644
--- a/include/comphelper/interfacecontainer2.hxx
+++ b/include/comphelper/interfacecontainer2.hxx
@@ -100,9 +100,9 @@ public:
 
 private:
     OInterfaceContainerHelper2 & rCont;
-    bool const                   bIsList;
     detail::element_alias2       aData;
     sal_Int32                    nRemain;
+    bool                         bIsList;
 
     OInterfaceIteratorHelper2( const OInterfaceIteratorHelper2 & ) = delete;
     OInterfaceIteratorHelper2 &  operator = ( const OInterfaceIteratorHelper2 & ) = delete;
diff --git a/include/comphelper/propertysetinfo.hxx b/include/comphelper/propertysetinfo.hxx
index ee413ac51611..aaf8484ad879 100644
--- a/include/comphelper/propertysetinfo.hxx
+++ b/include/comphelper/propertysetinfo.hxx
@@ -44,8 +44,8 @@ namespace comphelper
 struct PropertyMapEntry
 {
     OUString       maName;
-    sal_Int32      mnHandle;
     css::uno::Type maType;
+    sal_Int32      mnHandle;
     /// flag bitmap, @see css::beans::PropertyAttribute
     sal_Int16      mnAttributes;
     sal_uInt8      mnMemberId;
@@ -54,8 +54,8 @@ struct PropertyMapEntry
     PropertyMapEntry(OUString _aName, sal_Int32 _nHandle, css::uno::Type const & _rType,
                      sal_Int16 _nAttributes, sal_uInt8 _nMemberId, PropertyMoreFlags _nMoreFlags = PropertyMoreFlags::NONE)
         : maName( _aName )
-        , mnHandle( _nHandle )
         , maType( _rType )
+        , mnHandle( _nHandle )
         , mnAttributes( _nAttributes )
         , mnMemberId( _nMemberId )
         , mnMoreFlags( _nMoreFlags )
diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx
index a048c4e06ac0..3d71ac19818b 100644
--- a/include/editeng/outliner.hxx
+++ b/include/editeng/outliner.hxx
@@ -126,9 +126,9 @@ private:
 
     Paragraph& operator=(const Paragraph& rPara ) = delete;
 
-    ParaFlag            nFlags;
     OUString            aBulText;
     Size                aBulSize;
+    ParaFlag            nFlags;
     bool                bVisible;
 
     bool                IsVisible() const { return bVisible; }
@@ -526,16 +526,16 @@ public:
     SdrPage*        GetSdrPage() const { return mpSdrPage; }
 };
 
-struct EBulletInfo
+ struct EBulletInfo
 {
-    bool        bVisible;
-    sal_uInt16  nType;          // see SvxNumberType
-    OUString    aText;
-    SvxFont     aFont;
-    sal_Int32   nParagraph;
-    tools::Rectangle   aBounds;
-
-    EBulletInfo() : bVisible( false ), nType( 0 ), nParagraph( EE_PARA_NOT_FOUND ) {}
+    SvxFont           aFont;
+    tools::Rectangle  aBounds;
+    OUString          aText;
+    sal_Int32         nParagraph;
+    sal_uInt16        nType;          // see SvxNumberType
+    bool              bVisible;
+
+    EBulletInfo() : nParagraph( EE_PARA_NOT_FOUND ), nType( 0 ), bVisible( false ) {}
 };
 
 enum class OutlinerMode {
diff --git a/include/formula/FormulaCompiler.hxx b/include/formula/FormulaCompiler.hxx
index ecc9e5dd3f4f..9fdd5a521087 100644
--- a/include/formula/FormulaCompiler.hxx
+++ b/include/formula/FormulaCompiler.hxx
@@ -60,8 +60,8 @@ struct FormulaArrayStack
 {
     FormulaArrayStack*  pNext;
     FormulaTokenArray*  pArr;
-    sal_uInt16          nIndex;
     FormulaTokenRef     mpLastToken;
+    sal_uInt16          nIndex;
     bool bTemp;
 };
 
diff --git a/include/xmloff/maptype.hxx b/include/xmloff/maptype.hxx
index b09d48b31e6b..dbde180797cf 100644
--- a/include/xmloff/maptype.hxx
+++ b/include/xmloff/maptype.hxx
@@ -32,9 +32,9 @@ struct XMLPropertyMapEntry
 {
     const char*     msApiName;      /// Property-Name
     sal_Int32       nApiNameLength; /// length of property name
+    enum ::xmloff::token::XMLTokenEnum meXMLName;       /// XML-Name
     sal_uInt16      mnNameSpace;    /** declares the Namespace in which this
                                         property exists */
-    enum ::xmloff::token::XMLTokenEnum meXMLName;       /// XML-Name
 
     /**
      * The lowest 14 bits specify the basic XML type of the property value, of
@@ -98,6 +98,21 @@ struct XMLPropertyMapEntry
         Property-Name exist, all except one must have this flag set.
      */
     bool            mbImportOnly;
+
+    XMLPropertyMapEntry(
+            const char*     sApiName,
+            sal_Int32       nApiNameLength_,
+            sal_uInt16      nNameSpace,
+            enum ::xmloff::token::XMLTokenEnum eXMLName,
+            sal_uInt32 nType,
+            sal_Int16       nContextId,
+            SvtSaveOptions::ODFSaneDefaultVersion nEarliestODFVersionForExport,
+            bool            bImportOnly)
+        : msApiName(sApiName), nApiNameLength(nApiNameLength_),
+        meXMLName(eXMLName), mnNameSpace(nNameSpace), mnType(nType),
+        mnContextId(nContextId), mnEarliestODFVersionForExport(nEarliestODFVersionForExport),
+        mbImportOnly(bImportOnly)
+    {}
 };
 
 
diff --git a/include/xmloff/xmlictxt.hxx b/include/xmloff/xmlictxt.hxx
index 64927daf693b..29975774bf00 100644
--- a/include/xmloff/xmlictxt.hxx
+++ b/include/xmloff/xmlictxt.hxx
@@ -47,12 +47,12 @@ class XMLOFF_DLLPUBLIC SvXMLImportContext : public css::xml::sax::XFastContextHa
 {
     friend class SvXMLImport;
 
-    oslInterlockedCount                m_nRefCount;
     SvXMLImport&                       mrImport;
-    sal_uInt16                         mnPrefix;
     OUString                           maLocalName;
-    bool                               mbPrefixAndLocalNameFilledIn;
     std::unique_ptr<SvXMLNamespaceMap> m_pRewindMap;
+    oslInterlockedCount                m_nRefCount;
+    sal_uInt16                         mnPrefix;
+    bool                               mbPrefixAndLocalNameFilledIn;
 
     SAL_DLLPRIVATE std::unique_ptr<SvXMLNamespaceMap> TakeRewindMap() { return std::move(m_pRewindMap); }
     SAL_DLLPRIVATE void PutRewindMap(std::unique_ptr<SvXMLNamespaceMap> p) { m_pRewindMap = std::move(p); }
diff --git a/xmloff/source/core/xmlictxt.cxx b/xmloff/source/core/xmlictxt.cxx
index e24ee7bcc041..bc1d2a8486bf 100644
--- a/xmloff/source/core/xmlictxt.cxx
+++ b/xmloff/source/core/xmlictxt.cxx
@@ -28,17 +28,17 @@ using namespace ::com::sun::star;
 
 SvXMLImportContext::SvXMLImportContext( SvXMLImport& rImp, sal_uInt16 nPrfx,
                               const OUString& rLName )
-    : m_nRefCount(0)
-    , mrImport(rImp)
-    , mnPrefix(nPrfx)
+    : mrImport(rImp)
     , maLocalName(rLName)
+    , m_nRefCount(0)
+    , mnPrefix(nPrfx)
     , mbPrefixAndLocalNameFilledIn(true)
 {
 }
 
 SvXMLImportContext::SvXMLImportContext( SvXMLImport& rImp )
-    : m_nRefCount(0)
-    , mrImport(rImp)
+    : mrImport(rImp)
+    , m_nRefCount(0)
     , mnPrefix(0)
     , mbPrefixAndLocalNameFilledIn(false)
 {


More information about the Libreoffice-commits mailing list