Exemple #1
0
void Heap::collectAllGarbageIfNotDoneRecently()
{
    if (!m_fullActivityCallback) {
        collectAllGarbage();
        return;
    }

    if (m_fullActivityCallback->didSyncGCRecently()) {
        // A synchronous GC was already requested recently so we merely accelerate next collection.
        reportAbandonedObjectGraph();
        return;
    }

    m_fullActivityCallback->setDidSyncGCRecently();
    collectAllGarbage();
}
Exemple #2
0
void Heap::reportExtraMemoryCostSlowCase(size_t cost)
{
    // Our frequency of garbage collection tries to balance memory use against speed
    // by collecting based on the number of newly created values. However, for values
    // that hold on to a great deal of memory that's not in the form of other JS values,
    // that is not good enough - in some cases a lot of those objects can pile up and
    // use crazy amounts of memory without a GC happening. So we track these extra
    // memory costs. Only unusually large objects are noted, and we only keep track
    // of this extra cost until the next GC. In garbage collected languages, most values
    // are either very short lived temporaries, or have extremely long lifetimes. So
    // if a large value survives one garbage collection, there is not much point to
    // collecting more frequently as long as it stays alive.

    if (m_extraCost > maxExtraCost && m_extraCost > m_objectSpace.highWaterMark() / 2)
        collectAllGarbage();
    m_extraCost += cost;
}
void* Heap::allocate(NewSpace::SizeClass& sizeClass)
{
#if COLLECT_ON_EVERY_ALLOCATION
    collectAllGarbage();
    ASSERT(m_operationInProgress == NoOperation);
#endif

    m_operationInProgress = Allocation;
    void* result = m_newSpace.allocate(sizeClass);
    m_operationInProgress = NoOperation;

    if (result)
        return result;

    if (m_newSpace.waterMark() < m_newSpace.highWaterMark()) {
        m_newSpace.addBlock(sizeClass, allocateBlock(sizeClass.cellSize));
        return allocate(sizeClass);
    }

    collect(DoNotSweep);
    return allocate(sizeClass);
}
void* Heap::allocateSlowCase(size_t bytes)
{
    ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
    ASSERT(JSLock::lockCount() > 0);
    ASSERT(JSLock::currentThreadIsHoldingLock());
    ASSERT(bytes <= MarkedSpace::maxCellSize);
    ASSERT(m_operationInProgress == NoOperation);

#if COLLECT_ON_EVERY_SLOW_ALLOCATION
    collectAllGarbage();
    ASSERT(m_operationInProgress == NoOperation);
#endif

    reset(DoNotSweep);

    m_operationInProgress = Allocation;
    void* result = m_markedSpace.allocate(bytes);
    m_operationInProgress = NoOperation;

    ASSERT(result);
    return result;
}