WeakGCMap.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * Copyright (C) 2009 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
  14. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  15. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
  17. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  18. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  19. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  21. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  22. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  23. * THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #ifndef WeakGCMap_h
  26. #define WeakGCMap_h
  27. #include <heap/Weak.h>
  28. #include <heap/WeakInlines.h>
  29. #include <wtf/HashMap.h>
  30. namespace JSC {
  31. // A HashMap with Weak<JSCell> values, which automatically removes values once they're garbage collected.
  32. template<typename KeyArg, typename RawMappedArg, typename HashArg = typename DefaultHash<KeyArg>::Hash,
  33. typename KeyTraitsArg = HashTraits<KeyArg> >
  34. class WeakGCMap : public HashMap_shared<KeyArg, Weak<RawMappedArg>, HashArg, KeyTraitsArg> {
  35. #if ENABLE_DETACHED_JIT
  36. DETACHED_JIT_MAKE_SHARED_DATA_ALLOCATED;
  37. #endif
  38. typedef Weak<RawMappedArg> MappedType;
  39. typedef HashMap_shared<KeyArg, MappedType, HashArg, KeyTraitsArg> Base;
  40. typedef WeakGCMap<KeyArg, RawMappedArg, HashArg, KeyTraitsArg> Self;
  41. typedef HashTraits<MappedType> MappedTraits;
  42. typedef typename MappedTraits::PassInType MappedPassInType;
  43. public:
  44. typedef typename Base::KeyType KeyType;
  45. typedef typename Base::AddResult AddResult;
  46. typedef typename Base::iterator iterator;
  47. typedef typename Base::const_iterator const_iterator;
  48. using Base::begin;
  49. using Base::end;
  50. using Base::size;
  51. using Base::remove;
  52. WeakGCMap()
  53. : m_gcThreshold(minGCThreshold)
  54. {
  55. }
  56. AddResult set(const KeyType& key, MappedPassInType value)
  57. {
  58. gcMapIfNeeded();
  59. return Base::set(key, value);
  60. }
  61. AddResult add(const KeyType& key, MappedPassInType value)
  62. {
  63. gcMapIfNeeded();
  64. AddResult addResult = Base::add(key, nullptr);
  65. if (!addResult.iterator->value) { // New value or found a zombie value.
  66. addResult.isNewEntry = true;
  67. addResult.iterator->value = value;
  68. }
  69. return addResult;
  70. }
  71. iterator find(const KeyType& key)
  72. {
  73. iterator it = Base::find(key);
  74. iterator end = Base::end();
  75. if (it != end && !it->value) // Found a zombie value.
  76. return end;
  77. return it;
  78. }
  79. const_iterator find(const KeyType& key) const
  80. {
  81. return const_cast<Self*>(this)->find(key);
  82. }
  83. bool contains(const KeyType& key) const
  84. {
  85. return find(key) != end();
  86. }
  87. private:
  88. static const int minGCThreshold = 3;
  89. void gcMap()
  90. {
  91. Vector<KeyType, 4> zombies;
  92. iterator end = this->end();
  93. for (iterator it = begin(); it != end; ++it) {
  94. if (!it->value)
  95. zombies.append(it->key);
  96. }
  97. for (size_t i = 0; i < zombies.size(); ++i)
  98. remove(zombies[i]);
  99. }
  100. void gcMapIfNeeded()
  101. {
  102. if (size() < m_gcThreshold)
  103. return;
  104. gcMap();
  105. m_gcThreshold = std::max(minGCThreshold, size() * 2 - 1);
  106. }
  107. int m_gcThreshold;
  108. };
  109. template<typename KeyArg, typename RawMappedArg, typename HashArg, typename KeyTraitsArg>
  110. const int WeakGCMap<KeyArg, RawMappedArg, HashArg, KeyTraitsArg>::minGCThreshold;
  111. } // namespace JSC
  112. #endif // WeakGCMap_h