Reviewed by Darin and Geoff.
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Apr 2007 03:28:45 +0000 (03:28 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Apr 2007 03:28:45 +0000 (03:28 +0000)
        - remove the concept of oversize objects, now that there aren't any (for now
        only enforced with an assert).
        http://bugs.webkit.org/show_bug.cgi?id=13382

        This change is a .66% speedup on JS iBench for 32-bit platforms, probably much more
        for 64-bit since it finally gives a reasonable cell size, but I did not test that.

        * kjs/collector.cpp:
        (KJS::): Use different cell size for 32-bit and 64-bit, now that there is no
        oversize allocation.
        (KJS::Collector::allocate): Remove oversize allocator.
        (KJS::Collector::markStackObjectsConservatively): Don't check oversize objects.
        (KJS::Collector::markMainThreadOnlyObjects): Ditto.
        (KJS::Collector::collect): Ditto.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@21015 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/kjs/collector.cpp

index fdc57da..908b124 100644 (file)
@@ -1,3 +1,22 @@
+2007-04-22  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Darin and Geoff.
+        
+        - remove the concept of oversize objects, now that there aren't any (for now
+        only enforced with an assert).
+        http://bugs.webkit.org/show_bug.cgi?id=13382
+
+        This change is a .66% speedup on JS iBench for 32-bit platforms, probably much more
+        for 64-bit since it finally gives a reasonable cell size, but I did not test that.
+        
+        * kjs/collector.cpp:
+        (KJS::): Use different cell size for 32-bit and 64-bit, now that there is no
+        oversize allocation.
+        (KJS::Collector::allocate): Remove oversize allocator.
+        (KJS::Collector::markStackObjectsConservatively): Don't check oversize objects.
+        (KJS::Collector::markMainThreadOnlyObjects): Ditto.
+        (KJS::Collector::collect): Ditto.
+
 2007-04-21  Mitz Pettel  <mitz@webkit.org>
 
         Reviewed by Adam.
index 0b40208..a7f31fd 100644 (file)
@@ -25,6 +25,7 @@
 #include <wtf/FastMalloc.h>
 #include <wtf/FastMallocInternal.h>
 #include <wtf/HashCountedSet.h>
+#include <wtf/UnusedParam.h>
 #include "internal.h"
 #include "list.h"
 #include "value.h"
@@ -58,8 +59,14 @@ using std::max;
 
 namespace KJS {
 
+
+
 // tunable parameters
-const size_t MINIMUM_CELL_SIZE = 48;
+
+template<size_t bytesPerWord> struct CellSize;
+template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 48; }; // 32-bit
+template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 80; }; // 64-bit
+
 const size_t BLOCK_SIZE = (8 * 4096);
 const size_t SPARE_EMPTY_BLOCKS = 2;
 const size_t MIN_ARRAY_SIZE = 14;
@@ -68,10 +75,10 @@ const size_t LOW_WATER_FACTOR = 4;
 const size_t ALLOCATIONS_PER_COLLECTION = 1000;
 
 // derived constants
-const size_t CELL_ARRAY_LENGTH = (MINIMUM_CELL_SIZE / sizeof(double)) + (MINIMUM_CELL_SIZE % sizeof(double) != 0 ? sizeof(double) : 0);
+const size_t MINIMUM_CELL_SIZE = CellSize<sizeof(void*)>::m_value;
+const size_t CELL_ARRAY_LENGTH = (MINIMUM_CELL_SIZE / sizeof(double)) + (MINIMUM_CELL_SIZE % sizeof(double) != 0 ? 1 : 0);
 const size_t CELL_SIZE = CELL_ARRAY_LENGTH * sizeof(double);
