KJS

collector.h
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (C) 1999-2000 Harri Porten ([email protected])
4  * Copyright (C) 2001 Peter Kelly ([email protected])
5  * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
6  * Copyright (C) 2007 Maksim Orlovich ([email protected])
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  */
23 
24 #ifndef KJSCOLLECTOR_H_
25 #define KJSCOLLECTOR_H_
26 
27 #include <wtf/HashCountedSet.h>
28 #include <cstring>
29 #include <cstddef>
30 
31 #define KJS_MEM_LIMIT 500000
32 
33 namespace KJS
34 {
35 class JSCell;
36 class JSValue;
37 class CollectorBlock;
38 
42 class KJS_EXPORT Collector
43 {
44  // disallow direct construction/destruction
45  Collector();
46 public:
57  static void *allocate(size_t s);
62  static bool collect();
63 
64  static const size_t minExtraCostSize = 256;
65 
66  static void reportExtraMemoryCost(size_t cost);
67 
68  static size_t size();
69  static bool isOutOfMemory()
70  {
71  return memoryFull;
72  }
73 
74 #ifdef KJS_DEBUG_MEM
75 
78  static void finalCheck();
79 #endif
80 
81  static void protect(JSValue *);
82  static void unprotect(JSValue *);
83 
84  static size_t numInterpreters();
85  static size_t numProtectedObjects();
86  static HashCountedSet<const char *> *rootObjectTypeCounts();
87 
88  class Thread;
89  static void registerThread();
90 
91  static bool isCellMarked(const JSCell *);
92  static void markCell(JSCell *);
93 
94 private:
95  static const CollectorBlock *cellBlock(const JSCell *);
96  static CollectorBlock *cellBlock(JSCell *);
97  static size_t cellOffset(const JSCell *);
98 
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);
105 
106  static bool memoryFull;
107  static void reportOutOfMemoryToAllInterpreters();
108 };
109 
110 // tunable parameters
111 template<size_t bytesPerWord> struct CellSize;
112 
113 // cell size needs to be a power of two for certain optimizations in collector.cpp
114 // below also assume it's divisible by 8, and that block size is divisible by it
115 template<> struct CellSize<4> {
116  static const size_t m_value = 32;
117 }; // 32-bit
118 template<> struct CellSize<8> {
119  static const size_t m_value = 64;
120 }; // 64-bit
121 const size_t BLOCK_SIZE = 16 * 4096; // 64k
122 
123 const size_t BLOCK_OFFSET_MASK = BLOCK_SIZE - 1;
124 const size_t BLOCK_MASK = ~BLOCK_OFFSET_MASK;
125 
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;
129 
130 // For each block, we can have at /most/ BLOCK_SIZE/CELL_SIZE entries.
131 // Sice the bitmap accordingly, don't try to be fancy
132 const size_t BITMAP_SIZE = (BLOCK_SIZE / CELL_SIZE + 7) / 8;
133 const size_t BITMAP_WORDS = (BITMAP_SIZE + 3) / sizeof(uint32_t);
134 
135 // In each block, we have 3 bitmaps (mark for all blocks, extension + allocd for oversize cell blocks),
136 // as well as an int and a pointer
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;
139 
140 struct CollectorBitmap {
141  uint32_t bits[BITMAP_WORDS];
142  bool get(size_t n) const
143  {
144  return !!(bits[n >> 5] & (1 << (n & 0x1F)));
145  }
146  void set(size_t n)
147  {
148  bits[n >> 5] |= (1 << (n & 0x1F));
149  }
150  void clear(size_t n)
151  {
152  bits[n >> 5] &= ~(1 << (n & 0x1F));
153  }
154  void clearAll()
155  {
156  std::memset(bits, 0, sizeof(bits));
157  }
158 };
159 
160 struct CollectorCell {
161  union {
162  double memory[CELL_ARRAY_LENGTH];
163  struct {
164  void *zeroIfFree;
165  ptrdiff_t next;
166  } freeCell;
167  } u;
168 };
169 
170 class CollectorBlock
171 {
172 public:
173  CollectorCell cells[CELLS_PER_BLOCK];
174  uint32_t usedCells;
175  CollectorCell *freeList;
176  CollectorBitmap marked;
177  CollectorBitmap allocd;
178  CollectorBitmap trailer;
179 };
180 
181 inline const CollectorBlock *Collector::cellBlock(const JSCell *cell)
182 {
183  return reinterpret_cast<const CollectorBlock *>(reinterpret_cast<uintptr_t>(cell) & BLOCK_MASK);
184 }
185 
186 inline CollectorBlock *Collector::cellBlock(JSCell *cell)
187 {
188  return const_cast<CollectorBlock *>(cellBlock(const_cast<const JSCell *>(cell)));
189 }
190 
191 inline size_t Collector::cellOffset(const JSCell *cell)
192 {
193  return (reinterpret_cast<uintptr_t>(cell) & BLOCK_OFFSET_MASK) / CELL_SIZE;
194 }
195 
196 inline bool Collector::isCellMarked(const JSCell *cell)
197 {
198  return cellBlock(cell)->marked.get(cellOffset(cell));
199 }
200 
201 inline void Collector::markCell(JSCell *cell)
202 {
203  cellBlock(cell)->marked.set(cellOffset(cell));
204 }
205 
206 inline void Collector::reportExtraMemoryCost(size_t cost)
207 {
208  if (cost > minExtraCostSize) {
209  recordExtraCost(cost / (CELL_SIZE * 2));
210  }
211 }
212 }
213 
214 #endif /* _KJSCOLLECTOR_H_ */
JSValue is the base type for all primitives (Undefined, Null, Boolean, String, Number) and objects in...
Definition: value.h:58
Garbage collector.
Definition: collector.h:42
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Tue Jul 14 2020 23:00:08 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.