24 #ifndef KJSCOLLECTOR_H_ 25 #define KJSCOLLECTOR_H_ 27 #include <wtf/HashCountedSet.h> 31 #define KJS_MEM_LIMIT 500000 57 static void *allocate(
size_t s);
62 static bool collect();
64 static const size_t minExtraCostSize = 256;
66 static void reportExtraMemoryCost(
size_t cost);
69 static bool isOutOfMemory()
78 static void finalCheck();
82 static void unprotect(
JSValue *);
84 static size_t numInterpreters();
85 static size_t numProtectedObjects();
86 static HashCountedSet<const char *> *rootObjectTypeCounts();
89 static void registerThread();
91 static bool isCellMarked(
const JSCell *);
92 static void markCell(JSCell *);
95 static const CollectorBlock *cellBlock(
const JSCell *);
96 static CollectorBlock *cellBlock(JSCell *);
97 static size_t cellOffset(
const JSCell *);
99 static void recordExtraCost(
size_t);
100 static void markProtectedObjects();
101 static void markCurrentThreadConservatively();
102 static void markOtherThreadConservatively(Thread *);
103 static void markStackObjectsConservatively();
104 static void markStackObjectsConservatively(
void *start,
void *end);
106 static bool memoryFull;
107 static void reportOutOfMemoryToAllInterpreters();
111 template<
size_t bytesPerWord>
struct CellSize;
115 template<>
struct CellSize<4> {
116 static const size_t m_value = 32;
118 template<>
struct CellSize<8> {
119 static const size_t m_value = 64;
121 const size_t BLOCK_SIZE = 16 * 4096;
123 const size_t BLOCK_OFFSET_MASK = BLOCK_SIZE - 1;
124 const size_t BLOCK_MASK = ~BLOCK_OFFSET_MASK;
126 const size_t CELL_SIZE = CellSize<sizeof(void *)>::m_value;
127 const size_t CELL_ARRAY_LENGTH = (CELL_SIZE /
sizeof(double));
128 const size_t CELL_MASK = CELL_SIZE - 1;
132 const size_t BITMAP_SIZE = (BLOCK_SIZE / CELL_SIZE + 7) / 8;
133 const size_t BITMAP_WORDS = (BITMAP_SIZE + 3) /
sizeof(uint32_t);
137 const size_t BLOCK_METADATA_SIZE = 3 * 4 * BITMAP_WORDS +
sizeof(uint32_t) +
sizeof(
void *);
138 const size_t CELLS_PER_BLOCK = (BLOCK_SIZE - BLOCK_METADATA_SIZE) / CELL_SIZE;
140 struct CollectorBitmap {
141 uint32_t bits[BITMAP_WORDS];
142 bool get(
size_t n)
const 144 return !!(bits[n >> 5] & (1 << (n & 0x1F)));
148 bits[n >> 5] |= (1 << (n & 0x1F));
152 bits[n >> 5] &= ~(1 << (n & 0x1F));
156 std::memset(bits, 0,
sizeof(bits));
160 struct CollectorCell {
162 double memory[CELL_ARRAY_LENGTH];
173 CollectorCell cells[CELLS_PER_BLOCK];
175 CollectorCell *freeList;
176 CollectorBitmap marked;
177 CollectorBitmap allocd;
178 CollectorBitmap trailer;
181 inline const CollectorBlock *Collector::cellBlock(
const JSCell *cell)
183 return reinterpret_cast<const CollectorBlock *
>(
reinterpret_cast<uintptr_t
>(cell) & BLOCK_MASK);
186 inline CollectorBlock *Collector::cellBlock(JSCell *cell)
188 return const_cast<CollectorBlock *
>(cellBlock(const_cast<const JSCell *>(cell)));
191 inline size_t Collector::cellOffset(
const JSCell *cell)
193 return (reinterpret_cast<uintptr_t>(cell) & BLOCK_OFFSET_MASK) / CELL_SIZE;
196 inline bool Collector::isCellMarked(
const JSCell *cell)
198 return cellBlock(cell)->marked.get(cellOffset(cell));
201 inline void Collector::markCell(JSCell *cell)
203 cellBlock(cell)->marked.set(cellOffset(cell));
206 inline void Collector::reportExtraMemoryCost(
size_t cost)
208 if (cost > minExtraCostSize) {
209 recordExtraCost(cost / (CELL_SIZE * 2));
JSValue is the base type for all primitives (Undefined, Null, Boolean, String, Number) and objects in...