Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / platform / heap / CallbackStack.h
blob0df035438c4904e45366b25d0991d20cf6da9a25
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.
5 #ifndef CallbackStack_h
6 #define CallbackStack_h
8 #include "platform/heap/ThreadState.h"
9 #include "wtf/Assertions.h"
11 namespace blink {
13 // The CallbackStack contains all the visitor callbacks used to trace and mark
14 // objects. A specific CallbackStack instance contains at most bufferSize elements.
15 // If more space is needed a new CallbackStack instance is created and chained
16 // together with the former instance. I.e. a logical CallbackStack can be made of
17 // multiple chained CallbackStack object instances.
18 class CallbackStack {
19 public:
20 class Item {
21 public:
22 Item() { }
23 Item(void* object, VisitorCallback callback)
24 : m_object(object)
25 , m_callback(callback)
28 void* object() { return m_object; }
29 VisitorCallback callback() { return m_callback; }
30 void call(Visitor* visitor) { m_callback(visitor, m_object); }
32 private:
33 void* m_object;
34 VisitorCallback m_callback;
37 CallbackStack();
38 ~CallbackStack();
40 void clear();
42 Item* allocateEntry();
43 Item* pop();
45 bool isEmpty() const;
47 void invokeEphemeronCallbacks(Visitor*);
49 #if ENABLE(ASSERT)
50 bool hasCallbackForObject(const void*);
51 #endif
53 private:
54 static const size_t blockSize = 8192;
56 class Block {
57 public:
58 explicit Block(Block* next)
59 : m_limit(&(m_buffer[blockSize]))
60 , m_current(&(m_buffer[0]))
61 , m_next(next)
63 clearUnused();
66 ~Block()
68 clearUnused();
71 void clear();
73 Block* next() const { return m_next; }
74 void setNext(Block* next) { m_next = next; }
76 bool isEmptyBlock() const
78 return m_current == &(m_buffer[0]);
81 size_t size() const
83 return blockSize - (m_limit - m_current);
86 Item* allocateEntry()
88 if (LIKELY(m_current < m_limit))
89 return m_current++;
90 return nullptr;
93 Item* pop()
95 if (UNLIKELY(isEmptyBlock()))
96 return nullptr;
97 return --m_current;
100 void invokeEphemeronCallbacks(Visitor*);
101 #if ENABLE(ASSERT)
102 bool hasCallbackForObject(const void*);
103 #endif
105 private:
106 void clearUnused();
108 Item m_buffer[blockSize];
109 Item* m_limit;
110 Item* m_current;
111 Block* m_next;
114 Item* popSlow();
115 Item* allocateEntrySlow();
116 void invokeOldestCallbacks(Block*, Block*, Visitor*);
117 bool hasJustOneBlock() const;
119 Block* m_first;
120 Block* m_last;
123 ALWAYS_INLINE CallbackStack::Item* CallbackStack::allocateEntry()
125 Item* item = m_first->allocateEntry();
126 if (LIKELY(!!item))
127 return item;
129 return allocateEntrySlow();
132 ALWAYS_INLINE CallbackStack::Item* CallbackStack::pop()
134 Item* item = m_first->pop();
135 if (LIKELY(!!item))
136 return item;
138 return popSlow();
141 } // namespace blink
143 #endif // CallbackStack_h