1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""This parser turns the heap_dump output into a |NativeHeap| object."""
6
7import json
8
9from memory_inspector.core import native_heap
10from memory_inspector.core import stacktrace
11
12
13# These are defined in heap_profiler/heap_profiler.h
14FLAGS_MALLOC = 1
15FLAGS_MMAP = 2
16FLAGS_MMAP_FILE = 4
17FLAGS_IN_ZYGOTE = 8
18
19
20def Parse(content):
21  """Parses the output of the heap_dump binary (part of libheap_profiler).
22
23  heap_dump provides a conveniente JSON output.
24  See the header of tools/android/heap_profiler/heap_dump.c for more details.
25
26  Args:
27      content: string containing the command output.
28
29  Returns:
30      An instance of |native_heap.NativeHeap|.
31  """
32  data = json.loads(content)
33  assert('allocs' in data), 'Need to run heap_dump with the -x (extended) arg.'
34  nativeheap = native_heap.NativeHeap()
35  strace_by_index = {}   # index (str) -> |stacktrace.Stacktrace|
36
37  for index, entry in data['stacks'].iteritems():
38    strace = stacktrace.Stacktrace()
39    for absolute_addr in entry['f']:
40      strace.Add(nativeheap.GetStackFrame(absolute_addr))
41    strace_by_index[index] = strace
42
43  for start_addr, entry in data['allocs'].iteritems():
44    flags = int(entry['f'])
45    # TODO(primiano): For the moment we just skip completely the allocations
46    # made in the Zygote (pre-fork) because this is usually reasonable. In the
47    # near future we will expose them with some UI to selectively filter them.
48    if flags & FLAGS_IN_ZYGOTE:
49      continue
50    nativeheap.Add(native_heap.Allocation(
51      size=entry['l'],
52      stack_trace=strace_by_index[entry['s']],
53      start=int(start_addr, 16),
54      flags=flags))
55
56  return nativeheap
57