]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - heap/MarkedAllocator.cpp
JavaScriptCore-1218.35.tar.gz
[apple/javascriptcore.git] / heap / MarkedAllocator.cpp
index 2135e99566c5b2e1876f2249527378916d3291e9..cbdbfd5321a22c4fd4f4d4cdb03f1409aaeacb09 100644 (file)
@@ -3,7 +3,8 @@
 
 #include "GCActivityCallback.h"
 #include "Heap.h"
-#include "JSGlobalData.h"
+#include "IncrementalSweeper.h"
+#include "VM.h"
 #include <wtf/CurrentTime.h>
 
 namespace JSC {
@@ -11,7 +12,7 @@ namespace JSC {
 bool MarkedAllocator::isPagedOut(double deadline)
 {
     unsigned itersSinceLastTimeCheck = 0;
-    HeapBlock* block = m_blockList.head();
+    MarkedBlock* block = m_blockList.head();
     while (block) {
         block = block->next();
         ++itersSinceLastTimeCheck;
@@ -26,18 +27,30 @@ bool MarkedAllocator::isPagedOut(double deadline)
     return false;
 }
 
-inline void* MarkedAllocator::tryAllocateHelper()
+inline void* MarkedAllocator::tryAllocateHelper(size_t bytes)
 {
     if (!m_freeList.head) {
-        for (MarkedBlock*& block = m_currentBlock; block; block = static_cast<MarkedBlock*>(block->next())) {
-            m_freeList = block->sweep(MarkedBlock::SweepToFreeList);
-            if (m_freeList.head)
-                break;
-            block->didConsumeFreeList();
+        for (MarkedBlock*& block = m_blocksToSweep; block; block = block->next()) {
+            MarkedBlock::FreeList freeList = block->sweep(MarkedBlock::SweepToFreeList);
+            if (!freeList.head) {
+                block->didConsumeFreeList();
+                continue;
+            }
+
+            if (bytes > block->cellSize()) {
+                block->canonicalizeCellLivenessData(freeList);
+                continue;
+            }
+
+            m_currentBlock = block;
+            m_freeList = freeList;
+            break;
         }
         
-        if (!m_freeList.head)
+        if (!m_freeList.head) {
+            m_currentBlock = 0;
             return 0;
+        }
     }
     
     MarkedBlock::FreeCell* head = m_freeList.head;
@@ -46,18 +59,18 @@ inline void* MarkedAllocator::tryAllocateHelper()
     return head;
 }
     
-inline void* MarkedAllocator::tryAllocate()
+inline void* MarkedAllocator::tryAllocate(size_t bytes)
 {
     ASSERT(!m_heap->isBusy());
     m_heap->m_operationInProgress = Allocation;
-    void* result = tryAllocateHelper();
+    void* result = tryAllocateHelper(bytes);
     m_heap->m_operationInProgress = NoOperation;
     return result;
 }
     
-void* MarkedAllocator::allocateSlowCase()
+void* MarkedAllocator::allocateSlowCase(size_t bytes)
 {
-    ASSERT(m_heap->globalData()->apiLock().currentThreadIsHoldingLock());
+    ASSERT(m_heap->vm()->apiLock().currentThreadIsHoldingLock());
 #if COLLECT_ON_EVERY_ALLOCATION
     m_heap->collectAllGarbage();
     ASSERT(m_heap->m_operationInProgress == NoOperation);
@@ -66,7 +79,7 @@ void* MarkedAllocator::allocateSlowCase()
     ASSERT(!m_freeList.head);
     m_heap->didAllocate(m_freeList.bytes);
     
-    void* result = tryAllocate();
+    void* result = tryAllocate(bytes);
     
     if (LIKELY(result != 0))
         return result;
@@ -74,33 +87,33 @@ void* MarkedAllocator::allocateSlowCase()
     if (m_heap->shouldCollect()) {
         m_heap->collect(Heap::DoNotSweep);
 
-        result = tryAllocate();
+        result = tryAllocate(bytes);
         if (result)
             return result;
     }
 
     ASSERT(!m_heap->shouldCollect());
     
-    MarkedBlock* block = allocateBlock();
+    MarkedBlock* block = allocateBlock(bytes);
     ASSERT(block);
     addBlock(block);
         
-    result = tryAllocate();
+    result = tryAllocate(bytes);
     ASSERT(result);
     return result;
 }
-    
-MarkedBlock* MarkedAllocator::allocateBlock()
+
+MarkedBlock* MarkedAllocator::allocateBlock(size_t bytes)
 {
-    MarkedBlock* block = static_cast<MarkedBlock*>(m_heap->blockAllocator().allocate());
-    if (block)
-        block = MarkedBlock::recycle(block, m_heap, m_cellSize, m_cellsNeedDestruction);
-    else
-        block = MarkedBlock::create(m_heap, m_cellSize, m_cellsNeedDestruction);
-    
-    m_markedSpace->didAddBlock(block);
-    
-    return block;
+    size_t minBlockSize = MarkedBlock::blockSize;
+    size_t minAllocationSize = WTF::roundUpToMultipleOf(WTF::pageSize(), sizeof(MarkedBlock) + bytes);
+    size_t blockSize = std::max(minBlockSize, minAllocationSize);
+
+    size_t cellSize = m_cellSize ? m_cellSize : WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(bytes);
+
+    if (blockSize == MarkedBlock::blockSize)
+        return MarkedBlock::create(m_heap->blockAllocator().allocate<MarkedBlock>(), this, cellSize, m_destructorType);
+    return MarkedBlock::create(m_heap->blockAllocator().allocateCustomSize(blockSize, MarkedBlock::blockSize), this, cellSize, m_destructorType);
 }
 
 void MarkedAllocator::addBlock(MarkedBlock* block)
@@ -109,14 +122,19 @@ void MarkedAllocator::addBlock(MarkedBlock* block)
     ASSERT(!m_freeList.head);
     
     m_blockList.append(block);
-    m_currentBlock = block;
+    m_blocksToSweep = m_currentBlock = block;
     m_freeList = block->sweep(MarkedBlock::SweepToFreeList);
+    m_markedSpace->didAddBlock(block);
 }
 
 void MarkedAllocator::removeBlock(MarkedBlock* block)
 {
-    if (m_currentBlock == block)
-        m_currentBlock = 0;
+    if (m_currentBlock == block) {
+        m_currentBlock = m_currentBlock->next();
+        m_freeList = MarkedBlock::FreeList();
+    }
+    if (m_blocksToSweep == block)
+        m_blocksToSweep = m_blocksToSweep->next();
     m_blockList.remove(block);
 }