-void MarkStack::drain()
-{
-#if !ASSERT_DISABLED
- ASSERT(!m_isDraining);
- m_isDraining = true;
-#endif
- while (!m_markSets.isEmpty() || !m_values.isEmpty()) {
- while (!m_markSets.isEmpty() && m_values.size() < 50) {
- ASSERT(!m_markSets.isEmpty());
- MarkSet& current = m_markSets.last();
- ASSERT(current.m_values);
- JSValue* end = current.m_end;
- ASSERT(current.m_values);
- ASSERT(current.m_values != end);
- findNextUnmarkedNullValue:
- ASSERT(current.m_values != end);
- JSValue value = *current.m_values;
- current.m_values++;
-
- JSCell* cell;
- if (!value || !value.isCell() || Heap::testAndSetMarked(cell = value.asCell())) {
- if (current.m_values == end) {
- m_markSets.removeLast();
- continue;
- }
- goto findNextUnmarkedNullValue;
- }
-
- if (cell->structure()->typeInfo().type() < CompoundType) {
- cell->JSCell::visitChildren(*this);
- if (current.m_values == end) {
- m_markSets.removeLast();
- continue;
- }
- goto findNextUnmarkedNullValue;
- }
-
- if (current.m_values == end)
- m_markSets.removeLast();
-
- visitChildren(cell);
- }
- while (!m_values.isEmpty())
- visitChildren(m_values.removeLast());
+ validatePrevious();
+ other.validatePrevious();
+
+ // Remove our head and the head of the other list before we start moving segments around.
+ // We'll add them back on once we're done donating.
+ GCArraySegment<const JSCell*>* myHead = m_segments.removeHead();
+ GCArraySegment<const JSCell*>* otherHead = other.m_segments.removeHead();
+
+ while (segmentsToDonate--) {
+ GCArraySegment<const JSCell*>* current = m_segments.removeHead();
+ ASSERT(current);
+ ASSERT(m_numberOfSegments > 1);
+ other.m_segments.push(current);
+ m_numberOfSegments--;
+ other.m_numberOfSegments++;