// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_TRACE_EVENT_PROCESS_MEMORY_DUMP_H_
#define BASE_TRACE_EVENT_PROCESS_MEMORY_DUMP_H_

#include <stddef.h>

#include <map>
#include <unordered_map>
#include <vector>

#include "base/base_export.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/trace_event/heap_profiler_allocation_context.h"
#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/memory_allocator_dump_guid.h"
#include "base/trace_event/memory_dump_request_args.h"
#include "build/build_config.h"

// Define COUNT_RESIDENT_BYTES_SUPPORTED if platform supports counting of the
// resident memory.
#if !defined(OS_NACL)
#define COUNT_RESIDENT_BYTES_SUPPORTED
#endif

namespace base {

class SharedMemory;
class UnguessableToken;

namespace trace_event {

class TracedValue;

// ProcessMemoryDump is as a strongly typed container which holds the dumps
// produced by the MemoryDumpProvider(s) for a specific process.
class BASE_EXPORT ProcessMemoryDump {
 public:
  struct BASE_EXPORT MemoryAllocatorDumpEdge {
    bool operator==(const MemoryAllocatorDumpEdge&) const;
    bool operator!=(const MemoryAllocatorDumpEdge&) const;

    MemoryAllocatorDumpGuid source;
    MemoryAllocatorDumpGuid target;
    int importance = 0;
    bool overridable = false;
  };

  // Maps allocator dumps absolute names (allocator_name/heap/subheap) to
  // MemoryAllocatorDump instances.
  using AllocatorDumpsMap =
      std::map<std::string, std::unique_ptr<MemoryAllocatorDump>>;

  // Stores allocator dump edges indexed by source allocator dump GUID.
  using AllocatorDumpEdgesMap =
      std::map<MemoryAllocatorDumpGuid, MemoryAllocatorDumpEdge>;

#if defined(COUNT_RESIDENT_BYTES_SUPPORTED)
  // Returns the number of bytes in a kernel memory page. Some platforms may
  // have a different value for kernel page sizes from user page sizes. It is
  // important to use kernel memory page sizes for resident bytes calculation.
  // In most cases, the two are the same.
  static size_t GetSystemPageSize();

  // Returns the total bytes resident for a virtual address range, with given
  // |start_address| and |mapped_size|. |mapped_size| is specified in bytes. The
  // value returned is valid only if the given range is currently mmapped by the
  // process. The |start_address| must be page-aligned.
  static size_t CountResidentBytes(void* start_address, size_t mapped_size);

  // The same as above, but the given mapped range should belong to the
  // shared_memory's mapped region.
  static base::Optional<size_t> CountResidentBytesInSharedMemory(
      void* start_address,
      size_t mapped_size);
#endif

  explicit ProcessMemoryDump(const MemoryDumpArgs& dump_args);
  ProcessMemoryDump(ProcessMemoryDump&&);
  ~ProcessMemoryDump();

  ProcessMemoryDump& operator=(ProcessMemoryDump&&);

  // Creates a new MemoryAllocatorDump with the given name and returns the
  // empty object back to the caller.
  // Arguments:
  //   absolute_name: a name that uniquely identifies allocator dumps produced
  //       by this provider. It is possible to specify nesting by using a
  //       path-like string (e.g., v8/isolate1/heap1, v8/isolate1/heap2).
  //       Leading or trailing slashes are not allowed.
  //   guid: an optional identifier, unique among all processes within the
  //       scope of a global dump. This is only relevant when using
  //       AddOwnershipEdge() to express memory sharing. If omitted,
  //       it will be automatically generated.
  // ProcessMemoryDump handles the memory ownership of its MemoryAllocatorDumps.
  MemoryAllocatorDump* CreateAllocatorDump(const std::string& absolute_name);
  MemoryAllocatorDump* CreateAllocatorDump(const std::string& absolute_name,
                                           const MemoryAllocatorDumpGuid& guid);

  // Looks up a MemoryAllocatorDump given its allocator and heap names, or
  // nullptr if not found.
  MemoryAllocatorDump* GetAllocatorDump(const std::string& absolute_name) const;

