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 } | |
309 } | 302 } |
310 | 303 |
311 int64_t modifications() const { return m_impl.modifications(); } | 304 int64_t modifications() const { return m_impl.modifications(); } |
312 void checkModifications(int64_t mods) const { | 305 void checkModifications(int64_t mods) const { |
313 m_impl.checkModifications(mods); | 306 m_impl.checkModifications(mods); |
314 } | 307 } |
315 | 308 |
316 private: | 309 private: |
317 Node* anchor() { return reinterpret_cast<Node*>(&m_anchor); } | 310 Node* anchor() { return reinterpret_cast<Node*>(&m_anchor); } |
318 const Node* anchor() const { | 311 const Node* anchor() const { |
(...skipping 14 matching lines...) Expand all Loading... |
333 const_iterator makeConstIterator(const Node* position) const { | 326 const_iterator makeConstIterator(const Node* position) const { |
334 return const_iterator(position, this); | 327 return const_iterator(position, this); |
335 } | 328 } |
336 reverse_iterator makeReverseIterator(const Node* position) { | 329 reverse_iterator makeReverseIterator(const Node* position) { |
337 return reverse_iterator(position, this); | 330 return reverse_iterator(position, this); |
338 } | 331 } |
339 const_reverse_iterator makeConstReverseIterator(const Node* position) const { | 332 const_reverse_iterator makeConstReverseIterator(const Node* position) const { |
340 return const_reverse_iterator(position, this); | 333 return const_reverse_iterator(position, this); |
341 } | 334 } |
342 | 335 |
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 | |
387 ImplType m_impl; | 336 ImplType m_impl; |
388 NodeBase m_anchor; | 337 NodeBase m_anchor; |
389 }; | 338 }; |
390 | 339 |
391 template <typename Value, typename HashFunctions, typename Allocator> | 340 template <typename Value, typename HashFunctions, typename Allocator> |
392 struct LinkedHashSetTranslator { | 341 struct LinkedHashSetTranslator { |
393 STATIC_ONLY(LinkedHashSetTranslator); | 342 STATIC_ONLY(LinkedHashSetTranslator); |
394 typedef LinkedHashSetNode<Value, Allocator> Node; | 343 typedef LinkedHashSetNode<Value, Allocator> Node; |
395 typedef LinkedHashSetNodeBase NodeBase; | 344 typedef LinkedHashSetNodeBase NodeBase; |
396 typedef typename HashTraits<Value>::PeekInType ValuePeekInType; | 345 typedef typename HashTraits<Value>::PeekInType ValuePeekInType; |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
925 swap(static_cast<Base&>(a), static_cast<Base&>(b)); | 874 swap(static_cast<Base&>(a), static_cast<Base&>(b)); |
926 swap(a.m_value, b.m_value); | 875 swap(a.m_value, b.m_value); |
927 Allocator::leaveGCForbiddenScope(); | 876 Allocator::leaveGCForbiddenScope(); |
928 } | 877 } |
929 | 878 |
930 } // namespace WTF | 879 } // namespace WTF |
931 | 880 |
932 using WTF::LinkedHashSet; | 881 using WTF::LinkedHashSet; |
933 | 882 |
934 #endif /* WTF_LinkedHashSet_h */ | 883 #endif /* WTF_LinkedHashSet_h */ |
OLD | NEW |