~ubuntu-branches/ubuntu/trusty/eclipse-linuxtools/trusty

« back to all changes in this revision

Viewing changes to valgrind/org.eclipse.linuxtools.valgrind.massif/src/org/eclipse/linuxtools/internal/valgrind/massif/MassifParser.java

  • Committer: Package Import Robot
  • Author(s): Jakub Adam
  • Date: 2012-06-29 12:07:30 UTC
  • Revision ID: package-import@ubuntu.com-20120629120730-bfri1xys1i71dpn6
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************************************
 
2
 * Copyright (c) 2008 Red Hat, Inc.
 
3
 * All rights reserved. This program and the accompanying materials
 
4
 * are made available under the terms of the Eclipse Public License v1.0
 
5
 * which accompanies this distribution, and is available at
 
6
 * http://www.eclipse.org/legal/epl-v10.html
 
7
 *
 
8
 * Contributors:
 
9
 *    Elliott Baron <ebaron@redhat.com> - initial API and implementation
 
10
 *******************************************************************************/ 
 
11
package org.eclipse.linuxtools.internal.valgrind.massif;
 
12
 
 
13
import java.io.BufferedReader;
 
14
import java.io.File;
 
15
import java.io.FileReader;
 
16
import java.io.IOException;
 
17
import java.util.ArrayList;
 
18
 
 
19
import org.eclipse.linuxtools.internal.valgrind.massif.MassifSnapshot.SnapshotType;
 
20
import org.eclipse.linuxtools.internal.valgrind.massif.MassifSnapshot.TimeUnit;
 
21
import org.eclipse.linuxtools.valgrind.core.ValgrindParserUtils;
 
22
import org.eclipse.osgi.util.NLS;
 
