Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: third_party/WebKit/Source/platform/heap/CallbackStack.h

Issue 2127453002: Oilpan: Introduce memory pool for CallbackStacks (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef CallbackStack_h 5 #ifndef CallbackStack_h
6 #define CallbackStack_h 6 #define CallbackStack_h
7 7
8 #include "platform/heap/BlinkGC.h" 8 #include "platform/heap/BlinkGC.h"
9 #include "wtf/Allocator.h" 9 #include "wtf/Allocator.h"
10 #include "wtf/Assertions.h" 10 #include "wtf/Assertions.h"
11 #include "wtf/Threading.h"
12 #include "wtf/ThreadingPrimitives.h"
11 13
12 namespace blink { 14 namespace blink {
13 15
14 // The CallbackStack contains all the visitor callbacks used to trace and mark 16 // The CallbackStack contains all the visitor callbacks used to trace and mark
15 // objects. A specific CallbackStack instance contains at most bufferSize elemen ts. 17 // objects. A specific CallbackStack instance contains at most bufferSize elemen ts.
16 // If more space is needed a new CallbackStack instance is created and chained 18 // If more space is needed a new CallbackStack instance is created and chained
17 // together with the former instance. I.e. a logical CallbackStack can be made o f 19 // together with the former instance. I.e. a logical CallbackStack can be made o f
18 // multiple chained CallbackStack object instances. 20 // multiple chained CallbackStack object instances.
19 class CallbackStack final { 21 class CallbackStack final {
20 USING_FAST_MALLOC(CallbackStack); 22 USING_FAST_MALLOC(CallbackStack);
21 public: 23 public:
22 class Item { 24 class Item {
23 DISALLOW_NEW(); 25 DISALLOW_NEW();
24 public: 26 public:
25 Item() { } 27 Item() { }
26 Item(void* object, VisitorCallback callback) 28 Item(void* object, VisitorCallback callback)
27 : m_object(object) 29 : m_object(object)
28 , m_callback(callback) 30 , m_callback(callback)
29 { 31 {
30 } 32 }
31 void* object() { return m_object; } 33 void* object() { return m_object; }
32 VisitorCallback callback() { return m_callback; } 34 VisitorCallback callback() { return m_callback; }
33 void call(Visitor* visitor) { m_callback(visitor, m_object); } 35 void call(Visitor* visitor) { m_callback(visitor, m_object); }
34 36
35 private: 37 private:
36 void* m_object; 38 void* m_object;
37 VisitorCallback m_callback; 39 VisitorCallback m_callback;
38 }; 40 };
39 41
40 explicit CallbackStack(size_t blockSize = kDefaultBlockSize); 42 CallbackStack();
41 ~CallbackStack(); 43 ~CallbackStack();
42 44
43 void clear(); 45 void commit();
44 void decommit(); 46 void decommit();
45 47
46 Item* allocateEntry(); 48 Item* allocateEntry();
47 Item* pop(); 49 Item* pop();
48 50
49 bool isEmpty() const; 51 bool isEmpty() const;
50 52
51 void invokeEphemeronCallbacks(Visitor*); 53 void invokeEphemeronCallbacks(Visitor*);
52 54
53 #if ENABLE(ASSERT) 55 #if ENABLE(ASSERT)
54 bool hasCallbackForObject(const void*); 56 bool hasCallbackForObject(const void*);
55 #endif 57 #endif
58 bool hasJustOneBlock() const;
56 59
57 static const size_t kMinimalBlockSize; 60 static const size_t kMinimalBlockSize;
58 static const size_t kDefaultBlockSize = (1 << 13); 61 static const size_t kDefaultBlockSize = (1 << 13);
59 62
60 private: 63 private:
61 class Block { 64 class Block {
62 USING_FAST_MALLOC(Block); 65 USING_FAST_MALLOC(Block);
63 public: 66 public:
64 Block(Block* next, size_t blockSize); 67 explicit Block(Block* next);
65 ~Block(); 68 ~Block();
66 69
67 #if ENABLE(ASSERT) 70 #if ENABLE(ASSERT)
68 void clear(); 71 void clear();
69 #endif 72 #endif
70 void reset();
71 void decommit();
72
73 Block* next() const { return m_next; } 73 Block* next() const { return m_next; }
74 void setNext(Block* next) { m_next = next; } 74 void setNext(Block* next) { m_next = next; }
75 75
76 bool isEmptyBlock() const 76 bool isEmptyBlock() const
77 { 77 {
78 return m_current == &(m_buffer[0]); 78 return m_current == &(m_buffer[0]);
79 } 79 }
80 80
81 size_t blockSize() const { return m_blockSize; } 81 size_t blockSize() const { return m_blockSize; }
82 82
(...skipping 22 matching lines...) Expand all
105 105
106 Item* m_buffer; 106 Item* m_buffer;
107 Item* m_limit; 107 Item* m_limit;
108 Item* m_current; 108 Item* m_current;
109 Block* m_next; 109 Block* m_next;
110 }; 110 };
111 111
112 Item* popSlow(); 112 Item* popSlow();
113 Item* allocateEntrySlow(); 113 Item* allocateEntrySlow();
114 void invokeOldestCallbacks(Block*, Block*, Visitor*); 114 void invokeOldestCallbacks(Block*, Block*, Visitor*);
115 bool hasJustOneBlock() const;
116 115
117 Block* m_first; 116 Block* m_first;
118 Block* m_last; 117 Block* m_last;
119 }; 118 };
120 119
120 class CallbackStackMemoryPool final {
121 USING_FAST_MALLOC(CallbackStackMemoryPool);
122 public:
123 // 2048 * 8 * sizeof(Item) = 256 KB is pre-allocated for the underlying
sof 2016/07/05 14:19:02 256Kb for some choice of pointer size, yes. :)
124 // buffer of CallbackStacks.
125 static const size_t kBlockSize = 2048;
126 static const size_t kPooledBlockCount = 8;
127
128 static CallbackStackMemoryPool& instance();
129
130 void initialize();
131 void shutdown();
132 CallbackStack::Item* allocate();
133 void free(CallbackStack::Item*);
134
135 private:
136 Mutex m_mutex;
137 int m_freeListFirst;
138 int m_freeListNext[kPooledBlockCount];
139 CallbackStack::Item* m_pooledMemory;
140 };
141
121 ALWAYS_INLINE CallbackStack::Item* CallbackStack::allocateEntry() 142 ALWAYS_INLINE CallbackStack::Item* CallbackStack::allocateEntry()
122 { 143 {
144 DCHECK(m_first);
123 Item* item = m_first->allocateEntry(); 145 Item* item = m_first->allocateEntry();
124 if (LIKELY(!!item)) 146 if (LIKELY(!!item))
125 return item; 147 return item;
126 148
127 return allocateEntrySlow(); 149 return allocateEntrySlow();
128 } 150 }
129 151
130 ALWAYS_INLINE CallbackStack::Item* CallbackStack::pop() 152 ALWAYS_INLINE CallbackStack::Item* CallbackStack::pop()
131 { 153 {
132 Item* item = m_first->pop(); 154 Item* item = m_first->pop();
133 if (LIKELY(!!item)) 155 if (LIKELY(!!item))
134 return item; 156 return item;
135 157
136 return popSlow(); 158 return popSlow();
137 } 159 }
138 160
139 } // namespace blink 161 } // namespace blink
140 162
141 #endif // CallbackStack_h 163 #endif // CallbackStack_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698