[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677
mjs
mjs at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 07:04:49 UTC 2009
The following commit has been merged in the debian/unstable branch:
commit 6d32b07d23f9e0ec8be6fd5694a01acbae1b3f10
Author: mjs <mjs at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Wed Nov 20 09:34:02 2002 +0000
JavaScriptCore:
Rewrote garbage collector to make blocks of actual memory instead
of blocks of pointers. 7% improvement on JavaScript
iBench. There's still lots of room to tune the new GC, this is
just my first cut.
* kjs/collector.cpp:
(Collector::allocate):
(Collector::collect):
(Collector::size):
(Collector::outOfMemory):
(Collector::finalCheck):
(Collector::numGCNotAllowedObjects):
(Collector::numReferencedObjects):
(Collector::liveObjectClasses):
* kjs/collector.h:
* kjs/function.cpp:
(ActivationImp::ActivationImp):
* kjs/function.h:
WebCore:
* force-js-clean-timestamp: Work around PB lameness yet again.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@2779 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index e8b6bb1..57f3c26 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,24 @@
+2002-11-20 Maciej Stachowiak <mjs at apple.com>
+
+ Rewrote garbage collector to make blocks of actual memory instead
+ of blocks of pointers. 7% improvement on JavaScript
+ iBench. There's still lots of room to tune the new GC, this is
+ just my first cut.
+
+ * kjs/collector.cpp:
+ (Collector::allocate):
+ (Collector::collect):
+ (Collector::size):
+ (Collector::outOfMemory):
+ (Collector::finalCheck):
+ (Collector::numGCNotAllowedObjects):
+ (Collector::numReferencedObjects):
+ (Collector::liveObjectClasses):
+ * kjs/collector.h:
+ * kjs/function.cpp:
+ (ActivationImp::ActivationImp):
+ * kjs/function.h:
+
2002-11-20 Darin Adler <darin at apple.com>
- on the road to killing ActivationImp
diff --git a/JavaScriptCore/ChangeLog-2002-12-03 b/JavaScriptCore/ChangeLog-2002-12-03
index e8b6bb1..57f3c26 100644
--- a/JavaScriptCore/ChangeLog-2002-12-03
+++ b/JavaScriptCore/ChangeLog-2002-12-03
@@ -1,3 +1,24 @@
+2002-11-20 Maciej Stachowiak <mjs at apple.com>
+
+ Rewrote garbage collector to make blocks of actual memory instead
+ of blocks of pointers. 7% improvement on JavaScript
+ iBench. There's still lots of room to tune the new GC, this is
+ just my first cut.
+
+ * kjs/collector.cpp:
+ (Collector::allocate):
+ (Collector::collect):
+ (Collector::size):
+ (Collector::outOfMemory):
+ (Collector::finalCheck):
+ (Collector::numGCNotAllowedObjects):
+ (Collector::numReferencedObjects):
+ (Collector::liveObjectClasses):
+ * kjs/collector.h:
+ * kjs/function.cpp:
+ (ActivationImp::ActivationImp):
+ * kjs/function.h:
+
2002-11-20 Darin Adler <darin at apple.com>
- on the road to killing ActivationImp
diff --git a/JavaScriptCore/ChangeLog-2003-10-25 b/JavaScriptCore/ChangeLog-2003-10-25
index e8b6bb1..57f3c26 100644
--- a/JavaScriptCore/ChangeLog-2003-10-25
+++ b/JavaScriptCore/ChangeLog-2003-10-25
@@ -1,3 +1,24 @@
+2002-11-20 Maciej Stachowiak <mjs at apple.com>
+
+ Rewrote garbage collector to make blocks of actual memory instead
+ of blocks of pointers. 7% improvement on JavaScript
+ iBench. There's still lots of room to tune the new GC, this is
+ just my first cut.
+
+ * kjs/collector.cpp:
+ (Collector::allocate):
+ (Collector::collect):
+ (Collector::size):
+ (Collector::outOfMemory):
+ (Collector::finalCheck):
+ (Collector::numGCNotAllowedObjects):
+ (Collector::numReferencedObjects):
+ (Collector::liveObjectClasses):
+ * kjs/collector.h:
+ * kjs/function.cpp:
+ (ActivationImp::ActivationImp):
+ * kjs/function.h:
+
2002-11-20 Darin Adler <darin at apple.com>
- on the road to killing ActivationImp
diff --git a/JavaScriptCore/kjs/collector.cpp b/JavaScriptCore/kjs/collector.cpp
index cab1076..971a339 100644
--- a/JavaScriptCore/kjs/collector.cpp
+++ b/JavaScriptCore/kjs/collector.cpp
@@ -26,167 +26,145 @@
#include <cxxabi.h>
#endif
-#include "collector.h"
-#include "internal.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#ifdef KJS_DEBUG_MEM
-#include <typeinfo>
-#endif
-
-namespace KJS {
-
- class CollectorBlock {
- public:
- CollectorBlock(int s);
- ~CollectorBlock();
- int size;
- int filled;
- void** mem;
- CollectorBlock *prev, *next;
- };
-
-}; // namespace
+#include <collector.h>
+#include <value.h>
+#include <internal.h>
using namespace KJS;
-
-CollectorBlock::CollectorBlock(int s)
- : size(s),
- filled(0),
- prev(0L),
- next(0L)
-{
- mem = new void*[size];
- memset(mem, 0, size * sizeof(void*));
-}
-
-CollectorBlock::~CollectorBlock()
-{
- delete [] mem;
- mem = 0L;
-}
-
-CollectorBlock* Collector::root = 0L;
-CollectorBlock* Collector::currentBlock = 0L;
-unsigned long Collector::filled = 0;
-unsigned long Collector::softLimit = KJS_MEM_INCREMENT;
-
-unsigned long Collector::timesFilled = 0;
-unsigned long Collector::increaseLimitAt = 1;
-
-bool Collector::memLimitReached = false;
-
-#ifdef KJS_DEBUG_MEM
-bool Collector::collecting = false;
-#endif
-
-#if APPLE_CHANGES
-static int numAllocationsSinceLastCollect = 0;
-#endif
+// tunable parameters
+static const int CELL_SIZE = 64;
+static const int BLOCK_SIZE = (4 * 4096);
+static const int SPARE_EMPTY_BLOCKS = 1;
+static const int MIN_ARRAY_SIZE = 14;
+static const int GROWTH_FACTOR = 2;
+static const int LOW_WATER_FACTOR = 4;
+
+// derived constants
+static const int WORD_SIZE = sizeof(uint32_t);
+static const int BITS_PER_WORD = WORD_SIZE * 8;
+static const int CELLS_PER_BLOCK = ((BLOCK_SIZE * 8 - 32) / (CELL_SIZE * 8 + 1));
+static const int BITMAP_SIZE = (CELLS_PER_BLOCK / BITS_PER_WORD) + (CELLS_PER_BLOCK % BITS_PER_WORD != 0 ? 1 : 0);
+
+
+struct CollectorCell {
+ char memory[CELL_SIZE];
+};
+
+static const int ALLOCATIONS_PER_COLLECTION = 1000;
+
+struct CollectorBlock {
+ CollectorBlock() : usedCells(0) { memset(bitmap, 0, BITMAP_SIZE * WORD_SIZE); }
+
+ uint32_t bitmap[BITMAP_SIZE];
+ int32_t usedCells;
+ CollectorCell cells[CELLS_PER_BLOCK];
+};
+
+struct CollectorHeap {
+ CollectorBlock **blocks;
+ int numBlocks;
+ int usedBlocks;
+
+ CollectorCell **oversizeCells;
+ int numOversizeCells;
+ int usedOversizeCells;
+
+ int numLiveObjects;
+ int numAllocationsSinceLastCollect;
+};
+
+static CollectorHeap heap = {NULL, 0, 0, NULL, 0, 0, 0, 0};
void* Collector::allocate(size_t s)
{
if (s == 0)
return 0L;
-
-#if APPLE_CHANGES
- if (++numAllocationsSinceLastCollect >= KJS_MEM_INCREMENT)
- collect();
-#else
- // Try and deal with memory requirements in a scalable way. Simple scripts
- // should only require small amounts of memory, but for complex scripts we don't
- // want to end up running the garbage collector hundreds of times a second.
- if (filled >= softLimit) {
- timesFilled++;
+
+ // collect if needed
+ if (++heap.numAllocationsSinceLastCollect >= ALLOCATIONS_PER_COLLECTION)
collect();
+
+ heap.numLiveObjects++;
- if (filled >= softLimit && softLimit < KJS_MEM_LIMIT) {
- // Even after collection we are still using more than the limit, so increase
- // the limit
- softLimit *= 2;
- }
- else if (timesFilled == increaseLimitAt && increaseLimitAt < 128) {
- // The allowed memory limit keeps getting reached (lots of objects created
- // and deleted). Increase it a bit so GC gets run less often.
- timesFilled = 0;
- softLimit *= 2;
- increaseLimitAt *= 2;
- }
+ if (heap.numLiveObjects >= KJS_MEM_LIMIT) {
+ // fprintf(stderr,"Out of memory");
}
-#endif
- void *m = malloc(s);
-#ifdef KJS_DEBUG_MEM
- //fprintf( stderr, "allocate: size=%d valueimp=%p\n",s,m);
-#endif
- // VI_CREATED and VI_GCALLOWED being unset ensure that value
- // is protected from GC before any constructors are run
- static_cast<ValueImp*>(m)->_flags = 0;
-
- if (!root) {
- root = new CollectorBlock(BlockSize);
- currentBlock = root;
+ if (s > (unsigned)CELL_SIZE) {
+ // oversize allocator
+ if (heap.usedOversizeCells == heap.numOversizeCells) {
+ heap.numOversizeCells = MAX(MIN_ARRAY_SIZE, heap.numOversizeCells * GROWTH_FACTOR);
+ heap.oversizeCells = (CollectorCell **)realloc(heap.oversizeCells, heap.numOversizeCells * sizeof(CollectorCell *));
+ }
+
+ void *newCell = malloc(s);
+ heap.oversizeCells[heap.usedOversizeCells] = (CollectorCell *)newCell;
+ heap.usedOversizeCells++;
+
+ return (void *)newCell;
}
-
- CollectorBlock *block = currentBlock;
- if (!block)
- block = root;
-
- // search for a block with space left
- while (block->next && block->filled == block->size)
- block = block->next;
-
- if (block->filled >= block->size) {
-#ifdef KJS_DEBUG_MEM
- //fprintf( stderr, "allocating new block of size %d\n", block->size);
-#endif
- CollectorBlock *tmp = new CollectorBlock(BlockSize);
- block->next = tmp;
- tmp->prev = block;
- block = tmp;
+
+ // slab allocator
+
+ CollectorBlock *targetBlock = NULL;
+
+ // try to find free space in an existing block
+ for (int i = 0; i < heap.usedBlocks; i++) {
+ if (heap.blocks[i]->usedCells < CELLS_PER_BLOCK) {
+ targetBlock = heap.blocks[i];
+ break;
+ }
}
- currentBlock = block;
- // look for a free spot in the block
- void **r = block->mem;
- while (*r)
- r++;
- *r = m;
- filled++;
- block->filled++;
-
- if (softLimit >= KJS_MEM_LIMIT) {
- memLimitReached = true;
- fprintf(stderr,"Out of memory");
+
+ if (targetBlock == NULL) {
+ // didn't find one, need to allocate a new block
+
+ if (heap.usedBlocks == heap.numBlocks) {
+ heap.numBlocks = MAX(MIN_ARRAY_SIZE, heap.numBlocks * GROWTH_FACTOR);
+ heap.blocks = (CollectorBlock **)realloc(heap.blocks, heap.numBlocks * sizeof(CollectorBlock *));
+ }
+
+ targetBlock = new CollectorBlock();
+ heap.blocks[heap.usedBlocks] = targetBlock;
+ heap.usedBlocks++;
}
+
+ // find a free spot in the block
+ for (int wordInBitmap = 0; wordInBitmap < BITMAP_SIZE; wordInBitmap++) {
+ uint32_t word = targetBlock->bitmap[wordInBitmap];
+ for (int bitInWord = 0; bitInWord < BITS_PER_WORD; bitInWord++) {
+ if ((word & (1 << bitInWord)) == 0) {
+ int cellPos = BITS_PER_WORD * wordInBitmap + bitInWord;
+ if (cellPos < CELLS_PER_BLOCK) {
+ targetBlock->bitmap[wordInBitmap] |= (1 << bitInWord);
+ targetBlock->usedCells++;
+ return (void *)(targetBlock->cells + cellPos);
+ }
+ }
+ }
+ }
+ // unreachable, if the free count wasn't 0 there has to be a free
+ // cell in the block
+ assert(false);
- return m;
+ return false;
}
-/**
- * Mark-sweep garbage collection.
- */
bool Collector::collect()
{
-#ifdef KJS_DEBUG_MEM
- fprintf(stderr,"Collector::collect()\n");
-#endif
bool deleted = false;
// MARK: first unmark everything
- CollectorBlock *block = root;
- while (block) {
- ValueImp **r = (ValueImp**)block->mem;
- assert(r);
- for (int i = 0; i < block->size; i++, r++)
- if (*r) {
- (*r)->_flags &= ~ValueImp::VI_MARKED;
- }
- block = block->next;
+ for (int block = 0; block < heap.usedBlocks; block++) {
+ for (int cell = 0; cell < CELLS_PER_BLOCK; cell++) {
+ ((ValueImp *)(heap.blocks[block]->cells + cell))->_flags &= ~ValueImp::VI_MARKED;
+ }
}
-
+ for (int cell = 0; cell < heap.usedOversizeCells; cell++) {
+ ((ValueImp *)heap.oversizeCells[cell])->_flags &= ~ValueImp::VI_MARKED;
+ }
+
// mark all referenced objects recursively
// starting out from the set of root objects
if (InterpreterImp::s_hook) {
@@ -197,105 +175,126 @@ bool Collector::collect()
scr = scr->next;
} while (scr != InterpreterImp::s_hook);
}
-
+
// mark any other objects that we wouldn't delete anyway
- block = root;
- while (block) {
- ValueImp **r = (ValueImp**)block->mem;
- assert(r);
- for (int i = 0; i < block->size; i++, r++)
- {
- ValueImp *imp = (*r);
- // Check for created=true, marked=false and (gcallowed=false or refcount>0)
- if (imp &&
- (imp->_flags & (ValueImp::VI_CREATED|ValueImp::VI_MARKED)) == ValueImp::VI_CREATED &&
- ( (imp->_flags & ValueImp::VI_GCALLOWED) == 0 || imp->refcount ) ) {
- //fprintf( stderr, "Collector marking imp=%p\n",(void*)imp);
- imp->mark();
+ for (int block = 0; block < heap.usedBlocks; block++) {
+ for (int wordInBitmap = 0; wordInBitmap < BITMAP_SIZE; wordInBitmap++) {
+ uint32_t word = heap.blocks[block]->bitmap[wordInBitmap];
+ for (int bitInWord = 0; bitInWord < BITS_PER_WORD; bitInWord++) {
+ ValueImp *imp = (ValueImp *)(heap.blocks[block]->cells + BITS_PER_WORD * wordInBitmap + bitInWord);
+
+ if ((word & (1 << bitInWord)) &&
+ (imp->_flags & (ValueImp::VI_CREATED|ValueImp::VI_MARKED)) == ValueImp::VI_CREATED &&
+ ((imp->_flags & ValueImp::VI_GCALLOWED) == 0 || imp->refcount != 0)) {
+ imp->mark();
+ }
}
}
- block = block->next;
}
-
+
+ for (int cell = 0; cell < heap.usedOversizeCells; cell++) {
+ ValueImp *imp = (ValueImp *)heap.oversizeCells[cell];
+ if ((imp->_flags & (ValueImp::VI_CREATED|ValueImp::VI_MARKED)) == ValueImp::VI_CREATED &&
+ ((imp->_flags & ValueImp::VI_GCALLOWED) == 0 || imp->refcount != 0)) {
+ imp->mark();
+ }
+ }
+
// SWEEP: delete everything with a zero refcount (garbage)
- // 1st step: destruct all objects
- block = root;
- while (block) {
- ValueImp **r = (ValueImp**)block->mem;
- int del = 0;
- for (int i = 0; i < block->size; i++, r++) {
- ValueImp *imp = (*r);
- // Can delete if refcount==0, created==true, gcAllowed==true, and marked==false
- // Make sure to update the test if you add more bits to _flags.
- if (imp &&
- !imp->refcount && imp->_flags == (ValueImp::VI_GCALLOWED | ValueImp::VI_CREATED)) {
- // emulate destructing part of 'operator delete()'
- //fprintf( stderr, "Collector::deleting ValueImp %p (%s)\n", (void*)imp, typeid(*imp).name());
- imp->~ValueImp();
- }
- if (imp && (imp->_flags & ValueImp::VI_DESTRUCTED) != 0) {
- free(imp);
- *r = 0L;
- del++;
+
+ int emptyBlocks = 0;
+
+ for (int block = 0; block < heap.usedBlocks; block++) {
+ for (int wordInBitmap = 0; wordInBitmap < BITMAP_SIZE; wordInBitmap++) {
+ uint32_t word = heap.blocks[block]->bitmap[wordInBitmap];
+ for (int bitInWord = 0; bitInWord < BITS_PER_WORD; bitInWord++) {
+ ValueImp *imp = (ValueImp *)(heap.blocks[block]->cells + BITS_PER_WORD * wordInBitmap + bitInWord);
+
+ if ((word & (1 << bitInWord)) &&
+ !imp->refcount && imp->_flags == (ValueImp::VI_GCALLOWED | ValueImp::VI_CREATED)) {
+ // emulate destructing part of 'operator delete()'
+ //fprintf( stderr, "Collector::deleting ValueImp %p (%s)\n", (void*)imp, typeid(*imp).name());
+ imp->~ValueImp();
+ heap.blocks[block]->bitmap[wordInBitmap] &= ~(1 << bitInWord);
+ heap.blocks[block]->usedCells--;
+ heap.numLiveObjects--;
+ deleted = true;
+ }
}
}
- filled -= del;
- block->filled -= del;
- if (del)
- deleted = true;
- CollectorBlock *next = block->next;
- if (block->filled == 0) {
- if (block->prev)
- block->prev->next = next;
- if (block == root)
- root = next;
- if (next)
- next->prev = block->prev;
- if (block == currentBlock) // we don't want a dangling pointer
- currentBlock = 0L;
- assert(block != root);
- delete block;
+
+ if (heap.blocks[block]->usedCells == 0) {
+ emptyBlocks++;
+ if (emptyBlocks > SPARE_EMPTY_BLOCKS) {
+ delete heap.blocks[block];
+
+ // swap with the last block so we compact as we go
+ heap.blocks[block] = heap.blocks[heap.usedBlocks - 1];
+ heap.usedBlocks--;
+ block--; // Don't move forward a step in this case
+
+ if (heap.numBlocks > MIN_ARRAY_SIZE && heap.usedBlocks < heap.numBlocks / LOW_WATER_FACTOR) {
+ heap.numBlocks = heap.numBlocks / GROWTH_FACTOR;
+ heap.blocks = (CollectorBlock **)realloc(heap.blocks, heap.numBlocks * sizeof(CollectorBlock *));
+ }
+ }
}
- block = next;
}
-#if APPLE_CHANGES
- numAllocationsSinceLastCollect = 0;
-#endif
-#if 0
- // This is useful to track down memory leaks
- static int s_count = 0;
- fprintf(stderr, "Collector done (was run %d)\n",s_count);
- if (s_count++ % 50 == 2)
- finalCheck();
-#endif
+
+ int cell = 0;
+ while (cell < heap.usedOversizeCells) {
+ ValueImp *imp = (ValueImp *)heap.oversizeCells[cell];
+
+ if (!imp->refcount &&
+ imp->_flags == (ValueImp::VI_GCALLOWED | ValueImp::VI_CREATED)) {
+
+ imp->~ValueImp();
+ free((void *)imp);
+
+ // swap with the last oversize cell so we compact as we go
+ heap.oversizeCells[cell] = heap.oversizeCells[heap.usedOversizeCells - 1];
+
+ heap.usedOversizeCells--;
+ deleted = true;
+ heap.numLiveObjects--;
+
+ if (heap.numOversizeCells > MIN_ARRAY_SIZE && heap.usedOversizeCells < heap.numOversizeCells / LOW_WATER_FACTOR) {
+ heap.numOversizeCells = heap.numOversizeCells / GROWTH_FACTOR;
+ heap.oversizeCells = (CollectorCell **)realloc(heap.oversizeCells, heap.numOversizeCells * sizeof(CollectorCell *));
+ }
+
+ } else {
+ cell++;
+ }
+ }
+
+ // possibly free some completely empty collector blocks ?
+ // compact array of collector blocks
+
+ heap.numAllocationsSinceLastCollect = 0;
+
return deleted;
}
+int Collector::size()
+{
+ return heap.numLiveObjects;
+}
+
+bool Collector::outOfMemory()
+{
+ return heap.numLiveObjects >= KJS_MEM_LIMIT;
+}
+
#ifdef KJS_DEBUG_MEM
void Collector::finalCheck()
{
- CollectorBlock *block = root;
- while (block) {
- ValueImp **r = (ValueImp**)block->mem;
- for (int i = 0; i < block->size; i++, r++) {
- if (*r ) {
- fprintf( stderr, "Collector::finalCheck() still having ValueImp %p (%s) [marked:%d gcAllowed:%d created:%d refcount:%d]\n",
- (void*)(*r), typeid( **r ).name(),
- (bool)((*r)->_flags & ValueImp::VI_MARKED),
- (bool)((*r)->_flags & ValueImp::VI_GCALLOWED),
- (bool)((*r)->_flags & ValueImp::VI_CREATED),
- (*r)->refcount);
- }
- }
- block = block->next;
- }
}
#endif
#if APPLE_CHANGES
-
int Collector::numInterpreters()
{
int count = 0;
@@ -312,38 +311,54 @@ int Collector::numInterpreters()
int Collector::numGCNotAllowedObjects()
{
int count = 0;
- CollectorBlock *block = root;
- while (block) {
- ValueImp **r = (ValueImp**)block->mem;
- assert(r);
- for (int i = 0; i < block->size; i++, r++)
- {
- ValueImp *imp = *r;
- if (imp && (imp->_flags & ValueImp::VI_GCALLOWED) == 0) {
- ++count;
+ for (int block = 0; block < heap.usedBlocks; block++) {
+ for (int wordInBitmap = 0; wordInBitmap < BITMAP_SIZE; wordInBitmap++) {
+ uint32_t word = heap.blocks[block]->bitmap[wordInBitmap];
+ for (int bitInWord = 0; bitInWord < BITS_PER_WORD; bitInWord++) {
+ ValueImp *imp = (ValueImp *)(heap.blocks[block]->cells + BITS_PER_WORD * wordInBitmap + bitInWord);
+
+ if ((word & (1 << bitInWord)) &&
+ (imp->_flags & ValueImp::VI_GCALLOWED) == 0) {
+ ++count;
+ }
}
}
- block = block->next;
}
+
+ for (int cell = 0; cell < heap.usedOversizeCells; cell++) {
+ ValueImp *imp = (ValueImp *)heap.oversizeCells[cell];
+ if ((imp->_flags & ValueImp::VI_GCALLOWED) == 0) {
+ ++count;
+ }
+ }
+
return count;
}
int Collector::numReferencedObjects()
{
int count = 0;
- CollectorBlock *block = root;
- while (block) {
- ValueImp **r = (ValueImp**)block->mem;
- assert(r);
- for (int i = 0; i < block->size; i++, r++)
- {
- ValueImp *imp = *r;
- if (imp && imp->refcount) {
- ++count;
+ for (int block = 0; block < heap.usedBlocks; block++) {
+ for (int wordInBitmap = 0; wordInBitmap < BITMAP_SIZE; wordInBitmap++) {
+ uint32_t word = heap.blocks[block]->bitmap[wordInBitmap];
+ for (int bitInWord = 0; bitInWord < BITS_PER_WORD; bitInWord++) {
+ ValueImp *imp = (ValueImp *)(heap.blocks[block]->cells + BITS_PER_WORD * wordInBitmap + bitInWord);
+
+ if ((word & (1 << bitInWord)) &&
+ imp->refcount == 0) {
+ ++count;
+ }
}
}
- block = block->next;
}
+
+ for (int cell = 0; cell < heap.usedOversizeCells; cell++) {
+ ValueImp *imp = (ValueImp *)heap.oversizeCells[cell];
+ if (imp->refcount == 0) {
+ ++count;
+ }
+ }
+
return count;
}
@@ -351,27 +366,40 @@ CFSetRef Collector::liveObjectClasses()
{
CFMutableSetRef classes = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
- CollectorBlock *block = root;
- while (block) {
- ValueImp **r = (ValueImp**)block->mem;
- assert(r);
- for (int i = 0; i < block->size; i++, r++)
- {
- ValueImp *imp = *r;
- if (imp != NULL) {
- const char *mangled_name = typeid(*imp).name();
- int status;
- char *demangled_name = __cxxabiv1::__cxa_demangle (mangled_name, NULL, NULL, &status);
-
- CFStringRef className = CFStringCreateWithCString(NULL, demangled_name, kCFStringEncodingASCII);
- free(demangled_name);
- CFSetAddValue(classes, className);
- CFRelease(className);
+ for (int block = 0; block < heap.usedBlocks; block++) {
+ for (int wordInBitmap = 0; wordInBitmap < BITMAP_SIZE; wordInBitmap++) {
+ uint32_t word = heap.blocks[block]->bitmap[wordInBitmap];
+ for (int bitInWord = 0; bitInWord < BITS_PER_WORD; bitInWord++) {
+ ValueImp *imp = (ValueImp *)(heap.blocks[block]->cells + BITS_PER_WORD * wordInBitmap + bitInWord);
+
+ if (word & (1 << bitInWord)) {
+ const char *mangled_name = typeid(*imp).name();
+ int status;
+ char *demangled_name = __cxxabiv1::__cxa_demangle (mangled_name, NULL, NULL, &status);
+
+ CFStringRef className = CFStringCreateWithCString(NULL, demangled_name, kCFStringEncodingASCII);
+ free(demangled_name);
+ CFSetAddValue(classes, className);
+ CFRelease(className);
+ }
}
}
- block = block->next;
}
+
+ for (int cell = 0; cell < heap.usedOversizeCells; cell++) {
+ ValueImp *imp = (ValueImp *)heap.oversizeCells[cell];
+
+ const char *mangled_name = typeid(*imp).name();
+ int status;
+ char *demangled_name = __cxxabiv1::__cxa_demangle (mangled_name, NULL, NULL, &status);
+
+ CFStringRef className = CFStringCreateWithCString(NULL, demangled_name, kCFStringEncodingASCII);
+ free(demangled_name);
+ CFSetAddValue(classes, className);
+ CFRelease(className);
+ }
+
return classes;
}
-#endif // APPLE_CHANGES
+#endif
diff --git a/JavaScriptCore/kjs/collector.h b/JavaScriptCore/kjs/collector.h
index 8b0abad..ad7712c 100644
--- a/JavaScriptCore/kjs/collector.h
+++ b/JavaScriptCore/kjs/collector.h
@@ -23,40 +23,15 @@
#ifndef _KJSCOLLECTOR_H_
#define _KJSCOLLECTOR_H_
-// KJS_MEM_LIMIT and KJS_MEM_INCREMENT can be tweaked to adjust how the
-// garbage collector allocates memory. KJS_MEM_LIMIT is the largest # of objects
-// the collector will allow to be present in memory. Once this limit is reached,
-// a running script will get an "out of memory" exception.
-//
-// KJS_MEM_INCREMENT specifies the amount by which the "soft limit" on memory is
-// increased when the memory gets filled up. The soft limit is the amount after
-// which the GC will run and delete unused objects.
-//
-// If you are debugging seemingly random crashes where an object has been deleted,
-// try setting KJS_MEM_INCREMENT to something small, e.g. 300, to force garbage
-// collection to happen more often, and disable the softLimit increase &
-// out-of-memory testing code in Collector::allocate()
-
-#define KJS_MEM_LIMIT 500000
-#define KJS_MEM_INCREMENT 1000
-
-#include <stdlib.h>
-
-// for DEBUG_*
-#include "value.h"
-#include "object.h"
-#include "types.h"
-#include "interpreter.h"
-
#if APPLE_CHANGES
#if !defined(__OBJC__) && !defined(_COLLECTOR)
typedef void *CFSetRef;
#endif
#endif
-namespace KJS {
+#define KJS_MEM_LIMIT 500000
- class CollectorBlock;
+namespace KJS {
/**
* @short Garbage collector.
@@ -81,36 +56,25 @@ namespace KJS {
* on each object and freeing the used memory.
*/
static bool collect();
- static int size() { return filled; }
- static bool outOfMemory() { return memLimitReached; }
+ static int size();
+ static bool outOfMemory();
#ifdef KJS_DEBUG_MEM
/**
* Check that nothing is left when the last interpreter gets deleted
*/
static void finalCheck();
- /**
- * @internal
- */
- static bool collecting;
#endif
+
#if APPLE_CHANGES
static int numInterpreters();
static int numGCNotAllowedObjects();
static int numReferencedObjects();
static CFSetRef liveObjectClasses();
#endif
- private:
- static CollectorBlock* root;
- static CollectorBlock* currentBlock;
- static unsigned long filled;
- static unsigned long softLimit;
- static unsigned long timesFilled;
- static unsigned long increaseLimitAt;
- static bool memLimitReached;
- enum { BlockSize = 100 };
};
};
-#endif
+
+#endif /* _KJSCOLLECTOR_H_ */
diff --git a/JavaScriptCore/kjs/function.cpp b/JavaScriptCore/kjs/function.cpp
index 7d84185..46a62cb 100644
--- a/JavaScriptCore/kjs/function.cpp
+++ b/JavaScriptCore/kjs/function.cpp
@@ -341,12 +341,8 @@ ActivationImp::ActivationImp(ExecState *exec, FunctionImp *f, const List &args)
{
Value protect(this);
arguments = new ArgumentsImp(exec,f, args);
- put(exec, argumentsPropertyName, Object(arguments), Internal|DontDelete);
-}
-
-ActivationImp::~ActivationImp()
-{
arguments->setGcAllowed();
+ put(exec, argumentsPropertyName, Object(arguments), Internal|DontDelete);
}
// ------------------------------ GlobalFunc -----------------------------------
diff --git a/JavaScriptCore/kjs/function.h b/JavaScriptCore/kjs/function.h
index 4895e62..4103d09 100644
--- a/JavaScriptCore/kjs/function.h
+++ b/JavaScriptCore/kjs/function.h
@@ -101,7 +101,8 @@ namespace KJS {
class ActivationImp : public ObjectImp {
public:
ActivationImp(ExecState *exec, FunctionImp *f, const List &args);
- ~ActivationImp();
+
+ Object argumentsObject() { return Object(arguments); }
virtual const ClassInfo *classInfo() const { return &info; }
static const ClassInfo info;
diff --git a/WebCore/ChangeLog-2002-12-03 b/WebCore/ChangeLog-2002-12-03
index 201fdab..4696257 100644
--- a/WebCore/ChangeLog-2002-12-03
+++ b/WebCore/ChangeLog-2002-12-03
@@ -1,3 +1,7 @@
+2002-11-20 Maciej Stachowiak <mjs at apple.com>
+
+ * force-js-clean-timestamp: Work around PB lameness yet again.
+
2002-11-19 Darin Adler <darin at apple.com>
* force-js-clean-timestamp: Make other people's builds work.
diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index 201fdab..4696257 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,7 @@
+2002-11-20 Maciej Stachowiak <mjs at apple.com>
+
+ * force-js-clean-timestamp: Work around PB lameness yet again.
+
2002-11-19 Darin Adler <darin at apple.com>
* force-js-clean-timestamp: Make other people's builds work.
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 201fdab..4696257 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,7 @@
+2002-11-20 Maciej Stachowiak <mjs at apple.com>
+
+ * force-js-clean-timestamp: Work around PB lameness yet again.
+
2002-11-19 Darin Adler <darin at apple.com>
* force-js-clean-timestamp: Make other people's builds work.
diff --git a/WebCore/force-js-clean-timestamp b/WebCore/force-js-clean-timestamp
index 3dd6dcd..87f3106 100644
--- a/WebCore/force-js-clean-timestamp
+++ b/WebCore/force-js-clean-timestamp
@@ -1 +1,2 @@
-UString constructor change 11/19 - Darin
+GC change 11/20 - Maciej
+
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list