23
 
 
24
public class MassifParser {
 
25
        private static final String COLON = ":"; //$NON-NLS-1$
 
26
        private static final String SPACE = " "; //$NON-NLS-1$
 
27
        private static final String EQUALS = "="; //$NON-NLS-1$
 
28
        
 
29
        private static final String CMD = "cmd"; //$NON-NLS-1$
 
30
        private static final String TIME_UNIT = "time_unit"; //$NON-NLS-1$
 
31
        private static final String SNAPSHOT = "snapshot"; //$NON-NLS-1$
 
32
        private static final String TIME = "time"; //$NON-NLS-1$
 
33
        private static final String MEM_HEAP_B = "mem_heap_B"; //$NON-NLS-1$
 
34
        private static final String MEM_HEAP_EXTRA_B = "mem_heap_extra_B"; //$NON-NLS-1$
 
35
        private static final String MEM_STACKS_B = "mem_stacks_B"; //$NON-NLS-1$
 
36
        private static final String HEAP_TREE = "heap_tree"; //$NON-NLS-1$
 
37
        
 
38
        private static final String INSTRUCTIONS = "i"; //$NON-NLS-1$
 
39
        private static final String MILLISECONDS = "ms"; //$NON-NLS-1$
 
40
        private static final String BYTES = "B"; //$NON-NLS-1$
 
41
        private static final String PEAK = "peak"; //$NON-NLS-1$
 
42
        private static final String DETAILED = "detailed"; //$NON-NLS-1$
 
43
        private static final String EMPTY = "empty"; //$NON-NLS-1$
 
44
 
 
45
        protected Integer pid;
 
46
        protected MassifSnapshot[] snapshots;
 
47
 
 
48
        public MassifParser(File inputFile) throws IOException {
 
49
                ArrayList<MassifSnapshot> list = new ArrayList<MassifSnapshot>();
 
50
                BufferedReader br = null;
 
51
                try {
 
52
                        br = new BufferedReader(new FileReader(inputFile));
 
53
                        String line;
 
54
                        MassifSnapshot snapshot = null;
 
55
                        String cmd = null;
 
56
                        TimeUnit unit = null;  
 
57
                        int n = 0;
 
58
 
 
59
                        // retrive PID from filename
 
60
                        String filename = inputFile.getName();
 
61
                        pid = ValgrindParserUtils.parsePID(filename, MassifLaunchDelegate.OUT_PREFIX);
 
62
 
 
63
                        // parse contents of file
 
64
                        while ((line = br.readLine()) != null) {
 
65
                                if (line.startsWith(CMD + COLON)){
 
66
                                        cmd = ValgrindParserUtils.parseStrValue(line, COLON + SPACE);
 
67
                                }
 
68
                                else if (line.startsWith(TIME_UNIT + COLON)) {
 
69
                                        unit = parseTimeUnit(line);
 
70
                                }                       
 
71
                                else if (line.startsWith(SNAPSHOT)) {
 
72
                                        if (snapshot != null) {
 
73
                                                // this snapshot finished parsing
 
74
                                                list.add(snapshot);
 
75
                                                n++;
 
76
                                        }
 
77
                                        snapshot = new MassifSnapshot(n);
 
78
                                        snapshot.setCmd(cmd);
 
79
                                        snapshot.setUnit(unit);
 
80
                                }
 
81
                                else if (line.startsWith(TIME + EQUALS)) {
 
82
                                        snapshot.setTime(ValgrindParserUtils.parseLongValue(line, EQUALS));
 
83
                                }
 
84
                                else if (line.startsWith(MEM_HEAP_B + EQUALS)) {
 
85
                                        snapshot.setHeapBytes(ValgrindParserUtils.parseLongValue(line, EQUALS));
 
86
                                }
 
87
                                else if (line.startsWith(MEM_HEAP_EXTRA_B + EQUALS)) {
 
88
                                        snapshot.setHeapExtra(ValgrindParserUtils.parseLongValue(line, EQUALS));
 
89
                                }
 
90
                                else if (line.startsWith(MEM_STACKS_B + EQUALS)) {
 
91
                                        snapshot.setStacks(ValgrindParserUtils.parseLongValue(line, EQUALS));
 
92
                                }
 
93
                                else if (line.startsWith(HEAP_TREE + EQUALS)) {
 
94
                                        SnapshotType type = parseSnapshotType(line);
 
95
                                        snapshot.setType(type);
 
96
                                        switch (type) {
 
97
                                        case DETAILED:
 
98
                                        case PEAK:
 
99
                                                MassifHeapTreeNode node = parseTree(snapshot, null, br);
 
100
                                                node.setText(NLS.bind(Messages.getString("MassifParser.Snapshot_n"), n, node.getText())); // prepend snapshot number //$NON-NLS-1$
 
101
                                                snapshot.setRoot(node);
 
102
                                        }
 
103
                                }
 
104
                        }
 
105
                        if (snapshot != null) {
 
106
                                // last snapshot that finished parsing
 
107
                                list.add(snapshot);
 
108
                        }
 
109
                        snapshots = list.toArray(new MassifSnapshot[list.size()]);
 
110
                } finally {
 
111
                        if (br != null) {
 
112
                                br.close();
 
113
                        }
 
114
                }
 
115
        }
 
116
 
 
117
        private MassifHeapTreeNode parseTree(MassifSnapshot snapshot, MassifHeapTreeNode parent, BufferedReader br) throws IOException {
 
118
                String line = br.readLine();
 
119
                if (line == null) {
 
120
                        throw new IOException(Messages.getString("MassifParser.Unexpected_EOF")); //$NON-NLS-1$
 
121
                }
 
122
                line = line.trim(); // remove leading whitespace
 
123
                String[] parts = line.split(" "); //$NON-NLS-1$
 
124
                // bounds checking so we can fail with a more informative error
 
125
                if (parts.length < 2) {
 
126
                        ValgrindParserUtils.fail(line);
 
127
                }
 
128
                
 
129
                Integer numChildren = parseNumChildren(parts[0]);
 
130
                if (numChildren == null) {
 
131
                        ValgrindParserUtils.fail(line);
 
132
                }
 
133
 
 
134
                Long numBytes = parseNumBytes(parts[1]);
 
135
                if (numBytes == null) {
 
136
                        ValgrindParserUtils.fail(line);
 
137
                }
 
138
                
 
139
                double percentage;
 
140
                if (numBytes.intValue() == 0) {
 
141
                        percentage = 0;
 
142
                }
 
143
                else {
 
144
                        percentage = numBytes.doubleValue() / snapshot.getTotal() * 100;
 
145
                }
 
146
 
 
147
                MassifHeapTreeNode node;
 
148
                String address = null;
 
149
                String function = null;
 
150
                String filename = null;
 
151
                int lineNo = 0;
 
152
                if (parts[2].startsWith("0x")) { //$NON-NLS-1$
 
153
                        // we extend the above bounds checking
 
154
                        if (parts.length < 3) {
 
155
                                ValgrindParserUtils.fail(line);
 
156
                        }
 
157
                        // remove colon from address
 
158
                        address = parts[2].substring(0, parts[2].length() - 1);
 
159
                        
 
160
                        function = parseFunction(parts[3], line);
 
161
                        
 
162
                        // Parse source file if specified
 
163
                        Object[] subparts = ValgrindParserUtils.parseFilename(line);
 
164
                        filename = (String) subparts[0];
 
165
                        lineNo = (Integer) subparts[1];
 
166
                        
 
167
                        node = new MassifHeapTreeNode(parent, percentage, numBytes, address, function, filename, lineNo);
 
168
                }
 
169
                else {
 
170
                        // concatenate the rest
 
171
                        StringBuffer text = new StringBuffer();
 
172
                        for (int i = 2; i < parts.length; i++) {
 
173
                                text.append(parts[i]);
 
174
                                text.append(" "); //$NON-NLS-1$
 
175
                        }
 
176
                        
 
177
                        node = new MassifHeapTreeNode(parent, percentage, numBytes, text.toString().trim());
 
178
                }
 
179
                
 
180
                
 
181
                for (int i = 0; i < numChildren.intValue(); i++) {
 
182
                        node.addChild(parseTree(snapshot, node, br));
 
183
                }
 
184
                return node;
 
185
        }
 
186
 
 
187
        private String parseFunction(String start, String line) throws IOException {
 
188
                String function = null;
 
189
                int ix = line.lastIndexOf("("); //$NON-NLS-1$
 
190
                if (ix >= 0) {
 
191
                        function = line.substring(line.indexOf(start), ix);
 
192
                }
 
193
                else {
 
194
                        function = line.substring(line.indexOf(start));
 
195
                }
 
196
                if (function != null) {
 
197
                        function = function.trim();
 
198
                }
 
199
                else {
 
200
                        ValgrindParserUtils.fail(line);
 
201
                }
 
202
                
 
203
                return function;
 
204
        }
 
205
 
 
206
        private Long parseNumBytes(String string) {
 
207
                Long result = null;
 
208
                if (ValgrindParserUtils.isNumber(string)) {
 
209
                        result = Long.parseLong(string);
 
210
                }
 
211
                return result;
 
212
        }
 
213
 
 
214
        /*
 
215
         * format is "n[0-9]+:"
 
216
         */
 
217
        private Integer parseNumChildren(String string) {
 
218
                Integer result = null;
 
219
                if (string.length() >= 3) {
 
220
                        String number = string.substring(1, string.length() - 1);
 
221
                        if (ValgrindParserUtils.isNumber(number)) {
 
222
                                result = Integer.parseInt(number);
 
223
                        }
 
224
                }
 
225
                return result;
 
226
        }
 
227
 
 
228
        public Integer getPid() {
 
229
                return pid;
 
230
        }
 
231
        
 
232
        public MassifSnapshot[] getSnapshots() {
 
233
                return snapshots;
 
234
        }
 
235
 
 
236
        protected SnapshotType parseSnapshotType(String line) throws IOException {
 
237
                SnapshotType result = null;
 
238
                String[] parts = line.split(EQUALS);
 
239
                if (parts.length > 1) {
 
240
                        String type = parts[1];
 
241
                        if (type.equals(EMPTY)) {
 
242
                                result = SnapshotType.EMPTY;
 
243
                        }
 
244
                        else if (type.equals(DETAILED)) {
 
245
                                result = SnapshotType.DETAILED;
 
246
                        }
 
247
                        else if (type.equals(PEAK)) {
 
248
                                result = SnapshotType.PEAK;
 
249
                        }
 
250
                }
 
251
                if (result == null) {
 
252
                        ValgrindParserUtils.fail(line);
 
253
                }
 
254
                return result;
 
255
        }
 
256
        
 
257
        protected TimeUnit parseTimeUnit(String line) throws IOException {
 
258
                TimeUnit result = null;
 
259
                String[] parts = line.split(COLON + SPACE);
 
260
                if (parts.length > 1) {
 
261
                        String type = parts[1];
 
262
                        if (type.equals(INSTRUCTIONS)) {
 
263
                                result = TimeUnit.INSTRUCTIONS;
 
264
                        }
 
265
                        else if (type.equals(MILLISECONDS)) {
 
266
                                result = TimeUnit.MILLISECONDS;
 
267
                        }
 
268
                        else if (type.equals(BYTES)) {
 
269
                                result = TimeUnit.BYTES;
 
270
                        }
 
271
                }
 
272
                if (result == null) {
 
273
                        ValgrindParserUtils.fail(line);
 
274
                }
 
275
                return result;
 
276
        }
 
277
}