Chromium Code Reviews| 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) { | |
|
haraken
2016/12/09 07:25:56
node.m_next < fromEnd ?
The same comment for othe
sof
2016/12/09 21:44:05
Yes, the range of these internal pointers is [from
| |
| 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 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 868 swap(static_cast<Base&>(a), static_cast<Base&>(b)); | 919 swap(static_cast<Base&>(a), static_cast<Base&>(b)); |
| 869 swap(a.m_value, b.m_value); | 920 swap(a.m_value, b.m_value); |
| 870 Allocator::leaveGCForbiddenScope(); | 921 Allocator::leaveGCForbiddenScope(); |
| 871 } | 922 } |
| 872 | 923 |
| 873 } // namespace WTF | 924 } // namespace WTF |
| 874 | 925 |
| 875 using WTF::LinkedHashSet; | 926 using WTF::LinkedHashSet; |
| 876 | 927 |
| 877 #endif /* WTF_LinkedHashSet_h */ | 928 #endif /* WTF_LinkedHashSet_h */ |
| OLD | NEW |