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

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

Issue 1115993003: Try reducing and balance GC callback stack sizes. Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: initialize stacks also before doing thread-terminating GCs Created 5 years, 7 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
« no previous file with comments | « no previous file | Source/platform/heap/CallbackStack.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/ThreadState.h" 8 #include "platform/heap/ThreadState.h"
9 9
10 namespace blink { 10 namespace blink {
11 11
12 // The CallbackStack contains all the visitor callbacks used to trace and mark 12 // The CallbackStack contains all the visitor callbacks used to trace and mark
13 // objects. A specific CallbackStack instance contains at most bufferSize elemen ts. 13 // objects. A specific CallbackStack instance contains at most bufferSize elemen ts.
14 // If more space is needed a new CallbackStack instance is created and chained 14 // If more space is needed a new CallbackStack instance is created and chained
15 // together with the former instance. I.e. a logical CallbackStack can be made o f 15 // together with the former instance. I.e. a logical CallbackStack can be made o f
16 // multiple chained CallbackStack object instances. 16 // multiple chained CallbackStack object instances.
17 class CallbackStack { 17 class CallbackStack {
18 public: 18 public:
19
20 // Callback stacks are extensible, chaining blocks together. However,
21 // all but the first block are deleted when 'popped empty', so it
22 // is in our interest to not spill over into additional blocks too
23 // often. The block sizes used here tries to reflect that -- plentiful
24 // for 'typical' GCs, but not wasting too much slop either in the
25 // initial block.
26 enum BlockSizes {
27 MarkingStackBlockSize = 8192,
28 WeakCallbackStackBlockSize = 2048,
29 PostMarkingStackBlockSize = 1024,
30 EphemeronCallbackStackBlockSize = 1024,
31 };
32
19 class Item { 33 class Item {
20 public: 34 public:
21 Item() { } 35 Item() { }
22 Item(void* object, VisitorCallback callback) 36 Item(void* object, VisitorCallback callback)
23 : m_object(object) 37 : m_object(object)
24 , m_callback(callback) 38 , m_callback(callback)
25 { 39 {
26 } 40 }
27 void* object() { return m_object; } 41 void* object() { return m_object; }
28 VisitorCallback callback() { return m_callback; } 42 VisitorCallback callback() { return m_callback; }
29 void call(Visitor* visitor) { m_callback(visitor, m_object); } 43 void call(Visitor* visitor) { m_callback(visitor, m_object); }
30 44
31 private: 45 private:
32 void* m_object; 46 void* m_object;
33 VisitorCallback m_callback; 47 VisitorCallback m_callback;
34 }; 48 };
35 49
36 CallbackStack(); 50 CallbackStack(unsigned blockSize);
37 ~CallbackStack(); 51 ~CallbackStack();
38 52
39 void clear(); 53 void clear();
40 54
41 Item* allocateEntry(); 55 Item* allocateEntry();
42 Item* pop(); 56 Item* pop();
43 57
44 bool isEmpty() const; 58 bool isEmpty() const;
45 59
46 void invokeEphemeronCallbacks(Visitor*); 60 void invokeEphemeronCallbacks(Visitor*);
47 61
48 #if ENABLE(ASSERT) 62 #if ENABLE(ASSERT)
49 bool hasCallbackForObject(const void*); 63 bool hasCallbackForObject(const void*);
50 #endif 64 #endif
51 65
52 static const size_t blockSize = 8192;
53
54 private: 66 private:
55 class Block { 67 class Block {
56 public: 68 public:
57 explicit Block(Block* next) 69 Block(Block* next, unsigned blockSize);
58 : m_limit(&(m_buffer[blockSize]))
59 , m_current(&(m_buffer[0]))
60 , m_next(next)
61 {
62 clearUnused();
63 }
64 70
65 ~Block() 71 ~Block()
66 { 72 {
67 clearUnused(); 73 clearUnused();
74 delete m_buffer;
68 } 75 }
69 76
70 void clear(); 77 void clear();
71 78
72 Block* next() const { return m_next; } 79 Block* next() const { return m_next; }
73 void setNext(Block* next) { m_next = next; } 80 void setNext(Block* next) { m_next = next; }
74 81
75 bool isEmptyBlock() const 82 bool isEmptyBlock() const
76 { 83 {
77 return m_current == &(m_buffer[0]); 84 return m_current == &(m_buffer[0]);
78 } 85 }
79 86
80 size_t size() const
81 {
82 return blockSize - (m_limit - m_current);
83 }
84
85 Item* allocateEntry() 87 Item* allocateEntry()
86 { 88 {
87 if (LIKELY(m_current < m_limit)) 89 if (LIKELY(m_current < m_limit))
88 return m_current++; 90 return m_current++;
89 return 0; 91 return 0;
90 } 92 }
91 93
92 Item* pop() 94 Item* pop()
93 { 95 {
94 if (UNLIKELY(isEmptyBlock())) 96 if (UNLIKELY(isEmptyBlock()))
95 return 0; 97 return 0;
96 return --m_current; 98 return --m_current;
97 } 99 }
98 100
99 void invokeEphemeronCallbacks(Visitor*); 101 void invokeEphemeronCallbacks(Visitor*);
100 #if ENABLE(ASSERT) 102 #if ENABLE(ASSERT)
101 bool hasCallbackForObject(const void*); 103 bool hasCallbackForObject(const void*);
102 #endif 104 #endif
103 105
104 private: 106 private:
105 void clearUnused(); 107 void clearUnused();
106 108
107 Item m_buffer[blockSize]; 109 Item* m_buffer;
108 Item* m_limit; 110 Item* m_limit;
109 Item* m_current; 111 Item* m_current;
110 Block* m_next; 112 Block* m_next;
113 #if ENABLE(ASSERT)
114 unsigned m_blockSize;
115 #endif
111 }; 116 };
112 117
113 Item* popSlow(); 118 Item* popSlow();
114 Item* allocateEntrySlow(); 119 Item* allocateEntrySlow();
115 void invokeOldestCallbacks(Block*, Block*, Visitor*); 120 void invokeOldestCallbacks(Block*, Block*, Visitor*);
116 bool hasJustOneBlock() const; 121 bool hasJustOneBlock() const;
117 void swap(CallbackStack* other);
118 122
119 Block* m_first; 123 Block* m_first;
120 Block* m_last; 124 Block* m_last;
125 unsigned m_blockSize;
121 }; 126 };
122 127
123 ALWAYS_INLINE CallbackStack::Item* CallbackStack::allocateEntry() 128 ALWAYS_INLINE CallbackStack::Item* CallbackStack::allocateEntry()
124 { 129 {
125 Item* item = m_first->allocateEntry(); 130 Item* item = m_first->allocateEntry();
126 if (LIKELY(!!item)) 131 if (LIKELY(!!item))
127 return item; 132 return item;
128 133
129 return allocateEntrySlow(); 134 return allocateEntrySlow();
130 } 135 }
131 136
132 ALWAYS_INLINE CallbackStack::Item* CallbackStack::pop() 137 ALWAYS_INLINE CallbackStack::Item* CallbackStack::pop()
133 { 138 {
134 Item* item = m_first->pop(); 139 Item* item = m_first->pop();
135 if (LIKELY(!!item)) 140 if (LIKELY(!!item))
136 return item; 141 return item;
137 142
138 return popSlow(); 143 return popSlow();
139 } 144 }
140 145
141 } // namespace blink 146 } // namespace blink
142 147
143 #endif // CallbackStack_h 148 #endif // CallbackStack_h
OLDNEW
« no previous file with comments | « no previous file | Source/platform/heap/CallbackStack.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698