Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'valgrind/org.eclipse.linuxtools.valgrind.massif/src/org/eclipse/linuxtools/internal/valgrind/massif/MassifParser.java')
-rw-r--r--valgrind/org.eclipse.linuxtools.valgrind.massif/src/org/eclipse/linuxtools/internal/valgrind/massif/MassifParser.java277
1 files changed, 277 insertions, 0 deletions
diff --git a/valgrind/org.eclipse.linuxtools.valgrind.massif/src/org/eclipse/linuxtools/internal/valgrind/massif/MassifParser.java b/valgrind/org.eclipse.linuxtools.valgrind.massif/src/org/eclipse/linuxtools/internal/valgrind/massif/MassifParser.java
new file mode 100644
index 0000000000..aed1ed9852
--- /dev/null
+++ b/valgrind/org.eclipse.linuxtools.valgrind.massif/src/org/eclipse/linuxtools/internal/valgrind/massif/MassifParser.java
@@ -0,0 +1,277 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Elliott Baron <ebaron@redhat.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.valgrind.massif;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.eclipse.linuxtools.internal.valgrind.massif.MassifSnapshot.SnapshotType;
+import org.eclipse.linuxtools.internal.valgrind.massif.MassifSnapshot.TimeUnit;
+import org.eclipse.linuxtools.valgrind.core.ValgrindParserUtils;
+import org.eclipse.osgi.util.NLS;
+
+public class MassifParser {
+ private static final String COLON = ":"; //$NON-NLS-1$
+ private static final String SPACE = " "; //$NON-NLS-1$
+ private static final String EQUALS = "="; //$NON-NLS-1$
+
+ private static final String CMD = "cmd"; //$NON-NLS-1$
+ private static final String TIME_UNIT = "time_unit"; //$NON-NLS-1$
+ private static final String SNAPSHOT = "snapshot"; //$NON-NLS-1$
+ private static final String TIME = "time"; //$NON-NLS-1$
+ private static final String MEM_HEAP_B = "mem_heap_B"; //$NON-NLS-1$
+ private static final String MEM_HEAP_EXTRA_B = "mem_heap_extra_B"; //$NON-NLS-1$
+ private static final String MEM_STACKS_B = "mem_stacks_B"; //$NON-NLS-1$
+ private static final String HEAP_TREE = "heap_tree"; //$NON-NLS-1$
+
+ private static final String INSTRUCTIONS = "i"; //$NON-NLS-1$
+ private static final String MILLISECONDS = "ms"; //$NON-NLS-1$
+ private static final String BYTES = "B"; //$NON-NLS-1$
+ private static final String PEAK = "peak"; //$NON-NLS-1$
+ private static final String DETAILED = "detailed"; //$NON-NLS-1$
+ private static final String EMPTY = "empty"; //$NON-NLS-1$
+
+ protected Integer pid;
+ protected MassifSnapshot[] snapshots;
+
+ public MassifParser(File inputFile) throws IOException {
+ ArrayList<MassifSnapshot> list = new ArrayList<MassifSnapshot>();
+ BufferedReader br = null;
+ try {
+ br = new BufferedReader(new FileReader(inputFile));
+ String line;
+ MassifSnapshot snapshot = null;
+ String cmd = null;
+ TimeUnit unit = null;
+ int n = 0;
+
+ // retrive PID from filename
+ String filename = inputFile.getName();
+ pid = ValgrindParserUtils.parsePID(filename, MassifLaunchDelegate.OUT_PREFIX);
+
+ // parse contents of file
+ while ((line = br.readLine()) != null) {
+ if (line.startsWith(CMD + COLON)){
+ cmd = ValgrindParserUtils.parseStrValue(line, COLON + SPACE);
+ }
+ else if (line.startsWith(TIME_UNIT + COLON)) {
+ unit = parseTimeUnit(line);
+ }
+ else if (line.startsWith(SNAPSHOT)) {
+ if (snapshot != null) {
+ // this snapshot finished parsing
+ list.add(snapshot);
+ n++;
+ }
+ snapshot = new MassifSnapshot(n);
+ snapshot.setCmd(cmd);
+ snapshot.setUnit(unit);
+ }
+ else if (line.startsWith(TIME + EQUALS)) {
+ snapshot.setTime(ValgrindParserUtils.parseLongValue(line, EQUALS));
+ }
+ else if (line.startsWith(MEM_HEAP_B + EQUALS)) {
+ snapshot.setHeapBytes(ValgrindParserUtils.parseLongValue(line, EQUALS));
+ }
+ else if (line.startsWith(MEM_HEAP_EXTRA_B + EQUALS)) {
+ snapshot.setHeapExtra(ValgrindParserUtils.parseLongValue(line, EQUALS));
+ }
+ else if (line.startsWith(MEM_STACKS_B + EQUALS)) {
+ snapshot.setStacks(ValgrindParserUtils.parseLongValue(line, EQUALS));
+ }
+ else if (line.startsWith(HEAP_TREE + EQUALS)) {
+ SnapshotType type = parseSnapshotType(line);
+ snapshot.setType(type);
+ switch (type) {
+ case DETAILED:
+ case PEAK:
+ MassifHeapTreeNode node = parseTree(snapshot, null, br);
+ node.setText(NLS.bind(Messages.getString("MassifParser.Snapshot_n"), n, node.getText())); // prepend snapshot number //$NON-NLS-1$
+ snapshot.setRoot(node);
+ }
+ }
+ }
+ if (snapshot != null) {
+ // last snapshot that finished parsing
+ list.add(snapshot);
+ }
+ snapshots = list.toArray(new MassifSnapshot[list.size()]);
+ } finally {
+ if (br != null) {
+ br.close();
+ }
+ }
+ }
+
+ private MassifHeapTreeNode parseTree(MassifSnapshot snapshot, MassifHeapTreeNode parent, BufferedReader br) throws IOException {
+ String line = br.readLine();
+ if (line == null) {
+ throw new IOException(Messages.getString("MassifParser.Unexpected_EOF")); //$NON-NLS-1$
+ }
+ line = line.trim(); // remove leading whitespace
+ String[] parts = line.split(" "); //$NON-NLS-1$
+ // bounds checking so we can fail with a more informative error
+ if (parts.length < 2) {
+ ValgrindParserUtils.fail(line);
+ }
+
+ Integer numChildren = parseNumChildren(parts[0]);
+ if (numChildren == null) {
+ ValgrindParserUtils.fail(line);
+ }
+
+ Long numBytes = parseNumBytes(parts[1]);
+ if (numBytes == null) {
+ ValgrindParserUtils.fail(line);
+ }
+
+ double percentage;
+ if (numBytes.intValue() == 0) {
+ percentage = 0;
+ }
+ else {
+ percentage = numBytes.doubleValue() / snapshot.getTotal() * 100;
+ }
+
+ MassifHeapTreeNode node;
+ String address = null;
+ String function = null;
+ String filename = null;
+ int lineNo = 0;
+ if (parts[2].startsWith("0x")) { //$NON-NLS-1$
+ // we extend the above bounds checking
+ if (parts.length < 3) {
+ ValgrindParserUtils.fail(line);
+ }
+ // remove colon from address
+ address = parts[2].substring(0, parts[2].length() - 1);
+
+ function = parseFunction(parts[3], line);
+
+ // Parse source file if specified
+ Object[] subparts = ValgrindParserUtils.parseFilename(line);
+ filename = (String) subparts[0];
+ lineNo = (Integer) subparts[1];
+
+ node = new MassifHeapTreeNode(parent, percentage, numBytes, address, function, filename, lineNo);
+ }
+ else {
+ // concatenate the rest
+ StringBuffer text = new StringBuffer();
+ for (int i = 2; i < parts.length; i++) {
+ text.append(parts[i]);
+ text.append(" "); //$NON-NLS-1$
+ }
+
+ node = new MassifHeapTreeNode(parent, percentage, numBytes, text.toString().trim());
+ }
+
+
+ for (int i = 0; i < numChildren.intValue(); i++) {
+ node.addChild(parseTree(snapshot, node, br));
+ }
+ return node;
+ }
+
+ private String parseFunction(String start, String line) throws IOException {
+ String function = null;
+ int ix = line.lastIndexOf("("); //$NON-NLS-1$
+ if (ix >= 0) {
+ function = line.substring(line.indexOf(start), ix);
+ }
+ else {
+ function = line.substring(line.indexOf(start));
+ }
+ if (function != null) {
+ function = function.trim();
+ }
+ else {
+ ValgrindParserUtils.fail(line);
+ }
+
+ return function;
+ }
+
+ private Long parseNumBytes(String string) {
+ Long result = null;
+ if (ValgrindParserUtils.isNumber(string)) {
+ result = Long.parseLong(string);
+ }
+ return result;
+ }
+
+ /*
+ * format is "n[0-9]+:"
+ */
+ private Integer parseNumChildren(String string) {
+ Integer result = null;
+ if (string.length() >= 3) {
+ String number = string.substring(1, string.length() - 1);
+ if (ValgrindParserUtils.isNumber(number)) {
+ result = Integer.parseInt(number);
+ }
+ }
+ return result;
+ }
+
+ public Integer getPid() {
+ return pid;
+ }
+
+ public MassifSnapshot[] getSnapshots() {
+ return snapshots;
+ }
+
+ protected SnapshotType parseSnapshotType(String line) throws IOException {
+ SnapshotType result = null;
+ String[] parts = line.split(EQUALS);
+ if (parts.length > 1) {
+ String type = parts[1];
+ if (type.equals(EMPTY)) {
+ result = SnapshotType.EMPTY;
+ }
+ else if (type.equals(DETAILED)) {
+ result = SnapshotType.DETAILED;
+ }
+ else if (type.equals(PEAK)) {
+ result = SnapshotType.PEAK;
+ }
+ }
+ if (result == null) {
+ ValgrindParserUtils.fail(line);
+ }
+ return result;
+ }
+
+ protected TimeUnit parseTimeUnit(String line) throws IOException {
+ TimeUnit result = null;
+ String[] parts = line.split(COLON + SPACE);
+ if (parts.length > 1) {
+ String type = parts[1];
+ if (type.equals(INSTRUCTIONS)) {
+ result = TimeUnit.INSTRUCTIONS;
+ }
+ else if (type.equals(MILLISECONDS)) {
+ result = TimeUnit.MILLISECONDS;
+ }
+ else if (type.equals(BYTES)) {
+ result = TimeUnit.BYTES;
+ }
+ }
+ if (result == null) {
+ ValgrindParserUtils.fail(line);
+ }
+ return result;
+ }
+}

Back to the top