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