blob: 08a9f6c737f2f8b8afe3c1087d6b23ccd13953eb [file] [log] [blame]
#include "config.h"
#include "IncrementalSweeper.h"
#include "APIShims.h"
#include "Heap.h"
#include "JSObject.h"
#include "JSString.h"
#include "MarkedBlock.h"
#include "ScopeChain.h"
#include <wtf/HashSet.h>
#include <wtf/WTFThreadData.h>
namespace JSC {
#if USE(CF)
static const CFTimeInterval decade = 60 * 60 * 24 * 365 * 10;
static const CFTimeInterval sweepTimeSlicePerBlock = 0.01;
static const CFTimeInterval sweepTimeMultiplier = 1.0 / sweepTimeSlicePerBlock;
void IncrementalSweeper::timerDidFire(CFRunLoopTimerRef, void* info)
{
Heap* heap = static_cast<Heap*>(info);
APIEntryShim shim(heap->globalData());
heap->sweeper()->doSweep(WTF::monotonicallyIncreasingTime());
}
IncrementalSweeper::IncrementalSweeper(Heap* heap, CFRunLoopRef runLoop)
: m_heap(heap)
, m_currentBlockToSweepIndex(0)
, m_lengthOfLastSweepIncrement(0.0)
{
memset(&m_context, 0, sizeof(CFRunLoopTimerContext));
m_context.info = m_heap;
m_runLoop = runLoop;
m_timer.adoptCF(CFRunLoopTimerCreate(0, CFAbsoluteTimeGetCurrent(), decade, 0, 0, &timerDidFire, &m_context));
CFRunLoopAddTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
}
IncrementalSweeper::~IncrementalSweeper()
{
CFRunLoopRemoveTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
CFRunLoopTimerInvalidate(m_timer.get());
}
PassOwnPtr<IncrementalSweeper> IncrementalSweeper::create(Heap* heap)
{
return adoptPtr(new IncrementalSweeper(heap, CFRunLoopGetCurrent()));
}
void IncrementalSweeper::scheduleTimer()
{
CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() + (m_lengthOfLastSweepIncrement * sweepTimeMultiplier));
}
void IncrementalSweeper::cancelTimer()
{
CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() + decade);
}
void IncrementalSweeper::doSweep(double sweepBeginTime)
{
for (; m_currentBlockToSweepIndex < m_blocksToSweep.size(); m_currentBlockToSweepIndex++) {
MarkedBlock* nextBlock = m_blocksToSweep[m_currentBlockToSweepIndex];
if (!nextBlock->needsSweeping())
continue;
nextBlock->sweep();
m_blocksToSweep[m_currentBlockToSweepIndex++] = 0;
m_lengthOfLastSweepIncrement = WTF::monotonicallyIncreasingTime() - sweepBeginTime;
scheduleTimer();
return;
}
m_blocksToSweep.clear();
cancelTimer();
}
void IncrementalSweeper::startSweeping(const HashSet<MarkedBlock*>& blockSnapshot)
{
WTF::copyToVector(blockSnapshot, m_blocksToSweep);
m_currentBlockToSweepIndex = 0;
scheduleTimer();
}
#else
IncrementalSweeper::IncrementalSweeper()
{
}
IncrementalSweeper::~IncrementalSweeper()
{
}
PassOwnPtr<IncrementalSweeper> IncrementalSweeper::create(Heap*)
{
return adoptPtr(new IncrementalSweeper());
}
void IncrementalSweeper::startSweeping(const HashSet<MarkedBlock*>&)
{
}
#endif
} // namespace JSC