summaryrefslogtreecommitdiff
path: root/base/trace_event/process_memory_dump.h
diff options
context:
space:
mode:
Diffstat (limited to 'base/trace_event/process_memory_dump.h')
-rw-r--r--base/trace_event/process_memory_dump.h284
1 files changed, 284 insertions, 0 deletions
diff --git a/base/trace_event/process_memory_dump.h b/base/trace_event/process_memory_dump.h
new file mode 100644
index 0000000000..e2457b7389
--- /dev/null
+++ b/base/trace_event/process_memory_dump.h
@@ -0,0 +1,284 @@
+// 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_