-const size_t CELLS_PER_BLOCK = ((BLOCK_SIZE * 8 - sizeof(uint32_t) * 8 - sizeof(void *) * 8) / (CELL_SIZE * 8));
-
+const size_t CELLS_PER_BLOCK = ((BLOCK_SIZE * 8 - sizeof(uint32_t) * 8 - sizeof(void*) * 8) / (CELL_SIZE * 8));
 
 
 struct CollectorCell {
@@ -97,15 +104,11 @@ struct CollectorHeap {
   size_t usedBlocks;
   size_t firstBlockWithPossibleSpace;
   
-  CollectorCell **oversizeCells;
-  size_t numOversizeCells;
-  size_t usedOversizeCells;
-
   size_t numLiveObjects;
   size_t numLiveObjectsAtLastCollect;
 };
 
-static CollectorHeap heap = {NULL, 0, 0, 0, NULL, 0, 0, 0, 0};
+static CollectorHeap heap = {NULL, 0, 0, 0, 0, 0};
 
 size_t Collector::mainThreadOnlyObjectCount = 0;
 bool Collector::memoryFull = false;
@@ -136,6 +139,8 @@ void* Collector::allocate(size_t s)
 {
   ASSERT(JSLock::lockCount() > 0);
   ASSERT(JSLock::currentThreadIsHoldingLock());
+  ASSERT(s <= CELL_SIZE);
+  UNUSED_PARAM(s); // s is now only used for the above assert
 
   // collect if needed
   size_t numLiveObjects = heap.numLiveObjects;
@@ -151,25 +156,6 @@ void* Collector::allocate(size_t s)
   GCLock lock;
 #endif
   
-  if (s > CELL_SIZE) {
-    // oversize allocator
-    size_t usedOversizeCells = heap.usedOversizeCells;
-    size_t numOversizeCells = heap.numOversizeCells;
-
-    if (usedOversizeCells == numOversizeCells) {
-      numOversizeCells = max(MIN_ARRAY_SIZE, numOversizeCells * GROWTH_FACTOR);
-      heap.numOversizeCells = numOversizeCells;
-      heap.oversizeCells = static_cast<CollectorCell **>(fastRealloc(heap.oversizeCells, numOversizeCells * sizeof(CollectorCell *)));
-    }
-    
-    void *newCell = fastMalloc(s);
-    heap.oversizeCells[usedOversizeCells] = static_cast<CollectorCell *>(newCell);
-    heap.usedOversizeCells = usedOversizeCells + 1;
-    heap.numLiveObjects = numLiveObjects + 1;
-
-    return newCell;
-  }
-  
   // slab allocator
   
   size_t usedBlocks = heap.usedBlocks;
@@ -386,8 +372,6 @@ void Collector::markStackObjectsConservatively(void *start, void *end)
   
   size_t usedBlocks = heap.usedBlocks;
   CollectorBlock **blocks = heap.blocks;
-  size_t usedOversizeCells = heap.usedOversizeCells;
-  CollectorCell **oversizeCells = heap.oversizeCells;
 
   const size_t lastCellOffset = sizeof(CollectorCell) * (CELLS_PER_BLOCK - 1);
 
@@ -396,19 +380,14 @@ void Collector::markStackObjectsConservatively(void *start, void *end)
     if (IS_CELL_ALIGNED(x) && x) {
       for (size_t block = 0; block < usedBlocks; block++) {
         size_t offset = x - reinterpret_cast<char *>(blocks[block]);
-        if (offset <= lastCellOffset && offset % sizeof(CollectorCell) == 0)
-          goto gotGoodPointer;
-      }
-      for (size_t i = 0; i != usedOversizeCells; i++)
-        if (x == reinterpret_cast<char *>(oversizeCells[i]))
-          goto gotGoodPointer;
-      continue;
-
-gotGoodPointer:
-      if (((CollectorCell *)x)->u.freeCell.zeroIfFree != 0) {
-        JSCell *imp = reinterpret_cast<JSCell *>(x);
-        if (!imp->marked())
-          imp->mark();
+        if (offset <= lastCellOffset && offset % sizeof(CollectorCell) == 0) {
+          if (((CollectorCell *)x)->u.freeCell.zeroIfFree != 0) {
+            JSCell *imp = reinterpret_cast<JSCell *>(x);
+            if (!imp->marked())
+              imp->mark();
+          }
+          break;
+        }
       }
     }
   }
@@ -701,18 +680,6 @@ void Collector::markMainThreadOnlyObjects()
             }
         }
     }
-
-    for (size_t cell = 0; cell < heap.usedOversizeCells; cell++) {
-        ASSERT(count < mainThreadOnlyObjectCount);
-
-        JSCell* imp = reinterpret_cast<JSCell*>(heap.oversizeCells[cell]);
-        if (imp->m_collectOnMainThreadOnly) {
-            if (!imp->marked())
-                imp->mark();
-            if (++count == mainThreadOnlyObjectCount)
-                return;
-        }
-    }
 }
 
 bool Collector::collect()
@@ -850,37 +817,6 @@ bool Collector::collect()
   if (heap.numLiveObjects != numLiveObjects)
     heap.firstBlockWithPossibleSpace = 0;
   
-  size_t cell = 0;
-  while (cell < heap.usedOversizeCells) {
-    JSCell *imp = (JSCell *)heap.oversizeCells[cell];
-    
-    if (imp->m_marked) {
-      imp->m_marked = false;
-      cell++;
-    } else {
-      ASSERT(currentThreadIsMainThread || !imp->m_collectOnMainThreadOnly);
-      if (imp->m_collectOnMainThreadOnly)
-        --mainThreadOnlyObjectCount;
-      imp->~JSCell();
-#if DEBUG_COLLECTOR
-      heap.oversizeCells[cell]->u.freeCell.zeroIfFree = 0;
-#else
-      fastFree(imp);
-#endif
-
-      // swap with the last oversize cell so we compact as we go
-      heap.oversizeCells[cell] = heap.oversizeCells[heap.usedOversizeCells - 1];
-
-      heap.usedOversizeCells--;
-      numLiveObjects--;
-
-      if (heap.numOversizeCells > MIN_ARRAY_SIZE && heap.usedOversizeCells < heap.numOversizeCells / LOW_WATER_FACTOR) {
-        heap.numOversizeCells = heap.numOversizeCells / GROWTH_FACTOR; 
-        heap.oversizeCells = (CollectorCell **)fastRealloc(heap.oversizeCells, heap.numOversizeCells * sizeof(CollectorCell *));
-      }
-    }
-  }
-  
   bool deleted = heap.numLiveObjects != numLiveObjects;
 
   heap.numLiveObjects = numLiveObjects;