2  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 
   3  *  Copyright (C) 2001 Peter Kelly (pmk@post.com) 
   4  *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved. 
   6  *  This library is free software; you can redistribute it and/or 
   7  *  modify it under the terms of the GNU Lesser General Public 
   8  *  License as published by the Free Software Foundation; either 
   9  *  version 2 of the License, or (at your option) any later version. 
  11  *  This library is distributed in the hope that it will be useful, 
  12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
  13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  14  *  Lesser General Public License for more details. 
  16  *  You should have received a copy of the GNU Lesser General Public 
  17  *  License along with this library; if not, write to the Free Software 
  18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA 
  25 #include <wtf/Bitmap.h> 
  26 #include <wtf/PageAllocationAligned.h> 
  27 #include <wtf/StdLibExtras.h> 
  35     typedef uintptr_t Bits
; 
  37     static const size_t KB 
= 1024; 
  41         static const size_t atomSize 
= sizeof(double); // Ensures natural alignment for all built-in types. 
  43         static MarkedBlock
* create(JSGlobalData
*, size_t cellSize
); 
  44         static void destroy(MarkedBlock
*); 
  46         static bool isAtomAligned(const void*); 
  47         static MarkedBlock
* blockFor(const void*); 
  48         static size_t firstAtom(); 
  52         void setPrev(MarkedBlock
*); 
  53         void setNext(MarkedBlock
*); 
  54         MarkedBlock
* prev() const; 
  55         MarkedBlock
* next() const; 
  71         bool contains(const void*); 
  72         size_t atomNumber(const void*); 
  73         bool isMarked(const void*); 
  74         bool testAndSetMarked(const void*); 
  75         void setMarked(const void*); 
  77         template <typename Functor
> void forEach(Functor
&); 
  80         static const size_t blockSize 
= 16 * KB
; 
  81         static const size_t blockMask 
= ~(blockSize 
- 1); // blockSize must be a power of two. 
  83         static const size_t atomMask 
= ~(atomSize 
- 1); // atomSize must be a power of two. 
  85         static const size_t atomsPerBlock 
= blockSize 
/ atomSize
; 
  87         typedef char Atom
[atomSize
]; 
  89         MarkedBlock(const PageAllocationAligned
&, JSGlobalData
*, size_t cellSize
); 
  93         size_t m_endAtom
; // This is a fuzzy end. Always test for < m_endAtom. 
  94         size_t m_atomsPerCell
; 
  95         WTF::Bitmap
<blockSize 
/ atomSize
> m_marks
; 
  96         PageAllocationAligned m_allocation
; 
 102     inline size_t MarkedBlock::firstAtom() 
 104         return WTF::roundUpToMultipleOf
<atomSize
>(sizeof(MarkedBlock
)) / atomSize
; 
 107     inline MarkedBlock::Atom
* MarkedBlock::atoms() 
 109         return reinterpret_cast<Atom
*>(this); 
 112     inline bool MarkedBlock::isAtomAligned(const void* p
) 
 114         return !((intptr_t)(p
) & ~atomMask
); 
 117     inline MarkedBlock
* MarkedBlock::blockFor(const void* p
) 
 119         return reinterpret_cast<MarkedBlock
*>(reinterpret_cast<uintptr_t>(p
) & blockMask
); 
 122     inline Heap
* MarkedBlock::heap() const 
 127     inline void MarkedBlock::setPrev(MarkedBlock
* prev
) 
 132     inline void MarkedBlock::setNext(MarkedBlock
* next
) 
 137     inline MarkedBlock
* MarkedBlock::prev() const 
 142     inline MarkedBlock
* MarkedBlock::next() const 
 147     inline void MarkedBlock::reset() 
 149         m_nextAtom 
= firstAtom(); 
 152     inline bool MarkedBlock::isEmpty() 
 154         return m_marks
.isEmpty(); 
 157     inline void MarkedBlock::clearMarks() 
 162     inline size_t MarkedBlock::markCount() 
 164         return m_marks
.count(); 
 167     inline size_t MarkedBlock::cellSize() 
 169         return m_atomsPerCell 
* atomSize
; 
 172     inline size_t MarkedBlock::size() 
 174         return markCount() * cellSize(); 
 177     inline size_t MarkedBlock::capacity() 
 179         return m_allocation
.size(); 
 182     inline bool MarkedBlock::contains(const void* p
) 
 184         ASSERT(p 
&& isAtomAligned(p
) && atomNumber(p
) < atomsPerBlock
); 
 186         // Even though we physically contain p, we only logically contain p if p 
 187         // points to a live cell. (Claiming to contain a dead cell would trick the 
 188         // conservative garbage collector into resurrecting the cell in a zombie state.) 
 192     inline size_t MarkedBlock::atomNumber(const void* p
) 
 194         return (reinterpret_cast<uintptr_t>(p
) - reinterpret_cast<uintptr_t>(this)) / atomSize
; 
 197     inline bool MarkedBlock::isMarked(const void* p
) 
 199         return m_marks
.get(atomNumber(p
)); 
 202     inline bool MarkedBlock::testAndSetMarked(const void* p
) 
 204         return m_marks
.testAndSet(atomNumber(p
)); 
 207     inline void MarkedBlock::setMarked(const void* p
) 
 209         m_marks
.set(atomNumber(p
)); 
 212     template <typename Functor
> inline void MarkedBlock::forEach(Functor
& functor
) 
 214         for (size_t i 
= firstAtom(); i 
< m_endAtom
; i 
+= m_atomsPerCell
) { 
 217             functor(reinterpret_cast<JSCell
*>(&atoms()[i
])); 
 223 #endif // MarkedSpace_h