File indexing completed on 2024-04-28 17:02:20

0001 /*
0002    This file is part of Massif Visualizer
0003 
0004    Copyright 2010 Milian Wolff <mail@milianw.de>
0005 
0006    This library is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU Lesser General Public
0008    License as published by the Free Software Foundation; either
0009    version 2.1 of the License, or (at your option) version 3, or any
0010    later version accepted by the membership of KDE e.V. (or its
0011    successor approved by the membership of KDE e.V.), which shall
0012    act as a proxy defined in Section 6 of version 3 of the license.
0013 
0014    This library is distributed in the hope that it will be useful,
0015    but WITHOUT ANY WARRANTY; without even the implied warranty of
0016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0017    Lesser General Public License for more details.
0018 
0019    You should have received a copy of the GNU Lesser General Public
0020    License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0021 */
0022 
0023 #ifndef MASSIF_PARSERPRIVATE_H
0024 #define MASSIF_PARSERPRIVATE_H
0025 
0026 #include <QtCore/QByteArray>
0027 #include <QtCore/QStringList>
0028 #include <QtCore/QSet>
0029 #include <QVector>
0030 
0031 class QIODevice;
0032 
0033 namespace Massif {
0034 
0035 class FileData;
0036 class SnapshotItem;
0037 class TreeLeafItem;
0038 class Parser;
0039 
0040 class ParserPrivate
0041 {
0042 public:
0043     explicit ParserPrivate(Parser* parser, QIODevice* file, Massif::FileData* data,
0044                            const QStringList& customAllocators, QAtomicInt* shouldStop);
0045     ~ParserPrivate();
0046 
0047     enum Error {
0048         NoError, ///< file could be parsed properly
0049         Invalid, ///< the file was invalid and could not be parsed
0050         Stopped ///< parser was stopped
0051     };
0052     /**
0053      * @return Whether an Error occurred or not.
0054      * @see errorLine()
0055      */
0056     Error error() const;
0057     /**
0058      * @return the line in which an error occurred or -1 if none.
0059      */
0060     int errorLine() const;
0061     /**
0062      * @return the line which could not be parsed.
0063      */
0064     QByteArray errorLineString() const;
0065 
0066 private:
0067     void parseFileDesc(const QByteArray& line);
0068     void parseFileCmd(const QByteArray& line);
0069     void parseFileTimeUnit(const QByteArray& line);
0070     void parseSnapshot(const QByteArray& line);
0071     void parseSnapshotHeapTree(const QByteArray& line);
0072     void parseSnapshotMemHeap(const QByteArray& line);
0073     void parseSnapshotMemHeapExtra(const QByteArray& line);
0074     void parseSnapshotTime(const QByteArray& line);
0075     void parseSnapshotMemStacks(const QByteArray& line);
0076     void parseHeapTreeLeaf(const QByteArray& line);
0077     bool parseheapTreeLeafInternal(const QByteArray& line, int depth);
0078     QByteArray readLine();
0079 
0080     QByteArray getLabel(const QByteArray& original);
0081 
0082     Parser* m_parser;
0083     QIODevice* m_file;
0084     FileData* m_data;
0085 
0086     /**
0087      * Each value in the enum identifies a line in the massif output file.
0088      */
0089     enum ExpectData {
0090         //BEGIN File wide data
0091         FileDesc, ///< desc: ...
0092         FileCmd, ///< cmd: ...
0093         FileTimeUnit, ///< time_unit: ...
0094         //END
0095         //BEGIN SnapShot data
0096         Snapshot, ///< actually three lines: #-----------\nsnapshot=N\n#-----------\n
0097         SnapshotTime, ///< time=N
0098         SnapshotMemHeap, ///< mem_heap_B=N
0099         SnapshotMemHeapExtra, ///< mem_heap_extra_B=N
0100         SnapshotMemStacks, ///< mem_stacks_B=N
0101         SnapshotHeapTree, ///< heap_tree=empty | heap_tree=detailed
0102         //END
0103         //BEGIN detailed Heap Tree data
0104         HeapTreeLeaf ///< nX: Y ... , where X gives the number of children and Y represents the heap size in bytes
0105                      /// the ... can be in one of three formats, here are examples for each of them:
0106                      /// 1) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
0107                      /// 2) in 803 places, all below massif's threshold (01.00%)
0108                      /// 3) 0x6F675AB: QByteArray::resize(int) (in /usr/lib/libQtCore.so.4.5.2)
0109         //END
0110     };
0111     ExpectData m_nextLine;
0112     int m_currentLine;
0113     QByteArray m_errorLineString;
0114 
0115     Error m_error;
0116 
0117     /// current snapshot that is parsed.
0118     SnapshotItem* m_snapshot;
0119     /// parent tree leaf item
0120     TreeLeafItem* m_parentItem;
0121     /// set to true if we had custom allocators
0122     bool m_hadCustomAllocators;
0123 
0124     /// list of custom allocator wildcards
0125     QVector<QRegExp> m_allocators;
0126     QVector<QByteArray> m_plainAllocators;
0127 
0128     /// improve memory consumption by re-using known labels
0129     /// and making use of the implicit sharing of QByteArrays
0130     QSet<QByteArray> m_labels;
0131 
0132     int m_expectedSnapshots;
0133 
0134     static const int BUF_SIZE = 4096;
0135     char m_lineBuffer[BUF_SIZE];
0136 };
0137 
0138 }
0139 
0140 #endif // MASSIF_PARSERPRIVATE_H