| OLD | NEW |
| 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 #include "config.h" | 5 #include "config.h" |
| 6 #include "platform/heap/CallbackStack.h" | 6 #include "platform/heap/CallbackStack.h" |
| 7 | 7 |
| 8 #include "platform/heap/Heap.h" | |
| 9 | |
| 10 namespace blink { | 8 namespace blink { |
| 11 | 9 |
| 12 void CallbackStack::Block::clear() | 10 void CallbackStack::Block::clear() |
| 13 { | 11 { |
| 14 m_current = &m_buffer[0]; | 12 m_current = &m_buffer[0]; |
| 15 m_next = 0; | 13 m_next = nullptr; |
| 16 clearUnused(); | 14 clearUnused(); |
| 17 } | 15 } |
| 18 | 16 |
| 19 void CallbackStack::Block::invokeEphemeronCallbacks(Visitor* visitor) | 17 void CallbackStack::Block::invokeEphemeronCallbacks(Visitor* visitor) |
| 20 { | 18 { |
| 21 // This loop can tolerate entries being added by the callbacks after | 19 // This loop can tolerate entries being added by the callbacks after |
| 22 // iteration starts. | 20 // iteration starts. |
| 23 for (unsigned i = 0; m_buffer + i < m_current; i++) { | 21 for (unsigned i = 0; m_buffer + i < m_current; i++) { |
| 24 Item& item = m_buffer[i]; | 22 Item& item = m_buffer[i]; |
| 25 item.call(visitor); | 23 item.call(visitor); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 47 } | 45 } |
| 48 | 46 |
| 49 CallbackStack::CallbackStack() : m_first(new Block(0)), m_last(m_first) | 47 CallbackStack::CallbackStack() : m_first(new Block(0)), m_last(m_first) |
| 50 { | 48 { |
| 51 } | 49 } |
| 52 | 50 |
| 53 CallbackStack::~CallbackStack() | 51 CallbackStack::~CallbackStack() |
| 54 { | 52 { |
| 55 clear(); | 53 clear(); |
| 56 delete m_first; | 54 delete m_first; |
| 57 m_first = 0; | 55 m_first = nullptr; |
| 58 m_last = 0; | 56 m_last = nullptr; |
| 59 } | 57 } |
| 60 | 58 |
| 61 void CallbackStack::clear() | 59 void CallbackStack::clear() |
| 62 { | 60 { |
| 63 Block* next; | 61 Block* next; |
| 64 for (Block* current = m_first->next(); current; current = next) { | 62 for (Block* current = m_first->next(); current; current = next) { |
| 65 next = current->next(); | 63 next = current->next(); |
| 66 delete current; | 64 delete current; |
| 67 } | 65 } |
| 68 m_first->clear(); | 66 m_first->clear(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 79 ASSERT(!m_first->allocateEntry()); | 77 ASSERT(!m_first->allocateEntry()); |
| 80 m_first = new Block(m_first); | 78 m_first = new Block(m_first); |
| 81 return m_first->allocateEntry(); | 79 return m_first->allocateEntry(); |
| 82 } | 80 } |
| 83 | 81 |
| 84 CallbackStack::Item* CallbackStack::popSlow() | 82 CallbackStack::Item* CallbackStack::popSlow() |
| 85 { | 83 { |
| 86 ASSERT(m_first->isEmptyBlock()); | 84 ASSERT(m_first->isEmptyBlock()); |
| 87 | 85 |
| 88 for (;;) { | 86 for (;;) { |
| 89 if (hasJustOneBlock()) { | 87 Block* next = m_first->next(); |
| 88 if (!next) { |
| 90 #if ENABLE(ASSERT) | 89 #if ENABLE(ASSERT) |
| 91 m_first->clear(); | 90 m_first->clear(); |
| 92 #endif | 91 #endif |
| 93 return 0; | 92 return nullptr; |
| 94 } | 93 } |
| 95 Block* next = m_first->next(); | |
| 96 delete m_first; | 94 delete m_first; |
| 97 m_first = next; | 95 m_first = next; |
| 98 if (Item* item = m_first->pop()) | 96 if (Item* item = m_first->pop()) |
| 99 return item; | 97 return item; |
| 100 } | 98 } |
| 101 } | 99 } |
| 102 | 100 |
| 103 void CallbackStack::invokeEphemeronCallbacks(Visitor* visitor) | 101 void CallbackStack::invokeEphemeronCallbacks(Visitor* visitor) |
| 104 { | 102 { |
| 105 // The first block is the only one where new ephemerons are added, so we | 103 // The first block is the only one where new ephemerons are added, so we |
| 106 // call the callbacks on that last, to catch any new ephemerons discovered | 104 // call the callbacks on that last, to catch any new ephemerons discovered |
| 107 // in the callbacks. | 105 // in the callbacks. |
| 108 // However, if enough ephemerons were added, we may have a new block that | 106 // However, if enough ephemerons were added, we may have a new block that |
| 109 // has been prepended to the chain. This will be very rare, but we can | 107 // has been prepended to the chain. This will be very rare, but we can |
| 110 // handle the situation by starting again and calling all the callbacks | 108 // handle the situation by starting again and calling all the callbacks |
| 111 // on the prepended blocks. | 109 // on the prepended blocks. |
| 112 Block* from = 0; | 110 Block* from = nullptr; |
| 113 Block* upto = 0; | 111 Block* upto = nullptr; |
| 114 while (from != m_first) { | 112 while (from != m_first) { |
| 115 upto = from; | 113 upto = from; |
| 116 from = m_first; | 114 from = m_first; |
| 117 invokeOldestCallbacks(from, upto, visitor); | 115 invokeOldestCallbacks(from, upto, visitor); |
| 118 } | 116 } |
| 119 } | 117 } |
| 120 | 118 |
| 121 void CallbackStack::invokeOldestCallbacks(Block* from, Block* upto, Visitor* vis
itor) | 119 void CallbackStack::invokeOldestCallbacks(Block* from, Block* upto, Visitor* vis
itor) |
| 122 { | 120 { |
| 123 if (from == upto) | 121 if (from == upto) |
| 124 return; | 122 return; |
| 125 ASSERT(from); | 123 ASSERT(from); |
| 126 // Recurse first (blockSize at a time) so we get to the newly added entries
last. | 124 // Recurse first (blockSize at a time) so we get to the newly added entries
last. |
| 127 invokeOldestCallbacks(from->next(), upto, visitor); | 125 invokeOldestCallbacks(from->next(), upto, visitor); |
| 128 from->invokeEphemeronCallbacks(visitor); | 126 from->invokeEphemeronCallbacks(visitor); |
| 129 } | 127 } |
| 130 | 128 |
| 131 bool CallbackStack::hasJustOneBlock() const | 129 bool CallbackStack::hasJustOneBlock() const |
| 132 { | 130 { |
| 133 return !m_first->next(); | 131 return !m_first->next(); |
| 134 } | 132 } |
| 135 | 133 |
| 136 void CallbackStack::swap(CallbackStack* other) | |
| 137 { | |
| 138 Block* tmp = m_first; | |
| 139 m_first = other->m_first; | |
| 140 other->m_first = tmp; | |
| 141 tmp = m_last; | |
| 142 m_last = other->m_last; | |
| 143 other->m_last = tmp; | |
| 144 } | |
| 145 | |
| 146 #if ENABLE(ASSERT) | 134 #if ENABLE(ASSERT) |
| 147 bool CallbackStack::hasCallbackForObject(const void* object) | 135 bool CallbackStack::hasCallbackForObject(const void* object) |
| 148 { | 136 { |
| 149 for (Block* current = m_first; current; current = current->next()) { | 137 for (Block* current = m_first; current; current = current->next()) { |
| 150 if (current->hasCallbackForObject(object)) | 138 if (current->hasCallbackForObject(object)) |
| 151 return true; | 139 return true; |
| 152 } | 140 } |
| 153 return false; | 141 return false; |
| 154 } | 142 } |
| 155 #endif | 143 #endif |
| 156 | 144 |
| 157 } | 145 } |
| OLD | NEW |