| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2009 Google Inc. All rights reserved. | 3 * Copyright (C) 2009 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * | 8 * |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 void removeFirst(); | 104 void removeFirst(); |
| 105 void removeLast(); | 105 void removeLast(); |
| 106 void remove(iterator&); | 106 void remove(iterator&); |
| 107 void remove(const_iterator&); | 107 void remove(const_iterator&); |
| 108 | 108 |
| 109 void clear(); | 109 void clear(); |
| 110 | 110 |
| 111 template<typename Predicate> | 111 template<typename Predicate> |
| 112 iterator findIf(Predicate&); | 112 iterator findIf(Predicate&); |
| 113 | 113 |
| 114 void trace(typename Allocator::Visitor*); | |
| 115 | |
| 116 private: | 114 private: |
| 117 friend class DequeIteratorBase<T, inlineCapacity, Allocator>; | 115 friend class DequeIteratorBase<T, inlineCapacity, Allocator>; |
| 118 | 116 |
| 119 typedef VectorBuffer<T, inlineCapacity, Allocator> Buffer; | 117 typedef VectorBuffer<T, inlineCapacity, Allocator> Buffer; |
| 120 typedef VectorTypeOperations<T> TypeOperations; | 118 typedef VectorTypeOperations<T> TypeOperations; |
| 121 typedef DequeIteratorBase<T, inlineCapacity, Allocator> IteratorBase; | 119 typedef DequeIteratorBase<T, inlineCapacity, Allocator> IteratorBase; |
| 122 | 120 |
| 123 void remove(size_t position); | 121 void remove(size_t position); |
| 124 void destroyAll(); | 122 void destroyAll(); |
| 125 void expandCapacityIfNeeded(); | 123 void expandCapacityIfNeeded(); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 Deque<T> copy(other); | 245 Deque<T> copy(other); |
| 248 swap(copy); | 246 swap(copy); |
| 249 return *this; | 247 return *this; |
| 250 } | 248 } |
| 251 | 249 |
| 252 template<typename T, size_t inlineCapacity, typename Allocator> | 250 template<typename T, size_t inlineCapacity, typename Allocator> |
| 253 inline void Deque<T, inlineCapacity, Allocator>::destroyAll() | 251 inline void Deque<T, inlineCapacity, Allocator>::destroyAll() |
| 254 { | 252 { |
| 255 if (m_start <= m_end) { | 253 if (m_start <= m_end) { |
| 256 TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffe
r() + m_end); | 254 TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffe
r() + m_end); |
| 257 m_buffer.clearUnusedSlots(m_buffer.buffer() + m_start, m_buffer.buff
er() + m_end); | |
| 258 } else { | 255 } else { |
| 259 TypeOperations::destruct(m_buffer.buffer(), m_buffer.buffer() + m_en
d); | 256 TypeOperations::destruct(m_buffer.buffer(), m_buffer.buffer() + m_en
d); |
| 260 m_buffer.clearUnusedSlots(m_buffer.buffer(), m_buffer.buffer() + m_e
nd); | |
| 261 TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffe
r() + m_buffer.capacity()); | 257 TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffe
r() + m_buffer.capacity()); |
| 262 m_buffer.clearUnusedSlots(m_buffer.buffer() + m_start, m_buffer.buff
er() + m_buffer.capacity()); | |
| 263 } | 258 } |
| 264 } | 259 } |
| 265 | 260 |
| 266 // Off-GC-heap deques: Destructor should be called. | 261 // Off-GC-heap deques: Destructor should be called. |
| 267 // On-GC-heap deques: Destructor should be called for inline buffers | 262 // On-GC-heap deques: Destructor should be called for inline buffers |
| 268 // (if any) but destructor shouldn't be called for vector backing since | 263 // (if any) but destructor shouldn't be called for vector backing since |
| 269 // it is managed by the traced GC heap. | 264 // it is managed by the traced GC heap. |
| 270 template<typename T, size_t inlineCapacity, typename Allocator> | 265 template<typename T, size_t inlineCapacity, typename Allocator> |
| 271 inline void Deque<T, inlineCapacity, Allocator>::finalize() | 266 inline void Deque<T, inlineCapacity, Allocator>::finalize() |
| 272 { | 267 { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 else | 372 else |
| 378 --m_start; | 373 --m_start; |
| 379 new (NotNull, &m_buffer.buffer()[m_start]) T(value); | 374 new (NotNull, &m_buffer.buffer()[m_start]) T(value); |
| 380 } | 375 } |
| 381 | 376 |
| 382 template<typename T, size_t inlineCapacity, typename Allocator> | 377 template<typename T, size_t inlineCapacity, typename Allocator> |
| 383 inline void Deque<T, inlineCapacity, Allocator>::removeFirst() | 378 inline void Deque<T, inlineCapacity, Allocator>::removeFirst() |
| 384 { | 379 { |
| 385 ASSERT(!isEmpty()); | 380 ASSERT(!isEmpty()); |
| 386 TypeOperations::destruct(&m_buffer.buffer()[m_start], &m_buffer.buffer()
[m_start + 1]); | 381 TypeOperations::destruct(&m_buffer.buffer()[m_start], &m_buffer.buffer()
[m_start + 1]); |
| 387 m_buffer.clearUnusedSlots(&m_buffer.buffer()[m_start], &m_buffer.buffer(
)[m_start + 1]); | |
| 388 if (m_start == m_buffer.capacity() - 1) | 382 if (m_start == m_buffer.capacity() - 1) |
| 389 m_start = 0; | 383 m_start = 0; |
| 390 else | 384 else |
| 391 ++m_start; | 385 ++m_start; |
| 392 } | 386 } |
| 393 | 387 |
| 394 template<typename T, size_t inlineCapacity, typename Allocator> | 388 template<typename T, size_t inlineCapacity, typename Allocator> |
| 395 inline void Deque<T, inlineCapacity, Allocator>::removeLast() | 389 inline void Deque<T, inlineCapacity, Allocator>::removeLast() |
| 396 { | 390 { |
| 397 ASSERT(!isEmpty()); | 391 ASSERT(!isEmpty()); |
| 398 if (!m_end) | 392 if (!m_end) |
| 399 m_end = m_buffer.capacity() - 1; | 393 m_end = m_buffer.capacity() - 1; |
| 400 else | 394 else |
| 401 --m_end; | 395 --m_end; |
| 402 TypeOperations::destruct(&m_buffer.buffer()[m_end], &m_buffer.buffer()[m
_end + 1]); | 396 TypeOperations::destruct(&m_buffer.buffer()[m_end], &m_buffer.buffer()[m
_end + 1]); |
| 403 m_buffer.clearUnusedSlots(&m_buffer.buffer()[m_end], &m_buffer.buffer()[
m_end + 1]); | |
| 404 } | 397 } |
| 405 | 398 |
| 406 template<typename T, size_t inlineCapacity, typename Allocator> | 399 template<typename T, size_t inlineCapacity, typename Allocator> |
| 407 inline void Deque<T, inlineCapacity, Allocator>::remove(iterator& it) | 400 inline void Deque<T, inlineCapacity, Allocator>::remove(iterator& it) |
| 408 { | 401 { |
| 409 remove(it.m_index); | 402 remove(it.m_index); |
| 410 } | 403 } |
| 411 | 404 |
| 412 template<typename T, size_t inlineCapacity, typename Allocator> | 405 template<typename T, size_t inlineCapacity, typename Allocator> |
| 413 inline void Deque<T, inlineCapacity, Allocator>::remove(const_iterator& it) | 406 inline void Deque<T, inlineCapacity, Allocator>::remove(const_iterator& it) |
| 414 { | 407 { |
| 415 remove(it.m_index); | 408 remove(it.m_index); |
| 416 } | 409 } |
| 417 | 410 |
| 418 template<typename T, size_t inlineCapacity, typename Allocator> | 411 template<typename T, size_t inlineCapacity, typename Allocator> |
| 419 inline void Deque<T, inlineCapacity, Allocator>::remove(size_t position) | 412 inline void Deque<T, inlineCapacity, Allocator>::remove(size_t position) |
| 420 { | 413 { |
| 421 if (position == m_end) | 414 if (position == m_end) |
| 422 return; | 415 return; |
| 423 | 416 |
| 424 T* buffer = m_buffer.buffer(); | 417 T* buffer = m_buffer.buffer(); |
| 425 TypeOperations::destruct(&buffer[position], &buffer[position + 1]); | 418 TypeOperations::destruct(&buffer[position], &buffer[position + 1]); |
| 426 | 419 |
| 427 // Find which segment of the circular buffer contained the remove elemen
t, and only move elements in that part. | 420 // Find which segment of the circular buffer contained the remove elemen
t, and only move elements in that part. |
| 428 if (position >= m_start) { | 421 if (position >= m_start) { |
| 429 TypeOperations::moveOverlapping(buffer + m_start, buffer + position,
buffer + m_start + 1); | 422 TypeOperations::moveOverlapping(buffer + m_start, buffer + position,
buffer + m_start + 1); |
| 430 m_buffer.clearUnusedSlots(buffer + m_start, buffer + m_start + 1); | |
| 431 m_start = (m_start + 1) % m_buffer.capacity(); | 423 m_start = (m_start + 1) % m_buffer.capacity(); |
| 432 } else { | 424 } else { |
| 433 TypeOperations::moveOverlapping(buffer + position + 1, buffer + m_en
d, buffer + position); | 425 TypeOperations::moveOverlapping(buffer + position + 1, buffer + m_en
d, buffer + position); |
| 434 m_buffer.clearUnusedSlots(buffer + m_end - 1, buffer + m_end); | |
| 435 m_end = (m_end - 1 + m_buffer.capacity()) % m_buffer.capacity(); | 426 m_end = (m_end - 1 + m_buffer.capacity()) % m_buffer.capacity(); |
| 436 } | 427 } |
| 437 } | 428 } |
| 438 | 429 |
| 439 template<typename T, size_t inlineCapacity, typename Allocator> | 430 template<typename T, size_t inlineCapacity, typename Allocator> |
| 440 inline DequeIteratorBase<T, inlineCapacity, Allocator>::DequeIteratorBase() | 431 inline DequeIteratorBase<T, inlineCapacity, Allocator>::DequeIteratorBase() |
| 441 : m_deque(0) | 432 : m_deque(0) |
| 442 { | 433 { |
| 443 } | 434 } |
| 444 | 435 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 | 497 |
| 507 template<typename T, size_t inlineCapacity, typename Allocator> | 498 template<typename T, size_t inlineCapacity, typename Allocator> |
| 508 inline T* DequeIteratorBase<T, inlineCapacity, Allocator>::before() const | 499 inline T* DequeIteratorBase<T, inlineCapacity, Allocator>::before() const |
| 509 { | 500 { |
| 510 ASSERT(m_index != m_deque->m_start); | 501 ASSERT(m_index != m_deque->m_start); |
| 511 if (!m_index) | 502 if (!m_index) |
| 512 return &m_deque->m_buffer.buffer()[m_deque->m_buffer.capacity() - 1]
; | 503 return &m_deque->m_buffer.buffer()[m_deque->m_buffer.capacity() - 1]
; |
| 513 return &m_deque->m_buffer.buffer()[m_index - 1]; | 504 return &m_deque->m_buffer.buffer()[m_index - 1]; |
| 514 } | 505 } |
| 515 | 506 |
| 516 // This is only called if the allocator is a HeapAllocator. It is used when | |
| 517 // visiting during a tracing GC. | |
| 518 template<typename T, size_t inlineCapacity, typename Allocator> | |
| 519 void Deque<T, inlineCapacity, Allocator>::trace(typename Allocator::Visitor*
visitor) | |
| 520 { | |
| 521 ASSERT(Allocator::isGarbageCollected); // Garbage collector must be enab
led. | |
| 522 const T* bufferBegin = m_buffer.buffer(); | |
| 523 const T* end = bufferBegin + m_end; | |
| 524 if (ShouldBeTraced<VectorTraits<T> >::value) { | |
| 525 if (m_start <= m_end) { | |
| 526 for (const T* bufferEntry = bufferBegin + m_start; bufferEntry !
= end; bufferEntry++) | |
| 527 Allocator::template trace<T, VectorTraits<T> >(visitor, *con
st_cast<T*>(bufferEntry)); | |
| 528 } else { | |
| 529 for (const T* bufferEntry = bufferBegin; bufferEntry != end; buf
ferEntry++) | |
| 530 Allocator::template trace<T, VectorTraits<T> >(visitor, *con
st_cast<T*>(bufferEntry)); | |
| 531 const T* bufferEnd = m_buffer.buffer() + m_buffer.capacity(); | |
| 532 for (const T* bufferEntry = bufferBegin + m_start; bufferEntry !
= bufferEnd; bufferEntry++) | |
| 533 Allocator::template trace<T, VectorTraits<T> >(visitor, *con
st_cast<T*>(bufferEntry)); | |
| 534 } | |
| 535 } | |
| 536 if (m_buffer.hasOutOfLineBuffer()) | |
| 537 Allocator::markNoTracing(visitor, m_buffer.buffer()); | |
| 538 } | |
| 539 | |
| 540 template<typename T, size_t inlineCapacity, typename Allocator> | 507 template<typename T, size_t inlineCapacity, typename Allocator> |
| 541 inline void swap(Deque<T, inlineCapacity, Allocator>& a, Deque<T, inlineCapa
city, Allocator>& b) | 508 inline void swap(Deque<T, inlineCapacity, Allocator>& a, Deque<T, inlineCapa
city, Allocator>& b) |
| 542 { | 509 { |
| 543 a.swap(b); | 510 a.swap(b); |
| 544 } | 511 } |
| 545 | 512 |
| 546 #if !ENABLE(OILPAN) | |
| 547 template<typename T, size_t N> | |
| 548 struct NeedsTracing<Deque<T, N> > { | |
| 549 static const bool value = false; | |
| 550 }; | |
| 551 #endif | |
| 552 | |
| 553 } // namespace WTF | 513 } // namespace WTF |
| 554 | 514 |
| 555 using WTF::Deque; | 515 using WTF::Deque; |
| 556 | 516 |
| 557 #endif // WTF_Deque_h | 517 #endif // WTF_Deque_h |
| OLD | NEW |