OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights | 2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights |
3 * reserved. | 3 * reserved. |
4 * Copyright (C) 2011, Benjamin Poulain <ikipou@gmail.com> | 4 * Copyright (C) 2011, Benjamin Poulain <ikipou@gmail.com> |
5 * | 5 * |
6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
10 * | 10 * |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 void remove(iterator); | 292 void remove(iterator); |
293 void clear() { m_impl.clear(); } | 293 void clear() { m_impl.clear(); } |
294 template <typename Collection> | 294 template <typename Collection> |
295 void removeAll(const Collection& other) { | 295 void removeAll(const Collection& other) { |
296 WTF::removeAll(*this, other); | 296 WTF::removeAll(*this, other); |
297 } | 297 } |
298 | 298 |
299 template <typename VisitorDispatcher> | 299 template <typename VisitorDispatcher> |
300 void trace(VisitorDispatcher visitor) { | 300 void trace(VisitorDispatcher visitor) { |
301 m_impl.trace(visitor); | 301 m_impl.trace(visitor); |
| 302 // Should the underlying table be moved by GC, register a callback |
| 303 // that fixes up the interior pointers that the (Heap)LinkedHashSet keeps. |
| 304 if (m_impl.m_table) { |
| 305 Allocator::registerBackingStoreCallback( |
| 306 visitor, m_impl.m_table, moveBackingCallback, |
| 307 reinterpret_cast<void*>(&m_anchor)); |
| 308 } |
302 } | 309 } |
303 | 310 |
304 int64_t modifications() const { return m_impl.modifications(); } | 311 int64_t modifications() const { return m_impl.modifications(); } |
305 void checkModifications(int64_t mods) const { | 312 void checkModifications(int64_t mods) const { |
306 m_impl.checkModifications(mods); | 313 m_impl.checkModifications(mods); |
307 } | 314 } |
308 | 315 |
309 private: | 316 private: |
310 Node* anchor() { return reinterpret_cast<Node*>(&m_anchor); } | 317 Node* anchor() { return reinterpret_cast<Node*>(&m_anchor); } |
311 const Node* anchor() const { | 318 const Node* anchor() const { |
(...skipping 14 matching lines...) Expand all Loading... |
326 const_iterator makeConstIterator(const Node* position) const { | 333 const_iterator makeConstIterator(const Node* position) const { |
327 return const_iterator(position, this); | 334 return const_iterator(position, this); |
328 } | 335 } |
329 reverse_iterator makeReverseIterator(const Node* position) { | 336 reverse_iterator makeReverseIterator(const Node* position) { |
330 return reverse_iterator(position, this); | 337 return reverse_iterator(position, this); |
331 } | 338 } |
332 const_reverse_iterator makeConstReverseIterator(const Node* position) const { | 339 const_reverse_iterator makeConstReverseIterator(const Node* position) const { |
333 return const_reverse_iterator(position, this); | 340 return const_reverse_iterator(position, this); |
334 } | 341 } |
335 | 342 |
| 343 static void moveBackingCallback(void* anchor, |
| 344 void* from, |
| 345 void* to, |
| 346 size_t size) { |
| 347 // Note: the hash table move may have been overlapping; linearly scan the |
| 348 // entire table and fixup interior pointers into the old region with |
| 349 // correspondingly offset ones into the new. |
| 350 size_t tableSize = size / sizeof(Node); |
| 351 Node* table = reinterpret_cast<Node*>(to); |
| 352 NodeBase* fromStart = reinterpret_cast<NodeBase*>(from); |
| 353 NodeBase* fromEnd = |
| 354 reinterpret_cast<NodeBase*>(reinterpret_cast<uintptr_t>(from) + size); |
| 355 for (Node* element = table + tableSize - 1; element >= table; element--) { |
| 356 Node& node = *element; |
| 357 if (ImplType::isEmptyOrDeletedBucket(node)) |
| 358 continue; |
| 359 if (node.m_next >= fromStart && node.m_next < fromEnd) { |
| 360 size_t diff = reinterpret_cast<uintptr_t>(node.m_next) - |
| 361 reinterpret_cast<uintptr_t>(from); |
| 362 node.m_next = |
| 363 reinterpret_cast<NodeBase*>(reinterpret_cast<uintptr_t>(to) + diff); |
| 364 } |
| 365 if (node.m_prev >= fromStart && node.m_prev < fromEnd) { |
| 366 size_t diff = reinterpret_cast<uintptr_t>(node.m_prev) - |
| 367 reinterpret_cast<uintptr_t>(from); |
| 368 node.m_prev = |
| 369 reinterpret_cast<NodeBase*>(reinterpret_cast<uintptr_t>(to) + diff); |
| 370 } |
| 371 } |
| 372 NodeBase* anchorNode = reinterpret_cast<NodeBase*>(anchor); |
| 373 if (anchorNode->m_next >= fromStart && anchorNode->m_next < fromEnd) { |
| 374 size_t diff = reinterpret_cast<uintptr_t>(anchorNode->m_next) - |
| 375 reinterpret_cast<uintptr_t>(from); |
| 376 anchorNode->m_next = |
| 377 reinterpret_cast<NodeBase*>(reinterpret_cast<uintptr_t>(to) + diff); |
| 378 } |
| 379 if (anchorNode->m_prev >= fromStart && anchorNode->m_prev < fromEnd) { |
| 380 size_t diff = reinterpret_cast<uintptr_t>(anchorNode->m_prev) - |
| 381 reinterpret_cast<uintptr_t>(from); |
| 382 anchorNode->m_prev = |
| 383 reinterpret_cast<NodeBase*>(reinterpret_cast<uintptr_t>(to) + diff); |
| 384 } |
| 385 } |
| 386 |
336 ImplType m_impl; | 387 ImplType m_impl; |
337 NodeBase m_anchor; | 388 NodeBase m_anchor; |
338 }; | 389 }; |
339 | 390 |
340 template <typename Value, typename HashFunctions, typename Allocator> | 391 template <typename Value, typename HashFunctions, typename Allocator> |
341 struct LinkedHashSetTranslator { | 392 struct LinkedHashSetTranslator { |
342 STATIC_ONLY(LinkedHashSetTranslator); | 393 STATIC_ONLY(LinkedHashSetTranslator); |
343 typedef LinkedHashSetNode<Value, Allocator> Node; | 394 typedef LinkedHashSetNode<Value, Allocator> Node; |
344 typedef LinkedHashSetNodeBase NodeBase; | 395 typedef LinkedHashSetNodeBase NodeBase; |
345 typedef typename HashTraits<Value>::PeekInType ValuePeekInType; | 396 typedef typename HashTraits<Value>::PeekInType ValuePeekInType; |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 swap(static_cast<Base&>(a), static_cast<Base&>(b)); | 925 swap(static_cast<Base&>(a), static_cast<Base&>(b)); |
875 swap(a.m_value, b.m_value); | 926 swap(a.m_value, b.m_value); |
876 Allocator::leaveGCForbiddenScope(); | 927 Allocator::leaveGCForbiddenScope(); |
877 } | 928 } |
878 | 929 |
879 } // namespace WTF | 930 } // namespace WTF |
880 | 931 |
881 using WTF::LinkedHashSet; | 932 using WTF::LinkedHashSet; |
882 | 933 |
883 #endif /* WTF_LinkedHashSet_h */ | 934 #endif /* WTF_LinkedHashSet_h */ |
OLD | NEW |