1/* 2 * Copyright (C) 2011 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#include "config.h" 27#include "HandleSet.h" 28 29#include "HandleBlock.h" 30#include "HandleBlockInlines.h" 31#include "HeapRootVisitor.h" 32#include "JSObject.h" 33#include "JSCInlines.h" 34#include <wtf/DataLog.h> 35 36namespace JSC { 37 38HandleSet::HandleSet(VM* vm) 39 : m_vm(vm) 40{ 41 grow(); 42} 43 44HandleSet::~HandleSet() 45{ 46 while (!m_blockList.isEmpty()) 47 m_vm->heap.blockAllocator().deallocate(HandleBlock::destroy(m_blockList.removeHead())); 48} 49 50void HandleSet::grow() 51{ 52 HandleBlock* newBlock = HandleBlock::create(m_vm->heap.blockAllocator().allocate<HandleBlock>(), this); 53 m_blockList.append(newBlock); 54 55 for (int i = newBlock->nodeCapacity() - 1; i >= 0; --i) { 56 Node* node = newBlock->nodeAtIndex(i); 57 new (NotNull, node) Node; 58 m_freeList.push(node); 59 } 60} 61 62void HandleSet::visitStrongHandles(HeapRootVisitor& heapRootVisitor) 63{ 64 Node* end = m_strongList.end(); 65 for (Node* node = m_strongList.begin(); node != end; node = node->next()) { 66#if ENABLE(GC_VALIDATION) 67 RELEASE_ASSERT(isLiveNode(node)); 68#endif 69 heapRootVisitor.visit(node->slot()); 70 } 71} 72 73void HandleSet::writeBarrier(HandleSlot slot, const JSValue& value) 74{ 75 if (!value == !*slot && slot->isCell() == value.isCell()) 76 return; 77 78 Node* node = toNode(slot); 79#if ENABLE(GC_VALIDATION) 80 RELEASE_ASSERT(isLiveNode(node)); 81#endif 82 SentinelLinkedList<Node>::remove(node); 83 if (!value || !value.isCell()) { 84 m_immediateList.push(node); 85 return; 86 } 87 88 m_strongList.push(node); 89#if ENABLE(GC_VALIDATION) 90 RELEASE_ASSERT(isLiveNode(node)); 91#endif 92} 93 94unsigned HandleSet::protectedGlobalObjectCount() 95{ 96 unsigned count = 0; 97 Node* end = m_strongList.end(); 98 for (Node* node = m_strongList.begin(); node != end; node = node->next()) { 99 JSValue value = *node->slot(); 100 if (value.isObject() && asObject(value.asCell())->isGlobalObject()) 101 count++; 102 } 103 return count; 104} 105 106#if ENABLE(GC_VALIDATION) || !ASSERT_DISABLED 107bool HandleSet::isLiveNode(Node* node) 108{ 109 if (node->prev()->next() != node) 110 return false; 111 if (node->next()->prev() != node) 112 return false; 113 114 return true; 115} 116#endif 117 118} // namespace JSC 119