summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/runtime/Collector.h
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/runtime/Collector.h')
-rw-r--r--JavaScriptCore/runtime/Collector.h94
1 files changed, 70 insertions, 24 deletions
diff --git a/JavaScriptCore/runtime/Collector.h b/JavaScriptCore/runtime/Collector.h
index 82aa8a1..237c139 100644
--- a/JavaScriptCore/runtime/Collector.h
+++ b/JavaScriptCore/runtime/Collector.h
@@ -22,12 +22,18 @@
#ifndef Collector_h
#define Collector_h
+#include "AlignedMemoryAllocator.h"
+#include "GCHandle.h"
#include <stddef.h>
#include <string.h>
+#include <wtf/Bitmap.h>
+#include <wtf/FixedArray.h>
#include <wtf/HashCountedSet.h>
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
+#include <wtf/PageAllocation.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/StdLibExtras.h>
#include <wtf/Threading.h>
@@ -40,6 +46,7 @@
namespace JSC {
class CollectorBlock;
+ class GCActivityCallback;
class JSCell;
class JSGlobalData;
class JSValue;
@@ -50,10 +57,19 @@ namespace JSC {
class LiveObjectIterator;
+#if OS(WINCE) || OS(SYMBIAN) || PLATFORM(BREWMP)
+ const size_t BLOCK_SIZE = 64 * 1024; // 64k
+#else
+ const size_t BLOCK_SIZE = 256 * 1024; // 256k
+#endif
+
+ typedef AlignedMemoryAllocator<BLOCK_SIZE> CollectorBlockAllocator;
+ typedef AlignedMemory<BLOCK_SIZE> AlignedCollectorBlock;
+
struct CollectorHeap {
size_t nextBlock;
size_t nextCell;
- CollectorBlock** blocks;
+ AlignedCollectorBlock* blocks;
void* nextNumber;
@@ -64,6 +80,11 @@ namespace JSC {
bool didShrink;
OperationInProgress operationInProgress;
+
+ CollectorBlock* collectorBlock(size_t index) const
+ {
+ return static_cast<CollectorBlock*>(blocks[index].base());
+ }
};
class Heap : public Noncopyable {
@@ -77,6 +98,7 @@ namespace JSC {
bool isBusy(); // true if an allocation or collection is in progress
void collectAllGarbage();
+ void setActivityCallback(PassOwnPtr<GCActivityCallback>);
static const size_t minExtraCost = 256;
static const size_t maxExtraCost = 1024 * 1024;
@@ -89,9 +111,12 @@ namespace JSC {
size_t free;
};
Statistics statistics() const;
+ size_t size() const;
void protect(JSValue);
- void unprotect(JSValue);
+ // Returns true if the value is no longer protected by any protect pointers
+ // (though it may still be alive due to heap/stack references).
+ bool unprotect(JSValue);
static Heap* heap(JSValue); // 0 for immediate values
static Heap* heap(JSCell*);
@@ -105,8 +130,11 @@ namespace JSC {
void registerThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
static bool isCellMarked(const JSCell*);
+ static bool checkMarkCell(const JSCell*);
static void markCell(JSCell*);
+ WeakGCHandle* addWeakGCHandle(JSCell*);
+
void markConservatively(MarkStack&, void* start, void* end);
HashSet<MarkedArgumentBuffer*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<MarkedArgumentBuffer*>; return *m_markListSet; }
@@ -129,7 +157,6 @@ namespace JSC {
NEVER_INLINE CollectorBlock* allocateBlock();
NEVER_INLINE void freeBlock(size_t);
- NEVER_INLINE void freeBlockPtr(CollectorBlock*);
void freeBlocks();
void resizeBlocks();
void growBlocks(size_t neededBlocks);
@@ -149,14 +176,20 @@ namespace JSC {
void markOtherThreadConservatively(MarkStack&, Thread*);
void markStackObjectsConservatively(MarkStack&);
+ void updateWeakGCHandles();
+ WeakGCHandlePool* weakGCHandlePool(size_t index);
+
typedef HashCountedSet<JSCell*> ProtectCountSet;
CollectorHeap m_heap;
ProtectCountSet m_protectedValues;
+ WTF::Vector<AlignedMemory<WeakGCHandlePool::poolSize> > m_weakGCHandlePools;
HashSet<MarkedArgumentBuffer*>* m_markListSet;
+ OwnPtr<GCActivityCallback> m_activityCallback;
+
#if ENABLE(JSC_MULTIPLE_THREADS)
void makeUsableFromMultipleThreads();
@@ -168,30 +201,18 @@ namespace JSC {
pthread_key_t m_currentThreadRegistrar;
#endif
+ // Allocates collector blocks with correct alignment
+ CollectorBlockAllocator m_blockallocator;
+ WeakGCHandlePool::Allocator m_weakGCHandlePoolAllocator;
+
JSGlobalData* m_globalData;
};
// tunable parameters
- template<size_t bytesPerWord> struct CellSize;
-
- // cell size needs to be a power of two for certain optimizations in collector.cpp
-#if USE(JSVALUE32)
- template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 32; };
-#else
- template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 64; };
-#endif
- template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 64; };
-
-#if OS(WINCE) || OS(SYMBIAN)
- const size_t BLOCK_SIZE = 64 * 1024; // 64k
-#else
- const size_t BLOCK_SIZE = 64 * 4096; // 256k
-#endif
-
// derived constants
const size_t BLOCK_OFFSET_MASK = BLOCK_SIZE - 1;
const size_t BLOCK_MASK = ~BLOCK_OFFSET_MASK;
- const size_t MINIMUM_CELL_SIZE = CellSize<sizeof(void*)>::m_value;
+ const size_t MINIMUM_CELL_SIZE = 64;
const size_t CELL_ARRAY_LENGTH = (MINIMUM_CELL_SIZE / sizeof(double)) + (MINIMUM_CELL_SIZE % sizeof(double) != 0 ? sizeof(double) : 0);
const size_t CELL_SIZE = CELL_ARRAY_LENGTH * sizeof(double);
const size_t SMALL_CELL_SIZE = CELL_SIZE / 2;
@@ -203,11 +224,26 @@ namespace JSC {
const size_t BITMAP_WORDS = (BITMAP_SIZE + 3) / sizeof(uint32_t);
struct CollectorBitmap {
- uint32_t bits[BITMAP_WORDS];
+ FixedArray<uint32_t, BITMAP_WORDS> bits;
bool get(size_t n) const { return !!(bits[n >> 5] & (1 << (n & 0x1F))); }
void set(size_t n) { bits[n >> 5] |= (1 << (n & 0x1F)); }
+ bool getset(size_t n)
+ {
+ unsigned i = (1 << (n & 0x1F));
+ uint32_t& b = bits[n >> 5];
+ bool r = !!(b & i);
+ b |= i;
+ return r;
+ }
void clear(size_t n) { bits[n >> 5] &= ~(1 << (n & 0x1F)); }
- void clearAll() { memset(bits, 0, sizeof(bits)); }
+ void clearAll() { memset(bits.data(), 0, sizeof(bits)); }
+ ALWAYS_INLINE void advanceToNextPossibleFreeCell(size_t& startCell)
+ {
+ if (!~bits[startCell >> 5])
+ startCell = (startCell & (~0x1F)) + 32;
+ else
+ ++startCell;
+ }
size_t count(size_t startCell = 0)
{
size_t result = 0;
@@ -229,12 +265,12 @@ namespace JSC {
};
struct CollectorCell {
- double memory[CELL_ARRAY_LENGTH];
+ FixedArray<double, CELL_ARRAY_LENGTH> memory;
};
class CollectorBlock {
public:
- CollectorCell cells[CELLS_PER_BLOCK];
+ FixedArray<CollectorCell, CELLS_PER_BLOCK> cells;
CollectorBitmap marked;
Heap* heap;
};
@@ -261,6 +297,11 @@ namespace JSC {
return cellBlock(cell)->marked.get(cellOffset(cell));
}
+ inline bool Heap::checkMarkCell(const JSCell* cell)
+ {
+ return cellBlock(cell)->marked.getset(cellOffset(cell));
+ }
+
inline void Heap::markCell(JSCell* cell)
{
cellBlock(cell)->marked.set(cellOffset(cell));
@@ -284,6 +325,11 @@ namespace JSC {
return result;
}
+
+ inline WeakGCHandlePool* Heap::weakGCHandlePool(size_t index)
+ {
+ return static_cast<WeakGCHandlePool*>(m_weakGCHandlePools[index].base());
+ }
} // namespace JSC
#endif /* Collector_h */