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 "MarkedBlock.h" 28 29 #include "JSCell.h" 30 #include "JSObject.h" 31 #include "JSZombie.h" 32 #include "ScopeChain.h" 33 34 namespace JSC { 35 36 MarkedBlock* MarkedBlock::create(JSGlobalData* globalData, size_t cellSize) 37 { 38 PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, blockSize, OSAllocator::JSGCHeapPages); 39 if (!static_cast<bool>(allocation)) 40 CRASH(); 41 return new (allocation.base()) MarkedBlock(allocation, globalData, cellSize); 42 } 43 44 void MarkedBlock::destroy(MarkedBlock* block) 45 { 46 for (size_t i = block->firstAtom(); i < block->m_endAtom; i += block->m_atomsPerCell) 47 reinterpret_cast<JSCell*>(&block->atoms()[i])->~JSCell(); 48 block->m_allocation.deallocate(); 49 } 50 51 MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, JSGlobalData* globalData, size_t cellSize) 52 : m_nextAtom(firstAtom()) 53 , m_allocation(allocation) 54 , m_heap(&globalData->heap) 55 , m_prev(0) 56 , m_next(0) 57 { 58 m_atomsPerCell = (cellSize + atomSize - 1) / atomSize; 59 m_endAtom = atomsPerBlock - m_atomsPerCell + 1; 60 61 Structure* dummyMarkableCellStructure = globalData->dummyMarkableCellStructure.get(); 62 for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) 63 new (&atoms()[i]) JSCell(*globalData, dummyMarkableCellStructure); 64 } 65 66 void MarkedBlock::sweep() 67 { 68 Structure* dummyMarkableCellStructure = m_heap->globalData()->dummyMarkableCellStructure.get(); 69 70 for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) { 71 if (m_marks.get(i)) 72 continue; 73 74 JSCell* cell = reinterpret_cast<JSCell*>(&atoms()[i]); 75 #if ENABLE(JSC_ZOMBIES) 76 if (cell->structure() && cell->structure() != dummyMarkableCellStructure && !cell->isZombie()) { 77 const ClassInfo* info = cell->classInfo(); 78 cell->~JSCell(); 79 new (cell) JSZombie(*m_heap->globalData(), info, m_heap->globalData()->zombieStructure.get()); 80 m_marks.set(i); 81 } 82 #else 83 cell->~JSCell(); 84 new (cell) JSCell(*m_heap->globalData(), dummyMarkableCellStructure); 85 #endif 86 } 87 } 88 89 } // namespace JSC 90