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#include "config.h" 27#include "WeakBlock.h" 28 29#include "Heap.h" 30#include "HeapRootVisitor.h" 31#include "JSObject.h" 32#include "JSCInlines.h" 33#include "Structure.h" 34 35namespace JSC { 36 37WeakBlock* WeakBlock::create(DeadBlock* block) 38{ 39 Region* region = block->region(); 40 return new (NotNull, block) WeakBlock(region); 41} 42 43WeakBlock::WeakBlock(Region* region) 44 : HeapBlock<WeakBlock>(region) 45{ 46 for (size_t i = 0; i < weakImplCount(); ++i) { 47 WeakImpl* weakImpl = &weakImpls()[i]; 48 new (NotNull, weakImpl) WeakImpl; 49 addToFreeList(&m_sweepResult.freeList, weakImpl); 50 } 51 52 ASSERT(isEmpty()); 53} 54 55void WeakBlock::lastChanceToFinalize() 56{ 57 for (size_t i = 0; i < weakImplCount(); ++i) { 58 WeakImpl* weakImpl = &weakImpls()[i]; 59 if (weakImpl->state() >= WeakImpl::Finalized) 60 continue; 61 weakImpl->setState(WeakImpl::Dead); 62 finalize(weakImpl); 63 } 64} 65 66void WeakBlock::sweep() 67{ 68 // If a block is completely empty, a sweep won't have any effect. 69 if (isEmpty()) 70 return; 71 72 SweepResult sweepResult; 73 for (size_t i = 0; i < weakImplCount(); ++i) { 74 WeakImpl* weakImpl = &weakImpls()[i]; 75 if (weakImpl->state() == WeakImpl::Dead) 76 finalize(weakImpl); 77 if (weakImpl->state() == WeakImpl::Deallocated) 78 addToFreeList(&sweepResult.freeList, weakImpl); 79 else 80 sweepResult.blockIsFree = false; 81 } 82 83 m_sweepResult = sweepResult; 84 ASSERT(!m_sweepResult.isNull()); 85} 86 87void WeakBlock::visit(HeapRootVisitor& heapRootVisitor) 88{ 89 // If a block is completely empty, a visit won't have any effect. 90 if (isEmpty()) 91 return; 92 93 SlotVisitor& visitor = heapRootVisitor.visitor(); 94 95 for (size_t i = 0; i < weakImplCount(); ++i) { 96 WeakImpl* weakImpl = &weakImpls()[i]; 97 if (weakImpl->state() != WeakImpl::Live) 98 continue; 99 100 const JSValue& jsValue = weakImpl->jsValue(); 101 if (Heap::isLive(jsValue.asCell())) 102 continue; 103 104 WeakHandleOwner* weakHandleOwner = weakImpl->weakHandleOwner(); 105 if (!weakHandleOwner) 106 continue; 107 108 if (!weakHandleOwner->isReachableFromOpaqueRoots(Handle<Unknown>::wrapSlot(&const_cast<JSValue&>(jsValue)), weakImpl->context(), visitor)) 109 continue; 110 111 heapRootVisitor.visit(&const_cast<JSValue&>(jsValue)); 112 } 113} 114 115void WeakBlock::reap() 116{ 117 // If a block is completely empty, a reaping won't have any effect. 118 if (isEmpty()) 119 return; 120 121 for (size_t i = 0; i < weakImplCount(); ++i) { 122 WeakImpl* weakImpl = &weakImpls()[i]; 123 if (weakImpl->state() > WeakImpl::Dead) 124 continue; 125 126 if (Heap::isLive(weakImpl->jsValue().asCell())) { 127 ASSERT(weakImpl->state() == WeakImpl::Live); 128 continue; 129 } 130 131 weakImpl->setState(WeakImpl::Dead); 132 } 133} 134 135} // namespace JSC 136