1/* 2 * Copyright (C) 2012 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 26#ifndef WeakSet_h 27#define WeakSet_h 28 29#include "WeakBlock.h" 30 31namespace JSC { 32 33class Heap; 34class WeakImpl; 35 36class WeakSet { 37public: 38 static WeakImpl* allocate(JSValue, WeakHandleOwner* = 0, void* context = 0); 39 static void deallocate(WeakImpl*); 40 41 WeakSet(VM*); 42 ~WeakSet(); 43 void lastChanceToFinalize(); 44 45 Heap* heap() const; 46 VM* vm() const; 47 48 bool isEmpty() const; 49 50 void visit(HeapRootVisitor&); 51 void reap(); 52 void sweep(); 53 void shrink(); 54 void resetAllocator(); 55 56private: 57 JS_EXPORT_PRIVATE WeakBlock::FreeCell* findAllocator(); 58 WeakBlock::FreeCell* tryFindAllocator(); 59 WeakBlock::FreeCell* addAllocator(); 60 void removeAllocator(WeakBlock*); 61 62 WeakBlock::FreeCell* m_allocator; 63 WeakBlock* m_nextAllocator; 64 DoublyLinkedList<WeakBlock> m_blocks; 65 VM* m_vm; 66}; 67 68inline WeakSet::WeakSet(VM* vm) 69 : m_allocator(0) 70 , m_nextAllocator(0) 71 , m_vm(vm) 72{ 73} 74 75inline VM* WeakSet::vm() const 76{ 77 return m_vm; 78} 79 80inline bool WeakSet::isEmpty() const 81{ 82 for (WeakBlock* block = m_blocks.head(); block; block = block->next()) { 83 if (!block->isEmpty()) 84 return false; 85 } 86 87 return true; 88} 89 90inline void WeakSet::deallocate(WeakImpl* weakImpl) 91{ 92 weakImpl->setState(WeakImpl::Deallocated); 93} 94 95inline void WeakSet::lastChanceToFinalize() 96{ 97 for (WeakBlock* block = m_blocks.head(); block; block = block->next()) 98 block->lastChanceToFinalize(); 99} 100 101inline void WeakSet::visit(HeapRootVisitor& visitor) 102{ 103 for (WeakBlock* block = m_blocks.head(); block; block = block->next()) 104 block->visit(visitor); 105} 106 107inline void WeakSet::reap() 108{ 109 for (WeakBlock* block = m_blocks.head(); block; block = block->next()) 110 block->reap(); 111} 112 113inline void WeakSet::shrink() 114{ 115 WeakBlock* next; 116 for (WeakBlock* block = m_blocks.head(); block; block = next) { 117 next = block->next(); 118 119 if (block->isEmpty()) 120 removeAllocator(block); 121 } 122 123 resetAllocator(); 124} 125 126inline void WeakSet::resetAllocator() 127{ 128 m_allocator = 0; 129 m_nextAllocator = m_blocks.head(); 130} 131 132} // namespace JSC 133 134#endif // WeakSet_h 135