summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h
diff options
context:
space:
mode:
authorKent Hansen <kent.hansen@nokia.com>2010-02-11 10:55:52 (GMT)
committerKent Hansen <kent.hansen@nokia.com>2010-03-10 09:19:43 (GMT)
commitd73e11d56a094544f036fac3f6e4483d1104261e (patch)
treec292c8f53c660dae3f7681dc7acbbe788730a580 /src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h
parent20e2b87b5194abf7e9f08b7c42c030a57e2d6b28 (diff)
downloadQt-d73e11d56a094544f036fac3f6e4483d1104261e.zip
Qt-d73e11d56a094544f036fac3f6e4483d1104261e.tar.gz
Qt-d73e11d56a094544f036fac3f6e4483d1104261e.tar.bz2
Update src/3rdparty/javascriptcore and adapt src/script to the changes
- Update qscriptvalueiterator test to expect length property when iterating arrays and strings. - Use EvalExecutable::create() instead of EvalExecutable constructor. The constructor is private. - Reimplement getOwnPropertyDescriptor() in all custom script objects. - Remove all reimplementations of getPropertyAttributes(). It doesn't exist in trunk anymore (getOwnPropertyDescriptor() is used instead). - Remove checkDontDelete argument from deleteProperty() reimplementations. The purpose of this argument was to support deleting properties with attribute Undeletable from C++. But it was quite an invasive patch to JavaScriptCore, and it doesn't seem worth it. If this feature is really crucial it should be re-done upstream. One of the tests needed to be updated so it's not sensitive to the C++ undeletability. - Adapt getOwnPropertyNames() reimplementations to signature change. - Add missing QScriptObject structure flags, otherwise we don't get all virtual calls. - Remove our patch for reporting column numbers in the debugger callbacks. It was just too intrusive. As with the checkDontDelete issue, this should be redone upstream if it's really important. In 4.7, QScriptEngineAgent will always report a column number of 1. Other compilation fixes: - InternalFunction::name() takes an ExecState* argument, not GlobalData* - ScopeChain::globalObject is no longer a function but a member variable - ScopeChainNode constructor takes a GlobalObject argument - Heap::collect() is called collectAllGarbage() - JSValue::strictEqual() takes an ExecState* argument - Debugger::exception() takes a bool hasHandler argument - Debugger no longer reports column number (we decided to drop that patch from JSC) - UString doesn't have operator+=(char*) - Update the autotests to reflect the columnNumber=1 change. - Add helper class to avoid crashing inside JSC. Ever since r52856 in WebKit trunk, this is needed. There are probably a lot of other public API functions that need this guard as well, but I'll add them as they are discovered. - Update mkdist-javascriptcore tag, exclude a few more files. - Set ENABLE_JSC_MULTIPLE_THREADS=0 define on Mac due to r52355 in trunk. Reviewed-by: Simon Hausmann
Diffstat (limited to 'src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h')
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h153
1 files changed, 69 insertions, 84 deletions
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h
index 0ecff19..7f7a679 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h
@@ -28,9 +28,9 @@
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
+#include <wtf/StdLibExtras.h>
#include <wtf/Threading.h>
-// This is supremely lame that we require pthreads to build on windows.
#if ENABLE(JSC_MULTIPLE_THREADS)
#include <pthread.h>
#endif
@@ -47,19 +47,21 @@ namespace JSC {
class MarkStack;
enum OperationInProgress { NoOperation, Allocation, Collection };
- enum HeapType { PrimaryHeap, NumberHeap };
- template <HeapType> class CollectorHeapIterator;
+ class LiveObjectIterator;
struct CollectorHeap {
+ size_t nextBlock;
+ size_t nextCell;
CollectorBlock** blocks;
+
+ void* nextNumber;
+
size_t numBlocks;
size_t usedBlocks;
- size_t firstBlockWithPossibleSpace;
- size_t numLiveObjects;
- size_t numLiveObjectsAtLastCollect;
size_t extraCost;
+ bool didShrink;
OperationInProgress operationInProgress;
};
@@ -67,36 +69,27 @@ namespace JSC {
class Heap : public Noncopyable {
public:
class Thread;
- typedef CollectorHeapIterator<PrimaryHeap> iterator;
void destroy();
-#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
- // We can inline these functions because everything is compiled as
- // one file, so the heapAllocate template definitions are available.
- // However, allocateNumber is used via jsNumberCell outside JavaScriptCore.
- // Thus allocateNumber needs to provide a non-inline version too.
- void* inlineAllocateNumber(size_t s) { return heapAllocate<NumberHeap>(s); }
- void* inlineAllocate(size_t s) { return heapAllocate<PrimaryHeap>(s); }
-#endif
void* allocateNumber(size_t);
void* allocate(size_t);
- bool collect();
bool isBusy(); // true if an allocation or collection is in progress
+ void collectAllGarbage();
- static const size_t minExtraCostSize = 256;
+ static const size_t minExtraCost = 256;
+ static const size_t maxExtraCost = 1024 * 1024;
void reportExtraMemoryCost(size_t cost);
- size_t objectCount();
+ size_t objectCount() const;
struct Statistics {
size_t size;
size_t free;
};
Statistics statistics() const;
- void setGCProtectNeedsLocking();
void protect(JSValue);
void unprotect(JSValue);
@@ -120,13 +113,12 @@ namespace JSC {
JSGlobalData* globalData() const { return m_globalData; }
static bool isNumber(JSCell*);
- // Iterators for the object heap.
- iterator primaryHeapBegin();
- iterator primaryHeapEnd();
+ LiveObjectIterator primaryHeapBegin();
+ LiveObjectIterator primaryHeapEnd();
private:
- template <HeapType heapType> void* heapAllocate(size_t);
- template <HeapType heapType> size_t sweep();
+ void reset();
+ void sweep();
static CollectorBlock* cellBlock(const JSCell*);
static size_t cellOffset(const JSCell*);
@@ -134,12 +126,22 @@ namespace JSC {
Heap(JSGlobalData*);
~Heap();
- template <HeapType heapType> NEVER_INLINE CollectorBlock* allocateBlock();
- template <HeapType heapType> NEVER_INLINE void freeBlock(size_t);
- NEVER_INLINE void freeBlock(CollectorBlock*);
- void freeBlocks(CollectorHeap*);
+ NEVER_INLINE CollectorBlock* allocateBlock();
+ NEVER_INLINE void freeBlock(size_t);
+ NEVER_INLINE void freeBlockPtr(CollectorBlock*);
+ void freeBlocks();
+ void resizeBlocks();
+ void growBlocks(size_t neededBlocks);
+ void shrinkBlocks(size_t neededBlocks);
+ void clearMarkBits();
+ void clearMarkBits(CollectorBlock*);
+ size_t markedCells(size_t startBlock = 0, size_t startCell = 0) const;
void recordExtraCost(size_t);
+
+ void addToStatistics(Statistics&) const;
+
+ void markRoots();
void markProtectedObjects(MarkStack&);
void markCurrentThreadConservatively(MarkStack&);
void markCurrentThreadConservativelyInternal(MarkStack&);
@@ -148,10 +150,8 @@ namespace JSC {
typedef HashCountedSet<JSCell*> ProtectCountSet;
- CollectorHeap primaryHeap;
- CollectorHeap numberHeap;
+ CollectorHeap m_heap;
- OwnPtr<Mutex> m_protectedValuesMutex; // Only non-null if the client explicitly requested it via setGCPrtotectNeedsLocking().
ProtectCountSet m_protectedValues;
HashSet<MarkedArgumentBuffer*>* m_markListSet;
@@ -181,7 +181,7 @@ namespace JSC {
#endif
template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 64; };
-#if PLATFORM(WINCE) || PLATFORM(SYMBIAN)
+#if OS(WINCE) || OS(SYMBIAN)
const size_t BLOCK_SIZE = 64 * 1024; // 64k
#else
const size_t BLOCK_SIZE = 64 * 4096; // 256k
@@ -196,87 +196,60 @@ namespace JSC {
const size_t SMALL_CELL_SIZE = CELL_SIZE / 2;
const size_t CELL_MASK = CELL_SIZE - 1;
const size_t CELL_ALIGN_MASK = ~CELL_MASK;
- const size_t CELLS_PER_BLOCK = (BLOCK_SIZE * 8 - sizeof(uint32_t) * 8 - sizeof(void *) * 8 - 2 * (7 + 3 * 8)) / (CELL_SIZE * 8 + 2);
- const size_t SMALL_CELLS_PER_BLOCK = 2 * CELLS_PER_BLOCK;
+ const size_t CELLS_PER_BLOCK = (BLOCK_SIZE - sizeof(Heap*)) * 8 * CELL_SIZE / (8 * CELL_SIZE + 1) / CELL_SIZE; // one bitmap byte can represent 8 cells.
+
const size_t BITMAP_SIZE = (CELLS_PER_BLOCK + 7) / 8;
const size_t BITMAP_WORDS = (BITMAP_SIZE + 3) / sizeof(uint32_t);
-
+
struct CollectorBitmap {
uint32_t bits[BITMAP_WORDS];
bool get(size_t n) const { return !!(bits[n >> 5] & (1 << (n & 0x1F))); }
void set(size_t n) { bits[n >> 5] |= (1 << (n & 0x1F)); }
void clear(size_t n) { bits[n >> 5] &= ~(1 << (n & 0x1F)); }
void clearAll() { memset(bits, 0, sizeof(bits)); }
+ size_t count(size_t startCell = 0)
+ {
+ size_t result = 0;
+ for ( ; (startCell & 0x1F) != 0; ++startCell) {
+ if (get(startCell))
+ ++result;
+ }
+ for (size_t i = startCell >> 5; i < BITMAP_WORDS; ++i)
+ result += WTF::bitCount(bits[i]);
+ return result;
+ }
+ size_t isEmpty() // Much more efficient than testing count() == 0.
+ {
+ for (size_t i = 0; i < BITMAP_WORDS; ++i)
+ if (bits[i] != 0)
+ return false;
+ return true;
+ }
};
struct CollectorCell {
- union {
- double memory[CELL_ARRAY_LENGTH];
- struct {
- void* zeroIfFree;
- ptrdiff_t next;
- } freeCell;
- } u;
- };
-
- struct SmallCollectorCell {
- union {
- double memory[CELL_ARRAY_LENGTH / 2];
- struct {
- void* zeroIfFree;
- ptrdiff_t next;
- } freeCell;
- } u;
+ double memory[CELL_ARRAY_LENGTH];
};
class CollectorBlock {
public:
CollectorCell cells[CELLS_PER_BLOCK];
- uint32_t usedCells;
- CollectorCell* freeList;
- CollectorBitmap marked;
- Heap* heap;
- HeapType type;
- };
-
- class SmallCellCollectorBlock {
- public:
- SmallCollectorCell cells[SMALL_CELLS_PER_BLOCK];
- uint32_t usedCells;
- SmallCollectorCell* freeList;
CollectorBitmap marked;
Heap* heap;
- HeapType type;
};
-
- template <HeapType heapType> struct HeapConstants;
- template <> struct HeapConstants<PrimaryHeap> {
+ struct HeapConstants {
static const size_t cellSize = CELL_SIZE;
static const size_t cellsPerBlock = CELLS_PER_BLOCK;
- static const size_t bitmapShift = 0;
typedef CollectorCell Cell;
typedef CollectorBlock Block;
};
- template <> struct HeapConstants<NumberHeap> {
- static const size_t cellSize = SMALL_CELL_SIZE;
- static const size_t cellsPerBlock = SMALL_CELLS_PER_BLOCK;
- static const size_t bitmapShift = 1;
- typedef SmallCollectorCell Cell;
- typedef SmallCellCollectorBlock Block;
- };
-
inline CollectorBlock* Heap::cellBlock(const JSCell* cell)
{
return reinterpret_cast<CollectorBlock*>(reinterpret_cast<uintptr_t>(cell) & BLOCK_MASK);
}
- inline bool Heap::isNumber(JSCell* cell)
- {
- return Heap::cellBlock(cell)->type == NumberHeap;
- }
-
inline size_t Heap::cellOffset(const JSCell* cell)
{
return (reinterpret_cast<uintptr_t>(cell) & BLOCK_OFFSET_MASK) / CELL_SIZE;
@@ -294,8 +267,20 @@ namespace JSC {
inline void Heap::reportExtraMemoryCost(size_t cost)
{
- if (cost > minExtraCostSize)
- recordExtraCost(cost / (CELL_SIZE * 2));
+ if (cost > minExtraCost)
+ recordExtraCost(cost);
+ }
+
+ inline void* Heap::allocateNumber(size_t s)
+ {
+ if (void* result = m_heap.nextNumber) {
+ m_heap.nextNumber = 0;
+ return result;
+ }
+
+ void* result = allocate(s);
+ m_heap.nextNumber = static_cast<char*>(result) + (CELL_SIZE / 2);
+ return result;
}
} // namespace JSC