  // Do NOT use this method. All dump providers should use
  // CreateAllocatorDump(). Tries to create a new MemoryAllocatorDump only if it
  // doesn't already exist. Creating multiple dumps with same name using
  // GetOrCreateAllocatorDump() would override the existing scalars in MAD and
  // cause misreporting. This method is used only in rare cases multiple
  // components create allocator dumps with same name and only one of them adds
  // size.
  MemoryAllocatorDump* GetOrCreateAllocatorDump(
      const std::string& absolute_name);

  // Creates a shared MemoryAllocatorDump, to express cross-process sharing.
  // Shared allocator dumps are allowed to have duplicate guids within the
  // global scope, in order to reference the same dump from multiple processes.
  // See the design doc goo.gl/keU6Bf for reference usage patterns.
  MemoryAllocatorDump* CreateSharedGlobalAllocatorDump(
      const MemoryAllocatorDumpGuid& guid);

  // Creates a shared MemoryAllocatorDump as CreateSharedGlobalAllocatorDump,
  // but with a WEAK flag. A weak dump will be discarded unless a non-weak dump
  // is created using CreateSharedGlobalAllocatorDump by at least one process.
  // The WEAK flag does not apply if a non-weak dump with the same GUID already
  // exists or is created later. All owners and children of the discarded dump
  // will also be discarded transitively.
  MemoryAllocatorDump* CreateWeakSharedGlobalAllocatorDump(
      const MemoryAllocatorDumpGuid& guid);

  // Looks up a shared MemoryAllocatorDump given its guid.
  MemoryAllocatorDump* GetSharedGlobalAllocatorDump(
      const MemoryAllocatorDumpGuid& guid) const;

  // Returns the map of the MemoryAllocatorDumps added to this dump.
  const AllocatorDumpsMap& allocator_dumps() const { return allocator_dumps_; }

  AllocatorDumpsMap* mutable_allocator_dumps_for_serialization() const {
    // Mojo takes a const input argument even for move-only types that can be
    // mutate while serializing (like this one). Hence the const_cast.
    return const_cast<AllocatorDumpsMap*>(&allocator_dumps_);
  }
  void SetAllocatorDumpsForSerialization(
      std::vector<std::unique_ptr<MemoryAllocatorDump>>);

  // Only for mojo serialization.
  std::vector<MemoryAllocatorDumpEdge> GetAllEdgesForSerialization() const;
  void SetAllEdgesForSerialization(const std::vector<MemoryAllocatorDumpEdge>&);

  // Dumps heap usage with |allocator_name|.
  void DumpHeapUsage(
      const std::unordered_map<base::trace_event::AllocationContext,
                               base::trace_event::AllocationMetrics>&
          metrics_by_context,
      base::trace_event::TraceEventMemoryOverhead& overhead,
      const char* allocator_name);

  // Adds an ownership relationship between two MemoryAllocatorDump(s) with the
  // semantics: |source| owns |target|, and has the effect of attributing
  // the memory usage of |target| to |source|. |importance| is optional and
  // relevant only for the cases of co-ownership, where it acts as a z-index:
  // the owner with the highest importance will be attributed |target|'s memory.
  // If an edge is present, its importance will not be updated unless
  // |importance| is larger.
  void AddOwnershipEdge(const MemoryAllocatorDumpGuid& source,
                        const MemoryAllocatorDumpGuid& target,
                        int importance);
  void AddOwnershipEdge(const MemoryAllocatorDumpGuid& source,
                        const MemoryAllocatorDumpGuid& target);

  // Adds edges that can be overriden by a later or earlier call to
  // AddOwnershipEdge() with the same source and target with a different
  // |importance| value.
  void AddOverridableOwnershipEdge(const MemoryAllocatorDumpGuid& source,
                                   const MemoryAllocatorDumpGuid& target,
                                   int importance);

