e49ed14ac0f29a6bb488678375bd0a89de96865f
[platform/framework/web/crosswalk-tizen.git] /
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 #ifndef COMPONENTS_DISCARDABLE_MEMORY_COMMON_DISCARDABLE_SHARED_MEMORY_HEAP_H_
6 #define COMPONENTS_DISCARDABLE_MEMORY_COMMON_DISCARDABLE_SHARED_MEMORY_HEAP_H_
7
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <memory>
12
13 #include "base/callback.h"
14 #include "base/containers/hash_tables.h"
15 #include "base/containers/linked_list.h"
16 #include "base/macros.h"
17 #include "base/memory/scoped_vector.h"
18 #include "base/trace_event/process_memory_dump.h"
19 #include "components/discardable_memory/common/discardable_memory_export.h"
20
21 namespace base {
22 class DiscardableSharedMemory;
23 }
24
25 namespace discardable_memory {
26
27 // Implements a heap of discardable shared memory. An array of free lists
28 // is used to keep track of free blocks.
29 class DISCARDABLE_MEMORY_EXPORT DiscardableSharedMemoryHeap {
30  public:
31   class DISCARDABLE_MEMORY_EXPORT Span : public base::LinkNode<Span> {
32    public:
33     ~Span();
34
35     base::DiscardableSharedMemory* shared_memory() { return shared_memory_; }
36     size_t start() const { return start_; }
37     size_t length() const { return length_; }
38     void set_is_locked(bool is_locked) { is_locked_ = is_locked; }
39
40    private:
41     friend class DiscardableSharedMemoryHeap;
42
43     Span(base::DiscardableSharedMemory* shared_memory,
44          size_t start,
45          size_t length);
46
47     base::DiscardableSharedMemory* shared_memory_;
48     size_t start_;
49     size_t length_;
50     bool is_locked_;
51
52     DISALLOW_COPY_AND_ASSIGN(Span);
53   };
54
55   explicit DiscardableSharedMemoryHeap(size_t block_size);
56   ~DiscardableSharedMemoryHeap();
57
58   // Grow heap using |shared_memory| and return a span for this new memory.
59   // |shared_memory| must be aligned to the block size and |size| must be a
60   // multiple of the block size. |deleted_callback| is called when
61   // |shared_memory| has been deleted.
62   std::unique_ptr<Span> Grow(
63       std::unique_ptr<base::DiscardableSharedMemory> shared_memory,
64       size_t size,
65       int32_t id,
66       const base::Closure& deleted_callback);
67
68   // Merge |span| into the free lists. This will coalesce |span| with
69   // neighboring free spans when possible.
70   void MergeIntoFreeLists(std::unique_ptr<Span> span);
71
72   // Split an allocated span into two spans, one of length |blocks| followed
73   // by another span of length "span->length - blocks" blocks. Modifies |span|
74   // to point to the first span of length |blocks|. Return second span.
75   std::unique_ptr<Span> Split(Span* span, size_t blocks);
76
77   // Search free lists for span that satisfies the request for |blocks| of
78   // memory. If found, the span is removed from the free list and returned.
79   // |slack| determines the fitness requirement. Only spans that are less
80   // or equal to |blocks| + |slack| are considered, worse fitting spans are
81   // ignored.
82   std::unique_ptr<Span> SearchFreeLists(size_t blocks, size_t slack);
83
84   // Release free shared memory segments.
85   void ReleaseFreeMemory();
86
87   // Release shared memory segments that have been purged.
88   void ReleasePurgedMemory();
89
90   // Returns total bytes of memory in heap.
91   size_t GetSize() const;
92
93   // Returns bytes of memory currently in the free lists.
94   size_t GetSizeOfFreeLists() const;
95
96   // Dumps memory statistics for chrome://tracing.
97   bool OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd);
98
99   // Returns a unique identifier for a given tuple of (process id, segment id)
100   // that can be used to match memory dumps across different processes.
101   static base::trace_event::MemoryAllocatorDumpGuid GetSegmentGUIDForTracing(
102       uint64_t tracing_process_id,
103       int32_t segment_id);
104
105   // Returns a MemoryAllocatorDump for a given span on |pmd| with the size of
106   // the span.
107   base::trace_event::MemoryAllocatorDump* CreateMemoryAllocatorDump(
108       Span* span,
109       const char* name,
110       base::trace_event::ProcessMemoryDump* pmd) const;
111
112  private:
113   class ScopedMemorySegment {
114    public:
115     ScopedMemorySegment(
116         DiscardableSharedMemoryHeap* heap,
117         std::unique_ptr<base::DiscardableSharedMemory> shared_memory,
118         size_t size,
119         int32_t id,
120         const base::Closure& deleted_callback);
121     ~ScopedMemorySegment();
122
123     bool IsUsed() const;
124     bool IsResident() const;
125
126     bool ContainsSpan(Span* span) const;
127
128     base::trace_event::MemoryAllocatorDump* CreateMemoryAllocatorDump(
129         Span* span,
130         size_t block_size,
131         const char* name,
132         base::trace_event::ProcessMemoryDump* pmd) const;
133
134     // Used for dumping memory statistics from the segment to chrome://tracing.
135     void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd) const;
136
137    private:
138     DiscardableSharedMemoryHeap* const heap_;
139     std::unique_ptr<base::DiscardableSharedMemory> shared_memory_;
140     const size_t size_;
141     const int32_t id_;
142     const base::Closure deleted_callback_;
143
144     DISALLOW_COPY_AND_ASSIGN(ScopedMemorySegment);
145   };
146
147   void InsertIntoFreeList(std::unique_ptr<Span> span);
148   std::unique_ptr<Span> RemoveFromFreeList(Span* span);
149   std::unique_ptr<Span> Carve(Span* span, size_t blocks);
150   void RegisterSpan(Span* span);
151   void UnregisterSpan(Span* span);
152   bool IsMemoryUsed(const base::DiscardableSharedMemory* shared_memory,
153                     size_t size);
154   bool IsMemoryResident(const base::DiscardableSharedMemory* shared_memory);
155   void ReleaseMemory(const base::DiscardableSharedMemory* shared_memory,
156                      size_t size);
157
158   // Dumps memory statistics about a memory segment for chrome://tracing.
159   void OnMemoryDump(const base::DiscardableSharedMemory* shared_memory,
160                     size_t size,
161                     int32_t segment_id,
162                     base::trace_event::ProcessMemoryDump* pmd);
163
164   size_t block_size_;
165   size_t num_blocks_;
166   size_t num_free_blocks_;
167
168   // Vector of memory segments.
169   ScopedVector<ScopedMemorySegment> memory_segments_;
170
171   // Mapping from first/last block of span to Span instance.
172   typedef base::hash_map<size_t, Span*> SpanMap;
173   SpanMap spans_;
174
175   // Array of linked-lists with free discardable memory regions. For i < 256,
176   // where the 1st entry is located at index 0 of the array, the kth entry
177   // is a free list of runs that consist of k blocks. The 256th entry is a
178   // free list of runs that have length >= 256 blocks.
179   base::LinkedList<Span> free_spans_[256];
180
181   DISALLOW_COPY_AND_ASSIGN(DiscardableSharedMemoryHeap);
182 };
183
184 }  // namespace discardable_memory
185
186 #endif  // COMPONENTS_DISCARDABLE_MEMORY_COMMON_DISCARDABLE_SHARED_MEMORY_HEAP_H_