11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci"""This parser turns the heap_dump output into a |NativeHeap| object."""
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciimport json
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifrom memory_inspector.core import native_heap
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifrom memory_inspector.core import stacktrace
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# These are defined in heap_profiler/heap_profiler.h
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciFLAGS_MALLOC = 1
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciFLAGS_MMAP = 2
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciFLAGS_MMAP_FILE = 4
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciFLAGS_IN_ZYGOTE = 8
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccidef Parse(content):
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  """Parses the output of the heap_dump binary (part of libheap_profiler).
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  heap_dump provides a conveniente JSON output.
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  See the header of tools/android/heap_profiler/heap_dump.c for more details.
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Args:
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      content: string containing the command output.
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Returns:
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      An instance of |native_heap.NativeHeap|.
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  """
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  data = json.loads(content)
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  assert('allocs' in data), 'Need to run heap_dump with the -x (extended) arg.'
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  nativeheap = native_heap.NativeHeap()
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  strace_by_index = {}   # index (str) -> |stacktrace.Stacktrace|
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for index, entry in data['stacks'].iteritems():
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    strace = stacktrace.Stacktrace()
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for absolute_addr in entry['f']:
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      strace.Add(nativeheap.GetStackFrame(absolute_addr))
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    strace_by_index[index] = strace
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for start_addr, entry in data['allocs'].iteritems():
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    flags = int(entry['f'])
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    # TODO(primiano): For the moment we just skip completely the allocations
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    # made in the Zygote (pre-fork) because this is usually reasonable. In the
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    # near future we will expose them with some UI to selectively filter them.
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if flags & FLAGS_IN_ZYGOTE:
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      continue
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    nativeheap.Add(native_heap.Allocation(
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      size=entry['l'],
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      stack_trace=strace_by_index[entry['s']],
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      start=int(start_addr, 16),
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      flags=flags))
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return nativeheap
57