  // Creates ownership edges for memory backed by base::SharedMemory. Handles
  // the case of cross process sharing and importnace of ownership for the case
  // with and without the base::SharedMemory dump provider. The new version
  // should just use global dumps created by SharedMemoryTracker and this
  // function handles the transition until we get SharedMemory IDs through mojo
  // channel crbug.com/713763. The weak version creates a weak global dump.
  // |client_local_dump_guid| The guid of the local dump created by the client
  // of base::SharedMemory.
  // |shared_memory_guid| The ID of the base::SharedMemory that is assigned
  // globally, used to create global dump edges in the new model.
  // |importance| Importance of the global dump edges to say if the current
  // process owns the memory segment.
  void CreateSharedMemoryOwnershipEdge(
      const MemoryAllocatorDumpGuid& client_local_dump_guid,
      const UnguessableToken& shared_memory_guid,
      int importance);
  void CreateWeakSharedMemoryOwnershipEdge(
      const MemoryAllocatorDumpGuid& client_local_dump_guid,
      const UnguessableToken& shared_memory_guid,
      int importance);

  const AllocatorDumpEdgesMap& allocator_dumps_edges() const {
    return allocator_dumps_edges_;
  }

  // Utility method to add a suballocation relationship with the following
  // semantics: |source| is suballocated from |target_node_name|.
  // This creates a child node of |target_node_name| and adds an ownership edge
  // between |source| and the new child node. As a result, the UI will not
  // account the memory of |source| in the target node.
  void AddSuballocation(const MemoryAllocatorDumpGuid& source,
                        const std::string& target_node_name);

  // Removes all the MemoryAllocatorDump(s) contained in this instance. This
  // ProcessMemoryDump can be safely reused as if it was new once this returns.
  void Clear();

  // Merges all MemoryAllocatorDump(s) contained in |other| inside this
  // ProcessMemoryDump, transferring their ownership to this instance.
  // |other| will be an empty ProcessMemoryDump after this method returns.
  // This is to allow dump providers to pre-populate ProcessMemoryDump instances
  // and later move their contents into the ProcessMemoryDump passed as argument
  // of the MemoryDumpProvider::OnMemoryDump(ProcessMemoryDump*) callback.
  void TakeAllDumpsFrom(ProcessMemoryDump* other);

  // Populate the traced value with information about the memory allocator
  // dumps.
  void SerializeAllocatorDumpsInto(TracedValue* value) const;

  const MemoryDumpArgs& dump_args() const { return dump_args_; }

 private:
  FRIEND_TEST_ALL_PREFIXES(ProcessMemoryDumpTest, BackgroundModeTest);
  FRIEND_TEST_ALL_PREFIXES(ProcessMemoryDumpTest, SharedMemoryOwnershipTest);
  FRIEND_TEST_ALL_PREFIXES(ProcessMemoryDumpTest, GuidsTest);

  MemoryAllocatorDump* AddAllocatorDumpInternal(
      std::unique_ptr<MemoryAllocatorDump> mad);

  // A per-process token, valid throughout all the lifetime of the current
  // process, used to disambiguate dumps with the same name generated in
  // different processes.
  const UnguessableToken& process_token() const { return process_token_; }
  void set_process_token_for_testing(UnguessableToken token) {
    process_token_ = token;
  };

  // Returns the Guid of the dump for the given |absolute_name| for
  // for the given process' token. |process_token| is used to disambiguate GUIDs
  // derived from the same name under different processes.
  MemoryAllocatorDumpGuid GetDumpId(const std::string& absolute_name);

  void CreateSharedMemoryOwnershipEdgeInternal(
      const MemoryAllocatorDumpGuid& client_local_dump_guid,
      const UnguessableToken& shared_memory_guid,
      int importance,
      bool is_weak);

  MemoryAllocatorDump* GetBlackHoleMad();

  UnguessableToken process_token_;
  AllocatorDumpsMap allocator_dumps_;

  // Keeps track of relationships between MemoryAllocatorDump(s).
  AllocatorDumpEdgesMap allocator_dumps_edges_;

  // Level of detail of the current dump.
  MemoryDumpArgs dump_args_;

  // This allocator dump is returned when an invalid dump is created in
  // background mode. The attributes of the dump are ignored and not added to
  // the trace.
  std::unique_ptr<MemoryAllocatorDump> black_hole_mad_;

  // When set to true, the DCHECK(s) for invalid dump creations on the
  // background mode are disabled for testing.
  static bool is_black_hole_non_fatal_for_testing_;

  DISALLOW_COPY_AND_ASSIGN(ProcessMemoryDump);
};

}  // namespace trace_event
}  // namespace base

#endif  // BASE_TRACE_EVENT_PROCESS_MEMORY_DUMP_H_
